前言
以前工程用的是正点原子的内存管理组件。 这次加了2片SRAM, 在正点原子原版的内存管理组件上,将第2片SRAM的操作加上了。 在lite-os的任务中跑了一下,好使。
但是主内存只能管理20KB, 要不lite-os初始化卡死或任务建立失败。可能是lite-os配置中,不用的特性开多了,导致内存用量大。以后再研究, 看看将不用的特性关了或不建立那么多任务或事件看看。我主要用外挂的2片SRAM(每片1MB),也不在乎主内存用多了。下次换F429, 用SDRAM.
正点原子的实现是MDK版的,用在IAR工程时,全局数据(变量,数组,结构)定义要改下,否则编译不过。 在IAR中,指定数据不需要编译器初始化,指定物理地址时,和MDK工程中的语法是不一样的。
笔记
更新后的内存管理组件
内存管理组件管理 CCM, 主内存,外挂2片SRAM.
#ifndef __INC_COMMON_H__
#define __INC_COMMON_H__
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#endif
#ifndef __MALLOC_H
#define __MALLOC_H
#include "inc_common.h"
#define SRAMCCM 0
#define SRAMIN 1
#define SRAMEX1 2
#define SRAMEX2 3
#define SRAMBANK 4
#define MEM_CCM_BLOCK_SIZE 32
#define MEM_CCM_MAX_SIZE (60 * 1024)
#define MEM_CCM_ALLOC_TABLE_SIZE (MEM_CCM_MAX_SIZE / MEM_CCM_BLOCK_SIZE)
#define MEM_IN_BLOCK_SIZE 32
#define MEM_IN_MAX_SIZE (20 * 1024)
#define MEM_IN_ALLOC_TABLE_SIZE (MEM_IN_MAX_SIZE / MEM_IN_BLOCK_SIZE)
#define MEM_EX1_BLOCK_SIZE 32
#define MEM_EX1_MAX_SIZE (960 * 1024)
#define MEM_EX1_ALLOC_TABLE_SIZE (MEM_EX1_MAX_SIZE / MEM_EX1_BLOCK_SIZE)
#define MEM_EX2_BLOCK_SIZE 32
#define MEM_EX2_MAX_SIZE (960 * 1024)
#define MEM_EX2_ALLOC_TABLE_SIZE (MEM_EX2_MAX_SIZE / MEM_EX2_BLOCK_SIZE)
struct _m_mallco_dev
{
void (*init)(uint8_t);
uint8_t (*perused)(uint8_t);
uint8_t* membase[SRAMBANK];
uint16_t* memmap[SRAMBANK];
uint8_t memrdy[SRAMBANK];
};
extern struct _m_mallco_dev mallco_dev;
void my_mem_init(uint8_t memx);
void mymemset(void* s, uint8_t c, uint32_t count);
void mymemcpy(void* des, void* src, uint32_t n);
uint32_t my_mem_malloc(uint8_t memx, uint32_t size);
uint8_t my_mem_free(uint8_t memx, uint32_t offset);
uint8_t my_mem_perused(uint8_t memx);
void myfree(uint8_t memx,void* ptr);
void* mymalloc(uint8_t memx, uint32_t size);
void* myrealloc(uint8_t memx, void* ptr, uint32_t size);
void my_mem_init_CCM();
void myfree_CCM(void* ptr);
void* mymalloc_CCM(uint32_t size);
void* myrealloc_CCM(void* ptr, uint32_t size);
uint8_t my_mem_perused_CCM();
void my_mem_init_IN();
void myfree_IN(void* ptr);
void* mymalloc_IN(uint32_t size);
void* myrealloc_IN(void* ptr, uint32_t size);
uint8_t my_mem_perused_IN();
void my_mem_init_EX1();
void myfree_EX1(void* ptr);
void* mymalloc_EX1(uint32_t size);
void* myrealloc_EX1(void* ptr, uint32_t size);
uint8_t my_mem_perused_EX1();
void my_mem_init_EX2();
void myfree_EX2(void* ptr);
void* mymalloc_EX2(uint32_t size);
void* myrealloc_EX2(void* ptr, uint32_t size);
uint8_t my_mem_perused_EX2();
#endif
#include "malloc.h"
#pragma pack(32)
__no_init volatile
uint8_t membase_CCM[MEM_CCM_MAX_SIZE] @ 0X10000000;
uint8_t membase_IN[MEM_IN_MAX_SIZE];
__no_init volatile
uint8_t membase_EX1[MEM_EX1_MAX_SIZE] @ 0X68000000;
__no_init volatile
uint8_t membase_EX2[MEM_EX2_MAX_SIZE] @ 0X6C000000;
__no_init volatile
uint16_t memmapbase_CCM[MEM_CCM_ALLOC_TABLE_SIZE] @ (0X10000000 + MEM_CCM_MAX_SIZE);
__no_init volatile
uint16_t memmapbase_IN[MEM_IN_ALLOC_TABLE_SIZE];
__no_init volatile
uint16_t memmapbase_EX1[MEM_EX1_ALLOC_TABLE_SIZE] @ (0X68000000 + MEM_EX1_MAX_SIZE);
__no_init volatile
uint16_t memmapbase_EX2[MEM_EX2_ALLOC_TABLE_SIZE] @ (0X6C000000 + MEM_EX2_MAX_SIZE);
const uint32_t memtblsize[SRAMBANK] = {
MEM_CCM_ALLOC_TABLE_SIZE,
MEM_IN_ALLOC_TABLE_SIZE,
MEM_EX1_ALLOC_TABLE_SIZE,
MEM_EX2_ALLOC_TABLE_SIZE
};
const uint32_t memblksize[SRAMBANK] = {
MEM_CCM_BLOCK_SIZE,
MEM_IN_BLOCK_SIZE,
MEM_EX1_BLOCK_SIZE,
MEM_EX2_BLOCK_SIZE
};
const uint32_t memsize[SRAMBANK] = {
MEM_CCM_MAX_SIZE,
MEM_IN_MAX_SIZE,
MEM_EX1_MAX_SIZE,
MEM_EX2_MAX_SIZE
};
#pragma pack()
struct _m_mallco_dev mallco_dev =
{
my_mem_init,
my_mem_perused,
(uint8_t*)membase_CCM,
(uint8_t*)membase_IN,
(uint8_t*)membase_EX1,
(uint8_t*)membase_EX2,
(uint16_t*)memmapbase_CCM,
(uint16_t*)memmapbase_IN,
(uint16_t*)memmapbase_EX1,
(uint16_t*)memmapbase_EX2,
0,
0,
0,
0,
};
void mymemcpy(void* des, void* src, uint32_t n)
{
uint8_t* xdes = des;
uint8_t* xsrc = src;
while(n--) {
*xdes++ = *xsrc++;
}
}
void mymemset(void* s, uint8_t c, uint32_t count)
{
uint8_t* xs = s;
while(count--) {
*xs++ = c;
}
}
void my_mem_init(uint8_t memx)
{
mymemset(mallco_dev.memmap[memx], 0, memtblsize[memx] * sizeof(uint16_t));
mymemset(mallco_dev.membase[memx], 0, memsize[memx]);
mallco_dev.memrdy[memx] = 1;
}
uint8_t my_mem_perused(uint8_t memx)
{
uint32_t used = 0;
uint32_t i = 0;
for (i = 0; i < memtblsize[memx]; i++)
{
if (mallco_dev.memmap[memx][i]) {
used++;
}
}
return ((used * 100) / memtblsize[memx]);
}
uint32_t my_mem_malloc(uint8_t memx, uint32_t size)
{
signed long offset = 0;
uint32_t nmemb = 0;
uint32_t cmemb = 0;
uint32_t i = 0;
if (!mallco_dev.memrdy[memx]) {
mallco_dev.init(memx);
}
if (0 == size) {
return 0XFFFFFFFF;
}
nmemb = size / memblksize[memx];
if (size % memblksize[memx]) {
nmemb++;
}
for (offset = memtblsize[memx] - 1; offset >= 0; offset--)
{
if (!mallco_dev.memmap[memx][offset]) {
cmemb++;
} else {
cmemb=0;
}
if (cmemb == nmemb)
{
for (i = 0; i < nmemb; i++)
{
mallco_dev.memmap[memx][offset + i] = nmemb;
}
return (offset * memblksize[memx]);
}
}
return 0XFFFFFFFF;
}
uint8_t my_mem_free(uint8_t memx, uint32_t offset)
{
int i = 0;
if (!mallco_dev.memrdy[memx])
{
mallco_dev.init(memx);
return 1;
}
if (offset < memsize[memx])
{
int index = offset / memblksize[memx];
int nmemb = mallco_dev.memmap[memx][index];
for (i = 0; i < nmemb; i++)
{
mallco_dev.memmap[memx][index+i] = 0;
}
return 0;
} else {
return 2;
}
}
void myfree(uint8_t memx, void* ptr)
{
uint32_t offset = 0;
if (ptr == NULL) {
return;
}
offset = (uint32_t)ptr - (uint32_t)mallco_dev.membase[memx];
my_mem_free(memx,offset);
}
void* mymalloc(uint8_t memx, uint32_t size)
{
uint32_t offset = 0;
offset = my_mem_malloc(memx, size);
if (0XFFFFFFFF == offset) {
return NULL;
} else {
return (void*)((uint32_t)mallco_dev.membase[memx] + offset);
}
}
void* myrealloc(uint8_t memx, void* ptr, uint32_t size)
{
uint32_t offset = 0;
offset = my_mem_malloc(memx,size);
if (0XFFFFFFFF == offset) {
return NULL;
} else{
mymemcpy((void*)((uint32_t)mallco_dev.membase[memx] + offset), ptr, size);
myfree(memx, ptr);
return (void*)((uint32_t)mallco_dev.membase[memx] + offset);
}
}
void my_mem_init_CCM()
{
my_mem_init(SRAMCCM);
}
void myfree_CCM(void* ptr)
{
myfree(SRAMCCM, ptr);
}
void* mymalloc_CCM(uint32_t size)
{
return mymalloc(SRAMCCM, size);
}
void* myrealloc_CCM(void* ptr, uint32_t size)
{
return myrealloc(SRAMCCM, ptr, size);
}
uint8_t my_mem_perused_CCM()
{
return my_mem_perused(SRAMCCM);
}
void my_mem_init_IN()
{
my_mem_init(SRAMIN);
}
void myfree_IN(void* ptr)
{
myfree(SRAMIN, ptr);
}
void* mymalloc_IN(uint32_t size)
{
return mymalloc(SRAMIN, size);
}
void* myrealloc_IN(void* ptr, uint32_t size)
{
return myrealloc(SRAMIN, ptr, size);
}
uint8_t my_mem_perused_IN()
{
return my_mem_perused(SRAMIN);
}
void my_mem_init_EX1()
{
my_mem_init(SRAMEX1);
}
void myfree_EX1(void* ptr)
{
myfree(SRAMEX1, ptr);
}
void* mymalloc_EX1(uint32_t size)
{
return mymalloc(SRAMEX1, size);
}
void* myrealloc_EX1(void* ptr, uint32_t size)
{
return myrealloc(SRAMEX1, ptr, size);
}
uint8_t my_mem_perused_EX1()
{
return my_mem_perused(SRAMEX1);
}
void my_mem_init_EX2()
{
my_mem_init(SRAMEX2);
}
void myfree_EX2(void* ptr)
{
myfree(SRAMEX2, ptr);
}
void* mymalloc_EX2(uint32_t size)
{
return mymalloc(SRAMEX2, size);
}
void* myrealloc_EX2(void* ptr, uint32_t size)
{
return myrealloc(SRAMEX2, ptr, size);
}
uint8_t my_mem_perused_EX2()
{
return my_mem_perused(SRAMEX2);
}
测试代码
#include "main.h"
#include "lwip.h"
#include "sdio.h"
#include "spi.h"
#include "usart.h"
#include "gpio.h"
#include "fsmc.h"
#include "malloc.h"
void SystemClock_Config(void);
static void MX_NVIC_Init(void);
void led_app_running()
{
LOS_TaskDelay(1000);
HAL_GPIO_WritePin(MCU_LED0_GPIO_Port, MCU_LED0_Pin, GPIO_PIN_SET);
LOS_TaskDelay(1000);
HAL_GPIO_WritePin(MCU_LED0_GPIO_Port, MCU_LED0_Pin, GPIO_PIN_RESET);
}
void led_app_stop()
{
LOS_TaskDelay(100);
HAL_GPIO_WritePin(MCU_LED0_GPIO_Port, MCU_LED0_Pin, GPIO_PIN_SET);
LOS_TaskDelay(100);
HAL_GPIO_WritePin(MCU_LED0_GPIO_Port, MCU_LED0_Pin, GPIO_PIN_RESET);
}
void LAN8720_RESET(void)
{
HAL_GPIO_WritePin(ETH_RESET_GPIO_Port, ETH_RESET_Pin, GPIO_PIN_RESET);
HAL_Delay(55);
HAL_GPIO_WritePin(ETH_RESET_GPIO_Port, ETH_RESET_Pin, GPIO_PIN_SET);
HAL_Delay(55);
}
void test_mem_ccm(void)
{
uint8_t c_per = 0;
c_per = my_mem_perused_CCM();
uint8_t* puc_buf = mymalloc_CCM(0x4000);
c_per = my_mem_perused_CCM();
if (NULL != puc_buf)
{
strcpy((char*)puc_buf, "hello memory operation");
if (('h' == puc_buf[0]) && ('\0' == puc_buf[strlen((char*)puc_buf)]))
{
puc_buf[0] = puc_buf[0];
}
myfree_CCM(puc_buf);
}
}
void test_mem_in(void)
{
uint8_t c_per = 0;
c_per = my_mem_perused_IN();
uint8_t* puc_buf = mymalloc_IN(0x4000);
c_per = my_mem_perused_IN();
if (NULL != puc_buf)
{
strcpy((char*)puc_buf, "hello memory operation");
if (('h' == puc_buf[0]) && ('\0' == puc_buf[strlen((char*)puc_buf)]))
{
puc_buf[0] = puc_buf[0];
}
myfree_IN(puc_buf);
}
}
void test_mem_ex1(void)
{
uint8_t c_per = 0;
c_per = my_mem_perused_EX1();
uint8_t* puc_buf = mymalloc_EX1(0x4000);
c_per = my_mem_perused_EX1();
if (NULL != puc_buf)
{
strcpy((char*)puc_buf, "hello memory operation");
if (('h' == puc_buf[0]) && ('\0' == puc_buf[strlen((char*)puc_buf)]))
{
puc_buf[0] = puc_buf[0];
}
myfree_EX1(puc_buf);
}
}
void test_mem_ex2(void)
{
uint8_t c_per = 0;
c_per = my_mem_perused_EX2();
uint8_t* puc_buf = mymalloc_EX2(0x4000);
c_per = my_mem_perused_EX2();
if (NULL != puc_buf)
{
strcpy((char*)puc_buf, "hello memory operation");
if (('h' == puc_buf[0]) && ('\0' == puc_buf[strlen((char*)puc_buf)]))
{
puc_buf[0] = puc_buf[0];
}
myfree_EX2(puc_buf);
}
}
static void TaskTotal(void)
{
LOS_TaskDelay(1000);
MX_GPIO_Init();
LAN8720_RESET();
MX_SDIO_SD_Init();
MX_SPI2_Init();
MX_USART1_UART_Init();
MX_USART3_UART_Init();
MX_USART6_UART_Init();
MX_FSMC_Init();
my_mem_init_CCM();
my_mem_init_IN();
my_mem_init_EX1();
my_mem_init_EX2();
MX_LWIP_Init();
MX_NVIC_Init();
test_mem_ccm();
test_mem_in();
test_mem_ex1();
test_mem_ex2();
while(1)
{
MX_LWIP_Process();
}
}
UINT32 Test1_Task_Handle = 0;
static UINT32 Creat_TaskTotal()
{
UINT32 uwRet = LOS_OK;
TSK_INIT_PARAM_S task_init_param;
task_init_param.usTaskPrio = 3;
task_init_param.pcName = "TaskTotal";
task_init_param.pfnTaskEntry = (TSK_ENTRY_FUNC)TaskTotal;
task_init_param.uwStackSize = 1024;
uwRet = LOS_TaskCreate(&Test1_Task_Handle, &task_init_param);
return uwRet;
}
static UINT32 AppTaskCreate(void)
{
UINT32 uwRet = LOS_OK;
uwRet = Creat_TaskTotal();
if (uwRet != LOS_OK)
{
return uwRet;
}
return LOS_OK;
}
void HAL_Delay(uint32_t Delay)
{
LOS_TaskDelay(Delay);
}
int main(void)
{
UINT32 uwRet = 0;
HAL_Init();
SystemClock_Config();
uwRet = LOS_KernelInit();
if (uwRet != LOS_OK)
{
return LOS_NOK;
}
LOS_Inspect_Entry();
uwRet = AppTaskCreate();
if (uwRet != LOS_OK)
{
return LOS_NOK;
}
LOS_Start();
while (1)
{
}
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 4;
RCC_OscInitStruct.PLL.PLLN = 168;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
HAL_RCC_EnableCSS();
}
static void MX_NVIC_Init(void)
{
HAL_NVIC_SetPriority(RCC_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(RCC_IRQn);
}
void Error_Handler(void)
{
__disable_irq();
while (1)
{
}
}
#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line)
{
line = line;
}
#endif
|