第8篇 zephyr kernel之信號量Semaphores

目錄

摘要

1 概念

2 實現

2.1 定義一個信號量

2.2 釋放一個信號量

2.3 獲取信號量

3 參考鏈接


本學筆記基於zephyr 工程版本 2.2.99,主機環境爲ubuntu18.04,開發平臺 nrf52840dk_nrf52840

摘要

 信號量是一個多任務系統的標配,基本上任何多任務kernel都會有信號量接口。信號多用於同步,比如ISR和線程之間的同步,由ISR釋放信號量,由線程等待信號量,這樣ISR和線程就能同步執行。

1 概念

 任意數量的信號量可以被定義,每個信號量通過他的地址被引用,所以只要你的內存夠,那你就隨便定義吧。

 信號量有兩個關鍵的屬性:

  • 一個是count,表示信號可以被獲取(taken)的次數,當這個數是0,代表信號量無效。
  • 一個是limit,表示count能達到的最大值。

信號量在使用之前北徐被初始化,他的count值在初始化的時候,可以指定一個不超過limit的非負數。

信號量可以在線程或者ISR中被釋放(given),釋放之後,如果count值不大於limit,則count值自增。

信號量可以在線程中獲取(taken),相反,獲取信號量以後count值自減,但是count值不小於0。當想要獲取的信號量無效時,線程可以選擇等待。可以有很多個線程同時等待一個相同的無效的信號量,當信號量變得有效時,最高優先級等待時間最長的線程將獲取到信號量。理論上內核允許ISR中去獲取一個信號量,但是不要在信號量無效時去等待,可以嘗試獲取,獲取不到就返回。

2 實現

2.1 定義一個信號量

 使用struct k_sem類型定義一個信號量,信號量使用之前必須用k_sem_init()進行初始化。

下面的示例,定義一個信號量,設置count爲0,limit爲1:

struct k_sem my_sem;

k_sem_init(&my_sem, 0, 1);

信號量也可以使用K_SEM_DEFINE在編譯時初始化,代碼效果和上面相同:

K_SEM_DEFINE(my_sem, 0, 1);

2.2 釋放一個信號量

調用k_sem_give()釋放一個信號量。

下面示例,在中斷ISR中釋放一個信號量:

void input_data_interrupt_handler(void *arg)
{
    /* notify thread that data is available */
    k_sem_give(&my_sem);

    ...
}

2.3 獲取信號量

 調用k_sem_take()獲取一個信號量。

下面的代碼,表示當獲取信號量無效時,等待50ms:

void consumer_thread(void)
{
    ...

    if (k_sem_take(&my_sem, K_MSEC(50)) != 0) {
        printk("Input data not available!");
    } else {
        /* fetch available data */
        ...
    }
    ...
}

3 參考鏈接

https://docs.zephyrproject.org/latest/reference/kernel/synchronization/semaphores.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章