一。临界段的应用
临界段的作用
临界段API
临界段应用
1.什么是临界段?
在程序访问资源时,不希望被其他任务或者中断打断,这段要执行的代码,称为临界代码段
2.不想被打断访问的资源
(1)读取或者修改变量(全局变量)
(2)调用公共函数的代码(不可重入函数)
(3)使用硬件资源(外设)
(4)对时序有精准要求的操作
(5)用户不想被打断的代码
3.临界段API
4.临界段的应用
(1)功能要求
1、分别修改Usart_Task、DelayTask任务
2、配置延时周期为50ms打印一次运行状态,观察现象,是否出现,资源冲突问题
3、通过临界段解决共享资源冲突问题
(2)不修改Cubemx创建工程
(3)如果把延迟时间缩少,串口可能会发生问题,任务同时想占用资源导致冲突。
(4)解决方法
taskENTER_CRITICAL();
printf("DelayTask is Runing!\r\n");
taskEXIT_CRITICAL();
在串口输出之间使用开关中断管理。
二。临界段实现的原理
三。任务大小的确定
四。实验:堆栈检测应用
1.实验要求
1、打开栈溢出检测方案(共二种)
2、修改Usart_Task任务
3、在任务内模拟栈溢出,分析实验结果
2.Cubemx创建工程
注意:配置上述之后会在FREERTOS.c中出现判断溢出的回调函数 ,如下图所示。
3.检测溢出
《1》第一种检测溢出方式
(1)使用溢出回调函数,输出提示。
printf("%s is Stack OverFlow\r\n",pcTaskName);
(2)自己写一个溢出的函数,在任务中使用
void vStackOverFlowTest(void){
uint8_t u8TestBuff[128];
int16_t i;
(void)u8TestBuff;
for(i=360;i>=0;i--){
u8TestBuff[i]=0x88;
}
}
输出结果
《2》第二种检测方法
修改了什么位置的宏定义,效果就是在上一个检测的基础上多了一些未知东西。
补充实验:获取任务状态方案
1.实验要求
1、打开任务状态配置
2、修改key_Task任务
3、当检测按键按下时,打印任务状态信息
2.Cubemx创建工程
FREERTOS中Configure中使能两个Run Time的内容(原因应该是打开获取任务状态方法)
3.步骤:
//用来接受信息的字符串
uint8_t u8TaskListBuff[400];
//在按钮处
memset(u8TaskListBuff,0,400);
vTaskList((char*)u8TaskListBuff);
printf("Name State Priority Stack Num\r\n");
printf("******************************************************\r\n");
printf("%s",u8TaskListBuff);
printf("******************************************************\r\n");
4.结果
实验:CPU效率统计应用
1.cubemx创建工程(在计算堆栈的工程基础上)
(1)进入FREERTOS
(2)配置Tim6
Tim6的中断配置
2.步骤
(0)定义计时数据 uint32_t u32TimeCount;
注意:《1》tim.c中为最终数据,其余为extern(main.c中,FREERTOS.c中)
《2》注意头文件的加入
uint32_t u32TimeCount;
(1)在FREERTOS.c中生成了
实现前:
实现后:
复制版:
__weak void configureTimerForRunTimeStats(void)
{
//¿ªÆô¶¨Ê±Æ÷µÄÖжϣ¬Æô¶¯¶¨Ê±Æ÷
//¶¨Ê±Æ÷ͳ¼ÆÖµ£¬³õʼ»¯Îª0
HAL_TIM_Base_Start_IT(&htim6);
u32TimeCount = 0ul;
}
__weak unsigned long getRunTimeCounterValue(void)
{
return u32TimeCount;
}
(2)在main.c的时间中断函数中加入Tim6中断处理
if (htim->Instance == TIM6) {
u32TimeCount++;
}
(3)在以前的按钮下加入
vTaskGetRunTimeStats((char*)u8TaskListBuff);
printf("Name Abs Time Time\r\n");
3.结果
综上可知:vTaskGetRunTimeStats()需要使用高精度的定时器计数。这里使用的是Tim6,在一个FREERTOS.c中的回调函数中使能定时器与返回计数的数据,在main.c中的定时器中断回调函数中计数。