Nordic SDK nrf_setion和nrf_section_iter模塊分析


開發環境:
nRF5_SDK_14.2.0_17b948a
KEIL 5.27
Windows 10 x64
芯片:nRF51822/nRF52832/nRF52840
 
 
新版本SDK做了很多改弄,下面來分析一下兩個比較有意思的模塊,nrf_setion和nrf_section_iter
這個兩位模塊基本都是用宏定義的
nrf_setion
NRF_SECTION_START_ADDR
NRF_SECTION_END_ADDR
NRF_SECTION_LENGTH
NRF_SECTION_DEF
NRF_SECTION_ITEM_REGISTER
NRF_SECTION_ITEM_GET
NRF_SECTION_ITEM_COUNT
 
nrf_section_iter
NRF_SECTION_SET_DEF
NRF_SECTION_SET_ITEM_REGISTER
nrf_section_iter_init、nrf_section_iter_get、nrf_section_iter_next
 
1、NRF_SECTION_START_ADDR、NRF_SECTION_END_ADDR、 NRF_SECTION_LENGTH
        
剛看這個宏定義有點蒙,這是什么鬼,查閱一下資料仔細看看
CONCAT_2表示將兩個參數合並,使用的是C語言的##操作符
$$Base表示起始地址
$$Limit表示結束地址
 
NRF_SECTION_START_ADDR 表示獲取SECTION起始地址
NRF_SECTION_END_ADDR 表示獲取SECTION起始地址
NRF_SECTION_LENGTH 表示獲取SECTION大小
 
2、NRF_SECTION_DEF
例如:
/* Create the section "fs_data". */
NRF_SECTION_DEF(fs_data, nrf_fstorage_t);
宏替換完之后最終就是
extern nrf_fstorage_t * fs_data$$Base;
extern void * fs_data$$Limit;
聲明兩個變量fs_data$$Base和fs_data$$Limit,變量的值為fs_data section段的起始地址和結束地址
 
現在明白了,實際上NRF_SECTION_DEF表示聲明兩個變量,變量值分別為section段的起始地址和結束地址
 
3、NRF_SECTION_ITEM_REGISTER
STRINGIFY 表示將將宏參數轉換為字符串,使用使用的是C語言的#操作符
 
還是找個實例看一看:
#define NRF_FSTORAGE_DEF(inst) NRF_SECTION_ITEM_REGISTER(fs_data, inst)
NRF_FSTORAGE_DEF(nrf_fstorage_t m_fs) =
{
// The flash area boundaries are set in fds_init().
.evt_handler = fs_event_handler,
};
 
宏替換完之后最終就是
nrf_fstorage_t m_fs __attribute__ ((section(‘fs_data’))) __attribute__((used)) = {
// The flash area boundaries are set in fds_init().
.evt_handler = fs_event_handler,
};
 
那么NRF_SECTION_ITEM_REGISTER 就表示定義一個變量,並且指定這個變量在哪個section段,可以將多個變量指定到同一個section段
 
 
 
4、NRF_SECTION_ITEM_GET
還是找個實例看一看:
/**@brief Macro for retrieving an fstorage instance. */
#define NRF_FSTORAGE_INSTANCE_GET(i) NRF_SECTION_ITEM_GET(fs_data, nrf_fstorage_t, (i))
 
宏替換完之后最終就是
((nrf_fstorage_t*)fs_data$$Base + (i))
 
那么NRF_SECTION_ITEM_GET就表示獲取section段中的一個實例,i表示索引
結合上面的NRF_SECTION_ITEM_REGISTER來看,NRF_FSTORAGE_INSTANCE_GET(0)就是變量m_fs。
 
 
5、NRF_SECTION_ITEM_COUNT
 
NRF_SECTION_ITEM_COUNT 就表示獲取section段中有多少個變量實例,獲取到數量之后就可以通過NRF_SECTION_ITEM_GET遍歷整個section段全部變量實例
 
 
6、NRF_SECTION_SET_DEF
迭代器定義
 
7、NRF_SECTION_SET_ITEM_REGISTER
觀察者注冊到迭代器中
 
 
8、nrf_section_iter_init、 nrf_section_iter_get、 nrf_section_iter_next
遍歷迭代器
 
9、總結:
使用C語言和編譯器的一些功能實現 迭代器的效果,這樣的寫執行回調函數的時候就不用管有多少個回調函數,具體的回調函數是什么,只需要定義好section段,需要執行的回調函數注冊到這個section段中,這樣在需要執行回調函數的時候遍歷這個section段所以回調函數即可,實現解耦,代碼分離。例如藍牙連接這個事件,不需要知道有多少個service需要這個藍牙連接消息,只需要注冊一個藍牙的section段,誰需要誰就注冊回調函數到這個section中,在藍牙連接這個消息到來是只需要遍歷這個藍牙的section段,就可以通知所有需要該消息的觀察者
 
$$Base和$$Limit 非常有用,在SDK中很多地址都有用到,熟練掌握使用對代碼有很大的幫助
 
 
 
 
參考:
關於__attribute__中section部分的一些了解: https://blog.csdn.net/sadshen/article/details/9419267

 


免責聲明!

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



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