金牌会员
- 积分
- 1118
- 金钱
- 1118
- 注册时间
- 2016-3-25
- 在线时间
- 363 小时
|
本帖最后由 Mr.liu 于 2018-3-18 17:05 编辑
今天在折腾FreeRTOS中实现中断程序里实现置位事件组中的某一位或多位事件标志位。
实验背景:在跑FreeRTOS的板子中,很多都是通过轮询方式获取按键的状态。总觉得这样效率太低,很浪费资源(可能自己有些强迫症吧)。
所以想通过事件组的方式来获取按键信息。平时这个任务一直等待按键按下而进入阻塞状态。直到按键中断中把相应的事件标志位置1,任务才就绪,从而进行相应的逻辑处理,处理完又等待按键事件,周而复始。
实现方法:
1.移植好FreeRTOS(最简单的时拿正点原子提供的例程)
2.配置相应的GPIO为中断输入,映射到相应的Line上,分好组。(具体看正点原子的例程或者视频教程)
3.写按键中断程序。(下面是最终写好的程序)
void EXTI0_IRQHandler(void)
{
//delay_ms(10);//防抖
BaseType_t xHigherPriorityTaskWoken=pdTRUE; //pdFAIL
//ÔÚÕâÀïÌí¼ÓÐźÅÁ¿
xEventGroupSetBitsFromISR(EventGroupHandler, EVENTBIT_1 ,&xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
printf("key1 is pressed\r\n");
EXTI_ClearITPendingBit(EXTI_Line0); //清除中断标志
}
这里需要注意几个问题。
a.这里的延时(防抖)有严格的要求。经测试,延时在MS级,系统就会异常(OS是的嘀嗒时间好像就是1MS,可能与这个有关)。在MS以下不会,我是通过串口查看打印信息发现。但是不延时,每次都会产生两次中断。但是通过测试 ,中断中有操作时,可以不用防抖,操作的时间相当于延时了(谬论哈,我是这样理解的。)
b.关于xEventGroupSetBitsFromISR函数的最后一个参数。配置成pdFAIL,portYIELD_FROM_ISR(xHigherPriorityTaskWoken);也不调用。系统也会异常,同样是通过串口可以看到提示信息。这个参数配置成pdTRUE,而后面调用 portYIELD_FROM_ISR(xHigherPriorityTaskWoken);,这样系统就运行正常了。这里可能是我的任务优先级不是最高吧,不知道设置成最高会是怎样,没试过。
c.关于中断的响应优先级必须比系统最高优先级小,不然也会从串口中看到系统异常。默认操作系统的范围是:
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 15 //中断最低优先级
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 //系统可管理的最高中断优先级
只要中断 优先级在系统可管理的中断优先级范围内(5——15)即可。我这里设置的是6,
//中断配置
NVIC_InitTypeDef NVIC_InitStructure; //¶¨Òå½á¹¹Ìå
NVIC_InitStructure.NVIC_IRQChannel=EXTI0_IRQn; //ʹÄÜÍⲿÖжÏËùÔÚͨµÀ
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06; //ÇÀÕ¼ÓÅÏȼ¶ÉèÖÃ
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x01; //ÏìÓ¦ÓÅÏȼ¶
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //ʹÄÜÍⲿÖжÏͨµÀ
NVIC_Init(&NVIC_InitStructure); //¸ù¾Ý½á¹¹ÌåÐÅÏ¢½øÐÐÓÅÏȼ¶³õʼ»¯
NVIC_InitStructure.NVIC_IRQChannel=EXTI1_IRQn; //ʹÄÜÍⲿÖжÏËùÔÚͨµÀ
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x06; //ÇÀÕ¼ÓÅÏȼ¶ÉèÖÃ
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00; //ÏìÓ¦ÓÅÏȼ¶
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //ʹÄÜÍⲿÖжÏͨµÀ
NVIC_Init(&NVIC_InitStructure); //¸ù¾Ý½á¹¹ÌåÐÅÏ¢½øÐÐÓÅÏȼ¶³õʼ»¯
遇到好多问题,绕了很多弯,这也是自己没有熟悉操作系统,是直接拿来用。表达能力有限,勿喷。
参与 :http://www.mamicode.com/info-detail-1907369.html (FreeRTOS 事件标志组)这里描述更清楚
备注:这样很多事件都可以通过这种方式来提高效率,比如用W5500,就可以用它的nRST来触发事件,通知任务有数据来了,需要进行处理,效率会比轮询方式更高。但也要把数据处理任务的优先级设置的合理,能使任务马上可以进入就绪。
|
|