Hallo In meinem C Programm berechne ich die CRC des bootloaders mit einer ASM Routine. Board ist ein 8051(bootloader liegt auf 0x0000). Ich benutze SDCC. Das Programm wird auf Adresse 0x4000 geladen. Es funktioniert mit den Parameter: --code-loc 0x4000 --stack-auto --vc mit den Parameter: --code-loc 0x4000 --model-large --vc stimmt die berechnete CRC nicht mehr (immer 0xFFFF). Ich vermute, daß die Variablen von ASM zu C nicht übertragen werden. Fehlt da vielleicht noch eine Eistellung wegen XRAM. Wer kann helfen? Viele Grüße Peter
:
Verschoben durch User
Peter W. schrieb: > Ich vermute, daß > die Variablen von ASM zu C nicht übertragen werden. Ich würde versuchen, den Fehler weiter einzugrenzen. Was passiert, wenn die asm-Routine eine feste Zuweisung an 'wert' macht? An welche Stellen legt der Linker Stack und XStack? Vielleicht gibt es dort gar keinen RAM?! > Fehlt da vielleicht > noch eine Eistellung wegen XRAM.
1 | --xram-loc <Value> The start location of the external ram, default value is 0. |
Hast Du denn 'external RAM' (XRAM)? Wenn ja, an welcher Adresse? Laut sdccman.pdf wird beim Huge-Modell alles auf 'banking' eingestellt. Kann Deine Hardware das?
Hast mal ùberlegt, wie "mov A,_wert" funktionieren soll, wenn "_wert" im XRAM liegt? Schau dir doch einfach mal den Code an, den der Compiler bei Benutzung von "wert" im "large"-Modell generiert. An XRAM kommt man nur indirekt. Der Vorteil einer Hochsprache ist eben, daß man sich um solche Details nicht kümmern muß und der "Vorteil" von Assembler, das man jede Fehlermöglichkeit ausnutzen kann. Wobei die Toolchain (Assembler/Linker) schon Möglichkeiten hätte, sowas zu erkennen, offenbar aber nicht tut. Eigentlich könnte es solche Fälle auch in den Sourcen der Laufzeitumgebung finden lassen. Da kannst du ja mal schauen, wie die das gelöst haben. Vermutlich gibt es ein Preprozesser-Makro, daß das aktuell benutzte Speichermodell beinhaltet und zukünftig deine "large"-Implementierung statt der schon vorhandenen "small"-Implementierung per #if ... #endif freigibt. Edit: SDCC Doku sagt, diese Makros zeigen das Memorymodell: __SDCC_MODEL_SMALL __SDCC_MODEL_MEDIUM __SDCC_MODEL_LARGE PS: du mußt ja nicht alles austauschen, aber die Zugriffe auf Variablen müssen eben Memory-Modell-spezifisch geschrieben werden.
:
Bearbeitet durch User
@ TIM Bei einem festen 'wert' kommt auch das gleiche falsche Ergebnis. xram 0x0000 - 0x3FFF Was meinst Du mit banking - und ohne dem geht es wohl nicht? Ich habe eine "features.h" im Ordner "SDCC_ASM" entdeckt. Die wollte ich einbinden - funktioniert nicht. ... /* define _RETURN for correct returning from inline asm functions */ #if defined(__SDCC_MODEL_HUGE) #define _RETURN ljmp __sdcc_banked_ret #else #define _RETURN ret #endif ... Könnte hier die Ursache liegen? Übrigens finde ich kein model_huge im SDCC. @ Carl D. Ich dachte das macht alles der compiler für mich...! Muß ich das jetzt selber machen, aber wie? Programm Beispiele zu diesem Thema finde ich leider nicht. Viele Grüße Peter
Peter W. schrieb: > Ich habe eine "features.h" im Ordner "SDCC_ASM" entdeckt. Die wollte ich > einbinden - funktioniert nicht. Das ist keine valide Fehlerbeschreibung. > Übrigens finde ich kein model_huge im SDCC. Welche Version vom SDCC hast Du? Meine Doku ist von der Version 3.4.1. Ob die auch tatsächlich die angegebenen Compilerschalter hat, habe ich nicht geprüft.
Im large Model werden dir deine variablen in den XRam gelegt. Zugriff geht hier dann z.b. über den dptr und movx oder indirekt über Rx und dem Page select im sfr mit movx. Du kannst dir deine variablen im large model auch in den Data ram legen lassen mit dem Attribut __data vor der Deklaration. Schaue ruhig mal in die *.map Datei da kann man einsehen was vom sdcc wo abgelegt wird.
> @ Carl D. > Ich dachte das macht alles der compiler für mich...! Muß ich das jetzt > selber machen, aber wie? > Programm Beispiele zu diesem Thema finde ich leider nicht. Large Memory Model legt nur die Default-Storrage-Class für Daten fest. Um es ganz einfach zu machen könnte man einfach schreiben:
1 | ...
|
2 | //#define CRC_IS_SMALL_MODEL
|
3 | #define CRC_IS_LARGE_MODEL
|
4 | #if defined(CRC_IS_LARGE_MODEL)
|
5 | __xdata unsigned char wert = 0; |
6 | __xdata unsigned crc = 0xFFFF; // Startwert |
7 | #elif defined(CRC_IS_SMALL_MODEL)
|
8 | __data unsigned char wert = 0; |
9 | __data unsigned crc = 0xFFFF; // Startwert |
10 | #endif
|
11 | |
12 | void crc16() { |
13 | // clang-format off
|
14 | unsigned x = crc; |
15 | __asm__( |
16 | #if defined( CRC_IS_LARGE_MODEL )
|
17 | " mov dptr,#_crc \n" |
18 | " movx a,@dptr \n" |
19 | " mov R2,a \n" |
20 | " inc dptr \n" |
21 | " movx a,@dptr \n" |
22 | " mov R3,a \n" |
23 | " mov dptr,#_wert \n" |
24 | " movx a,@dptr \n" |
25 | |
26 | #elif defined( CRC_IS_SMALL_MODEL )
|
27 | " MOV R2,_crc ; \n" |
28 | " MOV R3,_crc+1 ; \n" |
29 | " MOV A, _wert ; \n" |
30 | #endif
|
31 | " XRL A,R3 ; \n" |
32 | " MOV R3,A ; \n" |
33 | " SWAP A ; \n" |
34 | " ANL A,#0x0F ; \n" |
35 | " ; \n" |
36 | " XRL A,R3 ; \n" |
37 | " MOV R3,A ; \n" |
38 | " SWAP A ; \n" |
39 | " RL A ; \n" |
40 | " MOV B,A ; \n" |
41 | " ANL A,#0x1F ; \n" |
42 | " XRL A,R2 ; \n" |
43 | " MOV R2,A ; \n" |
44 | " MOV A,B ; \n" |
45 | " RR A ; \n" |
46 | " ANL A,#0xF0 ; \n" |
47 | " XRL A,R2 ; \n" |
48 | " ANL B,#0xE0 ; \n" |
49 | " ; \n" |
50 | " push A ; \n" |
51 | " mov A,B ; \n" |
52 | " xrl A,R2 ; \n" |
53 | " mov B,A ; \n" |
54 | " pop A ; \n" |
55 | " ; \n" |
56 | #ifdef CRC_IS_LARGE_MODEL
|
57 | " mov dptr,#_crc \n" |
58 | " mov A,R2 \n" |
59 | " movx @dptr,A \n" |
60 | " mov A,R3 \n" |
61 | " inc dptr \n" |
62 | " movx @dptr,A \n" |
63 | #elif defined( CRC_IS_SMALL_MODEL )
|
64 | " MOV _crc+1,A \n" |
65 | " MOV _crc, B \n" |
66 | #endif
|
67 | );
|
68 | // clang-format on
|
69 | }
|
70 | |
71 | int main() { |
72 | unsigned int i = 0; |
73 | unsigned int a = 0; |
74 | |
75 | for (i = 0; i < sizeof(dat); i++) { |
76 | wert = dat[i]; |
77 | crc16(); |
78 | }
|
79 | ...
|
"__data" sorgt dafür, daß die in Inline Assembler genutzten Variablen im direkt adressierbaren RAM liegen. BTW, - neue ASM Syntax, - crc als unsigned int inklusive Zugriff aus Inline Assembker, - "umschaltbares" Speichermodell
Vielen Dank für die Antworten __data, klappt wunderbar @ Florian H. das *.map ist interessant hab ich mir bis jetzt noch nie angeschaut @ Carl D. Du hast Dir ja echt viel Arbeit gemacht - Danke. Werde ich mal ausprobieren. Viele Grüße Peter
Peter W. schrieb: > @ Carl D. > Du hast Dir ja echt viel Arbeit gemacht - Danke. Werde ich mal > ausprobieren. > > Viele Grüße > Peter Naja, erstens wollte ich mal wieder das SDCC-Plugin in Eclipse ausprobieren und zweiten hab ich die CRC-Berechnung nur insoweit überarbeitet, daß ich crc und wert in Registern (die laut Doku SDCC frei verfügbar sind) abgelegt, um Speicherzugriff und Verarbeitung zu trennen. Für den eigentlichen Algorithmus bleiben sämmtliche Rechte und Risiken bei dir ;-) Ich würde aber ehrlich gesagt überlegen, ob das Small-Modell nicht grundsätzlich besser wäre und nur z.B. Puffer mit __xdata verziert werden sollten. Durch die Attribute kann man den Speicherort ja genau festlegen. Wenn ich anschaue, was bei Large an Code produziert werden muß, dann würde ich mich dazu erst durch Speicherengpaß zwingen lassen.
Hab das mal getestet mit mov dptr #_crc ....... funktioniert wunderbar. Ich hatte meinen 8051_board umgebaut, um XRAM nutzen zu können. Das hat bei nur C_Programmen sofort funktioniert. Da hab ich mich schon gewundert, daß das eben mit dem ASM nicht mehr klappt. So wie ich das jetzt sehe, werden beim model_large die lokalen Variablen zum größten Teil als globale im XRAM erzeugt - dazu noch reichlich. Das ist natürlich weniger schön. Small_model ist natürlich besser! Viele Grüße Peter
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.