LiteOs實驗

任務一 體驗任務的創(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) */
#define USER_TASK1_PRI  12  //低優(yōu)先級
#define USER_TASK2_PRI  11  //高優(yōu)先級

/* 任務ID */
uint32_t user_task1_id = 0;
uint32_t user_task2_id = 0;

/* 任務task1入口函數(shù) */
static int user_task1_entry()
{
    int n = 0;

    /* 每隔2s在串口打印一次,打印5次后主動結(jié)束 */
    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");

    /* 任務結(jié)束 */
    return 0;
}
/* 任務task2入口函數(shù) */
static int user_task2_entry()
{
    /* 每隔2s在串口打印一次,不結(jié)束 */
    while (1)
    {
        printf("task 2: my task id is %ld!\r\n", user_task2_id);
        
        /* 任務主動掛起2s */
        osal_task_sleep(2*1000);
    }
}

/* 標準demo啟動函數(shù),函數(shù)名不要修改,否則會影響下一步實驗 */
int standard_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);

    return 0;
}

編寫完成之后,要將我們編寫的osal_task_demo.c文件添加到makefile中,加入整個工程的編譯:

這里有個較為簡單的方法,直接修改Demo文件夾下的user_demo.mk配置文件,添加如下代碼:

#example for osal_task_demo
    ifeq ($(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 = -D CONFIG_OSAL_TASK_DEMO_ENABLE=1
    endif

添加位置如圖:
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結(jié)束,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) */
#define USER_TASK1_PRI  12  //低優(yōu)先級
#define USER_TASK2_PRI  11  //高優(yōu)先級

/* 共享資源 */
uint32_t public_value = 0;

/* 互斥鎖索引ID */
osal_mutex_t public_value_mutex;

/* 任務task1入口函數(shù) */
static int user_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);

            /* 滿足條件則結(jié)束任務 */
            if(public_value > 100)
                break;
            
        }
    }

    /* while(1)會執(zhí)行結(jié)束,所以需要返回值 */
    return 0;
}

/* 任務task2入口函數(shù) */
static int user_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);
            
            /* 滿足條件則結(jié)束任務 */
            if(public_value > 90)
                break;
            /* 優(yōu)先級較高,需要掛起一下,讓task1獲取到互斥鎖,否則task2再次上鎖,形成死鎖 */
            osal_task_sleep(10);
        }
    }

    /* while(1)會執(zhí)行結(jié)束,所以需要返回值 */
    return 0;
}

/* 標準demo啟動函數(shù),函數(shù)名不要修改,否則會影響下一步實驗 */
int standard_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);

    return 0;
}

編寫完成之后,要將我們編寫的 osal_mutex_demo.c文件添加到makefile中,加入整個工程的編譯:

這里有個較為簡單的方法,直接修改Demo文件夾下的user_demo.mk配置文件,添加如下代碼:

#example for osal_mutex_demo
ifeq ($(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í)行。

  1. 任務三 測試動態(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ù) */
static int mem_access_task_entry()
{
    uint32_t i = 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
        {
            /* 申請失敗,打印信息,任務結(jié)束 */
            printf("access %d bytes memory failed!\r\n", mem_size);
            return 0;
        }
    }
}

/* 標準demo啟動函數(shù),函數(shù)名不要修改,否則會影響下一步實驗 */
int standard_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);
    return 0;
}

編寫完成之后,要將我們編寫的 osal_mem_demo.c文件添加到makefile中,加入整個工程的編譯:

這里有個較為簡單的方法,直接修改Demo文件夾下的user_demo.mk配置文件,添加如下代碼:

#example for osal_mem_demo
ifeq ($(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é)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容