日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

嵌入式C語言輕量級程序架構內核編寫_C 語言

更新時間: 2022-05-06 編程語言

1.了解程序架構概念和作用

在寫單片機程序的時候往往會遇見下面的情況

  • 1、產品功能需要很多不同的延時效果,又不能用delay死延時,比方說按鍵檢測、led不同閃爍效果。
  • 2、程序功能一多起來,整個腦子就混亂了,不知道這么整合起來。
  • 3、不同功能區域的除了共享全局變量或數組以外不知道該怎么做。

實時操作系統rtosucoslinux系統,都是好的程序架構,它們就為開發者提供了系統實時性好、可靠性高、可移植性強等保障。工程師不需要研究復制的數據結構和算法,比如任務分配、任務調度、內存管理、消息機制等等,只需要學習使用系統就夠了。

2.了解單片機常見的程序架構

  • 1、傳統順序執行的程序架構

最多的時候,單片機程序都是使用while死循環,然后順序執行各種函數,這種程序設計比較簡單。

#include 
?
int main()
{
?? ?keys = KeyScan();
? ? while(1)
? ? {
?? ? ? ?if (keys ==1)
?? ? ? ?{
?? ??? ?//
?? ? ? ?}
? ? }
?
?
return 0;
}

缺點就是只適合做小項目,程序大了以后邏輯一定會非常混亂,實時性,穩定性,移植性差。

  • 2、實時操作系統

比如ucosrtos,用戶使用這些系統就只需要把系統移植好能跑起來就行。這種架構的優點就是它自身就是一個穩定性、實時性高的,有的甚至提供了圖形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; i OS_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

欄目分類
最近更新