網站首頁 編程語言 正文
1.了解程序架構概念和作用
在寫單片機程序的時候往往會遇見下面的情況
- 1、產品功能需要很多不同的延時效果,又不能用delay死延時,比方說按鍵檢測、
led
不同閃爍效果。 - 2、程序功能一多起來,整個腦子就混亂了,不知道這么整合起來。
- 3、不同功能區域的除了共享全局變量或數組以外不知道該怎么做。
實時操作系統rtos
、ucos
、linux
系統,都是好的程序架構,它們就為開發者提供了系統實時性好、可靠性高、可移植性強等保障。工程師不需要研究復制的數據結構和算法,比如任務分配、任務調度、內存管理、消息機制等等,只需要學習使用系統就夠了。
2.了解單片機常見的程序架構
- 1、傳統順序執行的程序架構
最多的時候,單片機程序都是使用while死循環,然后順序執行各種函數,這種程序設計比較簡單。
#include? int main() { ?? ?keys = KeyScan(); ? ? while(1) ? ? { ?? ? ? ?if (keys ==1) ?? ? ? ?{ ?? ??? ?// ?? ? ? ?} ? ? } ? ? return 0; }
缺點就是只適合做小項目,程序大了以后邏輯一定會非常混亂,實時性,穩定性,移植性差。
- 2、實時操作系統
比如ucos
、rtos
,用戶使用這些系統就只需要把系統移植好能跑起來就行。這種架構的優點就是它自身就是一個穩定性、實時性高的,有的甚至提供了圖形gui和網絡tcp/ip等強大的功能。
缺點就是占用內存資源比較嚴重,移植起來比較復雜,應用以后如果不去深耕,系統架構的工作原理出了問題就會無從下手。所以這種系統一般針對大型項目,對某些功能有需要,比如帶屏幕的需要做大量界面的,或者帶網絡通信的。
- 3、輕量級的程序架構
這個程序架構的定位是能夠應用在大多數的中低端單片機,占用單片機內存資源比較少,在1kb左右。
3.輕量級程序架構設計思想
主要分為兩個部分:
- 1、程序架構系統內核
- 2、任務通訊
系統內核用于任務的統一分配管理。
任務通信就是不同模塊間的通信,比如說硬件層和應用層的數據傳遞,這個就是通過回調函數來實現的。
本文的重點就是為了編寫一個有任務分配、任務調度的系統內核代碼。能滿足移植性高,穩定性強,實時性好的特點。
4.程序架構內核代碼的實現原理
內核代碼主要是用來分配任務和任務調度的,任務就是各功能模塊輪詢的處理函數。分配任務就是創建任務,把各功能模塊處理函數加入到任務管理列表里。
任務調度就是定時喚醒和休眠任務列表里的任務。
這里的喚醒就是調用,休眠就是把任務掛起,不讓它執行。
程序架構的系統內核工作流程:
任務初始化:包括硬件的初始化,如gpio
的配置,定時器初始化,串口初始化等等。然后任務的創建和任務執行函數的初始化。
任務調度:即我們傳統的while(1)
循環里面輪詢的函數,只是我們為每一個任務提供不一樣的時間節拍,還可以讓任意一個任務進入休眠。
5.掌握輕量級程序架構內核編寫
系統內核說白了就是寫一個任務的管理程序,通過這個程序可以更加靈活控制整個程序的允許狀態,特別是需要做低功耗的產品來說。
系統內核主要完成以下工作:
- 1、任務創建 ? ? ? ?
- 2、任務調度
- 3、任務掛起
- 4、任務休眠
優點:
- 1、可以為每個任務提供不同時鐘節拍。
- 2、可以靈活控制每個任務的執行狀態。
- 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; ? ? /******************************************************************************************************** * ?@函數名 ? OS_CPUInterruptCBSRegister?? ??? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? * ?@描述 ? ? 注冊CPU中斷控制函數?? ??? ??? ??? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? * ?@參數 ? ? pCPUInterruptCtrlCBS-CPU中斷控制回調函數地址 * ?@返回值 ? 無 ?? * ?@注意 ? ? 無 ********************************************************************************************************/ void OS_CPUInterruptCBSRegister(CPUInterrupt_CallBack_t pCPUInterruptCtrlCBS) { ?? ?if(CPUInterrupptCtrlCBS == 0) ?? ?{ ?? ??? ?CPUInterrupptCtrlCBS = pCPUInterruptCtrlCBS; ?? ?} } ? /******************************************************************************************************** * ?@函數名 ? OS_TaskInit?? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? * ?@描述 ? ? 系統任務初始化?? ??? ??? ??? ??? ??? ??? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?? * ?@參數 ? ? 無 * ?@返回值 ? 無 * ?@注意 ? ? 無 ********************************************************************************************************/ void OS_TaskInit(void) { ?? ?unsigned char i; ?? ?for(i=0; iOS_Task[i].RunPeriod)?? ?//判斷計時器值是否到達任務需要執行的時間 ?? ??? ??? ?{ ?? ??? ??? ??? ?OS_Task[i].RunTimer = 0; ?? ??? ??? ??? ?OS_Task[i].RunFlag = OS_RUN;//把任務的狀態設置成執行,任務調度函數會一直判斷這個變量的值,如果是OS_RUN就會執行task指向的函數。 ?? ??? ??? ?} ?? ??? ??? ? ?? ??? ?} ?? ?} ?? ? } ? /******************************************************************************* * Function Name ?: void OS_Start(void) * Description ? ?: 開始任務? * 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中斷控制回調函數指針,別名CPUInterrupt_CallBack_t, typedef void (*CPUInterrupt_CallBack_t)(CPU_EA_TYPEDEF cmd,unsigned char *pSta); ? ? //系統任務ID typedef enum { ?? ?OS_TASK1, ?? ?OS_TASK_SUM?? ? }OS_TaskIDTypeDef; ? ? //系統任務運行狀態,暫時沒用到 typedef enum { ?? ?OS_SLEEP,?? ??? ??? ?//任務休眠 ?? ?OS_RUN=!OS_SLEEP?? ?//任務運行 }OS_TaskStatusTypeDef; ? //系統任務結構體 typedef struct { ?? ?void (*task)(void);?? ??? ??? ??? ??? ?//任務函數指針 ?? ?OS_TaskStatusTypeDef RunFlag;?? ??? ?//任務運行狀態 ?? ?unsigned short?? ?RunPeriod;?? ??? ??? ?//任務調度頻率 ?? ?unsigned short RunTimer;?? ??? ??? ?//任務調度計時器 }OS_TaskTypeDef; ? ? /*?? ?函數聲明 */? /*******************************************************************************/ 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.掌握輕量級程序架構內核移植
了解ucos
或者其他操作系統的朋友都知道,單片機想要跑這些實時操作系統,必須進行系統的移植,移植就是把單片機的硬件資源,比如說中斷的打開和關閉,定時器,堆棧的處理等和ucos系統的內核關聯起來,比如說我們這個內核文件需要關閉中斷了,那么它是不知道你是用什么單片機,要怎么關閉單片機中斷的,只要靠你來寫一個關閉中斷的函數,然后把這個函數地址賦值給它們的相關函數指針變量。同樣的,我們這個系統內核也是需要用到單片機一些資源的,比如說10ms的定時時間,打開和關閉中斷。所以我們單片機來實現這個過程就叫移植,那么我們這個內核移植非常簡單,大家可以通過這個來理解一些操作系統的移植原理也會比較容易,移植的流程:
- 1、把
OS_ClockInterruptHandle()
函數放到單片機定時器中斷處理函數里,定時頻率10ms - 2、重寫單片機總中斷開關
- 3、通過
OS_CPUInterruptCBSRegister()
函數把內核中斷處理函數指針指向單片機總中斷開關處理函數。
原文鏈接:https://blog.csdn.net/weixin_44795447/article/details/123255232
相關推薦
- 2022-06-12 超詳細分析C語言動態內存管理問題_C 語言
- 2023-01-03 Redis實現優惠券限一單限制詳解_Redis
- 2023-10-24 ElementUI日期選擇器DatePicker限制所選時間范圍(例如限制前后時長不超一個月)的實現
- 2022-11-28 ContentProvider客戶端處理provider邏輯分析_Android
- 2022-06-13 詳解Python+Matplotlib繪制面積圖&熱力圖_python
- 2022-04-28 Python中turtle.write方法使用說明_python
- 2022-11-24 詳解python中@classmethod和@staticmethod方法_python
- 2022-12-07 C++?如何將Lambda轉換成函數指針_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支