FreeRTOS临界区应用与总结

https://blog.csdn.net/chipsea_mltsum/article/details/85612939

项目背景:

        做一个测量阻抗脉搏波的设备,设备功能其中之一是采集阻抗信号,通过一个高精度ADC转换为AD值,并将AD值输出。软件模块示例如下:

if (CS1259Ready())             //等待ADC转换完成
 
    {
    
        Z13Adc = ReadADC();        //转换完成后读取ADC值;
        printf("%d\t\t",Z13Adc); 
        Z13Res = CalRes(Z13Adc);    //通过ADC值计算阻抗值
        printf("%d\r\n",Z13Res);
        
        vTaskDelay(5/portTICK_RATE_MS);
    }
遇到的问题:

        在连续读取ADC值时,会随机的中断测量,导致测量停止,或者可能会随机的发送错误数据,经排查非串口传输的原因。且传输错误的数据通常为随机性的产生FF,例如24bit的ADC,会出现后几个bit为F的情况。现象如下:

 问题分析:

      用逻辑分析仪抓取 ,发现是ADC的读取程序在读取过程中,受到了中断的干扰,导致其去做其他事情了。

例如:正常读取进程时,通信帧的情况如下:

而出现上述情况时,通信帧的情况如下: 

因此软件需保证读取任务进程不能被其他中断干扰。这里采用了FreeRTOS临界区的方式实现。代码示例如下图:

if (CS1259Ready())             //等待AD开始信号
    {
        taskENTER_CRITICAL();        //进入临界区
 
        Z13Adc = ReadADC();
        printf("%d\t\t",Z13Adc); 
        Z13Res = CalRes(Z13Adc);
        printf("%d\r\n",Z13Res);
 
        taskEXIT_CRITICAL();         //退出临界区
        vTaskDelay(5/portTICK_RATE_MS);
    }
FreeRTOS中临界区总结:

1)互斥的概念?

        访问一个被多任务共享,或是被多任务和中断共享的资源时,需要采用“互斥”技术以保证数据在任何时候都保持一致性。这样做的目的是要确保任务从开始访问资源就具有排它性,直到这个资源又恢复到完整状态。

2)什么是基本临界区?

        基本临界区是指宏taskENTER_CRITICAL()和taskEXIT_CRITICAL()之间的代码区间。也被称为Critical Section或者Critical Regions. 使用方法如下:

// 为了保证PORTA的访问不被中断,将访问操作放入临界区运行
taskENTER_CRITICAL();        //进入基本临界区
 
// 在taskENTER_CRITICAL()和taskEXIT_CRITICAL()之间不会切换到其他任务,中断可以执行,也允许嵌
//套,但只是针对优先级高于configMAX_SYSCALL_INTERRUPT_PRIORITY的任务,而且这些中断不允许访问
//FreeRTOS的API函数。
 
PORTA |= 0x01;
 
 
taskEXIT_CRITICAL();        //退出基本临界区
3)基本临界区的原理?

      临界区是提供互斥功能的一种非常原始的实现方法。临界区的工作 仅仅是简单的把中断全部关掉,或者是关掉优先级在configMAX_SYSCALL_INTERRUPT_PRIORITY以下的中断-依赖具体使用的FreeRTOS移植。抢占式的上下文切换只可能在某中断中完成,因此调用taskENTER_CRITICAL()可以在中断关闭的时段一直保持持续运行状态直到退出临界区。

4)基本临界区使用注意事项?

   临界区必须具有很短的时间,否则会反过来影响中断的响应时间。在每次使用taskENTER_CRITICAL()之后必须尽快的配套一个taskEXIT_CRITICAL()来退出临界区。

如何用挂起调度器来创建临界区?

     挂起调度器也被称为锁定调度器。

vTaskSuspendAll(void);   //挂起调度器创建临界区(禁止任务调度 suspend the scheduler)
 
/*
   通过vTaskSuspendAll()来挂起调度器。挂起调度器可以停止上下文切换而不用关中断,如果某个中断在调
度器挂起过程中要求进行上下文切换,则这个要求也会被挂起,直到调度器被唤醒后才会得到执行。
*/
 
vTaskResumeAll(void);  //(解除禁止任务调度 resuming the scheduler; 成对使用)
/*
返回值:pdTRUE: 
   在调度器挂起过程中,上下文切换请求也会被挂起,直到调度器唤醒才被执行,如果一个挂起的上下文切换请求在vTaskResumeAll()返回前得到执行,则返回pdTRUE.
返回值:pdFALSE:
   如果是其他情况,则返回pdFALSE.
*/
 
// 注意1:两个函数成对使用;
// 注意2:两者之间不能调用FreeRTOS系统API.
     基本临界区是保护一段代码区间不被其他任务或中断打断。而由挂起调度器实现的临界区只能保护一段代码不被其他任务打断,并不能约束中断,因为在这种方式下,中断是使能的。

     调度器处于挂起状态时,不能调用FreeRTOS的API函数。

 
--------------------- 
作者:滴水石穿裤子 
来源:CSDN 
原文:https://blog.csdn.net/chipsea_mltsum/article/details/85612939 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容使用说明 YOLO高分设计资源源码,详情请查看资源内容使用说明 YOLO高分设计资源源码,详情请查看资源内容使用说明 YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明YOLO高分设计资源源码,详情请查看资源内容使用说明

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值