mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Warnung bei Benutzung von "strncmp_PF"?


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: AVRli (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
...
const char pgm_cmd_run[] PROGMEM = "run";
...

//--- run ------------------------------------------------------
if (!strncmp_PF(buf_uart_read, (uint_farptr_t)(pgm_cmd_run), 3)) {
     ...
     ...am liebsten Kaffee trinken...
     ...
}

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...

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hilft es pgm_cmd_run mit PROGMEM_FAR zu attributieren?

Autor: Harry L. (mysth)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Irre ich mich, oder muß das nicht so aussehen?
if (!strncmp_PF(buf_uart_read, (uint_farptr_t)(&pgm_cmd_run), 3)) {

Autor: Stefan E. (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

if (!strncmp_PF(buf_uart_read,  pgm_get_far_address(pgm_cmd_run), 3)) {

: Bearbeitet durch User
Autor: AVRli .. (avrli)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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...

Autor: AVRli .. (avrli)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für alle die genauso gesucht haben...

uint_farptr_t

ist als Pointer Variable festgelegt...

Grüße AVRli...

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
...
SECTIONS
{
  ...
  /* Internal text space or external memory.  */
  .text   :
  {
    *(.vectors)
    KEEP(*(.vectors))
    /* For data that needs to reside in the lower 64k of progmem.  */
     *(.progmem.gcc*)
    /* PR 13812: Placing the trampolines here gives a better chance
       that they will be in range of the code that uses them.  */
    . = ALIGN(2);
     __trampolines_start = . ;
    /* The jump trampolines for the 16-bit limited relocs will reside here.  */
    *(.trampolines)
     *(.trampolines*)
     __trampolines_end = . ;
    /* avr-libc expects these data to reside in lower 64K. */
     *libprintf_flt.a:*(.progmem.data)
     *libc.a:*(.progmem.data)
     *(.progmem.*)

    ...

    *(.text)

    ...

     *(.progmemx.*)

    ...

    /* For tablejump instruction arrays.  We don't relax
       JMP / CALL instructions within these sections.  */
    *(.jumptables)
     *(.jumptables*)
     _etext = . ;
  }  > text

  ...
}

__memx liefert 24-Bit Adressen

Beispiel:
// $ avr-gcc-7 -mmcu=avr6 -Os -save-temps -fverbose-asm ...

#include <avr/pgmspace.h>

const __memx char str_run[] = "run";

int testrun1 (void)
{
    return strncmp_PF ("text1", (__uint24) &str_run, 3);
}

int testrun2 (void)
{
    return strncmp_PF ("text1", pgm_get_far_address (str_run), 3);
}
testrun1:
 ;  main.c:7:     return strncmp_PF ("text1", (__uint24) &str_run, 3);
  ldi r24,lo8(str_run)   ;  tmp45,
  ldi r25,hi8(str_run)
  ldi r26,hlo8(str_run)
  ldi r18,lo8(3)
  ldi r19,0
  movw r20,r24   ; , tmp45
  mov r22,r26
  ldi r23,0
  ldi r24,lo8(.LC0)
  ldi r25,hi8(.LC0)
  jmp strncmp_PF


testrun2:
 ;  main.c:12:     return strncmp_PF ("text1", pgm_get_far_address (str_run), 3);
/* #APP */
  ldi  r20, lo8(str_run)   ;  tmp,
  ldi  r21, hi8(str_run)   ;  tmp,
  ldi  r22, hh8(str_run)   ;  tmp,
  clr  r23   ;  tmp
 ;  main.c:12:     return strncmp_PF ("text1", pgm_get_far_address (str_run), 3);
/* #NOAPP */
  ldi r18,lo8(3)
  ldi r19,0
  ldi r24,lo8(.LC0)
  ldi r25,hi8(.LC0)
  jmp strncmp_PF

.section  .rodata.str1.1,"aMS",@progbits,1
.LC0:
  .string  "text1"

Autor: Stefan E. (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Johann L. (gjlayde) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.