[nRF51822] 3、 新年也來個總結——圖解nRF51 SDK中的Button handling library和FIFO library


 

:本篇是我翻譯並加入自己理解的nRF51 SDK中按鈕相關操作的庫和先進先出隊列庫。雖然是nRF51的SDK,但是通過此文你將更多地了解到在BSP(板級支持)上層嵌入式程序或OS的構建方法。

 

1、按鈕相關操作庫

  按鍵管理程序是通過GPIO事務和事件管理程序來檢測一個按鈕是否被按下的。當然,其中也做了消抖的工作——在GPIOTE事件中啟動一個定時器用來延時一段時間,當該定時器失效后如果按鈕仍然處於按下狀態,則會產生一個按鈕事件。如果在延時的過程中又有一個新的GPIOTE,那么這個定時器會重新被啟動。此外,在APP_BUTTON_INIT()參數中,使用USE_SCHEDULER參數來決定是否使用scheduler。(關於GPIOTE和SCHEDULER會在下面詳細講)

  app_button模塊會用到app_timer模塊。用戶必須確保app_timer的隊列足夠大來容納app_timer_stop()和app_timer_start()操作(注意:這兩個操作會在每個GPIOTE事件中執行,所以頻度很高!)

ps:即使scheduler沒被用,app_button.h也要包含app_scheduler.h!

2、先進先出隊列

該隊列采用環形緩沖,其大小和緩沖區在初始化的地方配置,如下:

1 // Create a FIFO 
2 structureapp_fifo_t my_fifo;
3 
4 // Create a buffer for the FIFO
5 uint16_t buffer_size = 8;
6 uint8_t buffer[buffer_size];
7 
8 // Initialize FIFO structure
9 uint32_t err_code = app_fifo_init(&test_fifo, buffer, (uint16_t)sizeof(buffer));

ps:1.通過app_fifo_init函數,test_fifo會被初始化(其結構體如下)。2.buffer的大小應該是2的倍數。3.一定要確保當FIFO在用的時候,app_fifo_t的緩沖內存不被回收了

 

1 typedef struct{    
2     uint8_t *          p_buf;           /**< Pointer to FIFO buffer memory. */    
3     uint16_t           buf_size_mask;   /**< Read/write index mask. Also used for size checking. */    
4     volatile uint32_t  read_pos;        /**< Next read position in the FIFO buffer.              */    
5     volatile uint32_t  write_pos;       /**< Next write position in the FIFO buffer.             */
6 } app_fifo_t;

這是個環形FIFO隊列,p_buf是調用初始化函數中傳入的數據池地址,read_pos和write_pos是讀地址和寫地址~此外,既然是環形FIFO就要用到mod,即:假設環形fifo數據池大小為n,當前寫入數據為第x個,則應該寫在xmodn位置。這里官方用了個小技巧(如下英語),首先要保證buffer-size是2的倍數,這樣xMODn就等於xAND(n-1)。

>>To simplify the index handling, the FIFO is restricted to require the buffer size <n>, to be a power of two, as this reduces the modulus operation to become a simple  AND operation with <n> - 1

n     = 8 = 0b00001000
n - 1 = 7 = 0b00000111

ANDing any number with <n>-1 , is identical to the modulus operation of <n>, when <n> is a power of two, see below:
3 = 11 mod 8 = 11 AND 7 = 0b00001011 & 0b00000111 = 0b00000011 = 3 . 

 

♠ 若n=8,則初始狀態下FIFO為:

 

♠ 插入一個8位uint8數據則:

1 uint8_t data = 88;
2 // Add an element to the FIFO
3 err_code = app_fifo_put(&my_fifo, data);

 

  上圖為插入4個uint8的效果~

 

 ♠ 取出一個8位uint8數據的代碼為:

1 // Consume one element from FIFO
2 uint8_t return_val;
3 err_code = app_fifo_get(&my_fifo, &return_val);

   下圖為取出兩個的效果~

 

 

♠ Empty Buffer

當read_pos=write_pos時表示buffer是空的。

初始化的時候讀寫位置都置為0、buffer內的內容被取完或者調用app_fifo_flush。

此時再調用讀函數則返回沒數據。

 

♠ Full Buffer

write_pos == read_pos + <n>時表示buffer是滿的。

此時再調用寫函數則返回沒內存。

 

 

@beautifulzzzz 2016-01-01 continue~  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM