• FreeRTOS学习笔记-基于stm32(4)临界段代码保护与任务调度器的挂起和恢复


    一、临界段代码保护

    1、什么是临界段代码

            临界段代码指的是那些不能被打断的代码,例如 IIC,SPI 等对时序有着严格的控制的代码。

    2、临界段保护的函数

            任务级进入临界区:        taskENTER_CRITICAL();

            任务级退出临界区:        taskEXIT_CRITICAL();

            中断级进入临界区:        taskENTER_CRITICAL_FROM_ISR();

            中断级退出临界区:        taskEXIT_CRITICAL_FROM_ISR( x );

    1. #define taskENTER_CRITICAL() portENTER_CRITICAL()
    2. #define taskENTER_CRITICAL_FROM_ISR() portSET_INTERRUPT_MASK_FROM_ISR()
    3. #define taskEXIT_CRITICAL() portEXIT_CRITICAL()
    4. #define taskEXIT_CRITICAL_FROM_ISR( x ) portCLEAR_INTERRUPT_MASK_FROM_ISR( x )

            其实仔细分析其内部实现,发现调用的还是上一片文章讲到的中断开启与关闭函数。不同的是多了一个变量 uxCriticalNesting 可以支持嵌套,即每次调用一次进入临界区函数,uxCriticalNesting 值加1,每次退出一次临界区,uxCriticalNesting 值减1。当 uxCriticalNesting 值为 0时,才会调用开启中断函数来退出临界区

    3、应用模板

    1. taskENTER_CRITICAL(); //进入临界区
    2. {
    3. …… …… /*临界区代码部分*/
    4. }
    5. taskEXIT_CRITICAL(); //退出临界区
    1. uint32_t save_status;
    2. save_status=taskENTER_CRITICAL_FROM_ISR();
    3. {
    4. …… …… /*临界区代码部分*/
    5. }
    6. taskEXIT_CRITICAL_FROM_ISR(save_status);

    二、 任务调度器的挂起与恢复

    1、任务调度器挂起

            挂起任务调度器之后,任务不能被调度但是中断可以正常运行。一般适用于临界区位于任务与任务之间。既不用延时中断又可以做到临界区的相对安全。

    2、任务调度器的挂起与恢复函数

            任务调度器挂起函数:vTaskSuspendAll();

            任务调度器恢复函数:xTaskResumeAll();返回值为 BaseType_t 类型,如果返回 pdFALSE 则代表恢复的任务优先级比较高,需要进行任务切换,返回 pdTRUE 表示不需要进行任务切换

            任务的调度本质还是pendsv的中断来执行的。而pendsv中的中断在 if 判断语句中执行:

    if( uxSchedulerSuspended == ( UBaseType_t ) pdFALSE )

            如果条件不成立就不会执行中断。所以任务调度器挂起函数:vTaskSuspendAll();通过修改 uxSchedulerSuspended 的值来挂起任务调度器

    1. void vTaskSuspendAll( void )
    2. {
    3. /* A critical section is not required as the variable is of type
    4. BaseType_t. Please read Richard Barry's reply in the following link to a
    5. post in the FreeRTOS support forum before reporting this as a bug! -
    6. http://goo.gl/wu4acr */
    7. ++uxSchedulerSuspended;
    8. }

             同理,  任务调度器恢复函数:xTaskResumeAll();通过 --uxSchedulerSuspended 来恢复任务调度器。

    3、应用模版

    1. {
    2. ...//代码
    3. vTaskSuspendAll();
    4. {
    5. ...//被保护的代码
    6. }
    7. xAlreadyYielded = xTaskResumeAll();
    8. /* Force a reschedule if xTaskResumeAll has not already done so, we may have put ourselves to sleep. */
    9. if( xAlreadyYielded == pdFALSE )
    10. {
    11. portYIELD_WITHIN_API(); //任务切换函数
    12. }
    13. else
    14. {
    15. mtCOVERAGE_TEST_MARKER();
    16. }
    17. ...//代码
    18. }

    4、实例 vTaskDelay() 的实现

    1. void vTaskDelay( const TickType_t xTicksToDelay )
    2. {
    3. BaseType_t xAlreadyYielded = pdFALSE;
    4. /* A delay time of zero just forces a reschedule. */
    5. if( xTicksToDelay > ( TickType_t ) 0U )
    6. {
    7. configASSERT( uxSchedulerSuspended == 0 );
    8. vTaskSuspendAll();
    9. {
    10. traceTASK_DELAY();
    11. /* A task that is removed from the event list while the
    12. scheduler is suspended will not get placed in the ready
    13. list or removed from the blocked list until the scheduler
    14. is resumed.This task cannot be in an event list as it is the currently
    15. executing task. */
    16. prvAddCurrentTaskToDelayedList( xTicksToDelay, pdFALSE );
    17. }
    18. xAlreadyYielded = xTaskResumeAll();
    19. }
    20. else
    21. {
    22. mtCOVERAGE_TEST_MARKER();
    23. }
    24. /* Force a reschedule if xTaskResumeAll has not already done so, we may
    25. have put ourselves to sleep. */
    26. if( xAlreadyYielded == pdFALSE )
    27. {
    28. portYIELD_WITHIN_API();
    29. }
    30. else
    31. {
    32. mtCOVERAGE_TEST_MARKER();
    33. }
    34. }
  • 相关阅读:
    sql 查重与去重
    GUI 编程Tkinter----(未完,洗漱)
    【Pytorch基础教程35】引入非线性的激活函数
    three.js初体验 如何将400M的3d模型压缩到3M
    SpringBoot篇---第二篇
    25计算机考研院校数据分析 | 四川大学
    重点区域人员徘徊识别监测系统
    k8s驱逐篇(6)-kube-controller-manager驱逐-NodeLifecycleController源码分析
    特征工程(文本特征提取CountVectorizer、TF-IDF 分词jieba、归一化、标准化 )、python示例
    i.MX6ULL驱动开发 | 31 - Linux内核网络设备驱动框架
  • 原文地址:https://blog.csdn.net/m0_74800695/article/details/136565287