Hallo Forum,
ich möchte alle ISR Funktionen beim STM32F05x (M0 Core) im RAM ausführen
lassen. Grund ist der, das bei meiner EEPROM Simulation ab und zu eine
Flash Page gelöscht werden muss, das zu einem Stall der CPU von 20ms bis
60ms bei den Flash zugriffen führt. Das wäre nicht so kritisch, aber
wenn in dieser Zeit eine ISR Anforderung kommt, führt dies zu einem
undefiniertem Crash.
Die beste Lösung ist, alle ISR's ins RAM zu verlegen, anstelle alle ISR
zu dieser Zeit zu deaktivieren.
Die Zusammenhänge sind mir klar.
Der fürs RAM Lauffähige Code muss natürlich erst mal ins Flash und von
dort ins RAM copiert werden.
Ist das Aufgabe des Reset_Handlers, oder von Main?
Die Interrupt Vector Tabelle muss auf die Adressen der ISR's im RAM
verweisen.
Beim M0 muss dann noch in der Main die Interrupt Vector Tabelle ins RAM
copiert werden und der NVIC umconfiguriert werden.
Nur wie bringe ich das dem Compiler und Linker bei?
Als IDE benutze ich CooCox mit dem gcc 4.9 2015q1.
Leider fehlt mir da bisher jede Erfahrung mit Linker Scripts und
sections.
Einige Recherchen habe ich natürlich angestellt und einige Doku's
reingezogen, komme aber immer noch nicht klar.
Wenn man es weiß, ist es sicher einfach.
Im ersten Ansatz reicht es mir, die SysTick_Handler() und
USART1_IRQHandler() Funktions im RAM ausführen zu lassen.
Wenn ich ds richtig interpretiere muss zuerst im Header File die
Funktion einer section zugeordnet werden.
extern void SysTick_Handler(void) _attribute_ ((section ("isr_ram")));
Ist das so richtig und wie geht es weiter?
Grüße Ingo
Ist das ein Cortex M0 oder ein "Cortex M0+"? Ich frage das, weil ein Cortex M0 das VTOR Register zum verlegen der Interrupt Tabelle nicht im Core eingebaut hat. Man müsste dann im Handbuch nachschlagen ob es einen Workaround gibt. Ingo S. schrieb: > Der fürs RAM Lauffähige Code muss natürlich erst mal ins Flash und von > dort ins RAM copiert werden. > Ist das Aufgabe des Reset_Handlers, oder von Main? Das ist die Aufgabe des Startup Code, der normalerweise vom Reset Handler aufgerufen wird. Die Änderungen dort sind abhängig von Compiler, LibC und Toolchain, zu der Du natürlich keine Angaben gemacht hast.
Hi. das ist ein M0, die IDE+Compiler Info hatte ich vergessen und eben anchgetragen (CooCox + gcc 4.9 2015q1). Was und wie man die notwendige Verlegung der Interrupt Tabelle ins RAM macht, ist mir bekannt. Musste das in Verbindung mit einem Bootloader schon mal machen. Den Reset Handler bzw. Startup Code habe ich mir angesehen. Der ist minimal, nur einige Zeilen Assembler, der zum Schluss in main() springt. Grüße Ingo
Wenn man die typischen Adresse 0x0800.0000 für Flash und 0x2000.0000 für RAM nutzt, ist der Rest garnicht so schwer. Anfangs ist der Flash auf Adresse 0 gespiegelt. Dies läßt sich so umschalten, dass der RAM auf Adresse 0 gespiegelt wird. Du musst somit den vorderen Bereich des Rams für deine Pläne reservieren. Als erstes dann mit der Vectortable und den Funktionen initialiseren (da noch ab 0x2000.0000). Dann umschalten. Ansonsten ist nichts zu ändern. die oben genannten Adressen sind weiterhin verfügbar.
1 | // Enable the SYSCFG peripheral clock
|
2 | __SYSCFG_CLK_ENABLE(); |
3 | __SYSCFG_RELEASE_RESET(); |
4 | // Remap SRAM at 0x00000000
|
5 | __HAL_REMAPMEMORY_SRAM(); |
Mit der alten STM-Lib sieht das bei mir so aus:
int main(void)
{
#ifdef BOOLOADER_START
uint32_t *VectorTable = (uint32_t *)0x20000000;
uint32_t i = 0;
for(i = 0; i < 48; i++)
VectorTable[i] = *(__IO uint32_t*)(APPLICATION_ADDRESS + (i<<2));
// Enable the SYSCFG peripheral clock
RCC_APB2PeriphResetCmd(RCC_APB2Periph_SYSCFG, ENABLE);
// Remap SRAM at 0x00000000
SYSCFG_MemoryRemapConfig(SYSCFG_MemoryRemap_SRAM);
#endif
....
In der IDE-Configuration, muss RAM Startadresse und Länge um die 48*4
Bytes angepasst werden.
Gruß Ingo
Inhalt des Linker-Scripts? Evtl. sind darin schon einige Input-Sections
vorgesehen. Ansonsten kann man das Linkerscript etwas anpassen.
Im einfachsten Fall, wenn die VMA Start-Adresse der output-section .data
mit der Adresse übereinstimmt, bei der der die Vector-Tabelle im RAM
beginnen kann (bei den "CMSIS"-Codes war das zumindest so, aktuellen
Stand kenne ich nicht), muss man nur dafür sorgen, dass die
input-section der Vektortabelle im Linker-Script unmittelbar nach der
Definition der Startadresse (Symbol heisst oft sdata oder ähnlich) in
der output-section für .data eingetragen ist. Im einfachsten Fall
einfach die Zeile aus der Definition der output-section .text
verschieben (KEEP("vectors") o.ä). Dahinter dann die Section, die man
für die ISR angelegt hat (oben "isr_ram", aber .data als
input-section-Name tut dafür aber auch, wenn man keine genau Kontrolle
über die Adresse der ISRen im RAM braucht) und dann die "normalen" .data
input-sections, die im Linker-Script schon eingetragen sind.
Den Code zum umkopieren der Vektortabelle und der ISR kann man sich dann
sparen, da mit Startup-Code ohnehin schon die Kopierroutine drin ist,
die initialiserte Daten vom FLASH(ab .data-LMA-Start) ins RAM (ab
.data-VMA-Start) kopiert. Vector-Table und ISRs werden dann dabei
einfach mitkopiert. Im Code sind dann nur doch die erforderlichen
Anweisungen zum remap zu ergänzen.
MAP-File hilft bei Kontrolle, ob alles wie gewünscht angelegt wurde.
Danke für die Hinweise, aber ... Ich sehe gerade das die CoIDE den Linker Sript dynamisch erzeugt. In der Linker Configuration kann man aber ein Scatter File angeben. Ich bin in der Situation, das ein Linker File für mich Neuland ist, und ich noch nicht weiss was ein Scatter File ist. Nur das die CoIDE damit je nach Version, laut Forum, noch Probleme hat. Das heisst im Endeffekt, viel Einarbeitungs Zeit opfern bis man alles im Griff hat. Das passt im Moment nicht, da werde ich mich später mal schlau machen und das Problem im Moment anders lösen. Vielen Dank Gruß Ingo
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.