CPU operating modes auf dem STM32

Gast #3043031
Lesenswert?

Hallo, ich habe derzeit eine Applikation auf dem STM32 am Laufen.
Nun möchte ich wenn ein Interrupt ausgelöst wird, die anderen Interrupt 
sperren und kurz vor dem Verlassen des Interrupts sollen alle Interrupts 
wieder freigegeben werden. Ein RTOS verwende ich nicht.
1
__istate_t get_int_state = __get_interrupt_state();
2

3
__istate_t get_primask = __get_PRIMASK();

Wenn ich diese beiden Codezeilen in meiner Applikation (in der while(1)) 
ausführe, dann erhalte ich immer den Wert 0.
Muss ich womöglich den STM32 in einem anderen Modus bringen ? Wenn ja, 
was müsste ich da genau tun ?
#3043036
Lesenswert?

Komplett falscher Ansatz. Dass Cortex-M Cores bereits über ein voll 
entwickeltes Prioritäts-Management verfügen ist dir entgangen?

Du musst lediglich den exklusiven Interrupts eine höhere Priorität als 
den anderen zuweisen und schon kommt während der Ausführung des Handlers 
kein anderer Interrupt mehr durch.
Gast #3043054
Lesenswert?

Vielen Dank für deinen Beitrag. Ich habe auf meinem System mehrere 
Interrupts: Can, Usart, Ethernet, Systick.

Müsste ich dann für jeden Interrupt in der NVIC_InitStructure die 
Priorität festlegen ?
1
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
Gast #3043103
Lesenswert?

Folgende Prioritäten habe ich vergeben:

Usart:
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1

Can:
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2

Ethernet:
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3

Es ändert sich nichts. get_int_state ist immer 0.
Gast #3044100
Lesenswert?

Guten Morgen,

danke für deinen Post. Wie konnte so ein Prioritätsschema 
sinnvollerweise aussehen ?
Ich habe mir vlgendes überlegt. Dem SysTick würde ich die Priorität 0 in 
der Prioritätsgruppe 0 vergeben.
Die anderen Interrupts würde ich der Prioritätsgruppe 1 zuordnen. Die 
USART bekäme die Priorität 0, CAN die Priorität 1 sowie ETHERNET die 
Priorität 2.

Die Intrinsics Funktionen __get_interrupt_state, __set_interrupt_state, 
__enable_interrupt und __disable_interrupt werden überhaupt nicht mehr 
benötigt ?
#3044107
Lesenswert?

Ja, sie werden im laufenden System typischerweise nicht benötigt.

Bei den Prioritäten drauf achten dass hier - wie auch sonst oft in der 
Branche - die kleinere Zahl der höheren Priorität entspricht. Dem 
Systick als System-Timer maximale Priorität zuzuordnen ist etwas 
ungewöhnlich.
Gast #3044124
Lesenswert?

Der SysTick hat die Priorität 15.
1
static __INLINE uint32_t SysTick_Config(uint32_t ticks)
2
{
3
  if (ticks > SysTick_LOAD_RELOAD_Msk)  return (1);            /* Reload value impossible */
4

5
  SysTick->LOAD  = (ticks & SysTick_LOAD_RELOAD_Msk) - 1;      /* set reload register */
6
  NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1);  /* set Priority for Cortex-M0 System Interrupts */
7
  SysTick->VAL   = 0;                                          /* Load the SysTick Counter Value */
8
  SysTick->CTRL  = SysTick_CTRL_CLKSOURCE_Msk |
9
                   SysTick_CTRL_TICKINT_Msk   |
10
                   SysTick_CTRL_ENABLE_Msk;                    /* Enable SysTick IRQ and SysTick Timer */
11
  return (0);                                                  /* Function successful */
12
}

Das ist aber eine niedrige Priorität. Macht es nicht Sinn die Priorität 
für den SysTick auf 0 zu setzen ?

Würdest du alle Interrupts in eine Gruppe packen ?
Gast #3044156
Lesenswert?

Folgendes Prioritätsschema ist auf meiner Applikation vorhanden:

SysTick -> Priorität=15 Prioritätsgruppe=0
USART2 -> Priorität=0  Prioritätsgruppe=5
CAN1 -> Priorität=0  Prioritätsgruppe=5
Ethernet Link Ext. Interrupt -> Priorität=0 Prioritätsgruppe=5

Diese Werte habe ich mit folgenden Funktionen aushgelesen:

GetPriority = NVIC_GetPriority(InterruptNummer);
GetPriorityGrouping = NVIC_GetPriorityGrouping();

Wenn ich die Prioritäten und die Prioritätsgruppen ändern will, müsste 
ich folgende Funktionen verwenden:
NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
NVIC_SetPriorityGrouping(uint32_t PriorityGroup)

Mir ist noch folgendes unklar. In der Interruptinitialisierung der 
USART2 wird keine Prioritätsgruppe gesetzt. Warum lese ich den Wert 5 
mit der Funktion NVIC_GetPriorityGrouping aus ?
1
/* Enable the USART2 Interrupt */
2
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
3
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
4
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
5
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
6
NVIC_Init(&NVIC_InitStructure);
#3044163
Lesenswert?

leo schrieb:
> SysTick -> Priorität=15 Prioritätsgruppe=0
> USART2 -> Priorität=0  Prioritätsgruppe=5
> CAN1 -> Priorität=0  Prioritätsgruppe=5

Da im CM3 nur 4 Bits für Prio+Gruppe zur Verfügung stehen wird das 
schwierig.

> Würdest du alle Interrupts in eine Gruppe packen ?

Es ergibt Sinn, Interrupts die sich gegenseitig ausschliessen sollen, in 
eine Gruppe zu packen. Andernfalls ergibt das meist wenig Sinn.

> Macht es nicht Sinn die Priorität für den SysTick auf 0 zu setzen ?

Weshalb? Für welche Rolle hast du den Systick vorgesehen?
Gast #3044233
Lesenswert?

Mit den folgenden beiden Funktionen, können die Einstellungen 
vorgenommen werden.
1
  
2
NVIC_SetPriority(USART2_IRQn,1);  // Priorität=1
3
NVIC_SetPriorityGrouping(0);      // Prioritätsgruppe=0

Benötigt man prinzipiell die Funktion NVIC_EncodePriority(0, 1, 0); ?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren