網(wǎng)站首頁 編程語言 正文
1.了解程序架構(gòu)概念和作用
在寫單片機程序的時候往往會遇見下面的情況
- 1、產(chǎn)品功能需要很多不同的延時效果,又不能用delay死延時,比方說按鍵檢測、
led
不同閃爍效果。 - 2、程序功能一多起來,整個腦子就混亂了,不知道這么整合起來。
- 3、不同功能區(qū)域的除了共享全局變量或數(shù)組以外不知道該怎么做。
實時操作系統(tǒng)rtos
、ucos
、linux
系統(tǒng),都是好的程序架構(gòu),它們就為開發(fā)者提供了系統(tǒng)實時性好、可靠性高、可移植性強等保障。工程師不需要研究復制的數(shù)據(jù)結(jié)構(gòu)和算法,比如任務(wù)分配、任務(wù)調(diào)度、內(nèi)存管理、消息機制等等,只需要學習使用系統(tǒng)就夠了。
2.了解單片機常見的程序架構(gòu)
- 1、傳統(tǒng)順序執(zhí)行的程序架構(gòu)
最多的時候,單片機程序都是使用while死循環(huán),然后順序執(zhí)行各種函數(shù),這種程序設(shè)計比較簡單。
#include? int main() { ?? ?keys = KeyScan(); ? ? while(1) ? ? { ?? ? ? ?if (keys ==1) ?? ? ? ?{ ?? ??? ?// ?? ? ? ?} ? ? } ? ? return 0; }
缺點就是只適合做小項目,程序大了以后邏輯一定會非常混亂,實時性,穩(wěn)定性,移植性差。
- 2、實時操作系統(tǒng)
比如ucos
、rtos
,用戶使用這些系統(tǒng)就只需要把系統(tǒng)移植好能跑起來就行。這種架構(gòu)的優(yōu)點就是它自身就是一個穩(wěn)定性、實時性高的,有的甚至提供了圖形gui和網(wǎng)絡(luò)tcp/ip等強大的功能。
缺點就是占用內(nèi)存資源比較嚴重,移植起來比較復雜,應(yīng)用以后如果不去深耕,系統(tǒng)架構(gòu)的工作原理出了問題就會無從下手。所以這種系統(tǒng)一般針對大型項目,對某些功能有需要,比如帶屏幕的需要做大量界面的,或者帶網(wǎng)絡(luò)通信的。
- 3、輕量級的程序架構(gòu)
這個程序架構(gòu)的定位是能夠應(yīng)用在大多數(shù)的中低端單片機,占用單片機內(nèi)存資源比較少,在1kb左右。
3.輕量級程序架構(gòu)設(shè)計思想
主要分為兩個部分:
- 1、程序架構(gòu)系統(tǒng)內(nèi)核
- 2、任務(wù)通訊
系統(tǒng)內(nèi)核用于任務(wù)的統(tǒng)一分配管理。
任務(wù)通信就是不同模塊間的通信,比如說硬件層和應(yīng)用層的數(shù)據(jù)傳遞,這個就是通過回調(diào)函數(shù)來實現(xiàn)的。
本文的重點就是為了編寫一個有任務(wù)分配、任務(wù)調(diào)度的系統(tǒng)內(nèi)核代碼。能滿足移植性高,穩(wěn)定性強,實時性好的特點。
4.程序架構(gòu)內(nèi)核代碼的實現(xiàn)原理
內(nèi)核代碼主要是用來分配任務(wù)和任務(wù)調(diào)度的,任務(wù)就是各功能模塊輪詢的處理函數(shù)。分配任務(wù)就是創(chuàng)建任務(wù),把各功能模塊處理函數(shù)加入到任務(wù)管理列表里。
任務(wù)調(diào)度就是定時喚醒和休眠任務(wù)列表里的任務(wù)。
這里的喚醒就是調(diào)用,休眠就是把任務(wù)掛起,不讓它執(zhí)行。
程序架構(gòu)的系統(tǒng)內(nèi)核工作流程:
任務(wù)初始化:包括硬件的初始化,如gpio
的配置,定時器初始化,串口初始化等等。然后任務(wù)的創(chuàng)建和任務(wù)執(zhí)行函數(shù)的初始化。
任務(wù)調(diào)度:即我們傳統(tǒng)的while(1)
循環(huán)里面輪詢的函數(shù),只是我們?yōu)槊恳粋€任務(wù)提供不一樣的時間節(jié)拍,還可以讓任意一個任務(wù)進入休眠。
5.掌握輕量級程序架構(gòu)內(nèi)核編寫
系統(tǒng)內(nèi)核說白了就是寫一個任務(wù)的管理程序,通過這個程序可以更加靈活控制整個程序的允許狀態(tài),特別是需要做低功耗的產(chǎn)品來說。
系統(tǒng)內(nèi)核主要完成以下工作:
- 1、任務(wù)創(chuàng)建 ? ? ? ?
- 2、任務(wù)調(diào)度
- 3、任務(wù)掛起
- 4、任務(wù)休眠
優(yōu)點:
- 1、可以為每個任務(wù)提供不同時鐘節(jié)拍。
- 2、可以靈活控制每個任務(wù)的執(zhí)行狀態(tài)。
- 3、實時性更高
- 4、程序流程更加清晰
- 5、更適合做低功耗
OS_System.c代碼和OS_System.h代碼
#include "OS_System.h" ? volatile OS_TaskTypeDef OS_Task[OS_TASK_SUM]; ? CPUInterrupt_CallBack_t CPUInterrupptCtrlCBS; ? ? /******************************************************************************************************** * ?@函數(shù)名 ? OS_CPUInterruptCBSRegister?? ??? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? * ?@描述 ? ? 注冊CPU中斷控制函數(shù)?? ??? ??? ??? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? * ?@參數(shù) ? ? pCPUInterruptCtrlCBS-CPU中斷控制回調(diào)函數(shù)地址 * ?@返回值 ? 無 ?? * ?@注意 ? ? 無 ********************************************************************************************************/ void OS_CPUInterruptCBSRegister(CPUInterrupt_CallBack_t pCPUInterruptCtrlCBS) { ?? ?if(CPUInterrupptCtrlCBS == 0) ?? ?{ ?? ??? ?CPUInterrupptCtrlCBS = pCPUInterruptCtrlCBS; ?? ?} } ? /******************************************************************************************************** * ?@函數(shù)名 ? OS_TaskInit?? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? * ?@描述 ? ? 系統(tǒng)任務(wù)初始化?? ??? ??? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? * ?@參數(shù) ? ? 無 * ?@返回值 ? 無 * ?@注意 ? ? 無 ********************************************************************************************************/ void OS_TaskInit(void) { ?? ?unsigned char i; ?? ?for(i=0; iOS_Task[i].RunPeriod)?? ?//判斷計時器值是否到達任務(wù)需要執(zhí)行的時間 ?? ??? ??? ?{ ?? ??? ??? ??? ?OS_Task[i].RunTimer = 0; ?? ??? ??? ??? ?OS_Task[i].RunFlag = OS_RUN;//把任務(wù)的狀態(tài)設(shè)置成執(zhí)行,任務(wù)調(diào)度函數(shù)會一直判斷這個變量的值,如果是OS_RUN就會執(zhí)行task指向的函數(shù)。 ?? ??? ??? ?} ?? ??? ??? ? ?? ??? ?} ?? ?} ?? ? } ? /******************************************************************************* * Function Name ?: void OS_Start(void) * Description ? ?: 開始任務(wù)? * Input ? ? ? ? ?: None * Output ? ? ? ? : None * Return ? ? ? ? : None * Attention?? ??? ? : None *******************************************************************************/ void OS_Start(void) { ?? ?unsigned char i; ?? ?while(1) ?? ?{ ?? ??? ?for(i=0; i
?typedef enum { ?? ?CPU_ENTER_CRITICAL,?? ??? ?//CPU進入臨界 ?? ?CPU_EXIT_CRITICAL,?? ??? ?//CPU退出臨界 }CPU_EA_TYPEDEF; ? //定義一個CPU中斷控制回調(diào)函數(shù)指針,別名CPUInterrupt_CallBack_t, typedef void (*CPUInterrupt_CallBack_t)(CPU_EA_TYPEDEF cmd,unsigned char *pSta); ? ? //系統(tǒng)任務(wù)ID typedef enum { ?? ?OS_TASK1, ?? ?OS_TASK_SUM?? ? }OS_TaskIDTypeDef; ? ? //系統(tǒng)任務(wù)運行狀態(tài),暫時沒用到 typedef enum { ?? ?OS_SLEEP,?? ??? ??? ?//任務(wù)休眠 ?? ?OS_RUN=!OS_SLEEP?? ?//任務(wù)運行 }OS_TaskStatusTypeDef; ? //系統(tǒng)任務(wù)結(jié)構(gòu)體 typedef struct { ?? ?void (*task)(void);?? ??? ??? ??? ??? ?//任務(wù)函數(shù)指針 ?? ?OS_TaskStatusTypeDef RunFlag;?? ??? ?//任務(wù)運行狀態(tài) ?? ?unsigned short?? ?RunPeriod;?? ??? ??? ?//任務(wù)調(diào)度頻率 ?? ?unsigned short RunTimer;?? ??? ??? ?//任務(wù)調(diào)度計時器 }OS_TaskTypeDef; ? ? /*?? ?函數(shù)聲明 */? /*******************************************************************************/ void OS_CPUInterruptCBSRegister(CPUInterrupt_CallBack_t pCPUInterruptCtrlCBS); void OS_ClockInterruptHandle(void); void OS_TaskInit(void); void OS_CreatTask(unsigned char ID, void (*proc)(void), unsigned short TimeDly, OS_TaskStatusTypeDef flag); void OS_Start(void); void OS_ClockInterruptHandle(void); void OS_TaskGetUp(OS_TaskIDTypeDef taskID);?? ? void OS_TaskSleep(OS_TaskIDTypeDef taskID);
6.掌握輕量級程序架構(gòu)內(nèi)核移植
了解ucos
或者其他操作系統(tǒng)的朋友都知道,單片機想要跑這些實時操作系統(tǒng),必須進行系統(tǒng)的移植,移植就是把單片機的硬件資源,比如說中斷的打開和關(guān)閉,定時器,堆棧的處理等和ucos系統(tǒng)的內(nèi)核關(guān)聯(lián)起來,比如說我們這個內(nèi)核文件需要關(guān)閉中斷了,那么它是不知道你是用什么單片機,要怎么關(guān)閉單片機中斷的,只要靠你來寫一個關(guān)閉中斷的函數(shù),然后把這個函數(shù)地址賦值給它們的相關(guān)函數(shù)指針變量。同樣的,我們這個系統(tǒng)內(nèi)核也是需要用到單片機一些資源的,比如說10ms的定時時間,打開和關(guān)閉中斷。所以我們單片機來實現(xiàn)這個過程就叫移植,那么我們這個內(nèi)核移植非常簡單,大家可以通過這個來理解一些操作系統(tǒng)的移植原理也會比較容易,移植的流程:
- 1、把
OS_ClockInterruptHandle()
函數(shù)放到單片機定時器中斷處理函數(shù)里,定時頻率10ms - 2、重寫單片機總中斷開關(guān)
- 3、通過
OS_CPUInterruptCBSRegister()
函數(shù)把內(nèi)核中斷處理函數(shù)指針指向單片機總中斷開關(guān)處理函數(shù)。
原文鏈接:https://blog.csdn.net/weixin_44795447/article/details/123255232
相關(guān)推薦
- 2022-07-10 Spring依賴注入的幾種方式詳解
- 2023-03-22 C語言中不定參數(shù)?...?的語法以及函數(shù)封裝_C 語言
- 2022-09-29 C語言開發(fā)實現(xiàn)通訊錄管理系統(tǒng)_C 語言
- 2022-09-10 docker?machine安裝極狐gitlab的過程詳解_docker
- 2022-11-30 React之錯誤邊界?Error?Boundaries示例詳解_React
- 2023-07-05 cnpm安裝appium出現(xiàn)cannot find module xxx
- 2022-07-13 @postconstruct注解 和 InitializingBean 在bean實例化后執(zhí)行某些初
- 2022-08-01 C#中把FastReport.Net報表控件的數(shù)據(jù)保存到數(shù)據(jù)庫_C#教程
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支