Hallo Gemeinde, ich habe jetzt ein komplettes Wochenende verbraten und komme nicht weiter. Ich habe ein Nucleo-Board mit einem STM32L476RG. Entwicklung mit EmBitz (Em:Blocks) 0.42. mit arm-none-eabi. Der Controller hat 1M Flash und 96k RAM stack=0x0400 heap=0x0200 Das Prolem: Beim Aufruf einer pobligen Init-Routine geht direkt beim Step in die Funktion der Controller in Hard_Fault! Das ganze sieht so aus: /* initialize CANopen */ int32_t CANbaseAddress = 0; uint8_t nodeId = 1; uint16_t bitRate = 500; err = CO_init(CANbaseAddress, nodeId, bitRate); if(err != CO_ERROR_NO) { Ich bin ARM Cortex Anfänger aber solche Themen konnte ich eigentlich immer selber erschlagen. Den Hard_Fault_Handler habe ich mal bisschen "verbose" gemacht... Über Semi-Hosting spuckt der jetzt folgendes aus: R0 = 0 R1 = 2000057c R2 = 0 R3 = 0 R12 = 0 LR [R14] = 8002375 subroutine call return address PC [R15] = 800a0a0 program counter PSR = 41000000 BFAR = e000ed38 CFSR = 400 HFSR = 40000000 DFSR = a AFSR = 0 SCB_SHCSR = 0 Sieht man jetzt hier warum der Controller strauchelt? Ich bin mir auch nicht ganz sicher, ob vlt. ein Interrupt (1ms Tick) das Problem verursacht. Das Projekt ist mit "CubeMx/HAL" aufgesetzt. Bin für jeden Tipp dankbar
Besorg dir das Manual zum Cortex M4 (bei gurgel)! Dann könntest Du z.B. herausfinden, dass Dein "Verbose"-Code nicht die Inhalte sondern die Adressen der Register ausspuckt (z.B. bei BFAR). Und dann kann man auch einfach nachsehen, was die vielen Bits bedeuten.
danke, ich habe jetzt das hier: http://infocenter.arm.com/help/topic/com.arm.doc.dui0553a/DUI0553A_cortex_m4_dgug.pdf "ergurgelt". Hoffe es gibt keine Core(!)-Unterschiede zwischen M4 und L4 -Series. Grüße Runout
Finde mal heraus, was vor dem Fubktionsaufruf im Stack Pointer steht. Debugge das Programm mal in einzelnen Assembler Befehlen (stepi im GDB, kA wie das in deiner IDE geht) um zu sehen bei welcher Instruktion es hakt. Vielleicht ist's doch gar nicht der Fubktionsaufruf.
Ist bei Dir CANbaseAddress wirklich gleich Null? Klingt für mich nicht richtig und könnte die Ursache des Hardfaults sein. Würde man im Single Step aber IMHO sehen (mit Step into).
danke für die Hinweise. Ich habe das Disassembly-Fenster offen (s. Anhang) und sehe eigentlich genau was passiert. Ob ich die Funktion mit Variablen oder Konstanten aufrufe, spielt auch keine Rolle. "CANbaseAddress" ist nur die Basisadresse eines "CO_t"-Objekts, hat also nix mit der Teilnehmeradresse (noteId) zu tun. Dieses ist in meinem Fall (CANopen-Master) = 1. Aber wie "Karl" schon sagte: Systematisch vorgehen und die Register auswerten. Ich berichte, wenn ich den (Noob)Fehler gefunden habe. Mit'ner neuen Plattform ist es so ähnlich wie mit ner neuen Frau... **duck und wech** Runout
Hast du überprüft, ob für den Hardwareteil auch die Clock und Power konfiguriert sind?
Hi, Bist Du sicher, dass CANbaseAddress nicht die Adresse des CAN-HW-Blocks im STM ist. sieht mir nach einem Blick in CO_Driver.h so aus:
1 | typedef struct{ |
2 | CAN_TypeDef *CANbaseAddress; /* STM32F4xx specific */ |
3 | CO_CANrx_t *rxArray; |
4 | uint16_t rxSize; |
5 | CO_CANtx_t *txArray; |
6 | uint16_t txSize; |
7 | volatile uint8_t useCANrxFilters; |
8 | volatile uint8_t bufferInhibitFlag; |
9 | volatile uint8_t firstCANtxMessage; |
10 | volatile uint16_t CANtxCount; |
11 | uint32_t errOld; |
12 | void *em; |
13 | }CO_CANmodule_t; |
CAN_TypeDef ist im CMSIS beschrieben:
1 | typedef struct |
2 | {
|
3 | __IO uint32_t MCR; |
4 | __IO uint32_t MSR; |
5 | __IO uint32_t TSR; |
6 | __IO uint32_t RF0R; |
7 | __IO uint32_t RF1R; |
8 | __IO uint32_t IER; |
9 | __IO uint32_t ESR; |
10 | __IO uint32_t BTR; |
11 | uint32_t RESERVED0[88]; |
12 | CAN_TxMailBox_TypeDef sTxMailBox[3]; |
13 | CAN_FIFOMailBox_TypeDef sFIFOMailBox[2]; |
14 | uint32_t RESERVED1[12]; |
15 | __IO uint32_t FMR; |
16 | __IO uint32_t FM1R; |
17 | uint32_t RESERVED2; |
18 | __IO uint32_t FS1R; |
19 | uint32_t RESERVED3; |
20 | __IO uint32_t FFA1R; |
21 | uint32_t RESERVED4; |
22 | __IO uint32_t FA1R; |
23 | uint32_t RESERVED5[8]; |
24 | CAN_FilterRegister_TypeDef sFilterRegister[14]; |
25 | } CAN_TypeDef; |
BG, Tom
Du musst die Clocks für die Peripherals "CAN" und "Alternate Peripheral" (ggf. auch den GPIO, wo der CAN gemapped ist) einschalten. RCC->APB2ENR oder so... Ist ein Peri nicht geclockt, so geht der Core zwangsläufig in den HardFault. Nicht vergessen: Beim Alternate Peripheral die entsprechenden Pins auf CAN konfigurieren.
:
Bearbeitet durch User
Danke schon mal für die vielen Antworten. ja, die Funktion "SystemClock_Config()" von CubMx macht alle Initialisierungen. Ich kann auch über die HAL_Funktionen auf dem CAN senden und empfangen. Habe auch mal die "CANbaseAddress" auf "(APB1PERIPH_BASE + 0x6400U)" gesetzt, ohne Erfolg. Ziel der ganzen Übung ist ein STM32M4/L4-HAL!!-Treiber für das CANopenNode-Projekt. Der CANopenNode-Stack darf nirgends auf die Register zugreifen das macht HAL. ABER: CFSR = 00000400 heisst BusFaultStatusRegister = 0x04 = IMPRECISERR Imprecise data bus error 1 = a data bus error has occurred, but the return address in the stack frame is not related to the instruction that caused the error. When the processor sets this bit to 1, it does not write a fault address to the BFAR. This is an asynchronous fault. Therefore, if it is detected when the priority of the current process is higher than the BusFault priority, the BusFault becomes pending and becomes active only when the processor returns from all higher priority processes. If a precise fault occurs before the processor enters the handler for the imprecise BusFault, the handler detects both IMPRECISERR set to 1 and one of the precise fault status bits set to 1. Dort muss ich jetzt weitersuchen. Grüße Runout
Thomas T. schrieb: > Ich habe das Disassembly-Fenster offen (s. Anhang) > und sehe eigentlich genau was passiert. > Ob ich die Funktion mit Variablen oder Konstanten aufrufe, > spielt auch keine Rolle. Mach mal bei der BL Instruktion ein "step into" anstelle eines "Step over". Damit müsstest Du eigentlich rausfinden wo er genau aussteigt. Ist aber vermutlich ein Schreibzugriff auf "CANbaseAddress + X", d.h. auf die CAN Hardware.
Das Problem, bzw die Lösung, also die Antwort auf Deine Frage ist in Zeile 42.
ja, mittlerweile wird's lustig. Ich kann die ganze Funktion "leer" machen und trotzdem knallts... Es gibt aber ein "Auxiliary Control Register". Dort kann man mit "DISDEFWBUF" aus dem asynchronen "Imprecise data bus error" einen präzisen Error erzwingen welcher leichter zu debuggen sein soll ;-) Soweit die Theorie. Hätte nicht gedacht, dass ich soviel "Prozessorleergeld" bezahlen muss ;-) Wenn jemand das Nucleo-Board mit einem STM32L476RG hat, kann ich auch das ganze EmBitz-Projektchen mal hier rein stellen. Gute Nacht Runout
>Wenn jemand das Nucleo-Board mit einem STM32L476RG hat, >kann ich auch das ganze EmBitz-Projektchen mal hier rein stellen. Darum bat man DICH bereits. Nicht mitbekommen?
Nein, nicht mitbekommen. Hier das Projekt. Kompiliert/Linked ohne Fehler/Warnungen durch. Die (wichtigsten) EmBitz-Stettings stehen im root. Wenn ein williges Opfer noch eine HAL-basierende EEPROM-Emulation aus der Schublade ziehen, könnte wäre das... Die aktuellen ST-Appnotes wurden alle unter Verwendung von CMSIS oder StdPeriphLibs erstellt. Grüße Runout
sou, Problem NICHT gelöst, aber Ursache klar... im ACTLR den WriteBuffer ausgeschaltet: *((volatile unsigned long *)(0xE000E008)) |= SCnSCB_ACTLR_DISDEFWBUF_Msk; und siehe da: Das Programm ist "out-of-memory" (SRAM) die 98k RAM gehen von 20000000 - 20017FFF. Ein Zugriff auf 20018012 langt ins Datennirvana. Der STM32L476RG hat nun mal "nur" 1MB-Flash + 98k SRAM. Habt ihr eine Empfehlung, was ein etwas fetterer STM32F4/L4 wäre? Grüße Runout
:
Bearbeitet durch User
Thomas T. schrieb: > Habt ihr eine Empfehlung, was ein etwas fetterer STM32F4/L4 wäre? Du benutzt doch schon STM32CubeMX. Erstelle ein neues Projekt und wähle einen Controller/ ein Board nach deinen Wünschen.
Setzen bei uns den STM32-F417 ein. Der hat "up to 1MB Flash/192+4KB RAM". Wenn das nicht reicht brauchst du eh ne andere Maschine ;-)
Thomas T. schrieb: > Der STM32L476RG hat nun mal "nur" 1MB-Flash + 98k SRAM. > > Habt ihr eine Empfehlung, was ein etwas fetterer STM32F4/L4 wäre? 98kB ist doch schon riesig. Guck doch einfach mal ins map-File, wo dieser riesige RAM versickert. Ist eben kein Windosw-PC wo man für jedes Array erstmal 1MB reserviert.
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.