【STM32H7教程】第27章 STM32H7的TCM,SRAM等五塊內存的動態內存分配實現


完整教程下載地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980

第27章       STM32H7的TCM,SRAM等五塊內存的動態內存分配實現

本章教程為大家分享一種DTCM,SRAM1,SRAM2,SRAM3和SRAM4可以獨立管理的動態內存管理方案,在實際項目中有一定的實用價值,比如MP3編解碼,JPEG編解碼,視頻播放器,矢量字體等需要動態內存的場合。

27.1 初學者重要提示

27.2 動態內存管理移植

27.3 動態內存的使用方法

27.4 實驗例程說明(MDK)

27.5 實驗例程說明(IAR)

27.6 總結

 

 

27.1 初學者重要提示

  1.   學習本章節前,務必優先學習第25章,了解TCM,SRAM等五塊內存區的基礎知識,比較重要。
  2.   將RTX5系統的動態內存管理整理了出來,可以同時管理多個分區。如果其它RTOS中使用,記得做互斥保護或者加個調度鎖均可。
  3.   支持動態內存使用情況統計。

27.2 動態內存管理移植

移植比較簡單,僅需添加兩個文件到工程即可。

27.2.1 MDK版的移植

  •   第1步,添加如下兩個文件到MDK中

注,以本章配套例子為例,這兩個文件的路徑\User\malloc。

 

  •   第2步,添加路徑。

 

  •   第3步,添加頭文件。

如果哪個源文件要用到動態內存,包含rtx_lib.h即可,本章配套例子是直接將其放在了bsp.h文件里面,哪個源文件要用到動態內存,直接包含bsp.h頭文件即可。

 

通過這簡單的三步就完成了MDK的移植。

27.2.2 IAR版的移植

  •   第1步,添加如下兩個文件到IAR中

注,以本章配套例子為例,這兩個文件的路徑\User\malloc。

 

  •   第2步,添加路徑。

 

  •   第3步,添加頭文件。

如果哪個源文件要用到動態內存,包含rtx_lib.h即可,本章配套例子是直接將其放在了bsp.h文件里面,哪個源文件要用到動態內存,直接包含bsp.h頭文件即可。

 

通過這簡單的三步就完成了IAR的移植。

27.3 動態內存的使用方法

下面分別以MDK和IAR為例進行說明:

27.3.1 MDK上的動態內存用法

  •   定義動態內存區

比如當前的主RAM用的DTCM,我們就可以直接定義一塊大的數組作為動態內存空間:

/* DTCM, 64KB */
/* 用於獲取當前使用的空間大小 */
mem_head_t *DTCMUsed; 
/* 定義為64位變量,首地址是8字節對齊 */             
uint64_t AppMallocDTCM[64*1024/8]; 

如果要使用AXI SRAM作為動態內存空間,可以使用__attribute__((at( )))指定地址。

/* D1域, AXI SRAM, 512KB */
/* 用於獲取當前使用的空間大小 */
mem_head_t *AXISRAMUsed;  
/* 定義為64位變量,首地址是8字節對齊 */ 
uint64_t AppMallocAXISRAM[512*1024/8]__attribute__((at(0x24000000))); 

 

  •   初始化動態內存區

調用動態內存管理提供的函數osRtxMemoryInit即可做初始化:

osRtxMemoryInit(AppMallocDTCM,    sizeof(AppMallocDTCM));
osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));

 

  •   申請動態內存

通過函數void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type)做動態內存申請。

第1個參數填寫內存區首地址,比如申請的AppMallocDTCM,就填AppMallocDTCM即可。

第2個參數填寫申請的字節大小,單位字節。

第3個參數固定填0即可。

返回值是所申請緩沖區的首地址,如果沒有空間可用,將返回NULL,這點要特別注意!

舉個例子:

uint32_t *DTCM_Addres0, *AXISRAM_Addres0;

/* 從DTCM申請280字節空間,使用指針變量DTCM_Addres0操作這些空間時不要超過280字節大小 */    
DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, 280, 0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM總大小 = %d字節,申請大小 = 0280字節,當前共使用大小 = %d字節\r\n", 
                                             DTCMUsed->size, DTCMUsed->used);

/* 從AXI SRAM 申請160字節空間,使用指針變量AXISRAM_Addres0操作這些空間時不要超過160字節大小 */    
AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, 160, 0);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("AXI SRAM總大小 = %d字節,申請大小 = 0162字節,當前共使用大小 = %d字節\r\n", 
                                            AXISRAMUsed->size, AXISRAMUsed->used);

申請了空間后,就可以直接使用了。另外注意紅色字體部分,通過DTCMUsed->used和AXISRAMUsed->used可以獲取當前使用的空間大小。

  •   釋放動態內存

通過函數uint32_t osRtxMemoryFree (void *mem, void *block)做動態內存釋放。

第1個參數填寫內存區首地址,比如釋放的AppMallocDTCM,就填AppMallocDTCM即可。

第2個參數填寫申請內存時所獲取的內存區首地址,這里用於釋放。

返回值,返回1表示成功,返回0表示失敗。

舉個例子:

/* 釋放從DTCM申請的280字節空間 */
osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("釋放DTCM動態內存區申請的0280字節,當前共使用大小 = %d字節\r\n", DTCMUsed->used);

/* 釋放從AXI SRAM申請的160字節空間 */
osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("釋放AXI SRAM動態內存區申請的0160字節,當前共使用大小 = %d字節\r\n", AXISRAMUsed->used);

 

27.3.2 IAR上的動態內存用法

注:IAR使用這個動態內存管理,僅在定義時跟MDK略有不同,其它地方是一樣的。

  •   定義動態內存區

比如當前的主RAM用的DTCM,我們就可以直接定義一塊大的數組作為動態內存空間:

/* DTCM, 64KB */
/* 用於獲取當前使用的空間大小 */
mem_head_t *DTCMUsed; 
/* 定義為64位變量,首地址是8字節對齊 */             
uint64_t AppMallocDTCM[64*1024/8]; 

如果要使用AXI SRAM作為動態內存空間,可以使用__attribute__((at( )))指定地址。

/* D1域, AXI SRAM, 512KB */
/* 用於獲取當前使用的空間大小 */
mem_head_t *AXISRAMUsed;  
/* 指定下面數組的地址為0x24000000 */ 
#pragma location = 0x24000000
uint64_t AppMallocAXISRAM[512*1024/8];

 

  •   初始化動態內存區

調用動態內存管理提供的函數osRtxMemoryInit即可做初始化:

osRtxMemoryInit(AppMallocDTCM,    sizeof(AppMallocDTCM));
osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));

 

  •   申請動態內存

通過函數void *osRtxMemoryAlloc (void *mem, uint32_t size, uint32_t type)做動態內存申請。

第1個參數填寫內存區首地址,比如申請的AppMallocDTCM,就填AppMallocDTCM即可。

第2個參數填寫申請的字節大小,單位字節。

第3個參數固定填0即可。

返回值是所申請緩沖區的首地址,如果沒有空間可用,將返回NULL,這點要特別注意!

舉個例子:

uint32_t *DTCM_Addres0, *AXISRAM_Addres0;

/* 從DTCM申請280字節空間,使用指針變量DTCM_Addres0操作這些空間時不要超過280字節大小 */    
DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, 280, 0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("DTCM總大小 = %d字節,申請大小 = 0280字節,當前共使用大小 = %d字節\r\n", 
                                             DTCMUsed->size, DTCMUsed->used);

/* 從AXI SRAM 申請160字節空間,使用指針變量AXISRAM_Addres0操作這些空間時不要超過160字節大小 */    
AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, 160, 0);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("AXI SRAM總大小 = %d字節,申請大小 = 0162字節,當前共使用大小 = %d字節\r\n", 
                                            AXISRAMUsed->size, AXISRAMUsed->used);

申請了空間后,就可以直接使用了。另外注意紅色字體部分,通過DTCMUsed->used和AXISRAMUsed->used可以獲取當前使用的空間大小。

  •   釋放動態內存

通過函數uint32_t osRtxMemoryFree (void *mem, void *block)做動態內存釋放。

第1個參數填寫內存區首地址,比如釋放的AppMallocDTCM,就填AppMallocDTCM即可。

第2個參數填寫申請內存時所獲取的內存區首地址,這里用於釋放。

返回值,返回1表示成功,返回0表示失敗。

舉個例子:

/* 釋放從DTCM申請的280字節空間 */
osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);
DTCMUsed = MemHeadPtr(AppMallocDTCM);
printf("釋放DTCM動態內存區申請的0280字節,當前共使用大小 = %d字節\r\n", DTCMUsed->used);

/* 釋放從AXI SRAM申請的160字節空間 */
osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
printf("釋放AXI SRAM動態內存區申請的0160字節,當前共使用大小 = %d字節\r\n", AXISRAMUsed->used)

 

27.4 實驗例程說明(MDK)

配套例子:

V7-006_TCM,SRAM等五塊內存的動態內存分配實現

實驗目的:

  1. 學習TCM,SRAM等五塊內存的動態內存分配實現。

實驗內容:

  1. 啟動自動重裝軟件定時器0,每100ms翻轉一次LED2。

實驗操作:

  1. K1鍵按下,從DTCM依次申請280字節,64字節和6111字節。
  2. K1鍵松開,釋放從DTCM申請的空間。
  3. K2鍵按下,從AXI SRAM依次申請160字節,32字節和2333字節。
  4. K2鍵松開,釋放從AXI SRAM申請的空間。
  5. K3鍵按下,從D2域SRAM依次申請200字節,96字節和4111字節。
  6. K3鍵松開,釋放從D2域SRAM申請的空間。
  7. 搖桿OK鍵按下,從D3域SRAM依次申請300字節,128字節和5111字節。
  8. 搖桿OK鍵松開,釋放從D3域SRAM申請的空間。

上電后串口打印的信息:

波特率 115200,數據位 8,奇偶校驗位無,停止位 1

 

程序設計:

  系統棧大小分配:

 

RAM空間用的DTCM:

 

  硬件外設初始化

硬件外設的初始化是在 bsp.c 文件實現:

/*
*********************************************************************************************************
*    函 數 名: bsp_Init
*    功能說明: 初始化所有的硬件設備。該函數配置CPU寄存器和外設的寄存器並初始化一些全局變量。只需要調用一次
*    形    參:無
*    返 回 值: 無
*********************************************************************************************************
*/
void bsp_Init(void)
{
    /* 配置MPU */
    MPU_Config();
    
    /* 使能L1 Cache */
    CPU_CACHE_Enable();

    /* 
       STM32H7xx HAL 庫初始化,此時系統用的還是H7自帶的64MHz,HSI時鍾:
       - 調用函數HAL_InitTick,初始化滴答時鍾中斷1ms。
       - 設置NVIV優先級分組為4。
     */
    HAL_Init();

    /* 
       配置系統時鍾到400MHz
       - 切換使用HSE。
       - 此函數會更新全局變量SystemCoreClock,並重新配置HAL_InitTick。
    */
    SystemClock_Config();

    /* 
       Event Recorder:
       - 可用於代碼執行時間測量,MDK5.25及其以上版本才支持,IAR不支持。
       - 默認不開啟,如果要使能此選項,務必看V7開發板用戶手冊第xx章
    */    
#if Enable_EventRecorder == 1  
    /* 初始化EventRecorder並開啟 */
    EventRecorderInitialize(EventRecordAll, 1U);
    EventRecorderStart();
#endif
    
    bsp_InitKey();        /* 按鍵初始化,要放在滴答定時器之前,因為按鈕檢測是通過滴答定時器掃描 */
    bsp_InitTimer();      /* 初始化滴答定時器 */
    bsp_InitUart();    /* 初始化串口 */
    bsp_InitExtIO();    /* 初始化FMC總線74HC574擴展IO. 必須在 bsp_InitLed()前執行 */    
    bsp_InitLed();        /* 初始化LED */    
}

 

  •   MPU配置和Cache配置:

數據Cache和指令Cache都開啟。

AXI SRAM的MPU屬性:

Write back, Read allocate,Write allocate。

FMC的擴展IO的MPU屬性:

必須Device或者Strongly Ordered。

D2 SRAM1,SRAM2和SRAM3的MPU屬性:

Write through, read allocate,no write allocate。

D3 SRAM4的MPU屬性:

Write through, read allocate,no write allocate。

/*
*********************************************************************************************************
*    函 數 名: MPU_Config
*    功能說明: 配置MPU
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
static void MPU_Config( void )
{
    MPU_Region_InitTypeDef MPU_InitStruct;

    /* 禁止 MPU */
    HAL_MPU_Disable();

    /* 配置AXI SRAM的MPU屬性為Write back, Read allocate,Write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x24000000;
    MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    
    /* 配置FMC擴展IO的MPU屬性為Device或者Strongly Ordered */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x60000000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER1;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
    
    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    /* 配置SRAM1的屬性為Write through, read allocate,no write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x30000000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_128KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER2;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    /* 配置SRAM2的屬性為Write through, read allocate,no write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x30020000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_128KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER3;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    
    /* 配置SRAM3的屬性為Write through, read allocate,no write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x30040000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_32KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER4;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    
    /* 配置SRAM4的屬性為Write through, read allocate,no write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x38000000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER5;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    /*使能 MPU */
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

/*
*********************************************************************************************************
*    函 數 名: CPU_CACHE_Enable
*    功能說明: 使能L1 Cache
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
static void CPU_CACHE_Enable(void)
{
    /* 使能 I-Cache */
    SCB_EnableICache();

    /* 使能 D-Cache */
    SCB_EnableDCache();
}

 

  主功能:

主程序實現如下操作:

  •   啟動自動重裝軟件定時器0,每100ms翻轉一次LED2。
  •   K1鍵按下,從DTCM依次申請280字節,64字節和6111字節。
  •   K1鍵松開,釋放從DTCM申請的空間。
  •   K2鍵按下,從AXI SRAM依次申請160字節,32字節和2333字節。
  •   K2鍵松開,釋放從AXI SRAM申請的空間。
  •   K3鍵按下,從D2域SRAM依次申請200字節,96字節和4111字節。
  •   K3鍵松開,釋放從D2域SRAM申請的空間。
  •   搖桿OK鍵按下,從D3域SRAM依次申請300字節,128字節和5111字節。
  •   搖桿OK鍵松開,釋放從D3域SRAM申請的空間。
/*
*********************************************************************************************************
*    函 數 名: main
*    功能說明: c程序入口
*    形    參: 無
*    返 回 值: 錯誤代碼(無需處理)
*********************************************************************************************************
*/
int main(void)
{
    uint8_t ucKeyCode;        /* 按鍵代碼 */
    uint32_t *DTCM_Addres0, *AXISRAM_Addres0, *SRAM1_Addres0, *SRAM4_Addres0;
    uint16_t *DTCM_Addres1, *AXISRAM_Addres1, *SRAM1_Addres1, *SRAM4_Addres1;
    uint8_t  *DTCM_Addres2, *AXISRAM_Addres2, *SRAM1_Addres2, *SRAM4_Addres2;
    
    
    bsp_Init();        /* 硬件初始化 */
    
    /* 初始化動態內存空間 */
    osRtxMemoryInit(AppMallocDTCM,    sizeof(AppMallocDTCM));
    osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));
    osRtxMemoryInit(AppMallocSRAM1,   sizeof(AppMallocSRAM1));
    osRtxMemoryInit(AppMallocSRAM4,   sizeof(AppMallocSRAM4));
    
    PrintfLogo();    /* 打印例程名稱和版本等信息 */
    PrintfHelp();    /* 打印操作提示 */

    bsp_StartAutoTimer(0, 100);    /* 啟動1個100ms的自動重裝的定時器 */
    

    /* 進入主程序循環體 */
    while (1)
    {
        bsp_Idle();        /* 這個函數在bsp.c文件。用戶可以修改這個函數實現CPU休眠和喂狗 */

        /* 判斷定時器超時時間 */
        if (bsp_CheckTimer(0))    
        {
            /* 每隔100ms 進來一次 */  
            bsp_LedToggle(2);
        }

        /* 按鍵濾波和檢測由后台systick中斷服務程序實現,我們只需要調用bsp_GetKey讀取鍵值即可。 */
        ucKeyCode = bsp_GetKey();    /* 讀取鍵值, 無鍵按下時返回 KEY_NONE = 0 */
        if (ucKeyCode != KEY_NONE)
        {
            switch (ucKeyCode)
            {
                /* 從DTCM依次申請280字節,64字節和6111字節 */
                case KEY_DOWN_K1:    
                    /* 從DTCM申請280字節空間,使用指針變量DTCM_Addres0操作這些空間時不要超過280字節大小 */
                    printf("=========================================================\r\n");
                    DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, 280, 0);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("DTCM總大小 = %d字節,申請大小 = 0280字節,當前共使用大小 = %d字節\r\n", 
                                                                DTCMUsed->size, DTCMUsed->used);
                
            /* 從DTCM申請64字節空間,使用指針變量DTCM_Addres1操作這些空間時不要超過64字節大小 */    
                    DTCM_Addres1 = osRtxMemoryAlloc(AppMallocDTCM, 64, 0);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("DTCM總大小 = %d字節,申請大小 = 0064字節,當前共使用大小 = %d字節\r\n", 
                                                               DTCMUsed->size, DTCMUsed->used);
                
            /* 從DTCM申請6111字節空間,使用指針變量DTCM_Addres2操作這些空間時不要超過6111字節大小 */
                    DTCM_Addres2 = osRtxMemoryAlloc(AppMallocDTCM, 6111, 0);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("DTCM總大小 = %d字節,申請大小 = 6111字節,當前共使用大小 = %d字節\r\n", 
                                                                DTCMUsed->size, DTCMUsed->used);
                    break;
                
                /* 釋放從DTCM申請的空間 */
                case KEY_UP_K1:    
                    /* 釋放從DTCM申請的280字節空間 */
                    osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("釋放DTCM動態內存區申請的0280字節,當前共使用大小 = %d字節\r\n", 
DTCMUsed->used);
                
                    /* 釋放從DTCM申請的64字節空間 */
                    osRtxMemoryFree(AppMallocDTCM, DTCM_Addres1);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("釋放DTCM動態內存區申請的0064字節,當前共使用大小 = %d字節\r\n",
 DTCMUsed->used);
                
                    /* 釋放從DTCM申請的6111字節空間 */
                    osRtxMemoryFree(AppMallocDTCM, DTCM_Addres2);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("釋放DTCM動態內存區申請的6111字節,當前共使用大小 = %d字節\r\n",
 DTCMUsed->used);
                    break;
                
                /* 從AXI SRAM依次申請160字節,32字節和2333字節 */
                case KEY_DOWN_K2:    
            /* 從AXI SRAM 申請160字節空間,使用指針變量AXISRAM_Addres0操作這些空間時不要超過160字節大小 */
                    printf("=========================================================\r\n");        
                    AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, 160, 0);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("AXI SRAM總大小 = %d字節,申請大小 = 0162字節,當前共使用大小 = %d字節\r\n", 
                                                                AXISRAMUsed->size, AXISRAMUsed->used);
                
            /* 從AXI SRAM 申請32字節空間,使用指針變量AXISRAM_Addres1操作這些空間時不要超過32字節大小 */
                    AXISRAM_Addres1 = osRtxMemoryAlloc(AppMallocAXISRAM, 32, 0);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("AXI SRAM總大小 = %d字節,申請大小 = 0032字節,當前共使用大小 = %d字節\r\n", 
                                                          AXISRAMUsed->size, AXISRAMUsed->used);
                
/* 從AXI SRAM 申請2333字節空間,使用指針變量AXISRAM_Addres2操作這些空間時不要超過2333字節大小 */    
                    AXISRAM_Addres2 = osRtxMemoryAlloc(AppMallocAXISRAM, 2333, 0);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("AXI SRAM總大小 = %d字節,申請大小 = 2333字節,當前共使用大小 = %d字節\r\n", 
                                                                AXISRAMUsed->size, AXISRAMUsed->used);
                    break;
                
                /* 釋放從AXI SRAM申請的空間 */
                case KEY_UP_K2:    
                    /* 釋放從AXI SRAM申請的160字節空間 */
                    osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("釋放AXI SRAM動態內存區申請的0160字節,當前共使用大小 = %d字節\r\n",
 AXISRAMUsed->used);
                
                    /* 釋放從AXI SRAM申請的32字節空間 */
                    osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres1);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("釋放AXI SRAM動態內存區申請的0032字節,當前共使用大小 = %d字節\r\n",
 AXISRAMUsed->used);
                
                    /* 釋放從AXI SRAM申請的2333字節空間 */
                    osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres2);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("釋放AXI SRAM動態內存區申請的2333字節,當前共使用大小 = %d字節\r\n", 
AXISRAMUsed->used);
                    break;
                
                /* 從D2域SRAM依次申請200字節,96字節和4111字節 */
                case KEY_DOWN_K3:    
        /* 從D2域的SRAM申請200字節空間,使用指針變量SRAM1_Addres0操作這些空間時不要超過200字節大小 */
                    printf("=========================================================\r\n");        
                    SRAM1_Addres0 = osRtxMemoryAlloc(AppMallocSRAM1, 200, 0);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("D2域SRAM總大小 = %d字節,申請大小 = 0200字節,當前共使用大小 = %d字節\r\n", 
                                                                SRAM1Used->size, SRAM1Used->used);
                
     /* 從D2域的SRAM申請96字節空間,使用指針變量SRAM1_Addres1操作這些空間時不要超過96字節大小 */    
                    SRAM1_Addres1 = osRtxMemoryAlloc(AppMallocSRAM1, 96, 0);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("D2域SRAM總大小 = %d字節,申請大小 = 0096字節,當前共使用大小 = %d字節\r\n", 
                                                               SRAM1Used->size, SRAM1Used->used);
                
     /* 從D2域的SRAM申請4111字節空間,使用指針變量SRAM1_Addres2操作這些空間時不要超過4111字節大小 */
                    SRAM1_Addres2 = osRtxMemoryAlloc(AppMallocSRAM1, 4111, 0);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("D2域SRAM總大小 = %d字節,申請大小 = 4111字節,當前共使用大小 = %d字節\r\n", 
                                                                SRAM1Used->size, SRAM1Used->used);
                    break;
                
                /* 釋放從D2域SRAM申請的空間 */
                case KEY_UP_K3:    
                    /* 釋放從D2域的SRAM申請的200字節空間 */
                    osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres0);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("釋放D2域SRAM動態內存區申請的0200字節,當前共使用大小 = %d字節\r\n",
 SRAM1Used->used);
                
                    /* 釋放從D2域的SRAM申請的96字節空間 */
                    osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres1);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("釋放D2域SRAM動態內存區申請的0096字節,當前共使用大小 = %d字節\r\n",
 SRAM1Used->used);
                
                    /* 釋放從D2域的SRAM申請的4111字節空間 */
                    osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres2);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("釋放D2域SRAM動態內存區申請的4111字節,當前共使用大小 = %d字節\r\n",
 SRAM1Used->used);
                    break;
                
                /* 從D3域SRAM依次申請300字節,128字節和5111字節 */
                case JOY_DOWN_OK:    
            /* 從D3域的SRAM申請300字節空間,使用指針變量SRAM4_Addres0操作這些空間時不要超過300字節大小 */
                    printf("=========================================================\r\n");        
                    SRAM4_Addres0 = osRtxMemoryAlloc(AppMallocSRAM4, 300, 0);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("D3域SRAM總大小 = %d字節,申請大小 = 0300字節,當前共使用大小 = %d字節\r\n", 
                                                                SRAM4Used->size, SRAM4Used->used);
                
        /* 從D3域的SRAM申請96字節空間,使用指針變量SRAM4_Addres1操作這些空間時不要超過96字節大小 */
                    SRAM4_Addres1 = osRtxMemoryAlloc(AppMallocSRAM4, 128, 0);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("D3域SRAM總大小 = %d字節,申請大小 = 0128字節,當前共使用大小 = %d字節\r\n", 
                                                               SRAM4Used->size, SRAM4Used->used);
                
    /* 從D3域的SRAM申請5111字節空間,使用指針變量SRAM4_Addres2操作這些空間時不要超過5111字節大小 */
                    SRAM4_Addres2 = osRtxMemoryAlloc(AppMallocSRAM4, 5111, 0);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("D3域SRAM總大小 = %d字節,申請大小 = 5111字節,當前共使用大小 = %d字節\r\n", 
                                                                SRAM4Used->size, SRAM4Used->used);
                    break;
                
                /* 釋放從D3域SRAM申請的空間 */
                case JOY_UP_OK:    
                    /* 釋放從D3域的SRAM申請的300字節空間 */
                    osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres0);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("釋放D3域SRAM動態內存區申請的0300字節,當前共使用大小 = %d字節\r\n", 
SRAM4Used->used);
                
                    /* 釋放從D3域的SRAM申請的128字節空間 */
                    osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres1);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("釋放D3域SRAM動態內存區申請的0128字節,當前共使用大小 = %d字節\r\n",
 SRAM4Used->used);
                
                    /* 釋放從D3域的SRAM申請的5111字節空間 */
                    osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres2);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("釋放D3域SRAM動態內存區申請的5111字節,當前共使用大小 = %d字節\r\n",
 SRAM4Used->used);
                    break;
            
                default:
                  /* 其它的鍵值不處理 */
                  break;
            }
        }
    }
}

 

27.5 實驗例程說明(IAR)

配套例子:

V7-006_TCM,SRAM等五塊內存的動態內存分配實現

實驗目的:

  1. 學習TCM,SRAM等五塊內存的動態內存分配實現。

實驗內容:

  1. 啟動自動重裝軟件定時器0,每100ms翻轉一次LED2。

實驗操作:

  1. K1鍵按下,從DTCM依次申請280字節,64字節和6111字節。
  2. K1鍵松開,釋放從DTCM申請的空間。
  3. K2鍵按下,從AXI SRAM依次申請160字節,32字節和2333字節。
  4. K2鍵松開,釋放從AXI SRAM申請的空間。
  5. K3鍵按下,從D2域SRAM依次申請200字節,96字節和4111字節。
  6. K3鍵松開,釋放從D2域SRAM申請的空間。
  7. 搖桿OK鍵按下,從D3域SRAM依次申請300字節,128字節和5111字節。
  8. 搖桿OK鍵松開,釋放從D3域SRAM申請的空間。

上電后串口打印的信息:

波特率 115200,數據位 8,奇偶校驗位無,停止位 1

 

程序設計:

  系統棧大小分配:

 

  RAM空間用的DTCM:

 

  硬件外設初始化

硬件外設的初始化是在 bsp.c 文件實現:

/*
*********************************************************************************************************
*    函 數 名: bsp_Init
*    功能說明: 初始化所有的硬件設備。該函數配置CPU寄存器和外設的寄存器並初始化一些全局變量。只需要調用一次
*    形    參:無
*    返 回 值: 無
*********************************************************************************************************
*/
void bsp_Init(void)
{
    /* 配置MPU */
    MPU_Config();
    
    /* 使能L1 Cache */
    CPU_CACHE_Enable();

    /* 
       STM32H7xx HAL 庫初始化,此時系統用的還是H7自帶的64MHz,HSI時鍾:
       - 調用函數HAL_InitTick,初始化滴答時鍾中斷1ms。
       - 設置NVIV優先級分組為4。
     */
    HAL_Init();

    /* 
       配置系統時鍾到400MHz
       - 切換使用HSE。
       - 此函數會更新全局變量SystemCoreClock,並重新配置HAL_InitTick。
    */
    SystemClock_Config();

    /* 
       Event Recorder:
       - 可用於代碼執行時間測量,MDK5.25及其以上版本才支持,IAR不支持。
       - 默認不開啟,如果要使能此選項,務必看V7開發板用戶手冊第xx章
    */    
#if Enable_EventRecorder == 1  
    /* 初始化EventRecorder並開啟 */
    EventRecorderInitialize(EventRecordAll, 1U);
    EventRecorderStart();
#endif
    
    bsp_InitKey();        /* 按鍵初始化,要放在滴答定時器之前,因為按鈕檢測是通過滴答定時器掃描 */
    bsp_InitTimer();      /* 初始化滴答定時器 */
    bsp_InitUart();    /* 初始化串口 */
    bsp_InitExtIO();    /* 初始化FMC總線74HC574擴展IO. 必須在 bsp_InitLed()前執行 */    
    bsp_InitLed();        /* 初始化LED */    
}

 

  MPU配置和Cache配置:

數據Cache和指令Cache都開啟。

AXI SRAM的MPU屬性:

Write back, Read allocate,Write allocate。

FMC的擴展IO的MPU屬性:

必須Device或者Strongly Ordered。

D2 SRAM1,SRAM2和SRAM3的MPU屬性:

Write through, read allocate,no write allocate。

D3 SRAM4的MPU屬性:

Write through, read allocate,no write allocate。

/*
*********************************************************************************************************
*    函 數 名: MPU_Config
*    功能說明: 配置MPU
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
static void MPU_Config( void )
{
    MPU_Region_InitTypeDef MPU_InitStruct;

    /* 禁止 MPU */
    HAL_MPU_Disable();

    /* 配置AXI SRAM的MPU屬性為Write back, Read allocate,Write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x24000000;
    MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    
    /* 配置FMC擴展IO的MPU屬性為Device或者Strongly Ordered */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x60000000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER1;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;
    
    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    /* 配置SRAM1的屬性為Write through, read allocate,no write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x30000000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_128KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER2;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    /* 配置SRAM2的屬性為Write through, read allocate,no write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x30020000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_128KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER3;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    
    /* 配置SRAM3的屬性為Write through, read allocate,no write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x30040000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_32KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER4;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    
    /* 配置SRAM4的屬性為Write through, read allocate,no write allocate */
    MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
    MPU_InitStruct.BaseAddress      = 0x38000000;
    MPU_InitStruct.Size             = ARM_MPU_REGION_SIZE_64KB;    
    MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
    MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
    MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
    MPU_InitStruct.Number           = MPU_REGION_NUMBER5;
    MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL0;
    MPU_InitStruct.SubRegionDisable = 0x00;
    MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

    HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    /*使能 MPU */
    HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
}

/*
*********************************************************************************************************
*    函 數 名: CPU_CACHE_Enable
*    功能說明: 使能L1 Cache
*    形    參: 無
*    返 回 值: 無
*********************************************************************************************************
*/
static void CPU_CACHE_Enable(void)
{
    /* 使能 I-Cache */
    SCB_EnableICache();

    /* 使能 D-Cache */
    SCB_EnableDCache();
}

 

  主功能

主程序實現如下操作:

  •   啟動自動重裝軟件定時器0,每100ms翻轉一次LED2。
  •   K1鍵按下,從DTCM依次申請280字節,64字節和6111字節。
  •   K1鍵松開,釋放從DTCM申請的空間。
  •   K2鍵按下,從AXI SRAM依次申請160字節,32字節和2333字節。
  •   K2鍵松開,釋放從AXI SRAM申請的空間。
  •   K3鍵按下,從D2域SRAM依次申請200字節,96字節和4111字節。
  •   K3鍵松開,釋放從D2域SRAM申請的空間。
  •   搖桿OK鍵按下,從D3域SRAM依次申請300字節,128字節和5111字節。
  •   搖桿OK鍵松開,釋放從D3域SRAM申請的空間。
/*
*********************************************************************************************************
*    函 數 名: main
*    功能說明: c程序入口
*    形    參: 無
*    返 回 值: 錯誤代碼(無需處理)
*********************************************************************************************************
*/
int main(void)
{
    uint8_t ucKeyCode;        /* 按鍵代碼 */
    uint32_t *DTCM_Addres0, *AXISRAM_Addres0, *SRAM1_Addres0, *SRAM4_Addres0;
    uint16_t *DTCM_Addres1, *AXISRAM_Addres1, *SRAM1_Addres1, *SRAM4_Addres1;
    uint8_t  *DTCM_Addres2, *AXISRAM_Addres2, *SRAM1_Addres2, *SRAM4_Addres2;
    
    
    bsp_Init();        /* 硬件初始化 */
    
    /* 初始化動態內存空間 */
    osRtxMemoryInit(AppMallocDTCM,    sizeof(AppMallocDTCM));
    osRtxMemoryInit(AppMallocAXISRAM, sizeof(AppMallocAXISRAM));
    osRtxMemoryInit(AppMallocSRAM1,   sizeof(AppMallocSRAM1));
    osRtxMemoryInit(AppMallocSRAM4,   sizeof(AppMallocSRAM4));
    
    PrintfLogo();    /* 打印例程名稱和版本等信息 */
    PrintfHelp();    /* 打印操作提示 */

    bsp_StartAutoTimer(0, 100);    /* 啟動1個100ms的自動重裝的定時器 */
    

    /* 進入主程序循環體 */
    while (1)
    {
        bsp_Idle();        /* 這個函數在bsp.c文件。用戶可以修改這個函數實現CPU休眠和喂狗 */

        /* 判斷定時器超時時間 */
        if (bsp_CheckTimer(0))    
        {
            /* 每隔100ms 進來一次 */  
            bsp_LedToggle(2);
        }

        /* 按鍵濾波和檢測由后台systick中斷服務程序實現,我們只需要調用bsp_GetKey讀取鍵值即可。 */
        ucKeyCode = bsp_GetKey();    /* 讀取鍵值, 無鍵按下時返回 KEY_NONE = 0 */
        if (ucKeyCode != KEY_NONE)
        {
            switch (ucKeyCode)
            {
                /* 從DTCM依次申請280字節,64字節和6111字節 */
                case KEY_DOWN_K1:    
                    /* 從DTCM申請280字節空間,使用指針變量DTCM_Addres0操作這些空間時不要超過280字節大小 */
                    printf("=========================================================\r\n");
                    DTCM_Addres0 = osRtxMemoryAlloc(AppMallocDTCM, 280, 0);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("DTCM總大小 = %d字節,申請大小 = 0280字節,當前共使用大小 = %d字節\r\n", 
                                                                DTCMUsed->size, DTCMUsed->used);
                
            /* 從DTCM申請64字節空間,使用指針變量DTCM_Addres1操作這些空間時不要超過64字節大小 */    
                    DTCM_Addres1 = osRtxMemoryAlloc(AppMallocDTCM, 64, 0);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("DTCM總大小 = %d字節,申請大小 = 0064字節,當前共使用大小 = %d字節\r\n", 
                                                               DTCMUsed->size, DTCMUsed->used);
                
            /* 從DTCM申請6111字節空間,使用指針變量DTCM_Addres2操作這些空間時不要超過6111字節大小 */
                    DTCM_Addres2 = osRtxMemoryAlloc(AppMallocDTCM, 6111, 0);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("DTCM總大小 = %d字節,申請大小 = 6111字節,當前共使用大小 = %d字節\r\n", 
                                                                DTCMUsed->size, DTCMUsed->used);
                    break;
                
                /* 釋放從DTCM申請的空間 */
                case KEY_UP_K1:    
                    /* 釋放從DTCM申請的280字節空間 */
                    osRtxMemoryFree(AppMallocDTCM, DTCM_Addres0);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("釋放DTCM動態內存區申請的0280字節,當前共使用大小 = %d字節\r\n", 
DTCMUsed->used);
                
                    /* 釋放從DTCM申請的64字節空間 */
                    osRtxMemoryFree(AppMallocDTCM, DTCM_Addres1);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("釋放DTCM動態內存區申請的0064字節,當前共使用大小 = %d字節\r\n",
 DTCMUsed->used);
                
                    /* 釋放從DTCM申請的6111字節空間 */
                    osRtxMemoryFree(AppMallocDTCM, DTCM_Addres2);
                    DTCMUsed = MemHeadPtr(AppMallocDTCM);
                    printf("釋放DTCM動態內存區申請的6111字節,當前共使用大小 = %d字節\r\n",
 DTCMUsed->used);
                    break;
                
                /* 從AXI SRAM依次申請160字節,32字節和2333字節 */
                case KEY_DOWN_K2:    
            /* 從AXI SRAM 申請160字節空間,使用指針變量AXISRAM_Addres0操作這些空間時不要超過160字節大小 */
                    printf("=========================================================\r\n");        
                    AXISRAM_Addres0 = osRtxMemoryAlloc(AppMallocAXISRAM, 160, 0);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("AXI SRAM總大小 = %d字節,申請大小 = 0162字節,當前共使用大小 = %d字節\r\n", 
                                                                AXISRAMUsed->size, AXISRAMUsed->used);
                
            /* 從AXI SRAM 申請32字節空間,使用指針變量AXISRAM_Addres1操作這些空間時不要超過32字節大小 */
                    AXISRAM_Addres1 = osRtxMemoryAlloc(AppMallocAXISRAM, 32, 0);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("AXI SRAM總大小 = %d字節,申請大小 = 0032字節,當前共使用大小 = %d字節\r\n", 
                                                          AXISRAMUsed->size, AXISRAMUsed->used);
                
/* 從AXI SRAM 申請2333字節空間,使用指針變量AXISRAM_Addres2操作這些空間時不要超過2333字節大小 */    
                    AXISRAM_Addres2 = osRtxMemoryAlloc(AppMallocAXISRAM, 2333, 0);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("AXI SRAM總大小 = %d字節,申請大小 = 2333字節,當前共使用大小 = %d字節\r\n", 
                                                                AXISRAMUsed->size, AXISRAMUsed->used);
                    break;
                
                /* 釋放從AXI SRAM申請的空間 */
                case KEY_UP_K2:    
                    /* 釋放從AXI SRAM申請的160字節空間 */
                    osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres0);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("釋放AXI SRAM動態內存區申請的0160字節,當前共使用大小 = %d字節\r\n",
 AXISRAMUsed->used);
                
                    /* 釋放從AXI SRAM申請的32字節空間 */
                    osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres1);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("釋放AXI SRAM動態內存區申請的0032字節,當前共使用大小 = %d字節\r\n",
 AXISRAMUsed->used);
                
                    /* 釋放從AXI SRAM申請的2333字節空間 */
                    osRtxMemoryFree(AppMallocAXISRAM, AXISRAM_Addres2);
                    AXISRAMUsed = MemHeadPtr(AppMallocAXISRAM);
                    printf("釋放AXI SRAM動態內存區申請的2333字節,當前共使用大小 = %d字節\r\n", 
AXISRAMUsed->used);
                    break;
                
                /* 從D2域SRAM依次申請200字節,96字節和4111字節 */
                case KEY_DOWN_K3:    
        /* 從D2域的SRAM申請200字節空間,使用指針變量SRAM1_Addres0操作這些空間時不要超過200字節大小 */
                    printf("=========================================================\r\n");        
                    SRAM1_Addres0 = osRtxMemoryAlloc(AppMallocSRAM1, 200, 0);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("D2域SRAM總大小 = %d字節,申請大小 = 0200字節,當前共使用大小 = %d字節\r\n", 
                                                                SRAM1Used->size, SRAM1Used->used);
                
     /* 從D2域的SRAM申請96字節空間,使用指針變量SRAM1_Addres1操作這些空間時不要超過96字節大小 */    
                    SRAM1_Addres1 = osRtxMemoryAlloc(AppMallocSRAM1, 96, 0);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("D2域SRAM總大小 = %d字節,申請大小 = 0096字節,當前共使用大小 = %d字節\r\n", 
                                                               SRAM1Used->size, SRAM1Used->used);
                
     /* 從D2域的SRAM申請4111字節空間,使用指針變量SRAM1_Addres2操作這些空間時不要超過4111字節大小 */
                    SRAM1_Addres2 = osRtxMemoryAlloc(AppMallocSRAM1, 4111, 0);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("D2域SRAM總大小 = %d字節,申請大小 = 4111字節,當前共使用大小 = %d字節\r\n", 
                                                                SRAM1Used->size, SRAM1Used->used);
                    break;
                
                /* 釋放從D2域SRAM申請的空間 */
                case KEY_UP_K3:    
                    /* 釋放從D2域的SRAM申請的200字節空間 */
                    osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres0);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("釋放D2域SRAM動態內存區申請的0200字節,當前共使用大小 = %d字節\r\n",
 SRAM1Used->used);
                
                    /* 釋放從D2域的SRAM申請的96字節空間 */
                    osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres1);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("釋放D2域SRAM動態內存區申請的0096字節,當前共使用大小 = %d字節\r\n",
 SRAM1Used->used);
                
                    /* 釋放從D2域的SRAM申請的4111字節空間 */
                    osRtxMemoryFree(AppMallocSRAM1, SRAM1_Addres2);
                    SRAM1Used = MemHeadPtr(AppMallocSRAM1);
                    printf("釋放D2域SRAM動態內存區申請的4111字節,當前共使用大小 = %d字節\r\n",
 SRAM1Used->used);
                    break;
                
                /* 從D3域SRAM依次申請300字節,128字節和5111字節 */
                case JOY_DOWN_OK:    
            /* 從D3域的SRAM申請300字節空間,使用指針變量SRAM4_Addres0操作這些空間時不要超過300字節大小 */
                    printf("=========================================================\r\n");        
                    SRAM4_Addres0 = osRtxMemoryAlloc(AppMallocSRAM4, 300, 0);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("D3域SRAM總大小 = %d字節,申請大小 = 0300字節,當前共使用大小 = %d字節\r\n", 
                                                                SRAM4Used->size, SRAM4Used->used);
                
        /* 從D3域的SRAM申請96字節空間,使用指針變量SRAM4_Addres1操作這些空間時不要超過96字節大小 */
                    SRAM4_Addres1 = osRtxMemoryAlloc(AppMallocSRAM4, 128, 0);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("D3域SRAM總大小 = %d字節,申請大小 = 0128字節,當前共使用大小 = %d字節\r\n", 
                                                               SRAM4Used->size, SRAM4Used->used);
                
    /* 從D3域的SRAM申請5111字節空間,使用指針變量SRAM4_Addres2操作這些空間時不要超過5111字節大小 */
                    SRAM4_Addres2 = osRtxMemoryAlloc(AppMallocSRAM4, 5111, 0);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("D3域SRAM總大小 = %d字節,申請大小 = 5111字節,當前共使用大小 = %d字節\r\n", 
                                                                SRAM4Used->size, SRAM4Used->used);
                    break;
                
                /* 釋放從D3域SRAM申請的空間 */
                case JOY_UP_OK:    
                    /* 釋放從D3域的SRAM申請的300字節空間 */
                    osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres0);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("釋放D3域SRAM動態內存區申請的0300字節,當前共使用大小 = %d字節\r\n", 
SRAM4Used->used);
                
                    /* 釋放從D3域的SRAM申請的128字節空間 */
                    osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres1);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("釋放D3域SRAM動態內存區申請的0128字節,當前共使用大小 = %d字節\r\n",
 SRAM4Used->used);
                
                    /* 釋放從D3域的SRAM申請的5111字節空間 */
                    osRtxMemoryFree(AppMallocSRAM4, SRAM4_Addres2);
                    SRAM4Used = MemHeadPtr(AppMallocSRAM4);
                    printf("釋放D3域SRAM動態內存區申請的5111字節,當前共使用大小 = %d字節\r\n",
 SRAM4Used->used);
                    break;
            
                default:
                  /* 其它的鍵值不處理 */
                  break;
            }
        }
    }
}

 

27.6 總結

本章節就為大家講解這么多,還是比較有項目實用價值的,特別是MP3編解碼,JPEG編解碼,視頻播放器,矢量字體等需要動態內存的場合。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM