Hallo,
ich nutze den PROGMEM zur Ablage von Zeichenketten, welche über den UART
verarbeitet werden. Das nun im oberen Bereich eines ATmega 2560.
Die normalen Routinen wie strncmp_P funktionieren dort ja nicht mehr
wegen der 64k Beschränkung. Nun bekomme ich aber Warnungen das die Typen
nicht zusammenpassen.
1
...
2
constcharpgm_cmd_run[]PROGMEM="run";
3
...
4
5
//--- run ------------------------------------------------------
Erzeugt bei mir die Warnung:
Warning: cast from pointer to integer of different size
[-Wpointer-to-int-cast]
Ich könnte die Warnungen an dieser Stelle vlt. ignorieren aber ich lebe
ruhiger wenn erst gar keine kommen. Deshalb die Frage was genau wird
beanstandet und wie schafft man da Abhilfe?
Grüße AVRli...
AVRli schrieb:> Ich könnte die Warnungen an dieser Stelle vlt. ignorieren
Nein, kannst du nicht, denn es wird so auch nicht funktionieren, wenn
pgm_cmd_run jenseits der 64k liegt.
Stefan E. schrieb:> Nein, kannst du nicht, denn es wird so auch nicht funktionieren, wenn> pgm_cmd_run jenseits der 64k liegt.
Das wird der Fall sein, also das pgm_cmd_run eben noch nicht außerhalb
der 64k liegt. :-( Dann hätte es irgenwann geknallt und man wundert sich
warum. Also vielen Dank für!
> if (!strncmp_PF(buf_uart_read, pgm_get_far_address(pgm_cmd_run), 3)) {
Denn das funktioniert und es kommen auch keine WARNUNGEN mehr. :-)
Gibt es da auch einen Typen wie PGM_P ?
Wie übergibt man denn nun die ermittelte far_address an eine eigene
Funktion?
An die Anderen auch ein Dankeschön, PGM_FAR wird hier nicht erkannt und
das & davor hat nichts geändert.
Grüße AVRli...
AVRli .. schrieb:> Stefan E. schrieb:>> Nein, kannst du nicht, denn es wird so auch nicht funktionieren, wenn>> pgm_cmd_run jenseits der 64k liegt.>> Das wird der Fall sein, also das pgm_cmd_run eben noch nicht außerhalb> der 64k liegt. :-( Dann hätte es irgenwann geknallt und man wundert sich> warum. Also vielen Dank für!>>> if (!strncmp_PF(buf_uart_read, pgm_get_far_address(pgm_cmd_run), 3)) {>> Denn das funktioniert und es kommen auch keine WARNUNGEN mehr. :-)
Das Problem ist nur: Wenn Du pgm_cmd_run definierst als
AVRli schrieb:> const char pgm_cmd_run[] PROGMEM = "run";
Dann liegt das Objekt in den unteren 64KiB, und das ganze far Zeug
macht's nur aufwendiger, weil ein einfaches strncmp_P (...,
&pgm_cmd_run) genügen würde.
Neuere Versionen der Toolchain unterstützen __memx und lokatieren dies
nach .progmemx.data, das an einer höheren Flash-Adresse lokatiert wird
um nicht untere 64KiB zu verschwenden. Hier zB ein Auszug aus dem
default ld-Script für avr6:
1
...
2
SECTIONS
3
{
4
...
5
/* Internal text space or external memory. */
6
.text :
7
{
8
*(.vectors)
9
KEEP(*(.vectors))
10
/* For data that needs to reside in the lower 64k of progmem. */
11
*(.progmem.gcc*)
12
/* PR 13812: Placing the trampolines here gives a better chance
13
that they will be in range of the code that uses them. */
14
. = ALIGN(2);
15
__trampolines_start = . ;
16
/* The jump trampolines for the 16-bit limited relocs will reside here. */
17
*(.trampolines)
18
*(.trampolines*)
19
__trampolines_end = . ;
20
/* avr-libc expects these data to reside in lower 64K. */
21
*libprintf_flt.a:*(.progmem.data)
22
*libc.a:*(.progmem.data)
23
*(.progmem.*)
24
25
...
26
27
*(.text)
28
29
...
30
31
*(.progmemx.*)
32
33
...
34
35
/* For tablejump instruction arrays. We don't relax
Johann L. schrieb:> Das Problem ist nur: Wenn Du pgm_cmd_run definierst als>> AVRli schrieb:>> const char pgm_cmd_run[] PROGMEM = "run";>> Dann liegt das Objekt in den unteren 64KiB,
Aber nicht garantiert immer. Nämlich dann nicht, wenn
A) man so viel PROGMEN-Zeug anhäuft, dass es über die 64Ki hinaus
wächst,
oder
B) man einen Bootloader schreibt.
Ich hatte sein
> Das nun im oberen Bereich eines ATmega 2560.
so interpretiert, dass eines von beiden bei ihm zutrifft.
Ich hoffe mal, er ist nicht in dem Irrglauben, dass er die far-Varianten
auch dann braucht, wenn zwar nicht die Daten, aber der zugreifende Code
jenseits der 64Ki liegt.
Stefan E. schrieb:> Johann L. schrieb:>> Das Problem ist nur: Wenn Du pgm_cmd_run definierst als>>>> AVRli schrieb:>>> const char pgm_cmd_run[] PROGMEM = "run";>>>> Dann liegt das Objekt in den unteren 64KiB,>> Aber nicht garantiert immer. Nämlich dann nicht, wenn> A) man so viel PROGMEN-Zeug anhäuft, dass es über die 64Ki hinaus> wächst,
Selbst dann kann es in den unteren 64k liegen, aber andere Objekte dann
(teilweise) nicht mehr. Um Kontrolle darüber zu haben, welche Objekte
wo liegen, reicht ein PROGMEM hier nicht aus. Entweder muss man dann
entsprechende Objekte im ld-Skript händisch lokatieren, oder man nutzt
eben bereits vorhandene Sections wie .progmemx.data, evtl. auch via
section-Attribut.
Und schließlich gibt's noch die expliziten Flash-Seiten wie __flash1 bis
(bei ATmega256x) __flash3. Hier braucht's dann aber ein eigenes
ld-Script, dass .text und .progmem1.data etc. anordnet wie gewünscht.
Unterstützung im default ld-Script gibt's dafür nicht, weil es keine
kanonisches Lokatierung gibt.