1903020835 鄧柱

LiteOS內(nèi)核的任務(wù)管理

Huawei LiteOS 任務(wù)管理模塊提供任務(wù)創(chuàng)建、任務(wù)刪除、任務(wù)延時、任務(wù)掛起和任務(wù)恢復(fù)、更改任務(wù)優(yōu)先級、鎖任務(wù)調(diào)度和解鎖任務(wù)調(diào)度、根據(jù)任務(wù)控制塊查詢?nèi)蝿?wù) ID、根據(jù) ID 查詢?nèi)蝿?wù)控制塊信息功能。

1、任務(wù)的創(chuàng)建和管理

要求:本實驗中將創(chuàng)建兩個任務(wù),一個低優(yōu)先級任務(wù)task1,一個高優(yōu)先級任務(wù)task2,兩個任務(wù)都會每隔2s在串口打印自己的任務(wù)id號,在串口終端中觀察兩個任務(wù)的運行情況。
基于HELLO工程,進(jìn)行創(chuàng)建,在demo文件夾下創(chuàng)建oasl_kernel_demo文件存放內(nèi)核


image.png

接下來在此osal_kernel_demo文件夾中新建第一個實驗文件osal_task_demo.c文件,開始編寫代碼:

/* 使用osal接口需要包含該頭文件 */

#include <osal.h>

/* 任務(wù)優(yōu)先級宏定義(shell任務(wù)的優(yōu)先級為10) */
#define USER_TASK1_PRI  12  //低優(yōu)先級
#define USER_TASK2_PRI  11  //高優(yōu)先級

/* 任務(wù)ID */
uint32_t user_task1_id = 0;
uint32_t user_task2_id = 0;

/* 任務(wù)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);

        /* 任務(wù)主動掛起2s */
        osal_task_sleep(2*1000);
    }

    printf("user task 1 exit!\r\n");

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

/* 標(biāo)準(zhǔn)demo啟動函數(shù),函數(shù)名不要修改,否則會影響下一步實驗 */
int standard_app_demo_main()
{
    /* 創(chuàng)建任務(wù)task1 */
    user_task1_id = osal_task_create("user_task1",user_task1_entry,NULL,0x400,NULL,USER_TASK1_PRI);

    /* 創(chuàng)建任務(wù)task2 */
    user_task2_id = osal_task_create("user_task2",user_task2_entry,NULL,0x400,NULL,USER_TASK2_PRI);

    return 0;
image.png

編寫完成之后,要將我們編寫的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

接下來將osal_task_demo.c文件加入到makefile中進(jìn)行編譯。在工程根目錄下的.sdkconfig文件中的末尾即可配置:
CONFIG_USER_DEMO = "osal_task_demo"


image.png

因為我們修改了mk配置文件,所以點擊重新編譯按鈕進(jìn)行編譯,編譯完成后點擊下載按鈕燒錄程序。


image.png

燒錄過后,將串口打開,方法如下:
image.png

image.png

實驗現(xiàn)象:
image.png

總結(jié):可以看到,系統(tǒng)啟動后,首先打印版本號,串口shell的優(yōu)先級為10,最先打印shell信息,接下來task1先創(chuàng)建,但是優(yōu)先級為12,小于task2優(yōu)先級11,所以后創(chuàng)建的task2搶占執(zhí)行,task2輸出后主動掛起2s,這時低優(yōu)先級task1開始執(zhí)行,依次執(zhí)行5次后task1結(jié)束,task2一直保持運行。

2、LiteOS的互斥鎖

要求:本實驗中將創(chuàng)建兩個任務(wù),一個低優(yōu)先級任務(wù)task1,一個高優(yōu)先級任務(wù)task2,兩個任務(wù)之間依次對共享資源上鎖、操作、解鎖,在串口終端中觀察兩個任務(wù)的運行情況
實驗過程如下:
首先打開上一篇使用的 HelloWorld 工程,基于此工程進(jìn)行實驗。
在Demo文件夾右擊,新建文件夾osal_kernel_demo用于存放內(nèi)核的實驗文件,接下來在此文件夾中新建一個實驗文件 osal_mutex_demo.c


image.png

添加代碼如下:

/* 使用osal接口需要包含該頭文件 */
#include <osal.h>

/* 任務(wù)優(yōu)先級宏定義(shell任務(wù)的優(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;

/* 任務(wù)task1入口函數(shù) */
static int user_task1_entry()
{
    while(1)
    {
        /* 嘗試獲取互斥鎖 */
        if(true == osal_mutex_lock(public_value_mutex))
        {
            /* 獲取到互斥鎖,對共享資源進(jìn)行操作 */
            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é)束任務(wù) */
            if(public_value > 100)
                break;
            
        }
    }

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

/* 任務(wù)task2入口函數(shù) */
static int user_task2_entry()
{
    while (1)
    {
        /* 嘗試獲取互斥鎖 */
       if(true == osal_mutex_lock(public_value_mutex))
        {
            /* 獲取到互斥鎖,對共享資源進(jìn)行操作 */
            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é)束任務(wù) */
            if(public_value > 90)
                break;
            /* 優(yōu)先級較高,需要掛起一下,讓task1獲取到互斥鎖,否則task2再次上鎖,形成死鎖 */
            osal_task_sleep(10);
        }
    }

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

/* 標(biāo)準(zhǔn)demo啟動函數(shù),函數(shù)名不要修改,否則會影響下一步實驗 */
int standard_app_demo_main()
{
    /* 創(chuàng)建互斥鎖public_value_mutex */
    osal_mutex_create(&public_value_mutex);

    /* 創(chuàng)建任務(wù)task1 */
    osal_task_create("user_task1",user_task1_entry,NULL,0x400,NULL,USER_TASK1_PRI);

    /* 創(chuàng)建任務(wù)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配置文件,添加如下代碼(跟上一個任務(wù)添加方式一樣,所以不再演示細(xì)節(jié))截圖如下:

#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

將osal_mutex_demo.c文件加入到makefile中進(jìn)行編譯。在.sdkconfig中修改即可


image.png

重新編譯按鈕進(jìn)行編譯,編譯完成后點擊下載按鈕燒錄程序。
實驗現(xiàn)象如下:


image.png

總結(jié):可以看到,系統(tǒng)啟動后,首先打印版本號,串口shell的優(yōu)先級為10,最先打印shell信息,接下來優(yōu)先級高的task2執(zhí)行,獲得資源共享,執(zhí)行過后進(jìn)入鎖定狀態(tài),然后就是優(yōu)先級低的task1執(zhí)行,當(dāng)task1執(zhí)行過程中,task2是不能執(zhí)行的,必須有task1執(zhí)行完過后,解鎖完了,task2才能再次執(zhí)行。

3、LiteOS內(nèi)核的內(nèi)存管理

要求:本實驗中將創(chuàng)建一個任務(wù),從最小字節(jié)開始,不停的申請分配內(nèi)存,釋放分配的內(nèi)存,直到申請失敗,串口終端中觀察可以申請到的最大字節(jié)。
流程:
首先打開上一篇使用的 HelloWorld 工程,基于此工程進(jìn)行實驗。
在Demo文件夾右擊,新建文件夾osal_kernel_demo用于存放內(nèi)核的實驗文件
接下來在此文件夾中新建一個實驗文件 osal_mem_demo.c,開始編寫代碼:


image.png

代碼如下:

/* 使用osal接口需要包含該頭文件 */
#include <osal.h>

/* 任務(wù)入口函數(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
        {
            /* 申請失敗,打印信息,任務(wù)結(jié)束 */
            printf("access %d bytes memory failed!\r\n", mem_size);
            return 0;
        }
    }
}

/* 標(biāo)準(zhǔn)demo啟動函數(shù),函數(shù)名不要修改,否則會影響下一步實驗 */
int standard_app_demo_main()
{
    /* 創(chuàng)建任務(wù),任務(wù)優(yōu)先級為11,shell任務(wù)的優(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

講osal_mem_demo.c文件加入到makefile中進(jìn)行編譯。
那么,如何配置 CONFIG_USER_DEMO 宏定義呢?在工程根目錄下的.sdkconfig文件中的末尾即可配置,操作如下:


image.png

重新編譯按鈕進(jìn)行編譯,編譯完成后點擊下載按鈕燒錄程序。
實驗現(xiàn)象:


image.png

總結(jié):可以看到,系統(tǒng)啟動后,首先打印版本號,串口shell的優(yōu)先級為10,最先打印shell信息,接下來內(nèi)存申請任務(wù)創(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ā)布平臺,僅提供信息存儲服務(wù)。

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

  • 任務(wù)一: 任務(wù)的創(chuàng)建與切換 實驗內(nèi)容 在本實驗中將要創(chuàng)建兩個任務(wù),一個低優(yōu)先級任務(wù)task1,一個高優(yōu)先級任務(wù)ta...
    獨孤尚青閱讀 471評論 0 0
  • 任務(wù)一 體驗任務(wù)的創(chuàng)建與切換實驗內(nèi)容本實驗中將創(chuàng)建兩個任務(wù),一個低優(yōu)先級任務(wù)task1,一個高優(yōu)先級任務(wù)ta...
  • 1.LiteOS內(nèi)核的內(nèi)存管理 ①首先打開上一篇使用的 HelloWorld 工程,基于此工程進(jìn)行實驗。在Demo...
    土豆拌白米飯閱讀 694評論 0 0
  • 3. 動手實驗 —— 體驗任務(wù)的創(chuàng)建與切換 實驗內(nèi)容 本實驗中將創(chuàng)建兩個任務(wù),一個低優(yōu)先級任務(wù)task1,一個高優(yōu)...
    sss_7f59閱讀 864評論 0 0
  • 漸變的面目拼圖要我怎么拼? 我是疲乏了還是投降了? 不是不允許自己墜落, 我沒有滴水不進(jìn)的保護膜。 就是害怕變得面...
    悶熱當(dāng)乘涼閱讀 4,464評論 0 13

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