打印
[uCOS/RTOS]

FreeRTOS操作系统——临界段代码保护(七)

[复制链接]
767|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
我于nano|  楼主 | 2022-7-28 17:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
# FreeRTOS操作系统学习

@[TOC](文章目录)

</font>

<hr style=" border:solid; width:100px; height:1px;" color=#000000 size=1">

# 前言

     临界段代码也叫临界区,是指那些必须完整运行,不能被打断的代码,比如有的外设的初始化需要按照严格的时序,初始化过程不能被打断。FreeRTOS在进入临界段代码的时候需要关闭中断,当处理完临界段代码以后再打开中断。
     在FreeRTOS系统本身就有很多的临界段代码,这些代码都加了临界段代码保护,我们自己写的时候只需要在一些需要严格保持时序的模块中加入临界段代码保护即可。
     临界段保护就是你认为不能被打断的程序。


# 一、临界段代码保护函数
![在这里插入图片描述](?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5oiR5LiObmFubw==,size_20,color_FFFFFF,t_70,g_se,x_16)

```c
taskENTER_CRITICAL()
taskEXIT_CRITICAL()
taskENTER_CRITICAL_FROM_ISR()
taskEXIT_CRITICAL_FROM_ISR()
```



# 二、如何使用
## 1.任务级临界段代码保护
taskENTER_CRITICAL()和 taskEXIT_CRITICAL()是任务级的临界代码保护,一个是进入临界段,一个是退出临界段,这两个函数是成对使用的

(示例):



```c
void taskcritical_test(void)
{
while(1)
{
taskENTER_CRITICAL(); (1)//进入临界区
total_num+=0.01f;
printf("total_num 的值为: %.4f\r\n",total_num);
taskEXIT_CRITICAL(); (2)//退出临界区
vTaskDelay(1000);
} }
```
(1)和(2)中间的代码就是临界区代码,注意临界区代码一定要精简!因为进入临界区会关闭中断,这样会导致优先级低于 configMAX_SYSCALL_INTERRUPT_PRIORITY 的中断得不到及时响应。
## 2.中断级临界段代码保护
函数 taskENTER_CRITICAL_FROM_ISR()和taskEXIT_CRITICAL_FROM_ISR()中断级别临界段代码保护,是用在中断服务程序中的,而且这个中断的优先级一定要低于configMAX_SYSCALL_INTERRUPT_PRIORITY!

(示例):



```c
//定时器 3 中断服务函数
void TIM3_IRQHandler(void)
{
if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
{
status_value=taskENTER_CRITICAL_FROM_ISR(); (1)//进入临界区,进入有一个返回值要保存起来
total_num+=1;
printf("float_num 的值为: %d\r\n",total_num);
taskEXIT_CRITICAL_FROM_ISR(status_value); (2)//退出临界区,用上面的返回值作为参数写进来才可以完成
TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}
}
```
系统可管理的最高优先级是5,taskENTER_CRITICAL_FROM_ISR函数优先级一定要低于5,即5~15。


# 总结
临界段代码保护很简单,会使用这四个函数即可,使用中断级临界段代码保护的时候的要注意优先级的设定,一定要低于最高优先级。


使用特权

评论回复

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

9

帖子

1

粉丝