sigmrnd函数(sigpending函数)

sigmrnd函数(sigpending函数)在 RTOS 中 需要应对各类事件 这些事件很多时候是通过硬件中断产生 怎么处理中断呢 假设当前系统正在运行 Task1 时 用户按下了按键 触发了按键中断 这个中断的处理流程如下 你要注意到 ISR 是在内核中被调用的 ISR 执行过程中 用户的任务无法执行 ISR 要尽量快 否则 如果这个硬件中断的处理 就是非常耗费时间呢 对于这类中断的处理就要分为 2 部分 要在 FreeRTOS 中熟练使用中断 有几个原则要先说明 本章涉及如下内容 17 1 两套 API 函数 17 1 1



在RTOS中,需要应对各类事件。这些事件很多时候是通过硬件中断产生,怎么处理中断呢?

假设当前系统正在运行Task1时,用户按下了按键,触发了按键中断。这个中断的处理流程如下:

    你要注意到,ISR是在内核中被调用的,ISR执行过程中,用户的任务无法执行。ISR要尽量快,否则:

      如果这个硬件中断的处理,就是非常耗费时间呢?对于这类中断的处理就要分为2部分:

        要在FreeRTOS中熟练使用中断,有几个原则要先说明:

          本章涉及如下内容:

            #

            17.1 两套API函数

            #

            17.1.1 为什么需要两套API

            在任务函数中,我们可以调用各类API函数,比如队列操作函数:xQueueSendToBack。但是在ISR中使用这个函数会导致问题,应该使用另一个函数:xQueueSendToBackFromISR,它的函数名含有后缀"FromISR",表示"从ISR中给队列发送数据"。

            FreeRTOS中很多API函数都有两套:一套在任务中使用,另一套在ISR中使用。后者的函数名含有"FromISR"后缀。

            为什么要引入两套API函数?

              为什么不使用同一套函数,比如在函数里面分辨当前调用者是任务还是ISR呢?示例代码如下:

              FreeRTOS使用两套函数,而不是使用一套函数,是因为有如下好处:

              使用同一套函数的话,需要增加额外的判断代码、增加额外的分支,是的函数更长、更复杂、难以测试

                使用两套函数可以让程序更高效,但是也有一些缺点,比如你要使用第三方库函数时,即会在任务中调用它,也会在ISR总调用它。这个第三方库函数用到了FreeRTOS的API函数,你无法修改库函数。这个问题可以解决:

                  #

                  17.1.2 两套API函数列表

                  17.1.3 xHigherPriorityTaskWoken参数

                  xHigherPriorityTaskWoken的含义是:是否有更高优先级的任务被唤醒了。如果为pdTRUE,则意味着后面要进行任务切换。

                  还是以写队列为例。

                  任务A调用 xQueueSendToBack() 写队列,有几种情况发生:

                    可以看到,在任务中调用API函数可能导致任务阻塞、任务切换,这叫做"context switch",上下文切换。这个函数可能很长时间才返回,在函数的内部实现了任务切换。

                    xQueueSendToBackFromISR() 函数也可能导致任务切换,但是不会在函数内部进行切换,而是返回一个参数:表示是否需要切换,函数原型与用法如下:

                    pxHigherPriorityTaskWoken参数,就是用来保存函数的结果:是否需要切换

                      为什么不在"FromISR"函数内部进行任务切换,而只是标记一下而已呢?为了效率!示例代码如下:

                      ISR中有可能多次调用"FromISR"函数,如果在"FromISR"内部进行任务切换,会浪费时间。解决方法是:

                        上述的例子很常见,比如UART中断:在UART的ISR中读取多个字符,发现收到回车符时才进行任务切换。

                        在ISR中调用API时不进行任务切换,而只是在"xHigherPriorityTaskWoken"中标记一下,除了效率,还有多种好处:

                          使用"FromISR"函数时,如果不想使用xHigherPriorityTaskWoken参数,可以设置为NULL。

                          #

                          17.1.4 怎么切换任务

                          FreeRTOS的ISR函数中,使用两个宏进行任务切换:

                          这两个宏做的事情是完全一样的,在老版本的FreeRTOS中,

                            新版本都统一使用portYIELD_FROM_ISR。

                            使用示例如下:

                            17.2 中断的延迟处理

                            前面讲过,ISR要尽量快,否则:

                              如果这个硬件中断的处理,就是非常耗费时间呢?对于这类中断的处理就要分为2部分:

                                这种处理方式叫"中断的延迟处理"(Deferring interrupt processing),处理流程如下图所示:

                                  17.3 中断与任务间的通信

                                  前面讲解过的队列、信号量、互斥量、事件组、任务通知等等方法,都可使用。

                                  要注意的是,在ISR中使用的函数要有"FromISR"后缀。

                                  #

                                  17.4 示例: 优化实时性

                                  本节代码为:29_fromisr_game,主要看DshanMCU-F103driver_ir_receiver.c。

                                  以前,在中断函数里写队列时,代码如下:

                                  假设当前运行的是任务A,它的优先级比较低,在它运行过程中发生了中断,中断函数调用了DispatchKey函数写了队列,使得任务B被唤醒了。任务B的优先级比较高,它应该在中断执行完后马上就能运行。但是上述代码无法实现这个目标,xQueueSendFromISR函数会把任务B调整为就绪态,但是不会发起一次调度。

                                  需要如下修改代码:

                                  在第164行传入一个变量的地址:&xHigherPriorityTaskWoken,它的初始值是pdFALSE,表示无需发起调度。如果xQueueSendFromISR函数发现唤醒了更高优先级的任务,那么就会把这个变量设置为pdTRUE。

                                  第166行,如果xHigherPriorityTaskWoken为pdTRUE,它就会发起一次调度。

                                  本程序上机时,我们感觉不到有什么不同。

                                  编程小号
                                  上一篇 2025-01-29 22:46
                                  下一篇 2025-02-07 14:11

                                  相关推荐

                                  版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
                                  如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/58454.html