1.挂起和恢复任务调度器
任务挂起函数
void vTaskSuspend( TaskHandle_t xTaskToSuspend )
- xTaskToSuspend:待挂起任务的任务句柄,为NULL表示挂起任务自身。
- 需将宏INCLUDE_vTaskSuspend配置为 1。
任务恢复函数
void vTaskResume( TaskHandle_t xTaskToResume )
- INCLUDE_vTaskSuspend必须定义为 1。
- 不论任务被使用 vTaskSuspend() 挂起多少次,只需调用 vTaskResume() 一次,即可使其继续执行。被恢复的任务会重新进入就绪状态。
任务恢复函数(中断中恢复)函数说明
BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume )
返回值如下:
- pdTRUE:任务恢复后需要进行任务切换。
- pdFALSE:任务恢复后不需要进行任务切换。
注意事项
- INCLUDE_vTaskSuspend 和 INCLUDE_xTaskResumeFromISR 必须定义为 1。
- 在中断服务程序中调用FreeRTOS的API函数时,中断的优先级不能高于FreeRTOS所管理的最高中断优先级。
挂起与恢复调度器
- vTaskSuspendAll():挂起任务调度器,调度器不会进行任务切换,当前任务一直运行。
- xTaskResumeAll():恢复任务调度器,调度器继续任务切换。
实验目的
- task3:判断按键按下逻辑,KEY1短按下,挂起task1;KEY1长按任务中恢复task1;KEY2按下,挂起调度器;KEY2长按下,恢复调度器,并打印任务的状态。
开启宏定义
/* 开启任务挂起与恢复的功能 */
#define INCLUDE_vTaskSuspend 1
#define INCLUDE_xResumeFromISR 1
/* 开启跟踪task信息 */
#define configUSE_TRACE_FACILITY 1
#define configUSE_STATS_FORMATTING_FUNCTIONS 1
/**
* @description: 任务三:判断按键按下逻辑,KEY1短按下,挂起task1;KEY1长按任务中恢复task1;KEY2按下,挂起调度器;KEY2长按下,恢复调度器,并打印任务的状态。
* @param {void} *pvParameters
* @return {*}
*/
struct keys key[3] = {0}; // 定义按键结构体
char task_info[500]; // 定义接收任务信息
void task3(void *pvParameters)
{
while (1)
{
printf("task3 is running\r\n");
if (key[0].short_flag == 1)
{
/* key1短按下,挂起task1 */
printf("<<<挂起task1...\r\n");
vTaskSuspend(task1_handle);
key[0].short_flag = 0;
}
else if (key[0].long_flag == 1)
{
/* key1长按下,恢复task1 */
printf(">>>恢复task1...\r\n");
vTaskResume(task1_handle);
key[0].long_flag = 0;
}
else if (key[1].short_flag == 1)
{
/* key2短按下,挂起调度器 */
printf("<<<挂起调度器...\r\n");
vTaskSuspendAll();
key[1].short_flag = 0;
}
else if (key[1].long_flag == 1)
{
/* key2长按下,恢复调度器 */
printf(">>>恢复调度器...\r\n");
xTaskResumeAll();
key[1].long_flag = 0;
}
/* 打印任务状态 */
vTaskList(task_info);
printf("%s\r\n", task_info);
vTaskDelay(500);
// HAL_Delay(500); //这种delay不会让任务进入阻塞态,不会让出cpu使用权
}
}
创建任务和task1和task2和之前一样
stm\stm.axf: Error: L6406E: No space in execution regions with .ANY selector matching freertos_demo.o(.bss).芯片内存不足
现象:
注意事项:使用静态任务创建的时候,stm32f103c8t6芯片的RAM内存可能不足(如下图)
我们如何去查看stm32f103c8t6芯片的ROM、RAM内存
这个是我们创建任务时候自动生成的一个ROM内存和RAM内存
计算stmf103c8t6的大小
内存 | 十六进制 | 十进制(字节) | |
ROM | 64K | 0x10000 | 65536 |
RAM | 20K | 0x5000 | 20480 |
查看程序的内存
各个参数表示的含义:
Code(代码段)
含义:编译后的机器指令(如函数、逻辑代码)。
存储位置:ROM(只读存储器)。
RO-data(只读数据段)
含义:常量数据(如字符串常量、全局常量数组)。
存储位置:ROM。
RW-data(可读写数据段)
含义:已初始化的全局变量和静态变量。
存储位置:运行时占用RAM空间。
初始值存储在ROM中(程序启动时需加载到RAM)。
ZI-data(零初始化数据段)
含义:未初始化或显式初始化为零的全局变量和静态变量。
存储位置:RAM(程序启动时分配内存并清零)。
ROM需求 = Code + RO-data + RW-data的初始值
RAM需求 = RW-data(运行时占用) + ZI-data
在这里我们可以计算大小
ROM = 12976 (Code)+312 (RO-data)+152 (RW-data)=13440 字节 (≈13.1 KB)
RAM = 152 (RW-data)+23656 (ZI-data)=23808 字节 (≈23.25 KB) > 20 KB
这里看到我们的一个RAM内存不足
解决方法
寻找到占用内存比较大的一些调用函数,转换成其他的函数或者其他方式编写或者更换内存更多的芯片