中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

LiteOS內存管理方法是什么

發布時間:2021-12-29 10:27:39 來源:億速云 閱讀:138 作者:iii 欄目:互聯網科技

這篇文章主要講解了“LiteOS內存管理方法是什么”,文中的講解內容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“LiteOS內存管理方法是什么”吧!

1. LiteOS內核的內存管理

1.1. 內存管理

在系統運行的過程中,一些內存空間大小是不確定的,比如一些數據緩沖區,所以系統需要提供內存空間的管理能力,用戶可以在使用的時候申請需要的內存空間,使用完畢釋放該空間,以便再次利用。

Huawei LiteOS 的內存管理模塊通過對內存的申請/釋放操作,來管理用戶和OS對內存的使用,使內存的利用率和使用效率達到最優,同時最大限度地解決系統的內存碎片問題。

1.2. 動態內存管理

動態內存管理,即在內存資源充足的情況下,從系統配置的一塊比較大的連續內存(內存池),根據用戶需求,分配任意大小的內存塊。當用戶不需要該內存塊時,又可以釋放回系統供下一次使用。

與靜態內存相比,動態內存管理的好處是按需分配,缺點是內存池中容易出現碎片

LiteOS動態內存支持 DLINK 和 BEST LITTLE 兩種標準算法。

1.2.1. DLINK 動態內存管理算法

DLINK動態內存管理結構如下圖所示:

LiteOS內存管理方法是什么

  • 第一部分

堆內存(也稱內存池)的起始地址及堆區域總大小。

  • 第二部分

本身是一個數組,每個元素是一個雙向鏈表,所有free節點的控制頭都會被分類掛在這個數組的雙向鏈表中。

LiteOS內存管理方法是什么

  • 第三部分

占用內存池極大部分的空間,是用于存放各節點的實際區域

1.2.2. BEST LITTLE 算法(重點)

LiteOS 的動態內存分配支持最佳適配算法,即 BEST LITTLE,每次分配時選擇內存池中最小最適合的內存塊進行分配。

LiteOS 動態內存管理在最佳適配算法的基礎上加入了 SLAB 機制,用于分配固定大小的內存塊,進而減小產生內存碎片的可能性

LiteOS 內存管理中的 SLAB 機制支持可配置的 SLAB CLASS 數目及每個 CLASS 的最大空間

現以 SLAB CLASS 數目為 4,每個 CLASS 的最大空間為 512 字節為例說明 SLAB 機制:

在內存池中共有 4 個 SLAB CLASS,每個 SLAB CLASS 的總共可分配大小為 512 字節,第一個 SLAB CLASS 被分為 32 個16 字節的 SLAB 塊,第二個 SLAB CLASS 被分為 16 個 3 2字節的 SLAB 塊,第三個 SLAB CLASS 被分為 8 個 64 字節的 SLAB 塊,第四個 SLAB CLASS 被分為 4 個 128 字節的 SLAB 塊。這 4 個 SLAB CLASS 是從內存池中按照最佳適配算法分配出來的。

初始化內存管理時,首先初始化內存池,然后在初始化后的內存池中按照最佳適配算法申請 4 個 SLAB CLASS,再逐個按照 SLAB 內存管理機制初始化 4 個 SLAB CLASS。

每次申請內存時,先在滿足申請大小的最佳 SLAB CLASS 中申請,(比如用戶申請 20 字節內存,就在 SLAB 塊大小為 32 字節的 SLAB CLASS 中申請),如果申請成功,就將 SLAB 內存塊整塊返回給用戶,釋放時整塊回收。如果滿足條件的 SLAB CLASS 中已無可以分配的內存塊,則繼續向內存池按照最佳適配算法申請。需要注意的是,如果當前的 SLAB CLASS 中無可用 SLAB 塊了,則直接向內存池申請,而不會繼續向有著更大 SLAB 塊空間的 SLAB CLASS 申請。

釋放內存時,先檢查釋放的內存塊是否屬于 SLAB CLASS,如果是 SLAB CLASS 的內存塊,則還回對應的 SLAB CLASS 中,否則還回內存池中。

LiteOS內存管理方法是什么

1.2.3. 兩種動態內存管理方法的選擇

LiteOS動態內存管理的方法使用宏定義的方法使能,在用戶工程目錄下的OS_CONFIG中的target_config.h文件中配置。

在該文件中,找到下面這兩項宏定義,置為 YES 則表示使能:

  • 開啟BEST LITTLE 算法

#define LOSCFG_MEMORY_BESTFIT   YES
  • 開啟SLAB機制

#define LOSCFG_KERNEL_MEM_SLAB  YES

1.3. 動態內存管理的應用場景

內存管理的主要工作是動態的劃分并管理用戶分配好的內存區間。

動態內存管理主要是在用戶需要使用大小不等的內存塊的場景中使用。當用戶需要分配內存時,可以通過操作系統的動態內存申請函數索取指定大小內存塊,一旦使用完畢,通過動態內存釋放函數歸還所占用內存,使之可以重復使用。

2. 動態內存管理API

Huawei LiteOS 系統中的內存管理模塊管理系統的內存資源,主要提供內存的初始化、分配以及釋放功能。

Huawei LiteOS 系統中提供的內存管理 API 都是以 LOS 開頭,但是這些 API 使用起來比較復雜,所以本文中我們使用 Huawei IoT Link SDK 提供的統一API接口進行實驗,這些接口底層已經使用 LiteOS 提供的API實現,對用戶而言更為簡潔,API列表如下:

osal的api接口聲明在<osal.h>中,使用相關的接口需要包含該頭文件,關于函數的詳細參數請參考該頭文件的聲明。

相關的接口定義在osal.c中,基于LiteOS的接口實現在 liteos_imp.c文件中:

接口名功能描述
osal_malloc按字節申請分配動態內存空間
osal_free釋放已經分配的動態內存空間
osal_zalloc按字節申請分配動態內存空間,分配成功則初始化這塊內存所有值為0
osal_realloc重新申請分配動態內存空間
osal_calloc申請分配num個長度為size的動態內存空間

無論選擇使用哪種動態內存管理算法,都使用該API。

2.1. osal_malloc

osal_malloc接口用于按字節申請分配動態內存空間,其接口原型如下:

void *osal_malloc(size_t size)
{
    void *ret = NULL;

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->malloc))
    {
        ret = s_os_cb->ops->malloc(size);
    }

    return ret;

}

該接口的參數說明如下表:

參數描述
size申請分配的內存大小,單位Byte
返回值分配成功 - 返回內存塊指針

分配失敗 - 返回NULL

2.2. osal_free

osal_free接口用于釋放已經分配的動態內存空間,其接口原型如下:

void  osal_free(void *addr)
{

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->free))
    {
        s_os_cb->ops->free(addr);
    }

    return;
}

內存塊free之后,記得使內存塊指針為NULL,否則會成為野指針!

該接口的參數說明如下表:

參數描述
addr動態分配內存空間的指針
返回值無返回值

2.3. osal_zalloc

osal_zalloc接口用于按字節申請分配動態內存空間,分配成功則初始化這塊內存所有值為0,其接口原型如下:

void *osal_zalloc(size_t size)
{
    void *ret = NULL;

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->malloc))
    {
        ret = s_os_cb->ops->malloc(size);
        if(NULL != ret)
        {
            memset(ret,0,size);
        }
    }

    return ret;

}

該接口的參數說明如下表:

參數描述
size申請分配的內存大小,單位Byte
返回值分配成功 - 返回內存塊指針

分配失敗 - 返回NULL

2.4. osal_realloc

osal_realloc接口用于重新申請分配動態內存空間,其接口原型如下:

void *osal_realloc(void *ptr,size_t newsize)
{
    void *ret = NULL;

    if((NULL != s_os_cb) &&(NULL != s_os_cb->ops) &&(NULL != s_os_cb->ops->realloc))
    {
        ret = s_os_cb->ops->realloc(ptr,newsize);
    }

    return ret;
}

該接口的參數說明如下表:

參數描述
ptr已經分配了內存空間的指針
newsize申請分配的新的內存大小,單位Byte
返回值分配成功 - 返回內存塊指針

分配失敗 - 返回NULL

2.5. osal_calloc

osal_calloc接口用于申請分配num個長度為size的動態內存空間,其接口原型如下:

void *osal_calloc(size_t n, size_t size)
{
    void *p = osal_malloc(n * size);
    if(NULL != p)
    {
        memset(p, 0, n * size);
    }

    return p;
}

該接口的參數說明如下表:

參數描述
n申請分配內存塊的數目
size申請分配的每個內存塊的內存大小,單位Byte
返回值分配成功 - 返回內存塊指針

分配失敗 - 返回NULL

3. 動手實驗 —— 測試動態內存分配的最大字節

實驗內容

本實驗中將創建一個任務,從最小字節開始,不停的申請分配內存,釋放分配的內存,直到申請失敗,串口終端中觀察可以申請到的最大字節。

實驗代碼

首先打開上一篇使用的 HelloWorld 工程,基于此工程進行實驗。

在Demo文件夾右擊,新建文件夾osal_kernel_demo用于存放內核的實驗文件(如果已有請忽略這一步)。

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

LiteOS內存管理方法是什么

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

/* 任務入口函數 */
static int mem_access_task_entry()
{
    uint32_t i = 0;     //循環變量
    size_t mem_size;    //申請的內存塊大小
    uint8_t* mem_ptr = NULL;    //內存塊指針

    while (1)
    {
        /* 每次循環將申請內存的大小擴大一倍 */
        mem_size = 1 << i++;

        /* 嘗試申請分配內存 */
        mem_ptr = osal_malloc(mem_size);

        /* 判斷是否申請成功 */
        if(mem_ptr != NULL)
        {
            /* 申請成功,打印信息 */
            printf("access %d bytes memory success!\r\n", mem_size);

            /* 釋放申請的內存,便于下次申請 */
            osal_free(mem_ptr);

            /* 將內存塊指針置為NULL,避免稱為野指針 */
            mem_ptr = NULL;

            printf("free memory success!\r\n");
           
        }
        else
        {
            /* 申請失敗,打印信息,任務結束 */
            printf("access %d bytes memory failed!\r\n", mem_size);
            return 0;
        }
    }
}

/* 標準demo啟動函數,函數名不要修改,否則會影響下一步實驗 */
int standard_app_demo_main()
{
    /* 創建任務,任務優先級為11,shell任務的優先級為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

添加位置如圖:

LiteOS內存管理方法是什么

這段代碼的意思是:

如果 CONFIG_USER_DEMO 宏定義的值是osal_mem_demo,則將osal_mem_demo.c文件加入到makefile中進行編譯。

那么,如何配置 CONFIG_USER_DEMO 宏定義呢?在工程根目錄下的.sdkconfig文件中的末尾即可配置:

LiteOS內存管理方法是什么

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

實驗現象

程序燒錄之后,即可看到程序已經開始運行,在串口終端中可看到實驗的輸出內容:

linkmain:V1.2.1 AT 11:30:59 ON Nov 28 2019

WELCOME TO IOT_LINK SHELL

LiteOS:/>access 1 bytes memory success!
free memory success!
access 2 bytes memory success!
free memory success!
access 4 bytes memory success!
free memory success!
access 8 bytes memory success!
free memory success!
access 16 bytes memory success!
free memory success!
access 32 bytes memory success!
free memory success!
access 64 bytes memory success!
free memory success!
access 128 bytes memory success!
free memory success!
access 256 bytes memory success!
free memory success!
access 512 bytes memory success!
free memory success!
access 1024 bytes memory success!
free memory success!
access 2048 bytes memory success!
free memory success!
access 4096 bytes memory success!
free memory success!
access 8192 bytes memory success!
free memory success!
access 16384 bytes memory success!
free memory success!
access 32768 bytes memory failed!

可以看到,系統啟動后,首先打印版本號,串口shell的優先級為10,最先打印shell信息,接下來內存申請任務創建開始執行,在該芯片上最大能申請的空間為 16384 字節。

感謝各位的閱讀,以上就是“LiteOS內存管理方法是什么”的內容了,經過本文的學習后,相信大家對LiteOS內存管理方法是什么這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

彰武县| 沾化县| 宿州市| 当雄县| 孙吴县| 南和县| 大安市| 綦江县| 织金县| 三明市| 泽普县| 富平县| 青浦区| 松桃| 开封县| 玛曲县| 厦门市| 富源县| 婺源县| 柳江县| 外汇| 太湖县| 沙坪坝区| 阿鲁科尔沁旗| 天峻县| 崇义县| 清新县| 田阳县| 天门市| 水富县| 日照市| 信丰县| 桂东县| 汝城县| 怀宁县| 酉阳| 格尔木市| 衡东县| 大丰市| 冕宁县| 无为县|