完整教程下載地址: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 初學者重要提示
- 學習本章節前,務必優先學習第25章,了解TCM,SRAM等五塊內存區的基礎知識,比較重要。
- 將RTX5系統的動態內存管理整理了出來,可以同時管理多個分區。如果其它RTOS中使用,記得做互斥保護或者加個調度鎖均可。
- 支持動態內存使用情況統計。
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等五塊內存的動態內存分配實現
實驗目的:
- 學習TCM,SRAM等五塊內存的動態內存分配實現。
實驗內容:
- 啟動自動重裝軟件定時器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申請的空間。
上電后串口打印的信息:
波特率 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等五塊內存的動態內存分配實現
實驗目的:
- 學習TCM,SRAM等五塊內存的動態內存分配實現。
實驗內容:
- 啟動自動重裝軟件定時器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申請的空間。
上電后串口打印的信息:
波特率 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編解碼,視頻播放器,矢量字體等需要動態內存的場合。