前言
前面的章节多数的API使用都讲到中断专用和任务专用是分开的,为什么FreeRTOS会设计两套api函数呢?他们又有那些区别?
中断和任务的API区别
在任务中因为我们是多线程设计的模式可以允许任务阻塞等待,但是在中断中我们希望越快处理越好,我们可以来看看两套API函数的原形都有那些区别;
xQueueSend( xQueue, pvItemToQueue, xTicksToWait )
xQueueSendFromISR( xQueue, pvItemToQueue, pxHigherPriorityTaskWoken )
如果查看其他的API使用函数我们可以发现在中断使用的API只是在任务API的末尾添加了FromISR,参数从xTicksToWait等待时间换成了pxHigherPriorityTaskWoken;
任务等待时间我们已经很清楚了我们只需要了解pxHigherPriorityTaskWoken参数,pxHigherPriorityTaskWoken就是用来保存函数的结果:是否需要切换任务
pdTRUE:函数的操作导致更高优先级的任务就绪了,ISR应该进行任务切换
pdFALSE:没有进行任务切换的必要
为什么需要任务切换?
当我们中断频繁触发的时候就会造成我们的任务频繁切换,这样会浪费较多的资源效率较慢,所以可以使用xHigherPriorityTaskWoken避免不必要的任务切换提高效率,简单来说就是将任务切换变为可控提高效率;
如何进行任务切换?
FreeRTOS的ISR函数中,使用两个宏进行任务切换:
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken ); portYIELD_FROM_ISR( xHigherPriorityTaskWoken ); • 1
这两个宏做的事情是完全一样的,在老版本的FreeRTOS中,
portEND_SWITCHING_ISR使用汇编实现
portYIELD_FROM_ISR使用C语言实现
新版本都统一使用portYIELD_FROM_ISR。
使用CubeMX创建工程
先前的使用代码移植的方法来创建我们的工程其实CubeMX是可以直接帮我们生成FreeRTOS工程的;
配置时钟
配置调试模式
这里必须选择否则有可能出现下载程序的问题,这里的基准时钟我们不能选择滴答时钟因为我们的FreeRTOS会使用我们的滴答时钟作为任务切换;
配置串口
后面我们做队列实验就拿串口1来做实验
配置按键外部中断;
配置中断服务函数
配置按键触发模式
配置FreeRTOS
这里我选择默认配置即可,如果前面的文章看了的话这里面的选项还是比较熟悉的
配置时钟
这里的8是这块板子的晶振,根据自己硬件实际情况选择即可
生成工程
库文件单独分析.c/.h
添加串口printf支持
/* USER CODE BEGIN Includes */ #include <stdio.h> /* USER CODE END Includes */ /* USER CODE BEGIN 0 */ int fputc(int ch, FILE *f) { HAL_UART_Transmit(&huart1, (uint8_t *)&ch, 1, 0xFFFF); return ch; } /* USER CODE END 0 */
示例
虽然FreeRTOS被重新封装了但是API基本都没有改变我们还是可以使用之前那一套即可;可以看到这里的内核启动是在while之前的所以我们的代码要卸载begin2的位置
/* USER CODE BEGIN 2 */ /* USER CODE END 2 */
需要注意的是我们的外设的中断配置优先级不要超过5,否则可能会在中断中卡死;
队列、信号量、互斥量、事件组、任务通知的使用方法和下面的类似;
【FreeRTOS】中断管理(二)https://developer.aliyun.com/article/1472602