在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的函數也包含進去了。