作者 |Github -?54zorb ? ? ? ? ?
很多時(shí)候,做單片機(jī)項(xiàng)目,會(huì)因?yàn)樾阅芎蛢?nèi)存資源的限制,沒辦法運(yùn)行一些“大型”的通用框架,這個(gè)時(shí)候,一些輕量級(jí)的軟件框架有顯得尤為重要了。 ? 這里就給大家分享一款一款適合單片機(jī)裸機(jī)的開源軟件框架:Zorb
Zorb簡(jiǎn)介
Zorb Framework是一個(gè)基于面向?qū)ο蟮乃枷雭?lái)搭建一個(gè)輕量級(jí)的嵌入式框架。
搭建Zorb Framework的目的是為在不能運(yùn)行Linux的芯片上快速開發(fā)應(yīng)用,不用反復(fù)造輪子。
Zorb Framework的初步設(shè)計(jì)功能有:
1、時(shí)間系統(tǒng)功能zf_time
2、環(huán)形緩沖區(qū)功能zf_buffer
3、列表功能zf_list
4、狀態(tài)機(jī)功能zf_fsm
5、事件功能zf_event
6、定時(shí)器功能zf_timer
7、任務(wù)功能zf_task
前6個(gè)功能,就可以實(shí)現(xiàn)純事件驅(qū)動(dòng)的程序,基本可以滿足中小型嵌入式應(yīng)用程序開發(fā)的需求。加上任務(wù)功能,是為了滿足部分程序?qū)?shí)時(shí)性要求較高的需求。
當(dāng)然,也可以將前6個(gè)功能裁剪出來(lái),然后運(yùn)行在現(xiàn)有的嵌入式系統(tǒng)上面,這樣子也可以滿足實(shí)時(shí)性的需求。
環(huán)境搭建
采用STM32F429開發(fā)板作為硬件運(yùn)行環(huán)境,硬件資源用到串口1和systick,其中串口1提供調(diào)試打印功能,systick提供系統(tǒng)時(shí)間計(jì)數(shù)功能。
關(guān)于硬件環(huán)境的搭建不多說(shuō),可以參照開發(fā)板提供的例程來(lái)搭建,板級(jí)初始化完成了調(diào)試串口和systick的初始化。
/****************************************************************************** ?*?描述??:硬件環(huán)境初始化 ?*?參數(shù)??:無(wú) ?*?返回??:無(wú) ******************************************************************************/ void?BSP_init(void) { ????/*?嵌套向量中斷控制器組選擇?*/ ????NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); ????/*?初始化調(diào)試串口?*/ ????Debug_USART_init(); ????/*?Systick初始化?*/ ????SystemTick_init(); } /****************************************************************************** ?*?描述??:硬件底層程序 ?*?參數(shù)??:無(wú) ?*?返回??:無(wú) ******************************************************************************/ void?BSP_process(void) { }
調(diào)試
開發(fā)一個(gè)程序,最開始也最重要的是搭建調(diào)試的環(huán)境,我們采用串口1作為調(diào)試輸出(printf映射),然后調(diào)試信息分為三個(gè)等級(jí),后續(xù)上位機(jī)可以根據(jù)不同等級(jí)進(jìn)行高亮提示:
/** ??***************************************************************************** ??*?@file????zf_debug.h ??*?@author??Zorb ??*?@version?V1.0.0 ??*?@date????2018-06-28 ??*?@brief???調(diào)試輸出的頭文件 ??***************************************************************************** ??*?@history ??* ??*?1.?Date:2018-06-28 ??*????Author:Zorb ??*????Modification:建立文件 ??* ??***************************************************************************** ??*/ #ifndef?__ZF_DEBUG_H__ #define?__ZF_DEBUG_H__ #ifdef?__cplusplus extern?"C"?{ #endif #include?"stdio.h" #include?"stdbool.h" #define?LOG_D?0;?/*?信息等級(jí):正常?*/ #define?LOG_W?1;?/*?信息等級(jí):告警?*/ #define?LOG_E?2;?/*?信息等級(jí):錯(cuò)誤?*/ #define?_ZF_DEBUG?????????????/*?定義調(diào)試功能?*/ #define?ZF_DEBUG_ON?true??????/*?啟用調(diào)試功能?*/ #ifdef?_ZF_DEBUG ????#if?ZF_DEBUG_ON ????????#define?ZF_DEBUG(rank,?x...)?do????? ????????{??????????????????????????????????? ????????????char?code[10]?=?"[rank=0]";????? ????????????code[6]?=?'0'?+?(char)rank;????? ????????????if?(code[6]?!=?'0')????????????? ????????????{??????????????????????????????? ????????????????printf("%s",?code);????????? ????????????}??????????????????????????????? ????????????printf(x);?????????????????????? ????????}?while(0) ????#else ????????#define?ZF_DEBUG(rank,?x...) ????#endif?/*?ZF_DEBUG_ON?*/ #endif?/*?_ZF_DEBUG?*/ #ifdef?__cplusplus } #endif #endif?/*?__ZF_DEBUG_H__?*/ /********************************?END?OF?FILE?********************************/
斷言
在開發(fā)過(guò)程中,在關(guān)鍵地方進(jìn)行一些斷言,可以方便定位bug。
/** ??***************************************************************************** ??*?@file????zf_assert.h ??*?@author??Zorb ??*?@version?V1.0.0 ??*?@date????2018-06-28 ??*?@brief???斷言的頭文件 ??***************************************************************************** ??*?@history ??* ??*?1.?Date:2018-06-28 ??*????Author:Zorb ??*????Modification:建立文件 ??* ??***************************************************************************** ??*/ #ifndef?__ZF_ASSERT_H__ #define?__ZF_ASSERT_H__ #ifdef?__cplusplus extern?"C"?{ #endif #include?"stdint.h" #define?_ZF_ASSERT??????????????/*?定義斷言功能?*/ #define?ZF_ASSERT_ON?true???????/*?啟用斷言功能?*/ #ifdef?_ZF_ASSERT ????#if?ZF_ASSERT_ON ?????????#define?ZF_ASSERT(expression_)?((expression_)?? ????????????(void)0?:?ZF_assertHandle((uint8_t?*)__FILE__,?(int)__LINE__)); ????#else ?????????#define?ZF_ASSERT(expression_) ????#endif?/*?ZF_ASSERT_ON?*/ #endif?/*?_ZF_ASSERT?*/ /*?斷言產(chǎn)生時(shí)的處理?*/ void?ZF_assertHandle(uint8_t?*pFileName,?int?line); #ifdef?__cplusplus } #endif #endif?/*?__ZF_ASSERT_H__?*/ /********************************?END?OF?FILE?********************************/
斷言的處理很簡(jiǎn)單,就是告訴我們?cè)谀膫€(gè)文件哪一行出錯(cuò)就可以,實(shí)現(xiàn)如下
/** ??***************************************************************************** ??*?@file????zf_assert.c ??*?@author??Zorb ??*?@version?V1.0.0 ??*?@date????2018-06-28 ??*?@brief???斷言的實(shí)現(xiàn) ??***************************************************************************** ??*?@history ??* ??*?1.?Date:2018-06-28 ??*????Author:Zorb ??*????Modification:建立文件 ??* ??***************************************************************************** ??*/ #include?"zf_assert.h" #include?"zf_debug.h" /****************************************************************************** ?*?描述??:斷言產(chǎn)生時(shí)的處理 ?*?參數(shù)??:(in)-pFileName 文件名 ?*?????????(in)-line?行數(shù) ?*?返回??:無(wú) ******************************************************************************/ void?ZF_assertHandle(uint8_t?*pFileName,?int?line) { ????ZF_DEBUG(LOG_E,?"file:%s?line:%d:asserted ",?pFileName,?line); ????while?(1); } /********************************?END?OF?FILE?********************************/
調(diào)度時(shí)間
為了減少框架對(duì)資源的消耗,所以初步設(shè)定框架的最小時(shí)間周期為1ms,因此我們需要設(shè)置systick的定時(shí)周期為1ms,然后每次進(jìn)入中斷為我們的框架計(jì)數(shù)即可。
/****************************************************************************** ?*?描述??:SysTick中斷服務(wù)程序 ?*?參數(shù)??:無(wú) ?*?返回??:無(wú) ******************************************************************************/ void?SysTick_Handler(void) { ????/*?為zorb?framework提供計(jì)時(shí)?*/ ????ZF_timeTick(); }
現(xiàn)在時(shí)間系統(tǒng)提供的功能比較基礎(chǔ),只有系統(tǒng)滴答計(jì)數(shù)和系統(tǒng)死等待延時(shí),后面我們開發(fā)定時(shí)器功能和任務(wù)功能的時(shí)候會(huì)重新擴(kuò)展時(shí)間系統(tǒng)。
/** ??***************************************************************************** ??*?@file????zf_time.h ??*?@author??Zorb ??*?@version?V1.0.0 ??*?@date????2018-06-28 ??*?@brief???系統(tǒng)時(shí)間的頭文件 ??***************************************************************************** ??*?@history ??* ??*?1.?Date:2018-06-28 ??*????Author:Zorb ??*????Modification:建立文件 ??* ??***************************************************************************** ??*/ #ifndef?__ZF_TIME_H__ #define?__ZF_TIME_H__ #ifdef?__cplusplus extern?"C"?{ #endif #include?"stdbool.h" #include?"stdint.h" /*?系統(tǒng)滴答周期(ms)?*/ #define?ZF_TICK_PERIOD?1 /*?獲取系統(tǒng)滴答數(shù)?*/ #define?ZF_SYSTICK()?ZF_getSystemTick() /*?獲取系統(tǒng)時(shí)間(ms)?*/ #define?ZF_SYSTIME_MS()?ZF_getSystemTimeMS() /*?系統(tǒng)延時(shí)(ms)?*/ #define?ZF_DELAY_MS(ms_)?do???????????????????????????? {?????????????????????????????????????????????????????? ????if?(ms_?%?ZF_TICK_PERIOD)?????????????????????????? ????{?????????????????????????????????????????????????? ????????ZF_delayTick((ms_?/?ZF_TICK_PERIOD)?+?1);?????? ????}?????????????????????????????????????????????????? ????else??????????????????????????????????????????????? ????{?????????????????????????????????????????????????? ????????ZF_delayTick(ms_?/?ZF_TICK_PERIOD);???????????? ????}?????????????????????????????????????????????????? }?while(0) /*?獲取系統(tǒng)滴答數(shù)?*/ uint32_t?ZF_getSystemTick(void); /*?獲取系統(tǒng)時(shí)間(ms)?*/ uint32_t?ZF_getSystemTimeMS(void); /*?系統(tǒng)延時(shí)?*/ void?ZF_delayTick(uint32_t?tick); /*?系統(tǒng)滴答程序(需掛在硬件的時(shí)間中斷里邊)?*/ void?ZF_timeTick?(void); #ifdef?__cplusplus } #endif #endif?/*?__ZF_TIME_H__?*/ /********************************?END?OF?FILE?********************************/
最后
本篇實(shí)現(xiàn)的功能比較基礎(chǔ),但是整個(gè)框架開發(fā)的根基,后面所有擴(kuò)展的功能都需要在此環(huán)境下進(jìn)行開發(fā)。
搭建良好的調(diào)試輸出環(huán)境,可以幫我們快速定位bug的所在,從而提高開發(fā)效率。
審核編輯:黃飛
?
評(píng)論