首页 > 编程知识 正文

一个用于发送二进制信号的3khz信道,freertos的互斥信号量

时间:2023-05-04 06:30:48 阅读:113446 作者:295

另一方面,二值信号量摘要二值信号量通常用于排他访问或同步,二值信号量和排他信号量非常相似,但略有不同,排他信号量具有优先级继承机制,为二值信号量没有优先级继承。因此二值信号另更适合用于同步(任务与任务或任务与中断的同步),而互斥信号量适合用于简单的互斥访问。 与队列一样,信号API函数可以设置块时间,该时间是任务获取信号时由于信号无效而阻止任务的最大时钟数。 http://www.Sina.com/http://www.Sina.com /,这不是正好二值吗? 任务和中断使用此特殊队列不需要在意队列中存储的消息,而是需要知道队列是满还是空。 利用该机制,可以同步任务和中断。 在实际的APP应用中,通常使用处理具有MCU的外围设备的任务。 例如,在网络APP应用中,一般最简单的方法是使用任务来询问在MCU的eth中是否存在与网络相关的外围设备(如STM 32的以太网MAC )的数据,并且如果存在,则处理网络数据这样使用轮询会浪费CPU资源,阻止其他任务的执行。如果多个任务同时阻塞在同一个信号量上的话那么优先级最高的那个任务优先获得信号量,这样当信号量有效的时候高优先级的任务就会解除阻塞状态网络任务总是获取二进制信号量,而不会释放信号量。 另一方面,中断服务函数总是释放信号量,而不是获取信号量。 要在中断服务函数中发送信号量,请使用函数xSemaphoreGiveFromISR (或二值信号量其实就是一个只有一个队列项的队列,这个特殊的队列要么是满的,要么是空的)。 使用二进制信号量完成中断和任务同步的这种机制允许外围设备按任务优先级及时处理,从而延迟了中断处理过程。 也可以使用队列而不是二值信号量,通过外围事件的中断服务函数检索相关数据,并将相关数据通过队列发送到任务。 如果队列无效,则任务将被阻止,直到队列中有数据为止,任务在接收到数据后才开始相关的处理过程。 下面几个

的步骤显示了二值信号量的工作过程。

最理想的方法就是当没有网络数据的时候网络任务就进入阻塞态,把CPU让给其他的任务,当有数据的时候网络任务才去执行。现在使用二值信号量就可以实现这样的功能,任务通过获取信号量来判断是否有网络数据,没有的话就进入阻塞态,而网络中断服务函数(大多数的网络外设都有中断功能,比如STM32的MAC专用DMA中断,通过中断可以判断是否接收到数据)通过释放信号量来通知任务以太网外设接收到了网络数据,网络任务可以去提取处理了

在上图中,任务Task通过函数xSemaphoreTake ()取得信号量,但此时二值信号量无效,因此任务Task进入块状态。

任务通知功能来替代二值信号量,而且使用任务通知的话速度更快,代码量更少

此时,发生中断,并且在中断服务函数中,通过函数xSemaphoreGiveFromISR ) )释放信号量,因此信号量有效。

1、二值信号量无效

由于启用了信号,任务Task成功捕获信号,任务从拥塞中取消,并启动相关处理进程。

2、中断释放信号量

由于任务函数通常是大循环,因此在任务完成相关处理后,再次调用函数xSemaphoreTake0获取信号量。 执行步骤3后,二进制信号量被禁用,因此任务再次处于阻止状态,与第一步一样再次发生中断,并调用函数xSemaphoreGiveFromISR (以释放信号量。

二、二值信号量相关函数3、任务获取信号量成功

与队列一样,要使用二值信号量,必须首先创建二值信号量。 二进制信号量创建函数如下表所示。

函数描述vSemaphoreCreateBinary ()动态创建二值信号量。 这是一个API函数,用于创建旧版本的FreeRTOS中使用的二值信号量。 xSemaphoreCreateBinary ()是一个API函数,可动态创建二值信号量,并创建新版本的FreeRTOS使用的二值信号量。 SemaphoreCreateBinaryStatic ()静态二值信号量4、任务再次进入阻塞态

此函数是在旧版本的FreeRTOS中创建二进制信号量的函数,不再用于新版本。 较新版本的FreeRTOS使用xSemaphoreCreateBinary ) )。 这里还有这个函数,以确保与基于旧版FreeRTOS创建的APP应用层代码兼容。 该函数为宏,具体的创建过程为函数

xQueueGenericCreate ()在文件semphr.h中定义如下:

voidvsemaphorecreatebinary (semaphore handle _ tx semaphore )参数指示xsemaphore将存储成功创建的二进制信号量句柄。1、创建二值信号量

这是

函数是vSemaphoreCreateBinary()的新版本,新版本的FreeRTOS中统一用此函数来创建二值信号量。使用此函数创建二值信号量的话信号量所需要的RAM是由FreeRTOS的内存管理部分来动态分配的。此函数创建好的二值信号量默认是空的,也就是说刚创建好的二值信号量使用函数xSemaphoreTake()是获取不到的,此函数也是个宏,具体创建过程是由函数
xQueueGenericCreate()来完成的,函数原型如下:

SemaphoreHandle_t xSemaphoreCreateBinary(void) 参数描述返回值NULL:二值信号量创建失败。其他值:创建成功的二值信号量句柄。

- ③、函数xSemaphoreCreateBinaryStatic()

此函数也是创建二值信号量的,只不过使用此函数创建二值信号量的话信号量所需要的RAM需要由用户来分配,此函数是个宏,具体创建过程是通过函数xQueueGenericCreateStatic()来完成的,函数原型如下:

SemaphoreHandle_t xSemaphoreCreateBinaryStatic(StaticSemaphore_t*pxSemaphoreBuffer) 参数描述pxSemaphoreBuffer指向一个StaticSemaphore_t类型的变量,用来保存信号量结构体。返回值NULL:二值信号量创建失败。其他值:创建成功的二值信号量句柄。

2、释放信号量
释放信号量的函数有两个,如下表所示:

函数描述xSemaphoreGive()任务级信号量释放函数xSemaphoreGiveFromISR()中断级信号量释放函数

同队列一样,释放信号量也分为任务级和中断级。不管是二值信号量、计数型信号量还是互斥信号量,它们都使用上述表中的函数释放信号量,递归互斥信号量有专用的释放函数。

①、函数xSemaphoreGive()
此函数用于释放二值信号量、计数型信号量或互斥信号量,此函数是一个宏,真正释放信号量的过程是由函数xQueueGenericSend()来完成的,函数原型如下: BaseType_t xSemaphoreGive(xSemaphore) 参数描述xSemaphore要释放的信号量句柄。返回值pdPASS:释放信号量成功。errQUEUE_FULL:释放信号量失败。

- ②、函数xSemaphoreGiveFromISR()
此函数用于在中断中释放信号量,此函数只能用来释放二值信号量和计数型信号量,绝对不能用来在中断服务函数中释放互斥信号量!此函数是一个宏,真正执行的是函数xQueueGiveFromISR(),此函数原型如下:

BaseType_t xSemaphoreGiveFromISR(SemaphoreHandle_t xSemaphore,BaseType_t* pxHigherPriorityTaskWoken) 参数描述xSemaphore要释放的信号量句柄。pxHigherPriorityTaskWoken标记退出此函数以后是否进行任务切换,这个变量的值由这三个函数来设置的,用户不用进行设置,用户只需要提供一个变量来保存这个值就行了。当此值为pdTRUE的时候在退出中断服务函数之前一定要进行一次任务切换。返回值pdPASS:释放信号量成功。errQUEUE_FULL:释放信号量失败。

3、获取信号量
获取信号量也有两个函数,如下表所示:

函数描述xSemaphoreTake()任务级获取信号量函数xSemaphoreTakeFromISR()中断级获取信号量函数

上表获取信号量同释放信号量的API函数一样,不管是二值信号量、计数型信号量还是互斥信号量,它们都可以使用表中的函数获取信号量。

- ①、函数xSemaphoreTake()

此函数用于获取二值信号量、计数型信号量或互斥信号量,此函数是一个宏,真正获取信号量的过程是由函数xQueueGenericReceive()来完成的,函数原型如下:

BaseType_t xSemaphoreTake(SemaphoreHandle_t xSemaphore,TickType_t xBlockTime) 参数描述xSemaphore要获取的信号量句柄。xBlockTime阻塞时间。返回值pdTRUE:获取信号量成功。pdFALSE:超时,获取信号量失败。

- ②、函数xSemaphoreTakeFromISR()
此函数用于在中断服务函数中获取信号量,此函数用于获取二值信号量和计数型信号量,绝对不能使用此函数来获取互斥信号量!此函数是一个宏,真正执行的是函数
xQueueReceiveFromISR(),此函数原型如下:

Base Type_t xSemaphoreTakeFromISR(SemaphoreHandle_t xSemaphore,BaseType_t* pxHigherPriorityTaskWoken) 参数描述xSemaphore要获取的信号量句柄。pxHigherPriorityTaskWoken标记退出此函数以后是否进行任务切换,这个变量的值由这三个函数来设置的,用户不用进行设置,用户只需要提供一个变量来保存这个值就行了。当此值为pdTRUE的时候在退出中断服务函数之前一定要进行一次任务切换。返回值pdPASS:获取信号量成功。pdFALSE:获取信号量失败。

FreeRTOS二值信号量就讲解到这里啦!!!下一讲计数信号量。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。