任務一: 任務的創(chuàng)建與切換
實驗內(nèi)容
在本實驗中將要創(chuàng)建兩個任務橘沥,一個低優(yōu)先級任務task1窗轩,一個高優(yōu)先級任務task2,兩個任務都會每隔2s在串口打印自己的任務id號座咆,在串口終端中觀察兩個任務的運行情況痢艺。
實驗代碼
首先打開之前創(chuàng)建的 HelloWorld 工程,基于此工程進行實驗介陶。
在Demo文件夾右擊堤舒,選擇新建文件夾:
YQ63GEYE6PCHRAX5(@3LMER.png
新建osal_kernel_demo文件夾,用于存放內(nèi)核的實驗文件:
image.png
接下來在此osal_kernel_demo文件夾中新建第一個實驗文件osal_task_demo.c文件哺呜,開始編寫代碼:
image.png
/* 使用osal接口需要包含該頭文件 */#include<osal.h>/* 任務優(yōu)先級宏定義(shell任務的優(yōu)先級為10) */#defineUSER_TASK1_PRI? 12//低優(yōu)先級#defineUSER_TASK2_PRI? 11//高優(yōu)先級/* 任務ID */uint32_tuser_task1_id=0;uint32_tuser_task2_id=0;/* 任務task1入口函數(shù) */staticintuser_task1_entry(){intn=0;/* 每隔2s在串口打印一次舌缤,打印5次后主動結束 */for(n=0;n<5;n++){printf("task1: my task id is %ld, n = %d!\r\n",user_task1_id,n);/* 任務主動掛起2s */osal_task_sleep(2*1000);}printf("user task 1 exit!\r\n");/* 任務結束 */return0;}/* 任務task2入口函數(shù) */staticintuser_task2_entry(){/* 每隔2s在串口打印一次,不結束 */while(1){printf("task 2: my task id is %ld!\r\n",user_task2_id);/* 任務主動掛起2s */osal_task_sleep(2*1000);}}/* 標準demo啟動函數(shù)某残,函數(shù)名不要修改国撵,否則會影響下一步實驗 */intstandard_app_demo_main(){/* 創(chuàng)建任務task1 */user_task1_id=osal_task_create("user_task1",user_task1_entry,NULL,0x400,NULL,USER_TASK1_PRI);/* 創(chuàng)建任務task2 */user_task2_id=osal_task_create("user_task2",user_task2_entry,NULL,0x400,NULL,USER_TASK2_PRI);return0;}
編寫完成之后,要將我們編寫的osal_task_demo.c文件添加到makefile中玻墅,加入整個工程的編譯:
這里有個較為簡單的方法卸留,直接修改Demo文件夾下的user_demo.mk配置文件,添加如下代碼:
#example for osal_task_demoifeq($(CONFIG_USER_DEMO),"osal_task_demo")user_demo_src=${wildcard $(TOP_DIR)/targets/STM32L431_BearPi/Demos/osal_kernel_demo/osal_task_demo.c}user_demo_defs=-DCONFIG_OSAL_TASK_DEMO_ENABLE=1endif
添加位置如圖:
image.png
之后在工程根目錄下的.sdkconfig文件中的末尾進行配置:
image.png
image.png
因為我們修改了mk配置文件椭豫,所以點擊重新編譯按鈕
image.png
進行編譯,編譯完成后點擊下載按鈕燒錄程序。
實驗現(xiàn)象
程序燒錄之后赏酥,即可看到程序已經(jīng)開始運行喳整,在串口終端中可看到實驗的輸出內(nèi)容:
ST76NVR%1UI1M$H)FN}QPSV.png
可以看到,系統(tǒng)啟動后裸扶,首先打印版本號框都,串口shell的優(yōu)先級為10,最先打印shell信息呵晨,接下來task1先創(chuàng)建魏保,但是優(yōu)先級較低,所以后創(chuàng)建的task2搶占執(zhí)行摸屠,task2打印后主動掛起2s谓罗,這時task1開始執(zhí)行,依次執(zhí)行5次后task1結束季二,task2一直保持運行檩咱。
image.png
任務二 LiteOS的互斥鎖
實驗內(nèi)容
本實驗中將創(chuàng)建兩個任務,一個低優(yōu)先級任務task1胯舷,一個高優(yōu)先級任務task2刻蚯,兩個任務之間依次對共享資源上鎖、操作桑嘶、解鎖炊汹,在串口終端中觀察兩個任務的運行情況。
實驗代碼
首先打開上一篇使用的 HelloWorld 工程逃顶,基于此工程進行實驗讨便。
在Demo文件夾右擊,新建文件夾osal_kernel_demo用于存放內(nèi)核的實驗文件(如果已有請忽略這一步)口蝠。
接下來在此文件夾中新建一個實驗文件 osal_mutex_demo.c器钟,開始編寫代碼:
image.png
/* 使用osal接口需要包含該頭文件 */#include<osal.h>/* 任務優(yōu)先級宏定義(shell任務的優(yōu)先級為10) */#defineUSER_TASK1_PRI? 12//低優(yōu)先級#defineUSER_TASK2_PRI? 11//高優(yōu)先級/* 共享資源 */uint32_tpublic_value=0;/* 互斥鎖索引ID */osal_mutex_t public_value_mutex;/* 任務task1入口函數(shù) */staticintuser_task1_entry(){while(1){/* 嘗試獲取互斥鎖 */if(true==osal_mutex_lock(public_value_mutex)){/* 獲取到互斥鎖,對共享資源進行操作 */printf("\r\ntask1: lock a mutex.\r\n");public_value+=10;printf("task1: public_value = %ld.\r\n",public_value);/* 對共享資源操作完畢妙蔗,釋放互斥鎖 */printf("task1: unlock a mutex.\r\n\r\n");osal_mutex_unlock(public_value_mutex);/* 滿足條件則結束任務 */if(public_value>100)break;}}/* while(1)會執(zhí)行結束傲霸,所以需要返回值 */return0;}/* 任務task2入口函數(shù) */staticintuser_task2_entry(){while(1){/* 嘗試獲取互斥鎖 */if(true==osal_mutex_lock(public_value_mutex)){/* 獲取到互斥鎖,對共享資源進行操作 */printf("\r\ntask2: lock a mutex.\r\n");public_value+=5;printf("task2: public_value = %ld.\r\n",public_value);/* 對共享資源操作完畢眉反,釋放互斥鎖 */printf("task2: unlock a mutex.\r\n\r\n");osal_mutex_unlock(public_value_mutex);/* 滿足條件則結束任務 */if(public_value>90)break;/* 優(yōu)先級較高昙啄,需要掛起一下,讓task1獲取到互斥鎖寸五,否則task2再次上鎖梳凛,形成死鎖 */osal_task_sleep(10);}}/* while(1)會執(zhí)行結束,所以需要返回值 */return0;}/* 標準demo啟動函數(shù)梳杏,函數(shù)名不要修改韧拒,否則會影響下一步實驗 */intstandard_app_demo_main(){/* 創(chuàng)建互斥鎖public_value_mutex */osal_mutex_create(&public_value_mutex);/* 創(chuàng)建任務task1 */osal_task_create("user_task1",user_task1_entry,NULL,0x400,NULL,USER_TASK1_PRI);/* 創(chuàng)建任務task2 */osal_task_create("user_task2",user_task2_entry,NULL,0x400,NULL,USER_TASK2_PRI);return0;}
編寫完成之后淹接,要將我們編寫的 osal_mutex_demo.c文件添加到makefile中,加入整個工程的編譯:
這里有個較為簡單的方法叛溢,直接修改Demo文件夾下的user_demo.mk配置文件塑悼,添加如下代碼:
#example for osal_mutex_demoifeq($(CONFIG_USER_DEMO),"osal_mutex_demo")user_demo_src=${wildcard $(TOP_DIR)/targets/STM32L431_BearPi/Demos/osal_kernel_demo/osal_mutex_demo.c}endif
添加位置如圖:
image.png
這段代碼的意思是:
如果 CONFIG_USER_DEMO 宏定義的值是osal_mutex_demo,則將osal_mutex_demo.c文件加入到makefile中進行編譯楷掉。
那么厢蒜,如何配置 CONFIG_USER_DEMO 宏定義呢?在工程根目錄下的.sdkconfig文件中的末尾即可配置:
image.png
因為我們修改了mk配置文件烹植,所以點擊重新編譯按鈕進行編譯斑鸦,編譯完成后點擊下載按鈕燒錄程序。
實驗現(xiàn)象
程序燒錄之后草雕,即可看到程序已經(jīng)開始運行巷屿,在串口終端中可看到實驗的輸出內(nèi)容:
ZI7RTUA4LGPM)0_1(_G4V`5.png
可以看到,系統(tǒng)啟動后促绵,首先打印版本號攒庵,串口shell的優(yōu)先級為10,最先打印shell信息败晴,接下來task1先創(chuàng)建浓冒,但是優(yōu)先級較低,所以后創(chuàng)建的task2搶占執(zhí)行尖坤,task2獲取到互斥鎖稳懒,對共享資源進行操作,操作完畢解鎖慢味,然后主動掛起场梆,task1獲取到互斥鎖,對共享資源進行另一個操作纯路,操作完畢解鎖或油,在task1操作的時候,task2早已掛起完畢驰唬,但是獲取不到互斥鎖顶岸,所以掛起等待,在task1解鎖后叫编,堵塞的task2被喚醒開始執(zhí)行辖佣。
任務三 測試動態(tài)內(nèi)存分配的最大字節(jié)
實驗內(nèi)容
本實驗中將創(chuàng)建一個任務,從最小字節(jié)開始搓逾,不停的申請分配內(nèi)存卷谈,釋放分配的內(nèi)存,直到申請失敗霞篡,串口終端中觀察可以申請到的最大字節(jié)世蔗。
實驗代碼
首先打開上一篇使用的 HelloWorld 工程端逼,基于此工程進行實驗。
在Demo文件夾右擊凸郑,新建文件夾osal_kernel_demo用于存放內(nèi)核的實驗文件(如果已有請忽略這一步)裳食。
接下來在此文件夾中新建一個實驗文件 osal_mem_demo.c,開始編寫代碼:
image.png
/* 使用osal接口需要包含該頭文件 */#include<osal.h>/* 任務入口函數(shù) */staticintmem_access_task_entry(){uint32_ti=0;//循環(huán)變量size_t mem_size;//申請的內(nèi)存塊大小uint8_t*mem_ptr=NULL;//內(nèi)存塊指針while(1){/* 每次循環(huán)將申請內(nèi)存的大小擴大一倍 */mem_size=1<<i++;/* 嘗試申請分配內(nèi)存 */mem_ptr=osal_malloc(mem_size);/* 判斷是否申請成功 */if(mem_ptr!=NULL){/* 申請成功芙沥,打印信息 */printf("access %d bytes memory success!\r\n",mem_size);/* 釋放申請的內(nèi)存,便于下次申請 */osal_free(mem_ptr);/* 將內(nèi)存塊指針置為NULL浊吏,避免稱為野指針 */mem_ptr=NULL;printf("free memory success!\r\n");}else{/* 申請失敗而昨,打印信息,任務結束 */printf("access %d bytes memory failed!\r\n",mem_size);return0;}}}/* 標準demo啟動函數(shù)找田,函數(shù)名不要修改歌憨,否則會影響下一步實驗 */intstandard_app_demo_main(){/* 創(chuàng)建任務,任務優(yōu)先級為11墩衙,shell任務的優(yōu)先級為10 */osal_task_create("mem_access_task",mem_access_task_entry,NULL,0x400,NULL,11);return0;}
編寫完成之后务嫡,要將我們編寫的 osal_mem_demo.c文件添加到makefile中,加入整個工程的編譯:
這里有個較為簡單的方法漆改,直接修改Demo文件夾下的user_demo.mk配置文件心铃,添加如下代碼:
#example for osal_mem_demoifeq($(CONFIG_USER_DEMO),"osal_mem_demo")user_demo_src=${wildcard $(TOP_DIR)/targets/STM32L431_BearPi/Demos/osal_kernel_demo/osal_mem_demo.c}endif
添加位置如圖:
image.png
這段代碼的意思是:
如果 CONFIG_USER_DEMO 宏定義的值是osal_mem_demo,則將osal_mem_demo.c文件加入到makefile中進行編譯挫剑。
那么去扣,如何配置 CONFIG_USER_DEMO 宏定義呢?在工程根目錄下的.sdkconfig文件中的末尾即可配置:
image.png
因為我們修改了mk配置文件樊破,所以點擊重新編譯按鈕進行編譯愉棱,編譯完成后點擊下載按鈕燒錄程序。
實驗現(xiàn)象
程序燒錄之后哲戚,即可看到程序已經(jīng)開始運行奔滑,在串口終端中可看到實驗的輸出內(nèi)容:![{[1_AY6Q$I)RWZ{~WF97_1.png
可以看到,系統(tǒng)啟動后顺少,首先打印版本號,串口shell的優(yōu)先級為10朋其,最先打印shell信息,接下來內(nèi)存申請任務創(chuàng)建開始執(zhí)行祈纯,在該芯片上最大能申請的空間為 16384 字節(jié)