FreeRTOS使用任務(wù)通知實(shí)現(xiàn)命令行解釋器
前言
雖然這是介紹FreeRTOS系列的文章,但這篇文章偏重于命令行解釋器的實(shí)現(xiàn)。這一方面是因?yàn)槿蝿?wù)通知使用起來非常簡(jiǎn)單,另一方面也因?yàn)閷?duì)于嵌入式程序來說,使用命令行解釋器來輔助程序調(diào)試是非常有用的。程序調(diào)試是一門技術(shù),基本上我們需要兩種調(diào)試手段,一種是可以單步仿真的硬件調(diào)試器,另外一種是可以長(zhǎng)期監(jiān)視程序狀態(tài)的狀態(tài)輸出,可以通過串口、顯示屏等等手段輸出異常信息或者某些關(guān)鍵點(diǎn)。這里的命令行解釋器就屬于后者。
本文實(shí)現(xiàn)的命令行解釋器具有以下特性:
支持十進(jìn)制參數(shù),識(shí)別負(fù)號(hào);
支持十六進(jìn)制參數(shù),十六進(jìn)制以‘0x’開始;
命令名長(zhǎng)度可定義,默認(rèn)最大20個(gè)字符;
參數(shù)數(shù)目可定義,默認(rèn)最多8個(gè)參數(shù);
命令名和參數(shù)之間以空格隔開,空格個(gè)數(shù)任意;
整條命令以回車換行符結(jié)束;
整條命令最大長(zhǎng)度可定義,默認(rèn)64字節(jié),包括回車換行符;
如果使用SecureCRT串口工具(推薦),支持該軟件的控制字符,比如退格鍵、左移鍵、右移鍵等。
一個(gè)帶參數(shù)的命令格式如下所示:
參數(shù)名 <參數(shù)1> <參數(shù)2> … <參數(shù)3>[回車換行符]
1.編碼風(fēng)格
FreeRTOS的編碼標(biāo)準(zhǔn)及風(fēng)格見FreeRTOS編碼標(biāo)準(zhǔn)及風(fēng)格指南,但我自己的編碼風(fēng)格跟FreeRTOS并不相同,并且我也不打算改變我當(dāng)前堅(jiān)持使用的編碼風(fēng)格。所以在這篇或者以后的文章中可能會(huì)在一個(gè)程序中看到兩種不同的編碼風(fēng)格,對(duì)于涉及FreeRTOS的代碼,我盡可能使用FreeRTOS建議的編碼風(fēng)格,與FreeRTOS無關(guān)的代碼,我仍然使用自己的編碼風(fēng)格。我可以保證,兩種編碼風(fēng)格決不會(huì)影響程序的可讀性,編寫良好可讀性的代碼,是我一直注重并堅(jiān)持的。
2.一些準(zhǔn)備工作
2.1串口硬件驅(qū)動(dòng)
命令行解釋器使用一個(gè)硬件串口,需要外部提供兩個(gè)串口底層函數(shù):一個(gè)是串口初始化函數(shù)init_cmd_uart(),用于初始化串口波特率、中斷等事件;另一個(gè)是發(fā)送單個(gè)字符函數(shù)my_putc()。此外,命令行為串口接收中斷服務(wù)程序提供函數(shù)fill_rec_buf(),用于保存接收到的字符,當(dāng)收到回車換行符后,該函數(shù)向命令行分析任務(wù)發(fā)送通知。
2.2一個(gè)類printf函數(shù)
類printf函數(shù)用來格式化輸出,我一般用來輔助調(diào)試,為了方便的將調(diào)試代碼從程序中去除,需要將類printf函數(shù)進(jìn)行封裝。我的文章嵌入式C程序優(yōu)質(zhì)編寫教程第5.2節(jié)給出了一個(gè)完整的類printf函數(shù)實(shí)現(xiàn)和封裝代碼,最終我們使用到的類printf函數(shù)是如下形式的宏:
MY_DEBUGF(CMD_LINE_DEBUG,("第%d個(gè)參數(shù):%d\n",i+1,arg[i]));
3.使用任務(wù)通知
我們將會(huì)創(chuàng)建一個(gè)任務(wù),用來分析接收到的命令,如果命令有效則調(diào)用命令實(shí)現(xiàn)函數(shù)。這個(gè)任務(wù)名字為vTaskCmdAnalyze()。串口接收中斷用于接收命令,如果接收到回車換行符,則向任務(wù)vTaskCmdAnalyze()發(fā)送任務(wù)通知,表明已經(jīng)接收到一條完整命令,任務(wù)可以去處理了。
示意框圖如圖3-1所示。
4.數(shù)據(jù)結(jié)構(gòu)
命令行解釋器程序需要涉及兩個(gè)數(shù)據(jù)結(jié)構(gòu):一個(gè)與命令有關(guān),包括命令的名字、命令的最大參數(shù)數(shù)目、命令的回調(diào)函數(shù)類型、命令幫助信息等;另一個(gè)與分析命令有關(guān),包括接收命令字符緩沖區(qū)、存放參數(shù)緩沖區(qū)等。
4.1與命令有關(guān)的數(shù)據(jù)結(jié)構(gòu)
定義如下:
typedef struct { char const *cmd_name; //命令字符串 int32_t max_args; //最大參數(shù)數(shù)目 void (*handle)(int argc,void * cmd_arg); //命令回調(diào)函數(shù) char *help; //幫助信息 }cmd_list_struct;
需要說明一下命令回調(diào)函數(shù)的參數(shù),argc保存接收到的參數(shù)數(shù)目,cmd_arg指向參數(shù)緩沖區(qū),目前只支持32位的整形參數(shù),這在絕大多數(shù)嵌入式場(chǎng)合是足夠的。
4.2與分析命令有關(guān)數(shù)據(jù)結(jié)構(gòu)
定義如下:
#define ARG_NUM 8 //命令中允許的參數(shù)個(gè)數(shù) #define CMD_LEN 20 //命令名占用的最大字符長(zhǎng)度 #define CMD_BUF_LEN 60 //命令緩存的最大長(zhǎng)度 typedef struct { char rec_buf[CMD_BUF_LEN]; //接收命令緩沖區(qū) char processed_buf[CMD_BUF_LEN]; //存儲(chǔ)加工后的命令(去除控制字符) int32_t cmd_arg[ARG_NUM]; //保存命令的參數(shù) }cmd_analyze_struct;
緩沖區(qū)的大小使用宏來定義,通過更改相應(yīng)的宏定義,可以設(shè)置整條命令的最大長(zhǎng)度、命令參數(shù)最大數(shù)目等。
5.串口接收中斷處理函數(shù)
本文使用的串口軟件是SecureCRT,在這個(gè)軟件下敲擊的任何鍵盤字符,都會(huì)立刻通過串口硬件發(fā)送出去,這與Telnet類似。所以我們無需使用串口的FIFO,每接收到一個(gè)字符就產(chǎn)生一次中斷。串口中斷與硬件關(guān)系密切,所以命令行解釋器提供了一個(gè)與硬件無關(guān)的函數(shù)fill_rec_buf(),每當(dāng)串口中斷接收到一個(gè)字符,就以收到的字符為參數(shù)調(diào)用這個(gè)函數(shù)。 fill_rec_buf()函數(shù)主要操作變量cmd_analyze,變量的聲明原型為:
cmd_analyze_struct cmd_analyze;
函數(shù)fill_rec_buf()的實(shí)現(xiàn)代碼為:
/*提供給串口中斷服務(wù)程序,保存串口接收到的單個(gè)字符*/ void fill_rec_buf(char data) { //接收數(shù)據(jù) static uint32_t rec_count=0; cmd_analyze.rec_buf[rec_count]=data; if(0x0A==cmd_analyze.rec_buf[rec_count] && 0x0D==cmd_analyze.rec_buf[rec_count-1]) { BaseType_t xHigherPriorityTaskWoken = pdFALSE; rec_count=0; /*收到一幀數(shù)據(jù),向命令行解釋器任務(wù)發(fā)送通知*/ vTaskNotifyGiveFromISR (xCmdAnalyzeHandle,&xHigherPriorityTaskWoken); /*是否需要強(qiáng)制上下文切換*/ portYIELD_FROM_ISR(xHigherPriorityTaskWoken ); } else { rec_count++; /*防御性代碼,防止數(shù)組越界*/ if(rec_count>=CMD_BUF_LEN) { rec_count=0; } } }
6.命令行分析任務(wù)
命令行分析任務(wù)大部分時(shí)間都會(huì)因?yàn)榈却蝿?wù)通知而處于阻塞狀態(tài)。當(dāng)接收到一個(gè)通知后,任務(wù)首先去除命令行中的無效字符和控制字符,然后找出命令名并分析參數(shù)數(shù)目、將參數(shù)轉(zhuǎn)換成十六進(jìn)制數(shù)并保存到參數(shù)緩沖區(qū)中,最后檢查命令名和參數(shù)是否合法,如果合法則調(diào)用命令回調(diào)函數(shù)處理本條命令。
6.1去除無效字符和控制字符
串口軟件SecureCRT支持控制字符。比如在輸入一串命令的時(shí)候,發(fā)現(xiàn)某個(gè)字符輸入錯(cuò)誤,就要使用退格鍵或者左右移動(dòng)鍵定位到錯(cuò)誤的位置進(jìn)行修改。這里的退格鍵和左右移動(dòng)鍵都屬于控制字符,比如退格鍵的鍵值為0x08、左移鍵的鍵值為0x1B0x5B 0x44。我們之前也說過,在軟件SecureCRT中輸入字符時(shí),每敲擊一個(gè)字符,該字符立刻通過串口發(fā)送給我們的嵌入式設(shè)備,也就是所有鍵值都會(huì)按照敲擊鍵盤的順序存入到接收緩沖區(qū)中,但這里面可能有我們不需要的字符,我們首先需要利用控制字符將不需要的字符刪除掉。這個(gè)工作由函數(shù)get_true_char_stream()實(shí)現(xiàn),代碼如下所示:
/** * 使用SecureCRT串口收發(fā)工具,在發(fā)送的字符流中可能帶有不需要的字符以及控制字符, * 比如退格鍵,左右移動(dòng)鍵等等,在使用命令行工具解析字符流之前,需要將這些無用字符以 * 及控制字符去除掉. * 支持的控制字符有: * 上移:1B 5B 41 * 下移:1B 5B 42 * 右移:1B 5B 43 * 左移:1B 5B 44 * 回車換行:0D 0A * Backspace:08 * Delete:7F */ static uint32_t get_true_char_stream(char *dest,const char *src) { uint32_t dest_count=0; uint32_t src_count=0; while(src[src_count]!=0x0D && src[src_count+1]!=0x0A) { if(isprint(src[src_count])) { dest[dest_count++]=src[src_count++]; } else { switch(src[src_count]) { case 0x08: //退格鍵鍵值 { if(dest_count>0) { dest_count --; } src_count ++; }break; case 0x1B: { if(src[src_count+1]==0x5B) { if(src[src_count+2]==0x41 || src[src_count+2]==0x42) { src_count +=3; //上移和下移鍵鍵值 } else if(src[src_count+2]==0x43) { dest_count++; //右移鍵鍵值 src_count+=3; } else if(src[src_count+2]==0x44) { if(dest_count >0) //左移鍵鍵值 { dest_count --; } src_count +=3; } else { src_count +=3; } } else { src_count ++; } }break; default: { src_count++; }break; } } } dest[dest_count++]=src[src_count++]; dest[dest_count++]=src[src_count++]; return dest_count; }
6.2參數(shù)分析
接收到的命令中可能帶有參數(shù),我們需要知道參數(shù)的數(shù)目,還需要把字符型的參數(shù)轉(zhuǎn)換成整形數(shù)并保存到參數(shù)緩沖區(qū)(這是因?yàn)槊罨卣{(diào)函數(shù)需要這兩個(gè)參數(shù))。這個(gè)工作由函數(shù)cmd_arg_analyze()實(shí)現(xiàn),代碼如下所示:
/** * 命令參數(shù)分析函數(shù),以空格作為一個(gè)參數(shù)結(jié)束,支持輸入十六進(jìn)制數(shù)(如:0x15),支持輸入負(fù)數(shù)(如-15) * @param rec_buf 命令參數(shù)緩存區(qū) * @param len 命令的最大可能長(zhǎng)度 * @return -1: 參數(shù)個(gè)數(shù)過多,其它:參數(shù)個(gè)數(shù) */ static int32_t cmd_arg_analyze(char *rec_buf,unsigned int len) { uint32_t i; uint32_t blank_space_flag=0; //空格標(biāo)志 uint32_t arg_num=0; //參數(shù)數(shù)目 uint32_t index[ARG_NUM]; //有效參數(shù)首個(gè)數(shù)字的數(shù)組索引 /*先做一遍分析,找出參數(shù)的數(shù)目,以及參數(shù)段的首個(gè)數(shù)字所在rec_buf數(shù)組中的下標(biāo)*/ for(i=0;i<len;i++) { if(rec_buf[i]==0x20) //為空格 { blank_space_flag=1; continue; } else if(rec_buf[i]==0x0D) //換行 { break; } else { if(blank_space_flag==1) { blank_space_flag=0; if(arg_num < ARG_NUM) { index[arg_num]=i; arg_num++; } else { return -1; //參數(shù)個(gè)數(shù)太多 } } } } for(i=0;i<arg_num;i++) { cmd_analyze.cmd_arg[i]=string_to_dec((unsigned char *)(rec_buf+index[i]),len-index[i]); } return arg_num; }
在這個(gè)函數(shù)cmd_arg_analyze()中,調(diào)用了字符轉(zhuǎn)整形函數(shù)string_to_dec()。我們只支持整形參數(shù),這里給出一個(gè)字符轉(zhuǎn)整形函數(shù)的簡(jiǎn)單實(shí)現(xiàn),可以識(shí)別負(fù)號(hào)和十六進(jìn)制的前綴’0x’。在這個(gè)函數(shù)中調(diào)用了三個(gè)C庫(kù)函數(shù),分別是isdigit()、isxdigit()和tolower(),因此需要包含頭文件#include <ctype.h>。函數(shù)string_to_dec()實(shí)現(xiàn)代碼如下:
/*字符串轉(zhuǎn)10/16進(jìn)制數(shù)*/ static int32_t string_to_dec(uint8_t *buf,uint32_t len) { uint32_t i=0; uint32_t base=10; //基數(shù) int32_t neg=1; //表示正負(fù),1=正數(shù) int32_t result=0; if((buf[0]=='0')&&(buf[1]=='x')) { base=16; neg=1; i=2; } else if(buf[0]=='-') { base=10; neg=-1; i=1; } for(;i<len;i++) { if(buf[i]==0x20 || buf[i]==0x0D) //為空格 { break; } result *= base; if(isdigit(buf[i])) //是否為0~9 { result += buf[i]-'0'; } else if(isxdigit(buf[i])) //是否為a~f或者A~F { result+=tolower(buf[i])-87; } else { result += buf[i]-'0'; } } result *= neg; return result ; }
6.3定義命令回調(diào)函數(shù)
我們舉兩個(gè)例子:第一個(gè)是不帶參數(shù)的例子,輸入命令后,函數(shù)返回一個(gè)“Helloworld!”字符串;第二個(gè)是帶參數(shù)的例子,我們輸入命令和參數(shù)后,函數(shù)返回每一個(gè)參數(shù)值。我們?cè)谥v數(shù)據(jù)結(jié)構(gòu)的時(shí)候特別提到過命令回調(diào)函數(shù)的原型,這里要根據(jù)這個(gè)函數(shù)原型來聲明命令回調(diào)函數(shù)。
6.3.1不帶參數(shù)的命令回調(diào)函數(shù)舉例
/*打印字符串:Hello world!*/ void printf_hello(int32_t argc,void *cmd_arg) { MY_DEBUGF(CMD_LINE_DEBUG,("Hello world!\n")); }
6.3.2帶參數(shù)的命令行回調(diào)函數(shù)舉例
/*打印每個(gè)參數(shù)*/ void handle_arg(int32_t argc,void * cmd_arg) { uint32_t i; int32_t *arg=(int32_t *)cmd_arg; if(argc==0) { MY_DEBUGF(CMD_LINE_DEBUG,("無參數(shù)\n")); } else { for(i=0;i<argc;i++) { MY_DEBUGF(CMD_LINE_DEBUG,("第%d個(gè)參數(shù):%d\n",i+1,arg[i])); } } }
6.4定義命令表
在講數(shù)據(jù)結(jié)構(gòu)的時(shí)候,我們定義了與命令有關(guān)的數(shù)據(jù)結(jié)構(gòu)。每條命令需要包括命名名、最大參數(shù)、命令回調(diào)函數(shù)、幫助等信息,這里要將每條命令組織成列表的形式。
/*命令表*/ const cmd_list_struct cmd_list[]={ /* 命令 參數(shù)數(shù)目 處理函數(shù) 幫助信息 */ {"hello", 0, printf_hello, "hello -打印HelloWorld!"}, {"arg", 8, handle_arg, "arg<arg1> <arg2> ... -測(cè)試用,打印輸入的參數(shù)"}, };
如果要定義自己的命令,只需要按照6.3節(jié)的格式編寫命令回調(diào)函數(shù),然后將命令名、參數(shù)數(shù)目、回調(diào)函數(shù)和幫助信息按照本節(jié)格式加入到命令表中即可。
6.5命令行分析任務(wù)實(shí)現(xiàn)
有了上面的基礎(chǔ),命令行分析任務(wù)實(shí)現(xiàn)起來就非常輕松了,源碼如下:
/*命令行分析任務(wù)*/ void vTaskCmdAnalyze( void *pvParameters ) { uint32_t i; int32_t rec_arg_num; char cmd_buf[CMD_LEN]; while(1) { uint32_t rec_num; ulTaskNotifyTake(pdTRUE,portMAX_DELAY); rec_num=get_true_char_stream(cmd_analyze.processed_buf,cmd_analyze.rec_buf); /*從接收數(shù)據(jù)中提取命令*/ for(i=0;i<CMD_LEN;i++) { if((i>0)&&((cmd_analyze.processed_buf[i]==' ')||(cmd_analyze.processed_buf[i]==0x0D))) { cmd_buf[i]='\0'; //字符串結(jié)束符 break; } else { cmd_buf[i]=cmd_analyze.processed_buf[i]; } } rec_arg_num=cmd_arg_analyze(&cmd_analyze.processed_buf[i],rec_num); for(i=0;i<sizeof(cmd_list)/sizeof(cmd_list[0]);i++) { if(!strcmp(cmd_buf,cmd_list[i].cmd_name)) //字符串相等 { if(rec_arg_num<0 || rec_arg_num>cmd_list[i].max_args) { MY_DEBUGF(CMD_LINE_DEBUG,("參數(shù)數(shù)目過多!\n")); } else { cmd_list[i].handle(rec_arg_num,(void *)cmd_analyze.cmd_arg); } break; } } if(i>=sizeof(cmd_list)/sizeof(cmd_list[0])) { MY_DEBUGF(CMD_LINE_DEBUG,("不支持的指令!\n")); } } }
7.使用的串口工具
推薦使用SecureCRT軟件,這是我覺得最適合命令行交互的串口工具。此外,這個(gè)軟件非常強(qiáng)大,除了支持串口,還支持SSH、Telnet等。對(duì)于串口,SecureCRT工具還支持文件發(fā)送協(xié)議:Xmodem、Ymodem和Zmodem。這在使用串口遠(yuǎn)程升級(jí)時(shí)很有用,可以用來發(fā)送新的程序二進(jìn)制文件。我曾經(jīng)使用Ymodem做過遠(yuǎn)程升級(jí),以后有時(shí)間再詳細(xì)介紹SecureCRT的Ymodem功能細(xì)節(jié)。
要用于本文介紹的命令行解釋器,要對(duì)SecureCRT軟件做一些設(shè)置。
7.1設(shè)置串口參數(shù)
選擇Serial功能、設(shè)置端口、波特率、校驗(yàn)等,特別要注意的是不要勾選任何流控制選項(xiàng),如圖2-1所示。
圖2-1:設(shè)置串口參數(shù)
7.2設(shè)置新行模式
依次點(diǎn)擊菜單欄的“選項(xiàng)”---“會(huì)話選項(xiàng)”,在彈出的“會(huì)話選項(xiàng)”界面中,點(diǎn)擊左邊樹形菜單的“終端”---“仿真”---“模式”,在右邊的仿真模式區(qū)域選中“換行”和“新行模式”,如圖2-2所示。
圖2-2:設(shè)置新行模式
7.3設(shè)置本地回顯
依次點(diǎn)擊菜單欄的“選項(xiàng)”---“會(huì)話選項(xiàng)”,在彈出的“會(huì)話選項(xiàng)”界面中,點(diǎn)擊左邊樹形菜單的“終端”---“仿真”---“高級(jí)”,在右邊的“高級(jí)仿真”區(qū)域,選中“本地回顯”,如圖2-3所示。
圖2-3:設(shè)置本地回顯
8.測(cè)試
我們通過6.3節(jié)和6.4接定義了兩個(gè)命令,第一條命令的名字為”hello”,這是一個(gè)無參數(shù)命令,直接輸出字符串”Hello world!”。第二條命令的名字為”arg”,是一個(gè)帶參數(shù)命令,輸出每個(gè)參數(shù)的值。下面對(duì)這兩個(gè)命令進(jìn)行測(cè)試。
8.1無參數(shù)命令測(cè)試
設(shè)置好SecureCRT軟件,輸入字符”hello”后,按下回車鍵,設(shè)備會(huì)返回字符串”Hello world!”。如圖8-1所示。
圖8-1:無參數(shù)命令測(cè)試
8.2帶參數(shù)命令測(cè)試
設(shè)置好SecureCRT軟件,輸入字符”arg 1 2 -3 0x0a”后,按下回車鍵,設(shè)備會(huì)返回每個(gè)參數(shù)值。如圖8-2所示。
圖8-2:帶參數(shù)命令測(cè)試
以上就是FreeRTOS使用任務(wù)通知實(shí)現(xiàn)命令行解釋器的詳細(xì)內(nèi)容,更多關(guān)于FreeRTOS任務(wù)通知命令行解釋器的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)創(chuàng)建與任務(wù)切換
- FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)創(chuàng)建和刪除
- FreeRTOS進(jìn)階之任務(wù)通知示例完全解析
- FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)通知方法
- FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)應(yīng)用函數(shù)詳解
- FreeRTOS實(shí)時(shí)操作系統(tǒng)空閑任務(wù)的阻塞延時(shí)實(shí)現(xiàn)
- FreeRTOS任務(wù)控制API函數(shù)的功能分析
- FreeRTOS進(jìn)階之任務(wù)創(chuàng)建完全解析
相關(guān)文章
FreeRTOS動(dòng)態(tài)內(nèi)存分配管理heap_2示例
這篇文章主要介紹了FreeRTOS動(dòng)態(tài)內(nèi)存分配管理heap_2示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS實(shí)時(shí)操作系統(tǒng)隊(duì)列的API函數(shù)講解
這篇文章主要為大家介紹了FreeRTOS實(shí)時(shí)操作系統(tǒng)隊(duì)列的API函數(shù)講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS動(dòng)態(tài)內(nèi)存分配管理heap_4示例
這篇文章主要為大家介紹了FreeRTOS動(dòng)態(tài)內(nèi)存分配管理heap_4示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)概要講解
這篇文章主要為大家介紹了FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)概要講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)創(chuàng)建與任務(wù)切換
這篇文章主要為大家介紹了FreeRTOS實(shí)時(shí)操作系統(tǒng)的任務(wù)創(chuàng)建與任務(wù)切換,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS信號(hào)量API函數(shù)基礎(chǔ)教程
這篇文章主要為大家介紹了FreeRTOS信號(hào)量API函數(shù)的基礎(chǔ)教程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS進(jìn)階之空閑任務(wù)示例完全解析
這篇文章主要為大家介紹了FreeRTOS進(jìn)階之空閑任務(wù)示例的完全解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04FreeRTOS進(jìn)階之調(diào)度器啟動(dòng)過程分析
這篇文章主要為大家介紹了FreeRTOS進(jìn)階之調(diào)度器啟動(dòng)過程分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪2022-04-04