Wie kann man den C-Compiler CCS veranlassen, dass er alle Stingkonstanten in den RAM ablegt. Standardmäßig ist es wohl der FLASH, was ggf. zu Zeigerproblemen führt.
Matthias schrieb: > was ggf. zu Zeigerproblemen führt nur, wenn du den falschen Zeigertyp verwendest. Nehme mal an, du verwendest einen PIC18. Da muss man nämlich zwischen Zeigern aufs RAM und Zeigern aufs Flash unterscheiden. Hier mal zwei Beispiele, wie sowas aussehen muss:
1 | // put RAM string to uart
|
2 | void uart_puts_ram(char * ptr) |
3 | {
|
4 | while(*ptr) |
5 | uart_puttxbyte(*ptr++); |
6 | }
|
7 | |
8 | |
9 | // put ROM string to uart
|
10 | void uart_puts_rom(rom far char * ptr) |
11 | {
|
12 | while(*ptr) |
13 | uart_puttxbyte(*ptr++); |
14 | }
|
plop schrieb: > Nehme mal an, du > verwendest einen PIC18. ja Gibt es ein Pragma oder ähnliches, welches veranlasst, dass Stingkonstanten in den RAM abgelegt wird? uart_puts_ram("my_put_constant"); würde im Bsp. ein Problem bedeuten, weil "my_put_constant" im FLASH liegt. Beim GCC/AVR liegt "my_put_constant" standardmäßig im RAM. Bedeutet zwar Platzverschwendung, aber ist im Handling einfacher.
Dann musst du wohl ein Array deklarieren und in der Initialisierungsroutine den ganzen Kram einfach mit memcopy rüberkopieren. Irgendwie müssen die Konstanten ja ins RAM reinkommen. Wenn du Spannung an den MCU anlegst ist der Inhalt des RAM erstmal leer oder undefiniert.
Ach ja: Das Ganze liegt übrigens daran, dass ein "normaler" Pointer beim PIC18 nur 16 Bit groß ist und ein far-Pointer 24 Bit.
Im C18 nutze ich das auf PIC18 ohne Probleme so:
1 | setRomText("Montag"); |
2 | ...
|
3 | |
4 | void setRomText(const rom char *data) |
5 | {
|
6 | while (*data) lcd_out_char(*data++); |
7 | }
|
Holger
kein Holger schrieb: > #device PASS_STRINGS=IN_RAM Hört sich gut an: PASS_STRINGS=IN_RAM A new way to pass constant strings to a function by first copying the string to RAM and then passing a pointer to RAM to the function. Das führ zu Fehlermeldungen: 23 Can not change device type this far into the code (far benutze ich nicht in Code)
Matthias schrieb: > Das führ zu Fehlermeldungen: > 23 Can not change device type this far into the code Schreibs an den Anfang deines Codes, da wird schon mindestens eine weitere #device ... Zeile sein. MfG Klaus
> 23 Can not change device type this far into the code > > (far benutze ich nicht in Code) :-) far hat hier nichts mit dem Code zu tun, so wie in den berühmten far-Pointern. "this far into" ist eine Phrase und bedeutet im wesentlichen "zu diesem Zeitpunkt", "an dieser Stelle", "ein Vorgang ist schon so weit fortgeschritten, dass ..." Der Compiler, der den Code ja von oben nach unten liest, will dir also sagen: An dieser Stelle ist es bereits zu spät. Ich muss die Direktive früher im Code sehen, damit ich sie berücksichtigen kann. Also hoch mit der Preprozessor-Directive. Ich würd mal sagen: Auf jeden Fall vor die erste Funktion.
Karl Heinz Buchegger schrieb: > Also hoch mit der Preprozessor-Directive. Ich würd mal sagen: Auf jeden > Fall vor die erste Funktion. steht schon ganz oben.
Matthias schrieb: > Klaus schrieb: >> da wird schon mindestens eine >> weitere >> >> #device ... > > Leider nicht. Woher weiß denn dann der Compiler, für welchen PIC er kompilieren soll? Übrigens, alle include-Files sind auch Teil deines Codes. MfG Klaus
Ich habe es anders gelöst und auf String-Konstanten ganz verzichtet. Da funktioniert es. Danke nochmal an alle für die Denkanstöße.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.