Forum: Mikrocontroller und Digitale Elektronik STM32F0 Interrupt Priorität nicht konfigurierbar


von Stefan (Gast)


Lesenswert?

Hallo zusammen

Bei meinem F0 lässt sich keine Priorität einstellen, ich habe gelesen, 
dass er nur Preemption und keine subpriority (muss übergeben werde, wird 
aber ignoriert) zulässt. So wie ich verstanden habe kann ich die Prio 
von 1-4 configurieren. Wenn ich im debug Fenster den NVIC aufrufe ist 
die Prio immer 0, egal ob ich 0,1,2,3,4 oder 0u,1u... übergeben habe. 
Bei TIM 15 zeigt er eine 64 an, wenn ich ihm eine 2 durch die Funktion 
HAL_NVIC_SetPriority als Parameter übergebe. Kann mir einer einen Tipp 
geben, was ich falsch mache oder wo ich nachlesen muss?


stm32f0xx_hal_msp:

    if (htim_base->Instance == TIM1)
    {
        /* USER CODE BEGIN TIM1_MspInit 0 */

        /* USER CODE END TIM1_MspInit 0 */
        /* Peripheral clock enable */
        __HAL_RCC_TIM1_CLK_ENABLE();
        /* Peripheral interrupt init */
        HAL_NVIC_SetPriority(TIM1_BRK_UP_TRG_COM_IRQn, 2,0);
        HAL_NVIC_EnableIRQ(TIM1_BRK_UP_TRG_COM_IRQn);
    }

    if (htim_base->Instance == TIM3)
    {
        /* USER CODE BEGIN TIM3_MspInit 0 */

        /* USER CODE END TIM3_MspInit 0 */
        /* Peripheral clock enable */
        __HAL_RCC_TIM3_CLK_ENABLE();
        /* TIM3 interrupt Init */
        HAL_NVIC_SetPriority(TIM3_IRQn, 1, 0);
        HAL_NVIC_EnableIRQ(TIM3_IRQn);
        /* USER CODE BEGIN TIM3_MspInit 1 */

        /* USER CODE END TIM3_MspInit 1 */
    }
}

von Jim M. (turboj)


Lesenswert?

Stefan schrieb:
> ich habe gelesen,
> dass er nur Preemption und keine subpriority (muss übergeben werde, wird
> aber ignoriert) zulässt.

Lies Dir mal bei ARM die Beschreibung des NVIC durch. Die Priority wird 
IIRC linksbündig in die Register geschrieben, d.h. beim Auslesen müsste 
man diesen Shift beachten. Dieser Shift ist vom Hersteller abhängig - 
die Anzahl der Prio Bits ist ein freier Parameter beim Instanziieren des 
Cores.

Das mit den Sub-Priority ist ein weiteres Register im NVIC, ich weiss 
aber grade nicht ob es das im Cortex-M0 überhaupt gibt.

von Stefan (Gast)


Lesenswert?

Jim M. schrieb:
> Das mit den Sub-Priority ist ein weiteres Register im NVIC, ich weiss
> aber grade nicht ob es das im Cortex-M0 überhaupt gibt.

Nein es kann nur PreemptPriority übergeben werden.


So übergebe ich die Prio:

    if (htim_base->Instance == TIM3)
    {
        /* USER CODE BEGIN TIM3_MspInit 0 */

        /* USER CODE END TIM3_MspInit 0 */
        /* Peripheral clock enable */
        __HAL_RCC_TIM3_CLK_ENABLE();
        /* TIM3 interrupt Init */
        HAL_NVIC_SetPriority(TIM3_IRQn, 1, 0);
        HAL_NVIC_EnableIRQ(TIM3_IRQn);
        /* USER CODE BEGIN TIM3_MspInit 1 */

        /* USER CODE END TIM3_MspInit 1 */
    }

dieser Funktion:
void HAL_NVIC_SetPriority(IRQn_Type IRQn, uint32_t PreemptPriority, 
uint32_t SubPriority)
{
  /* Check the parameters */
  assert_param(IS_NVIC_PREEMPTION_PRIORITY(PreemptPriority));
  NVIC_SetPriority(IRQn,PreemptPriority);
}

PreemptPriority ist aber 0, wenn ich in die Funktion hineingehe

Wenn ich direkt in das NVIC Register schreibe Funktioniert es

1 = 64
2 = 128
3 = 192

durch den Parameter 1 müsste ich eigentlich im NVIC Controller 64 als 
prio haben, komm einfach nicht weiter...

von Christopher J. (christopher_j23)


Lesenswert?

Das mit den Subpriorities ist in mindestens 95% der Fälle sowieso 
quatsch. Wie der Name schon sagt kann ein Interrupt mit niedrigerem 
Preempt-Priority-Wert, d.h. höherer Dringlichkeit einen anderen 
Interrupt unterbrechen (preemption). Der Subpriority-Wert hingegen 
spielt nur dann eine Rolle, wenn zwei Interrupts mit gleicher 
Preempt-Priority gleichzeitig anstehen, dann wird nämlich der mit dem 
niedrigeren Sub-Priority-Wert, d.h. mit höherer Dringlichkeit zuerst 
bedient. Ein Beispielszenario wo ein solcher Fall eintreten könnte wäre, 
wenn ein Interrupt mit höherer Dringlichkeit bedient wird und während 
dessen zwei Interrupts mit gleicher Preempt-Priority auftreten. Da die 
Subpriorities aber nicht kostenlos sind, da sie de facto 
Preempt-Priority-Bits "kosten", ist deren Nutzung wie gesagt zumeist 
eher nicht so sinnvoll.
Hier mal eine wirklich sehr gut Lektüre dazu:
https://embeddedgurus.com/state-space/2014/02/cutting-through-the-confusion-with-arm-cortex-m-interrupt-priorities/

Zusammenfassend kann man sagen, dass der Einsatz von STs HAL oder auch 
irgendeiner anderen Hersteller-Library für den NVIC einfach absolut 
keinen Sinn ergibt. Ganz im Gegenteil setzt ST bei den CM3/CM4 das 
Priority-Grouping per default, so dass zwei Prio-Bits völlig sinnlos für 
Subpriorities verschwendet werden. Alle Funktionen die man braucht sind 
bereits in den CMSIS-Core Headern drin und die wären:
1
NVIC_SetPriorityGrouping(0U); // um den Mist von ST rückgängig zu machen
2
void NVIC_SetPriority (IRQn_Type IRQn, uint32_t priority); // um eine Priorität zuzuweisen
3
void NVIC_EnableIRQ (IRQn_Type IRQn); // zum Interrupt einschalten
4
void NVIC_DisableIRQ (IRQn_Type IRQn); // zum Interrupt ausschalten


Stefan schrieb:
> Wenn ich im debug Fenster den NVIC aufrufe ist
> die Prio immer 0, egal ob ich 0,1,2,3,4 oder 0u,1u... übergeben habe.
> Bei TIM 15 zeigt er eine 64 an, wenn ich ihm eine 2 durch die Funktion
> HAL_NVIC_SetPriority als Parameter übergebe

Welches Fenster? Mehr Informationen bitte...

von Stefan (Gast)


Angehängte Dateien:

Lesenswert?

Bei dem Breakpoint in Zeile 339 ist TIM3 bereits initialisiert.

Das NVIC Fenster auf dem Bild in der Mitte meinte ich (weiss leider 
nicht wie es Bezeichnet wird), bei Pfeil Nr2. müsste Prio 64 stehen. Das 
NVIC Register IPR4 PRI_160 (Pfeil Nr.3 ist ebenfalls nicht beschrieben.

von Christopher J. (christopher_j23)


Angehängte Dateien:

Lesenswert?

Stefan schrieb:
> Bei dem Breakpoint in Zeile 339 ist TIM3 bereits initialisiert.

Bist du dir da ganz sicher? 100%? Schonmal den Breakpoint direkt auf die 
betreffende Funktion gesetzt (NVIC_SetPriority(TIM3_IRQn, 1)) und 
geschaut ob sich durch ausführen etwas ändert?

Hab mir das spaßeshalber mal kurz nachgebaut und in den Registern landen 
genau die Werte die dort rein sollen, siehe Bild. Alles andere hätte 
mich auch ehrlich gesagt sehr verwundert.

Stefan schrieb:
> So wie ich verstanden habe kann ich die Prio
> von 1-4 configurieren.

Du meinst wohl eher 0-3 ...

Stefan schrieb:
> Bei TIM 15 zeigt er eine 64 an, wenn ich ihm eine 2 durch die Funktion
> HAL_NVIC_SetPriority als Parameter übergebe.

> Wenn ich direkt in das NVIC Register schreibe Funktioniert es
>
> 1 = 64
> 2 = 128
> 3 = 192
>
> durch den Parameter 1 müsste ich eigentlich im NVIC Controller 64 als
> prio haben, komm einfach nicht weiter...

Da gebe ich dir definitiv recht und das ist auf jeden Fall auch sehr 
merkwürdig... Ich fürchte nur ich kann dir da nicht weiterhelfen.

von Stefan (Gast)


Lesenswert?

Also es funktioniert jetzt.. weiss nicht wirklich was das Problem war 
:(. Wenn ich es rausfinde schreib ich nochmal was dazu, hab mir mal die 
Register via uart ausgeben lassen und da waren die bits richtig gesetzt. 
Ich gehe davon aus, dass es ein debugg Problem ist.

Vielen Dank nochmal

von Vincent H. (vinci)


Lesenswert?

Christopher J. schrieb:
> Zusammenfassend kann man sagen, dass der Einsatz von STs HAL oder auch
> irgendeiner anderen Hersteller-Library für den NVIC einfach absolut
> keinen Sinn ergibt. Ganz im Gegenteil setzt ST bei den CM3/CM4 das
> Priority-Grouping per default, so dass zwei Prio-Bits völlig sinnlos für
> Subpriorities verschwendet werden.

Ich hab grad für F4, F7 und L4 nachgeschaut...
Bei allen wird Priority Group 4 als Default in der "HAL_Init()" gesetzt.
1
#define NVIC_PRIORITYGROUP_4         0x00000003U /*!< 4 bits for pre-emption priority
2
                                                      0 bits for subpriority */

von Christopher J. (christopher_j23)


Lesenswert?

Vincent H. schrieb:
> Ich hab grad für F4, F7 und L4 nachgeschaut...
> Bei allen wird Priority Group 4 als Default in der "HAL_Init()" gesetzt.

Dann haben sie scheinbar dazugelernt, was das angeht. Meine Infos waren 
auch nur die aus dem Blog-Artikel. Es gab vor nicht so langer Zeit hier 
aber schon mal einen ähnlichen Thread bei dem der Code von ST (damals 
SPL) die Sache für den Benutzer unnötig verkompliziert hat:
Beitrag "STM32 Interrupt-Prioritäten - mal wieder"

von Guido Körber (Gast)


Lesenswert?

Stefan schrieb:
> Also es funktioniert jetzt.. weiss nicht wirklich was das Problem war

Das ist eine Erfahrung die ich mit den Libraries von ST auch häufig 
mache, darum in ich dabei die systematisch durch eigenen Code zu 
ersetzen. Nervig ist bei dem Zeug auch, dass ST praktisch alles 
irgendwie mit C lösen will, auch Dinge die in Assembler nur einen 
winzigen Bruchteil des Aufwands benötigen.

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.