Interrupt Priority sorunu

Başlatan engineer, 31 Ekim 2014, 12:05:54

engineer

Merhaba, üç tane harici kesmem var bunlardan ikisi EXTI15_10_IRQHandler ile diğeri ise EXTI9_5_IRQHandler ile kontrol ediliyor. Yapmak istediğim şey EXTI15_10 kesmesini yüksek öncelikli yapmak. Bu interrupt handler'a bağlı her iki kesmede diğer interrupt handler 'daki kesmeden yüksek öncelikli olmalı. Örneğin EXTI9_5 kesmesi gerçekleşti, interrupt handler çalışırken EXTI15_10 kesmesi meydana geldi, işlemi bırakıp EXTI15_10 a gitsin istiyorum. Bu durumun tam tersi gerçekleşiyor şuanda, EXTI9_5 diğerinden daha yüksek öncelikli. Ne yaptıysam çözemedim bu sorunu.

NVIC_EnableIRQ(EXTI15_10_IRQn);
NVIC_SetPriority(EXTI15_10_IRQn, 0x0);


dedim olmadı, stdperiph içindeki nvic fonksiyonu ile yazayım o kısmı dedim, şöyle yaptım yine olmadı
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
	
NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&NVIC_InitStructure);


GroupPriority fonksiyonunuda denedim beceremedim bi türlü :(

CLR

@engineer

NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; yaptıysan interrupt'a girmez ki öncelik olsun. İnterrupt'a giriyorsa başka yerde başka tanımlamaların var demektir. Ama öncelik tanımlamaların doğru.
Knowledge and Experience are Power

engineer

Yukarda yazdığım fonksiyonu çok kurcaladım, denemediğim yöntem kalmadı arada disable edip programın başka bir bölümünde enable yapıp öyle denemiştim oda yemedi en son o kalmış yukarda, yoksa elbette girmez interrupta. Zaten o disable olan kanalın önceliği düşük olsun istiyorum, bu şekilde yapmama rağmen diğerinin önüne geçti yine.

kimlenbu

Öncelikli olmasını istediğiniz kesmenin "PreemptionPriority" değerini 0, diğerinin değerini 1 yapın. Bu da mı çalışmadı ?

engineer

aynen oda çalışmamıştı, bu kod üzerindeki bütün varyasyonları denedim başka biryerde hata yapıyorum sanırım delircem

kimlenbu

#5
Kodun tamamı yok, varsayımların da sonu yok. Kesme pinlerine ait GPIO init, NVIC init, kesme fonksiyonlarını da koyarsan daha iyi yorumlar yapılabilir.

Eğer kodun tamamı senin değilse bir yerlerde kesmeleri aktif/deaktif eden bir yapı olabilir mi ? Clockları unutuyor olabilir misin ?

Kendi kullandığım kodu yazıyorum belki gözüne çarpan bir şey olur :

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
  SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOC, EXTI_PinSource1); //A Girisi PC1 pininde
  EXTI_InitStructure.EXTI_Line = EXTI_Line1; //Kesme 1. Yola Tamimlandi. Kesme fonksiyonu stm32f4xx_it.c dosyasi icinde
  EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; //EXTI_Trigger_Rising_Falling;  
  EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  EXTI_Init(&EXTI_InitStructure);
  NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x0F;
  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  NVIC_Init(&NVIC_InitStructure);

engineer

#6
Kodun tamamını ben yazdım ancak 1500 küsur satıra vardığından artık takip edemez oldum.
Kodu yazarken standart kütüphaneyi kullanmadım, sadece interrupt priority işini beceremeyince nvic ile alakalı kütüphanesini kullanıp denedim.

__INLINE void SysInit(void)
{
/******************************************************************************/
/*                         GPIOA Initialization                               */
/******************************************************************************/
	/* GPIOA Portu Alternate Function Enable */
	RCC->APB2ENR = (uint32_t)(RCC_APB2ENR_IOPAEN | RCC_APB2ENR_AFIOEN);
	
	/* CRL Clear */
	GPIOA->CRL &= (uint32_t)~(GPIO_CRL_MODE | GPIO_CRL_CNF);
	
	/**
	  ******************************************************************************
	  * GPIOA1..4 (DIP Switch) ve GPIOA5 (Group-In) Input & Pull-Up
	  * GPIOA6 (Group-Out) Output & Push-Pull
	  * GPIOA7 (PIR Sensor) Input & Pull-Up
	  ******************************************************************************
	  */
	GPIOA->CRL = (uint32_t)(GPIO_CRL_CNF1_1 | GPIO_CRL_CNF2_1 | GPIO_CRL_CNF3_1 | GPIO_CRL_CNF4_1 |
												 GPIO_CRL_CNF5_1 | GPIO_CRL_CNF7_1 | GPIO_CRL_MODE6);
	
	GPIOA->ODR = (uint32_t)(GPIO_ODR_ODR1 | GPIO_ODR_ODR2 | GPIO_ODR_ODR3 |
	                        GPIO_ODR_ODR4 | GPIO_ODR_ODR5 | GPIO_ODR_ODR7);


/******************************************************************************/
/*                         GPIOB Initialization                               */
/******************************************************************************/
	/* GPIOB Portu Alternate Function Enable */
	RCC->APB2ENR |= (uint32_t)(RCC_APB2ENR_IOPBEN | RCC_APB2ENR_AFIOEN);
	
	/* CRH Clear */
	GPIOB->CRH &= (uint32_t)~(GPIO_CRH_MODE | GPIO_CRH_CNF);
	
	/* CRL Clear */
	GPIOB->CRL &= (uint32_t)~(GPIO_CRL_MODE | GPIO_CRH_CNF);
	
		
	/**
	  ******************************************************************************
		* Button 1 & Button 2 Settings
	  * GPIOB10 (Button1) & GPIOB11 (Button2) Input
		* ----------------------------------------------------------------------------
	  * PWM Ports Settings
		* GPIOB0 LED (PWM) Output & Alternate Function & Push-Pull 
	  * GPIOB13 (PWM1) & GPIO14 (PWM2) Ports Output & Alternate Function & Push-Pull
	  ******************************************************************************
	  */
	
	/* GPIOB0 (LED)(PWM) Output & Alternate Function & Push-Pull */
	GPIOB->CRL = (uint32_t)(GPIO_CRL_MODE | GPIO_CRL_CNF0_1);
	
	GPIOB->CRH = (uint32_t)(GPIO_CRH_CNF10_1 | GPIO_CRH_CNF11_1 | GPIO_CRH_CNF13_1 | 
													GPIO_CRH_MODE13 | GPIO_CRH_CNF14_1 | GPIO_CRH_MODE14);
	
	/* GPIOB10 & GPIOB11 Pull-Up */
	GPIOB->ODR = (uint32_t)(GPIO_ODR_ODR10 | GPIO_ODR_ODR11);


/******************************************************************************/
/*          GPIOA7, GPIOB10, GPIOB11 Interrupt Initialization                 */
/******************************************************************************/
	/* Alternate Function External Int. Conf. GPIOA7 (PIR Sensor) */
	//	AFIO->EXTICR[1] = (uint16_t)(AFIO_EXTICR2_EXTI7_PA);
	/* GPIOA7 (PIR Sensor) Interrupt Pins Masked */

	/* Alternate Function External Int. Conf. GPIOB10 (Button1) & GPIOB11 (Button 2) */
	AFIO->EXTICR[2] = (uint16_t)(AFIO_EXTICR3_EXTI10_PB | AFIO_EXTICR3_EXTI11_PB);
	
	/* GPIOA7 (PIR Sensor), GPIOB10 & GPIOB11 Interrupt Pins Masked */
	EXTI->IMR = (uint32_t)(EXTI_IMR_MR7 | EXTI_IMR_MR10 | EXTI_IMR_MR11);
		
	/* Sensor & Button Inputs Trigger: Falling */
	EXTI->FTSR = (uint32_t)(EXTI_FTSR_TR7 | EXTI_FTSR_TR10 | EXTI_FTSR_TR11);
	
	
	NVIC->ISER[0] |= (uint32_t)NVIC_ISER_SETENA_23;
        NVIC_SetPriority(EXTI9_5_IRQn, 0x3);
	
	/* GPIOB10 & GPIOB11 Interrupt Enable */
        NVIC->ISER[1] = (uint32_t)NVIC_ISER_SETENA_8;
	NVIC_SetPriority(EXTI15_10_IRQn, 0x0);
	
   .
   .
   .
}

CLR

Alıntı yapılan: engineer - 31 Ekim 2014, 18:04:08
Kodun tamamını ben yazdım ancak 1500 küsur satıra vardığından artık takip edemez oldum.
Kodu yazarken standart kütüphaneyi kullanmadım, sadece interrupt priority işini beceremeyince nvic ile alakalı kütüphanesini kullanıp denedim.

NVIC->ISER[0] |= (uint32_t)NVIC_ISER_SETENA_23;
        NVIC_SetPriority(EXTI9_5_IRQn, 0x3);
	
	/* GPIOB10 & GPIOB11 Interrupt Enable */
        NVIC->ISER[1] = (uint32_t)NVIC_ISER_SETENA_8;
	NVIC_SetPriority(EXTI15_10_IRQn, 0x0);
	
}


Merhaba,

EXTI9_5'in setena kanalı doğru ama Exti10_15'in değil (setena 8 değil 40 olacak), 2008'de ST'nin kütüphanesi yerine kendi kütüphanemi yazarak 2 büyük proje tamamlamıştım, Cortex m3 pdf yerine oradan baktım,

Ayarlar aşağıdaki gibi olması gerekiyor. Ben doğrudan priority'de değiştiriyordum.

Register isimleri açık olduğu için açıklama yapmaya gerek yok, registerlerle program yazdığın için anlayabilirsin

#define		exti9_5_int_set(pri)	        nvic_ipr5.bits.PRI_23=pri; nvic_iser0.bits.SETENA23=1;

#define		exti15_10_int_set(pri)	nvic_ipr10.bits.PRI_40=pri; nvic_iser1.bits.SETENA40=1;
 
Knowledge and Experience are Power

Gökhan BEKEN

2 adet kesme var ve "A" kesmesi "B" kesmesine göre daha öncelikli diyelim.
B kesmesine girmişken, A kesmesi gelirse, A kesmesinin fonksiyonunu gerçekleştirdikten sonra B'kesmesinde kaldığı yere mi gider yoksa, A kesmesini unutup ana fonksiyona mı döner?
Özel mesaj okumuyorum, lütfen göndermeyin.

CLR

A kesmesinin fonksiyonunu gerçekleştirdikten sonra B'kesmesinde kaldığı yere
Knowledge and Experience are Power

engineer

@CLR

İlgilendiğiniz için teşekkürler, ancak NVIC yapısındaki ISER 'in herbir elemanı 32 bitlik dolayısıyla 32 pozisyon belirtebiliyor. (0-31 arası)
Dediğiniz gibi EXTI_15_10 interruptının pozisyonu 40 ancak bunu 32 + 8 şeklinde ifade etmeniz gerekiyor dolayısıyla ISER register'ının bir sonraki elemanının
8. biti EXTI_15_10 u ifade ediyor. Bu satır doğru olmasaydı interrupt hiç aktif olmazdı zaten, bütün interruptlar çalışıyor sorun priorityde :(

CLR

tamam, haklısın, struct'ları ben yazdığım için register bit isimlerine sadık kalmışım, doğrudan ipr5 ve  ipr10'a yaz, priority sadece 4 bitle ifade edilebiliyor, düşük olan öncelikli, 16 tane priority tanımlanabilir. Sonra doğru yazılmış mı oku, olmuyorsa gerçekten ilginç bir durum olur.
Knowledge and Experience are Power