什么网站可以做数据调查问卷,环球外贸论坛官网,精准引流推广公司,企业网站页头背景图采用二值信号量同步
二值信号量可以在某个特殊的中断发生时#xff0c;让任务解除阻塞#xff0c;相当于让任务与中断 同步。这样就可以让中断事件处理量大的工作在同步任务中完成#xff0c;中断服务例程(ISR) 中只是快速处理少部份工作。如此#xff0c;中断处理可以说是…采用二值信号量同步
二值信号量可以在某个特殊的中断发生时让任务解除阻塞相当于让任务与中断 同步。这样就可以让中断事件处理量大的工作在同步任务中完成中断服务例程(ISR) 中只是快速处理少部份工作。如此中断处理可以说是被”推迟(deferred)”到一个”处理 (handler)”任务。 如果某个中断处理要求特别紧急其延迟处理任务的优先级可以设为最高以保证 延迟处理任务随时都抢占系统中的其它任务。这样延迟处理任务就成为其对应的 ISR 退出后第一个执行的任务在时间上紧接着 ISR 执行相当于所有的处理都在 ISR 中 完成一样。这种方案在图 图 26 中展现。 延迟处理任务对一个信号量进行带阻塞性质的”take”调用意思是进入阻塞态以等 待事件发生。当事件发生后ISR 对同一个信号量进行”give”操作使得延迟处理任务 解除阻塞从而事件在延迟处理任务中得到相应的处理。 “获取(Taking带走按通常的说法译为获取)”和”给出(Giving)”信号量从概念上讲
不同的应用场合有不同的含义。在经典的信号量术语中获取信号量等同于一个 P() 操作而给出信号量等同于一个 V()操作。
在这种中断同步的情形下信号量可以看作是一个深度为 1 的队列。这个队列由于 最多只能保存一个数据单元所以其不为空则为满(所谓”二值”)。延迟处理任务调用 xSemaphoreTake()时等效于带阻塞时间地读取队列如果队列为空的话任务则进入 阻塞态。当事件发生后ISR 简单地通过调用 xSemaphoreGiveFromISR()放置一个令 牌(信号量)到队列中使得队列成为满状态。这也使得延迟处理任务切出阻塞态并移 除令牌使得队列再次成为空。当任务完成处理后再次读取队列发现队列为空又 进入阻塞态等待下一次事件发生。整个流程在图 图 27 中有所展现。 如图 图 27 所示中断给出信号量甚至是在信号量第一次被获取之前就给出而任 务在获取信号量之后再也不给回来。这就是为什么说这种情况与读写队列相似。这也经 常会给大家造成迷惑因为这种情形和其它信号量的使用场合大不相同。在其它场合下 任务获得(Take)了信号量之后必须得给(Give)回来——如同第四章描述一样。
vSemaphoreCreateBinary() API 函数 FreeRTOS 中各种信号量的句柄都存储在 xSemaphoreHandle 类型的变量中。 在 使 用 信 号 量 之 前 必 须 先 创 建 它 。 创 建 二 值 信 号 量 使 用 vSemaphoreCreateBinary()API 函数 void vSemaphoreCreateBinary( xSemaphoreHandle xSemaphore );
xSemaphore 创建的信号量 需要说明的是 vSemaphoreCreateBinary()在实现上是一个宏所以 信号量变量应当直接传入而不是传址。本章中包含本函数调用的示 例可用于参考进行复制。 xSemaphoreTake() API 函数 “带走(Taking)”一个信号量意为”获取(Obtain)”或”接收(Receive)”信号量。只有当信 号量有效的时候才可以被获取。在经典信号量术中xSemaphoreTake()等同于一次 P() 操作。 除互斥信号量(Recursive Semaphore直译为递归信号量按通常的说法译为互 斥信号量)外所有类型的信号量都可以调用函数 xSemaphoreTake()来获取。 但 xSemaphoreTake()不能在中断服务例程中调用。
portBASE_TYPE xSemaphoreTake( xSemaphoreHandle xSemaphore, portTickType xTicksToWait );
xSemaphore 获取得到的信号量 信号量由定义为 xSemaphoreHandle 类型的变量引用。信号量在使 用前必须先创建。 xTicksToWait 阻塞超时时间。任务进入阻塞态以等待信号量有效的最长时间。 如果 xTicksToWait 为 0则 xSemaphoreTake()在信号量无效时会 立即返回。 阻塞时间是以系统心跳周期为单位的所以绝对时间取决于系统心 跳频率。常量 portTICK_RATE_MS 可以用来把心跳时间单位转换 为毫秒时间单位。 如 果 把 xTicksToWait 设 置 为 portMAX_DELAY 并 且 在 FreeRTOSConig.h 中设定 INCLUDE_vTaskSuspend 为 1那么阻 塞等待将没有超时限制。
返回值 有两个可能的返回值: 1. pdPASS 只有一种情况会返回 pdPASS那就是成功获得信号量。 如果设定了阻塞超时时间(xTicksToWait 非 0)在函数返回之前任务 将被转移到阻塞态以等待信号量有效。如果在超时到来前信号量变 为有效亦可被成功获取返回 pdPASS。 2. pdFALSE 未能获得信号量。 如果设定了阻塞超时时间xTicksToWait 非 0在函数返回之前任 务将被转移到阻塞态以等待信号量有效。但直到超时信号量也没有 变为有效所以不会获得信号量返回 pdFALSE。
xSemaphoreGiveFromISR() API 函数 除互斥信号量外FreeRTOS 支持的其它类型的信号量都可以通过调用 xSemaphoreGiveFromISR()给出。 xSemaphoreGiveFromISR()是 xSemaphoreGive()的特殊形式专门用于中断服务 例程中。 portBASE_TYPE xSemaphoreGiveFromISR( xSemaphoreHandle xSemaphore, portBASE_TYPE *pxHigherPriorityTaskWoken );
xSemaphore 给出的信号量 信号量由定义为 xSemaphoreHandle 类型的变量引用。 信号量在使用前必须先创建。 pxHigherPriorityTaskWoken 对某个信号量而言可能有不止一个任务处于阻塞态在 等待其有效。调用 xSemaphoreGiveFromISR()会让信 号量变为有效所以会让其中一个等待任务切出阻塞 态。如果调用 xSemaphoreGiveFromISR()使得一个任 务解除阻塞并且这个任务的优先级高于当前任务(也就 是被中断的任务)那么 xSemaphoreGiveFromISR()会 在 函 数 内 部 将 *pxHigherPriorityTaskWoken 设 为 pdTRUE。 如 果 xSemaphoreGiveFromISR() 将 此 值 设 为 pdTRUE则在中断退出前应当进行一次上下文切换。 这样才能保证中断直接返回到就绪态任务中优先级最 高的任务中。 返回值 有两个可能的返回值: 1. pdPASS xSemaphoreGiveFromISR()调用成功。 2. pdFAIL 如果信号量已经有效无法给出则返回 pdFAIL。