在freertos中,信号量有三种类型,二值信号量,计数信号量,互斥信号量,这里总结前两种。
1、二值信号量比较直观,类似于红绿灯,创建的时候,默认是红灯的,其他任务都得不到这个信号量的,只有give之后才能变成绿灯,其他任务才能得到信号量,得以运行。(本质上,信号量是用队列实现的)上面是类比,在代码中,创建的时候,初始值是0,give是相当于将计数值设置为1,take后相当于将计数值清0.
在cubemx集成的freertos中,已经封装了一层api,cmsis_os.c,把二值信号量,计数信号量封装进一个函数中。如下所示:(一般我们使用动态分配的方式。)
如果count为1,则说明是创建二值信号量,否则创建计数信号量。而且二值信号量主要用于同步,(我想想,好像只有这个应用场合),一个任务或中断释放信号量,另一个任务获取信号量,基本上类似于裸机的标志位。这一点和ucos是一样的,这个在另一篇文章中分析。
2、计数信号量中,有一点特别值得注意,在freertos的官放文档中,有这样的一段话:ps英文文档中,也是这个意思,说明基本原理不变的。
实际上,在cmsis_os的封装后,默认使用的是(2资源管理)的方案,类似于停车场的效果,创建后就有count个资源,如果要使用(事件计数)的方案,则需要修改如下的语句。return xSemaphoreCreateCounting(count, 0);
其实在freertos的原始api中,是可以让开发人员自己定义的。但是cubemx生成的freertos则经过了包装,因此这种方式需要额外注意,最好的方式是阅读源码。
顺便提一下take give两个函数的封装。
give的函数如下,他把isr的函数也包含进去了。
take函数如下,也把isr的函数也包含进去了。