0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

FreeRTOS任務(wù)掛起恢復(fù)與使用中斷遇到的坑

碼農(nóng)愛學(xué)習(xí) ? 來源:碼農(nóng)愛學(xué)習(xí) ? 作者:碼農(nóng)愛學(xué)習(xí) ? 2022-09-26 09:01 ? 次閱讀

任務(wù)掛起簡(jiǎn)單點(diǎn)理解就是現(xiàn)在不需要執(zhí)行這個(gè)任務(wù),讓它先暫停,就是掛起。恢復(fù)就是從剛才掛起的狀態(tài)下繼續(xù)運(yùn)行。

API函數(shù)

任務(wù)掛起vTaskSuspend()

函數(shù)原型(tasks.c中):

void vTaskSuspend( TaskHandle_t xTaskToSuspend )

參數(shù)

xTaskToSuspend:需要掛起的任務(wù)句柄

任務(wù)恢復(fù)vTaskResume()

函數(shù)原型(tasks.c中):

void vTaskResume( TaskHandle_t xTaskToResume )

參數(shù):

xTaskToSuspend:需要恢復(fù)的任務(wù)句柄

中斷函數(shù)中進(jìn)行任務(wù)恢復(fù)xTaskResumeFromISR()

BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )

參數(shù):

xTaskToSuspend:需要掛起的任務(wù)句柄

總結(jié)

這幾個(gè)函數(shù)用起來還是很簡(jiǎn)單的,只需要傳入任務(wù)的句柄即可。

注意,任務(wù)掛起是沒有FromISR版本的,所以在中斷中貌似就不可以使用任務(wù)掛起了。

程序驗(yàn)證

在上個(gè)例程的基礎(chǔ)上,增加一個(gè)按鍵檢測(cè)任務(wù)和外部中斷函數(shù),用來測(cè)試任務(wù)掛起與恢復(fù)。

按鍵任務(wù)

//key任務(wù)函數(shù)
void key_task(void *pvParameters)
{
	u8 key;
	static uint8_t flag=0;
	
	while(1)
	{
		key=KEY_Scan(0);
		switch(key)
		{
			case KEY1_PRES:
				if(!flag)
				{
					vTaskSuspend(Task1Task_Handler);//掛起任務(wù)1
					printf("1 suspendrn");
				}
				else
				{
					vTaskResume(Task1Task_Handler);	//恢復(fù)任務(wù)1
					printf("1 resumern");
				}
				flag=~flag;
				break;
			case K_UP_PRES:
				vTaskSuspend(Task2Task_Handler);//掛起任務(wù)2
				printf("2 suspendrn");
				break;
		}
		vTaskDelay(10);			//延時(shí)10ms 
	}
}

中斷配置與中斷函數(shù)

//==============中斷相關(guān)配置
void EXTIX_Init(void)
{
	NVIC_InitTypeDef   NVIC_InitStructure;
	EXTI_InitTypeDef   EXTI_InitStructure;
	
	//KEY_Init(); //按鍵對(duì)應(yīng)的IO口初始化
 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG時(shí)鐘
 
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);//PE4 連接到中斷線4
	
	/* 配置EXTI_Line4 */
	EXTI_InitStructure.EXTI_Line =  EXTI_Line4;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		//中斷事件
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發(fā)
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;				//中斷線使能
	EXTI_Init(&EXTI_InitStructure);							//配置
 
	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;		//外部中斷4
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;//搶占優(yōu)先級(jí)6
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;	//子優(yōu)先級(jí)0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//使能外部中斷通道
	NVIC_Init(&NVIC_InitStructure);							//配置	   
}

//外部中斷4服務(wù)程序
void EXTI4_IRQHandler(void)
{
	BaseType_t YieldRequired;
	
	//vTaskDelay(10);	//消抖-------//中斷函數(shù)中不可以使用vTaskDelay()?。?!
	if(KEY0==0)	 
	{			
        //vTaskResume(Task2Task_Handler);//這里必須使用FromISR版本的?。?!	
		YieldRequired=xTaskResumeFromISR(Task2Task_Handler);//恢復(fù)任務(wù)2
		printf("2 resumern");
		if(YieldRequired==pdTRUE)
		{
			/*如果函數(shù)xTaskResumeFromISR()返回值為pdTRUE,那么說明要恢復(fù)的這個(gè)
			任務(wù)的任務(wù)優(yōu)先級(jí)等于或者高于正在運(yùn)行的任務(wù)(被中斷打斷的任務(wù)),所以在
			退出中斷的時(shí)候一定要進(jìn)行上下文切換!*/
			portYIELD_FROM_ISR(YieldRequired);
		}
	}		 
	EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中斷標(biāo)志位  
}

整個(gè)主函數(shù)

//*******************************************
//STM32F407+FreeRTOS 任務(wù)掛起與恢復(fù)(結(jié)合中斷)
//File: main.c
//Author: xxpcb(wxgzh:碼農(nóng)愛學(xué)習(xí))
//Version: V1.0
//Date: 2020/06/04
//*******************************************

#include "stm32f4xx.h"
#include "led.h"
#include "key.h"
#include "usart.h"

#include "FreeRTOS.h"
#include "task.h"

//任務(wù)參數(shù)--------------------------
//優(yōu)先級(jí) 堆棧大小 任務(wù)句柄 任務(wù)函數(shù)
#define START_TASK_PRIO		1
#define START_STK_SIZE 		128  
TaskHandle_t StartTask_Handler;
void start_task(void *pvParameters);

#define TASK1_TASK_PRIO		3
#define TASK1_STK_SIZE 		128  
TaskHandle_t Task1Task_Handler;
void task1_task(void *pvParameters);

#define TASK2_TASK_PRIO		4	
#define TASK2_STK_SIZE 		128  
TaskHandle_t Task2Task_Handler;
void task2_task(void *pvParameters);

#define KEY_TASK_PRIO		2	
#define KEY_STK_SIZE 		128  
TaskHandle_t KeyTask_Handler;
void key_task(void *pvParameters);

void EXTIX_Init(void);

int main(void)
{ 	
	//設(shè)置系統(tǒng)中斷優(yōu)先級(jí)分組4(FreeRTOS中的默認(rèn)方式!)
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
	
	//初始化LED端口
	LED_Init();	
	//初始化按鍵
    KEY_Init();	
	//初始化外部中斷
	EXTIX_Init();
	//串口初始化
	uart_init(115200);

	//創(chuàng)建開始任務(wù)
	xTaskCreate((TaskFunction_t )start_task,            //任務(wù)函數(shù)
				(const char*    )"start_task",          //任務(wù)名稱
				(uint16_t       )START_STK_SIZE,        //任務(wù)堆棧大小
				(void*          )NULL,                  //傳遞給任務(wù)函數(shù)的參數(shù)
				(UBaseType_t    )START_TASK_PRIO,       //任務(wù)優(yōu)先級(jí)
				(TaskHandle_t*  )&StartTask_Handler);   //任務(wù)句柄  
	//開啟任務(wù)調(diào)度				
	vTaskStartScheduler();          
}

//開始任務(wù)任務(wù)函數(shù)
void start_task(void *pvParameters)
{
    taskENTER_CRITICAL();           //進(jìn)入臨界區(qū)
	
    //創(chuàng)建TASK1任務(wù)
    xTaskCreate((TaskFunction_t )task1_task,             
                (const char*    )"task1_task",           
                (uint16_t       )TASK1_STK_SIZE,        
                (void*          )NULL,                  
                (UBaseType_t    )TASK1_TASK_PRIO,        
                (TaskHandle_t*  )&Task1Task_Handler);   
    //創(chuàng)建TASK2任務(wù)
    xTaskCreate((TaskFunction_t )task2_task,     
                (const char*    )"task2_task",   
                (uint16_t       )TASK2_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )TASK2_TASK_PRIO,
                (TaskHandle_t*  )&Task2Task_Handler); 
    //創(chuàng)建KEY任務(wù)
    xTaskCreate((TaskFunction_t )key_task,     
                (const char*    )"key_task",   
                (uint16_t       )KEY_STK_SIZE,
                (void*          )NULL,
                (UBaseType_t    )KEY_TASK_PRIO,
                (TaskHandle_t*  )&KeyTask_Handler); 
				
    vTaskDelete(StartTask_Handler); //刪除開始任務(wù)
				
    taskEXIT_CRITICAL();            //退出臨界區(qū)
}

//task1任務(wù)函數(shù)
void task1_task(void *pvParameters)
{
	while(1)
	{
		LEDa_Toggle;
        vTaskDelay(500); //延時(shí)500ms
	}
}

//task2任務(wù)函數(shù)
void task2_task(void *pvParameters)
{
	while(1)
	{
        LEDb_ON;
        vTaskDelay(200); //延時(shí)200ms
		LEDb_OFF;
        vTaskDelay(800); //延時(shí)800ms
	}
}

//key任務(wù)函數(shù)
void key_task(void *pvParameters)
{
	u8 key;
	static uint8_t flag=0;
	
	while(1)
	{
		key=KEY_Scan(0);
		switch(key)
		{
			case KEY1_PRES:
				if(!flag)
				{
					vTaskSuspend(Task1Task_Handler);//掛起任務(wù)1
					printf("1 suspendrn");
				}
				else
				{
					vTaskResume(Task1Task_Handler);	//恢復(fù)任務(wù)1
					printf("1 resumern");
				}
				flag=~flag;
				break;
			case K_UP_PRES:
				vTaskSuspend(Task2Task_Handler);//掛起任務(wù)2
				printf("2 suspendrn");
				break;
		}
		vTaskDelay(10);			//延時(shí)10ms 
	}
}

//==============中斷相關(guān)配置
void EXTIX_Init(void)
{
	NVIC_InitTypeDef   NVIC_InitStructure;
	EXTI_InitTypeDef   EXTI_InitStructure;
	
	//KEY_Init(); //按鍵對(duì)應(yīng)的IO口初始化
 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG時(shí)鐘
 
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource4);//PE4 連接到中斷線4
	
	/* 配置EXTI_Line4 */
	EXTI_InitStructure.EXTI_Line =  EXTI_Line4;
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;		//中斷事件
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿觸發(fā)
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;				//中斷線使能
	EXTI_Init(&EXTI_InitStructure);							//配置
 
	NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;		//外部中斷4
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;//搶占優(yōu)先級(jí)6
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;	//子優(yōu)先級(jí)0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//使能外部中斷通道
	NVIC_Init(&NVIC_InitStructure);							//配置	   
}

//外部中斷4服務(wù)程序
void EXTI4_IRQHandler(void)
{
	BaseType_t YieldRequired;
	
	//vTaskDelay(10);	//消抖-------//中斷函數(shù)中不可以使用vTaskDelay()!??!
	if(KEY0==0)	 
	{			
        //vTaskResume(Task2Task_Handler);//這里必須使用FromISR版本的?。?!	
		YieldRequired=xTaskResumeFromISR(Task2Task_Handler);//恢復(fù)任務(wù)2
		printf("2 resumern");
		if(YieldRequired==pdTRUE)
		{
			/*如果函數(shù)xTaskResumeFromISR()返回值為pdTRUE,那么說明要恢復(fù)的這個(gè)
			任務(wù)的任務(wù)優(yōu)先級(jí)等于或者高于正在運(yùn)行的任務(wù)(被中斷打斷的任務(wù)),所以在
			退出中斷的時(shí)候一定要進(jìn)行上下文切換!*/
			portYIELD_FROM_ISR(YieldRequired);
		}
	}		 
	EXTI_ClearITPendingBit(EXTI_Line4);//清除LINE4上的中斷標(biāo)志位  
}

實(shí)驗(yàn)現(xiàn)象

程序運(yùn)行起來后,兩個(gè)LED任務(wù)按照自己的方式閃爍,按下KEY1,LED任務(wù)1掛起,即LED保持在常亮或常滅狀態(tài),再次按下KEY1,LED任務(wù)1恢復(fù),即LED繼續(xù)閃爍。按下KEY_UP,LED任務(wù)2掛起,再按下KEY0,LED任務(wù)2恢復(fù)。同時(shí)串口也會(huì)打印相關(guān)信息。

注意,中斷程序中沒有使用延時(shí)消抖,所以按下KEY0,從中斷恢復(fù)任務(wù)時(shí),可能會(huì)執(zhí)行多次恢復(fù),(1次掛起)多次恢復(fù)目前是沒有什么影響的。

注意事項(xiàng)(避免程序卡死)?。?!

中斷函數(shù)中不可以使用vTaskDelay()!

實(shí)驗(yàn)中用到了按鍵作為中斷,本想用vTaskDelay(10)進(jìn)行消抖,結(jié)果是程序運(yùn)行起來后,按下中斷的按鍵,程序卡死,通過調(diào)試運(yùn)行,發(fā)現(xiàn)程序死在了這里:

//port.c的429~443行
void vPortEnterCritical( void )
{
	portDISABLE_INTERRUPTS();
	uxCriticalNesting++;

	/* This is not the interrupt safe version of the enter critical function so
	assert() if it is being called from an interrupt context.  Only API
	functions that end in "FromISR" can be used in an interrupt.  Only assert if
	the critical nesting count is 1 to protect against recursive calls if the
	assert function also uses a critical section. */
	if( uxCriticalNesting == 1 )
	{
		configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
	}
}

英文注釋的大致意思是:

這不是進(jìn)入關(guān)鍵函數(shù)的中斷安全版本,所以assert()如果是從中斷上下文中調(diào)用的話。只有以“FromISR”結(jié)尾的API函數(shù)才能在中斷中使用。只有在關(guān)鍵嵌套計(jì)數(shù)為1時(shí)才使用assert,以防止assert函數(shù)也使用關(guān)鍵部分時(shí)出現(xiàn)遞歸調(diào)用。

所以FreeRTOS的API函數(shù)只有帶FromISR后綴的才能在中斷函數(shù)中使用,而vTaskDelay()好像也沒有FromISR版本,所以就不能使用!推而廣之,其它不帶FromISR后綴的API函數(shù)也不能在中斷函數(shù)中使用!

另外,中斷函數(shù)本來就是為了處理緊急情況,在中斷函數(shù)中延時(shí)是不太合理的。

中斷函數(shù)中必須使用帶FromISR后綴的API函數(shù)!

這一條和上一條其實(shí)是一個(gè)意思,實(shí)驗(yàn)中在中斷函數(shù)中對(duì)信號(hào)量進(jìn)行釋放,使用的是xTaskResumeFromISR()函數(shù),如果改成vTaskResume(),實(shí)測(cè)發(fā)現(xiàn)程序同樣會(huì)卡死在這里。

中斷的優(yōu)先級(jí)不能設(shè)置的過高(對(duì)應(yīng)數(shù)字過小)!

按鍵中斷的優(yōu)先級(jí)設(shè)置:

    NVIC_InitStructure.NVIC_IRQChannel = EXTI4_IRQn;		//外部中斷4
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06;//搶占優(yōu)先級(jí)6
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;	//子優(yōu)先級(jí)0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//使能外部中斷通道
	NVIC_Init(&NVIC_InitStructure);							//配置	

第2行的搶占優(yōu)先級(jí)為6是沒有問題的,如果改成3,程序在進(jìn)入按鍵中斷會(huì)卡死在這里(port.c文件的末尾):

#if( configASSERT_DEFINED == 1 )
	void vPortValidateInterruptPriority( void )
	{
	uint32_t ulCurrentInterrupt;
	uint8_t ucCurrentPriority;

		/* 獲取當(dāng)前正在執(zhí)行的中斷的數(shù)量。*/
		ulCurrentInterrupt = vPortGetIPSR();

		/* 中斷號(hào)是用戶定義的中斷嗎?*/
		if( ulCurrentInterrupt >= portFIRST_USER_INTERRUPT_NUMBER )
		{
			/* 查找中斷的優(yōu)先級(jí)。*/
			ucCurrentPriority = pcInterruptPriorityRegisters[ ulCurrentInterrupt ];

			/* 如果一個(gè)被分配了高于configMAX_SYSCALL_INTERRUPT_PRIORITY優(yōu)先級(jí)的中斷的服務(wù)
			例程(ISR)調(diào)用了一個(gè)ISR安全的FreeRTOS API函數(shù),那么下面的斷言將失敗。
			ISR安全FreeRTOS API函數(shù)必須*僅*被分配優(yōu)先級(jí)在
			configMAX_SYSCALL_INTERRUPT_PRIORITY或以下的中斷調(diào)用。

			數(shù)字上較低的中斷優(yōu)先級(jí)數(shù)在邏輯上代表較高的中斷優(yōu)先級(jí),因此中斷的優(yōu)先級(jí)必須設(shè)置為
			等于或數(shù)字上*高于* configMAX_SYSCALL_INTERRUPT_PRIORITY。

			使用FreeRTOS API的中斷不能保留其缺省優(yōu)先級(jí)為零,因?yàn)檫@是可能的最高優(yōu)先級(jí),它保證
			高于configMAX_SYSCALL_INTERRUPT_PRIORITY,因此也保證無效。

			FreeRTOS維護(hù)單獨(dú)的線程和ISR API函數(shù),以確保中斷條目盡可能快速和簡(jiǎn)單。

            以下鏈接提供詳細(xì)資料:
			http://www.freertos.org/RTOS-Cortex-M3-M4.html
			http://www.freertos.org/FAQHelp.html */
			configASSERT( ucCurrentPriority >= ucMaxSysCallPriority );
		}

		/* 優(yōu)先級(jí)分組:中斷控制器(NVIC)允許定義每個(gè)中斷優(yōu)先級(jí)的比特被分割成定義中斷的優(yōu)先級(jí)比特和
		定義中斷的次優(yōu)先級(jí)比特。為簡(jiǎn)單起見,必須將所有位定義為搶占優(yōu)先位。
		如果不是這樣(如果某些位表示次優(yōu)先級(jí)),下面的斷言將失敗。

		如果應(yīng)用程序只使用CMSIS庫(kù)進(jìn)行中斷配置,那么在啟動(dòng)調(diào)度程序之前,通過調(diào)用NVIC_SetPriorityGrouping(0);
		可以在所有Cortex-M設(shè)備上實(shí)現(xiàn)正確的設(shè)置。但是請(qǐng)注意,一些特定于供應(yīng)商的外設(shè)庫(kù)假設(shè)了非零優(yōu)先級(jí)組設(shè)置,
		在這種情況下,使用值為0將導(dǎo)致不可預(yù)測(cè)的行為。 */
		configASSERT( ( portAIRCR_REG & portPRIORITY_GROUP_MASK ) <= ulMaxPRIGROUPValue );
	}

#endif /* configASSERT_DEFINED */

注意里面的幾段:

中斷優(yōu)先級(jí)級(jí)別

如果一個(gè)被分配了高于configMAX_SYSCALL_INTERRUPT_PRIORITY優(yōu)先級(jí)的中斷的服務(wù)例程(ISR)調(diào)用了一個(gè)ISR安全的FreeRTOS API函數(shù),那么下面的斷言將失敗。ISR安全FreeRTOS API函數(shù)必須被分配優(yōu)先級(jí)在configMAX_SYSCALL_INTERRUPT_PRIORITY或以下的中斷調(diào)用。

這句的意思是,如果在中斷函數(shù)中使用了FreeRTOS的API函數(shù),當(dāng)然前提也是使用帶FromISR后綴的,中斷的優(yōu)先級(jí)不能高于宏定義configMAX_SYSCALL_INTERRUPT_PRIORITY,這個(gè)宏定義在FreeRTOSConfig.h中:

/* Cortex-M specific definitions. */
#ifdef __NVIC_PRIO_BITS
	/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
	#define configPRIO_BITS       		__NVIC_PRIO_BITS
#else
	#define configPRIO_BITS       		4        /* 15 priority levels */
#endif

/* 在調(diào)用“設(shè)置優(yōu)先級(jí)”函數(shù)時(shí)可以使用的最低中斷優(yōu)先級(jí) */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY			0xf

/* 可以被任何中斷服務(wù)程序使用的最高中斷優(yōu)先級(jí),它可以調(diào)用來中斷安全的FreeRTOS API函數(shù)。
不要從任何比這個(gè)優(yōu)先級(jí)更高的中斷調(diào)用中斷安全的FREERTOS API函數(shù)!(優(yōu)先級(jí)越高,數(shù)值越低)*/
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY	5

/* 內(nèi)核端口層本身使用的中斷優(yōu)先級(jí)。這些對(duì)所有Cortex-M端口都是通用的,并且不依賴于任何特定的庫(kù)函數(shù)。*/
#define configKERNEL_INTERRUPT_PRIORITY 		( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY 不能設(shè)置為零 !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) )

即中斷優(yōu)先級(jí)設(shè)置范圍為5~15(0xf)。

當(dāng)然,如果中斷函數(shù)中沒有使用FreeRTOS的API,那么中斷的優(yōu)先級(jí)就不受限制。

中斷優(yōu)先級(jí)分組

優(yōu)先級(jí)分組:中斷控制器(NVIC)允許定義每個(gè)中斷優(yōu)先級(jí)的比特被分割成定義中斷的優(yōu)先級(jí)比特和定義中斷的次優(yōu)先級(jí)比特。為簡(jiǎn)單起見,必須將所有位定義為搶占優(yōu)先位。如果不是這樣(如果某些位表示次優(yōu)先級(jí)),下面的斷言將失敗。

如果應(yīng)用程序只使用CMSIS庫(kù)進(jìn)行中斷配置,那么在啟動(dòng)調(diào)度程序之前,通過調(diào)用NVIC_SetPriorityGrouping(0);可以在所有Cortex-M設(shè)備上實(shí)現(xiàn)正確的設(shè)置。但是請(qǐng)注意,一些特定于供應(yīng)商的外設(shè)庫(kù)假設(shè)了非零優(yōu)先級(jí)組設(shè)置,在這種情況下,使用值為0將導(dǎo)致不可預(yù)測(cè)的行為。

這兩段意思是在說優(yōu)先級(jí)分組的事,即所有位都是搶占優(yōu)先級(jí),沒有次優(yōu)先級(jí),即中斷分組模式4,也就是在主函數(shù)設(shè)置的:

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);

如果換成其它的,比如NVIC_PriorityGroup_3,程序進(jìn)入中斷后也會(huì)卡死在。

審核編輯:湯梓紅

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • API
    API
    +關(guān)注

    關(guān)注

    2

    文章

    1500

    瀏覽量

    62011
  • 函數(shù)
    +關(guān)注

    關(guān)注

    3

    文章

    4331

    瀏覽量

    62605
  • FreeRTOS
    +關(guān)注

    關(guān)注

    12

    文章

    484

    瀏覽量

    62172
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    FreeRTOS中的任務(wù)管理

    任務(wù)FreeRTOS 中最基本的調(diào)度單元,它是一段可執(zhí)行的代碼,可以獨(dú)立運(yùn)行。FreeRTOS 中的任務(wù)是基于優(yōu)先級(jí)的搶占式調(diào)度,優(yōu)先級(jí)高的任務(wù)
    的頭像 發(fā)表于 11-27 17:03 ?1008次閱讀

    FreeRTOS里在中斷掛起任務(wù)出錯(cuò)的原因?怎么解決?

    各位大佬,新手剛學(xué)習(xí)FreeRTOS,現(xiàn)在想在中斷掛起某個(gè)任務(wù),我在教程里看到說有中斷中的恢復(fù)
    發(fā)表于 04-16 08:26

    轉(zhuǎn):第10章 FreeRTOS任務(wù)管理

    10.8FreeRTOS任務(wù)刪除10.9FreeRTOS任務(wù)掛起10.10FreeRTOS
    發(fā)表于 08-23 09:54

    freeRTOS操作系統(tǒng)的任務(wù)掛起

    freeRTOS在cntTask任務(wù)中,計(jì)數(shù)到10次之后便不再進(jìn)入該任務(wù)為什么?請(qǐng)led4Task并沒有被掛起,又是為什么?本人剛?cè)腴TfreeRTO
    發(fā)表于 10-18 21:39

    UCOSII的任務(wù)掛起恢復(fù)問題

    遇到一個(gè)問題,我在用ucosII時(shí),我任務(wù)A一直未被掛起,但我有一個(gè)任務(wù)B(優(yōu)先級(jí)比A高,1ms觸發(fā)一次),每執(zhí)行一次任務(wù)B都會(huì)
    發(fā)表于 07-04 04:35

    請(qǐng)問UCOSiii在中斷中是否可以進(jìn)行任務(wù)掛起恢復(fù)?

    UCOSiii的中斷不可以進(jìn)行任務(wù)的創(chuàng)建,我想問在中斷中可不可以進(jìn)行任務(wù)掛起恢復(fù)????
    發(fā)表于 07-16 23:42

    FreeRTOS掛起線程失敗怎么辦

    最近在ST的STA8090上做項(xiàng)目開發(fā),遇到個(gè)比較棘手的問題。希望各位大神能幫忙指點(diǎn)一下。環(huán)境:STA8090芯片+FreeRTOS+SDK固件庫(kù)目的:需要掛起線程我在代碼里加了幾個(gè)下面這樣的
    發(fā)表于 06-11 04:35

    FreeRTOS任務(wù)掛起恢復(fù)的相關(guān)資料推薦

    任務(wù)掛起恢復(fù)要使用著些API則需要使能宏定義:INCLUDE_vTaskSuspend、INCLUDE_xTaskResumeFromISR任務(wù)
    發(fā)表于 12-27 08:06

    uCOS-III任務(wù)掛起恢復(fù)

    任務(wù)掛起恢復(fù)掛起恢復(fù)掛起恢復(fù)任務(wù)
    發(fā)表于 01-20 06:51

    FreeRTOS任務(wù)掛起與刪除的區(qū)別在哪

    當(dāng)一個(gè)任務(wù)暫時(shí)需要停止運(yùn)行,那么就可以將任務(wù)掛起,在需要運(yùn)行的時(shí)候在恢復(fù)就可以了。任務(wù)恢復(fù)運(yùn)行以
    發(fā)表于 01-21 11:02

    對(duì)FreeRTOS任務(wù)的使用

    FreeRTOS學(xué)習(xí)筆記(二):任務(wù)創(chuàng)建/刪除,掛起/解掛上篇文章介紹了任務(wù)相關(guān)的基礎(chǔ)知識(shí),本篇文章對(duì)FreeRTOS
    發(fā)表于 02-18 07:14

    UCOS擴(kuò)展例程-UCOSIII任務(wù)掛起恢復(fù)

    UCOS擴(kuò)展例程-UCOSIII任務(wù)掛起恢復(fù)
    發(fā)表于 12-14 17:24 ?18次下載

    #FreeRTOS學(xué)習(xí)筆記(二):任務(wù)創(chuàng)建/刪除,掛起/解掛

    FreeRTOS學(xué)習(xí)筆記(二):任務(wù)創(chuàng)建/刪除,掛起/解掛上篇文章介紹了任務(wù)相關(guān)的基礎(chǔ)知識(shí),本篇文章對(duì)FreeRTOS
    發(fā)表于 12-23 19:56 ?2次下載
    #<b class='flag-5'>FreeRTOS</b>學(xué)習(xí)筆記(二):<b class='flag-5'>任務(wù)</b>創(chuàng)建/刪除,<b class='flag-5'>掛起</b>/解掛

    FreeRTOS系列第11篇---FreeRTOS任務(wù)控制

    FreeRTOS任務(wù)控制API函數(shù)主要實(shí)現(xiàn)任務(wù)延時(shí)、任務(wù)掛起、解除任務(wù)
    發(fā)表于 01-26 17:54 ?12次下載
    <b class='flag-5'>FreeRTOS</b>系列第11篇---<b class='flag-5'>FreeRTOS</b><b class='flag-5'>任務(wù)</b>控制

    FreeRTOS任務(wù)掛起恢復(fù)

    掛起API函數(shù)(可以在tasks.c中找到)
    的頭像 發(fā)表于 02-10 15:06 ?914次閱讀