Forum: Mikrocontroller und Digitale Elektronik Bootloader und Interrupts wollen nicht zusammen


von Heinz (Gast)


Lesenswert?

Hallo Leute,


Ich habe einen Booloader mit dessen Hilfe ich meinen eigentliches 
Programm an einer anderen Adresse starte.
Das ganze wird durch CAN Nachrichten angesteuert.
Falls ich im Bootloader keinen CAN  Interrupt benutze,
also die Funktion
1
#define APPLICATION_ADDRESS   (uint32_t)0x08004000 
2
3
uint32_t JumpAddress;
4
typedef  void (*pFunction)(void);
5
pFunction JumpToApplication;
6
7
8
void startMyApp(void)
9
{
10
    
11
      //__disable_irq();
12
  
13
   /* execute the new program */
14
      JumpAddress = *(__IO uint32_t*) (APPLICATION_ADDRESS + 4);
15
      /* Jump to user application */
16
      JumpToApplication = (pFunction) JumpAddress;
17
      /* Initialize user application's Stack Pointer */
18
      __set_MSP(*(__IO uint32_t*) APPLICATION_ADDRESS);
19
      JumpToApplication();
20
    
21
}
direkt aus der Main aufrufe funktioniert das alles wunderbar.
Sobald ich hingegen über eine ganz bestimmt CAN 
Nachricht(Can-Receive-Interrupt) die obige Funktion aufrufe, dann 
funktioniert im eigentliches Programm die Interrupts nicht mehr.


Viele Grüße, Heinz

von Heinz (Gast)


Lesenswert?

Nachtrag:
Es ist ein stm32f446
Sowohl der bootloader als auch das eigentliche Programm wurden mit HAL, 
cubemx und Keil mdk entwickelt.

von Jim M. (turboj)


Lesenswert?

Heinz schrieb:
> Sobald ich hingegen über eine ganz bestimmt CAN
> Nachricht(Can-Receive-Interrupt) die obige Funktion aufrufe, dann
> funktioniert im eigentliches Programm die Interrupts nicht mehr.

Da müsstest Du auch einen Interrupt Return einbauen oder irgendwie 
anders den Prozessor aus dem Interrupt Mode rausnehmen. Denn währen ein 
Interrupt läuft sind ja alle anderen gleicher oder niedrigerer Priorität 
gesperrt.

Ich hätte das aber einfacher über ein Flag in main() gelöst...

von Heinz (Gast)


Lesenswert?

Wo müsste ich einen Interrupt return einbauen. Was genau ist mit einem 
Interrupt return gemeint?

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Das Problem ist, wie Jim geschrieben hat, dass Du aus einem 
Interrupt-Kontext heraus einfach nur einen Jump ausführst und damit den 
Reset-Handler der Applikation aus diesem Interrupt-Handler heraus 
aufrufst.

Jim schlägt jetzt vor, nicht vom Interrupt-Handler aus die Applikation 
zu starten, sondern aus dem Interrupt-Handler einfach zurück zu kehren 
und aus dem Kontext von main() aus, die Applikation zu starten.

Ich würde ein extra Stück nicht initialisiertes RAM vorsehen, in dem Du 
einen bestimmten Code ablegst, um die Applikation neu zu starten. Dann 
resetest Du den Controller einfach und fragst im Start-Up code dieses 
RAM-Stelle ab, setzt sie zurück und startest dann die Applikation.

So findet die Applikation immer eine komplett initialisierten Controller 
vor, wenn sie startet.

von Bülent C. (mirki)


Lesenswert?

Hallo Heinz,

die Vorredner haben schon alles gesagt. Dennoch möchte ich Dir gerne 
noch ein zwei Punkte mit auf dem Weg geben:
1. Eine Interrupt Handler Funktion sollte so wenig wie möglich machen.
2. Niemals aus einem Interrupt Handler heraus irgendwelche Vektoren 
verschieben und hinspringen, bevor der Handler verlassen wurde.
3. Am besten setzt man innerhalb eines Interrupt Handlers irgendwelche 
Flags ein. Also, wenn Handler aufgerufen, dann flag = irgendwas. Den 
Flag fragst Du woanders ab (z.B. in der main())

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
Noch kein Account? Hier anmelden.