356f258e83
* use nuttx libc, disable system libc * use tlsf as default * update lhal flash driver * add example readme * add flash ini for new flash tool * add fw header for new flash tool
272 lines
8.4 KiB
C
272 lines
8.4 KiB
C
#include "bflb_mtimer.h"
|
|
#include "board.h"
|
|
#include "string.h"
|
|
#include "stdlib.h"
|
|
|
|
#include "mem.h"
|
|
|
|
//随机生成堆的参数
|
|
//堆区最大值
|
|
#define MAX_HEAP_REGION 1024
|
|
//堆区最小值
|
|
#define MIN_HEAP_REGION 16
|
|
//堆区倍乘数值
|
|
#define HEAP_BLOCK_SIZE 16
|
|
//堆区数量最大值
|
|
#define MAX_HEAP_REGION_NUM 10
|
|
//堆区数量最小值
|
|
#define MIN_HEAP_REGION_NUM 2
|
|
|
|
//随机申请内存的参数
|
|
//随机申请内存的最大对齐,2^MAX_ALIGN_MALLOC
|
|
#define MAX_ALIGN_MALLOC 10
|
|
//随机申请内存的最小对齐,2^MIN_ALIGN_MALLOC
|
|
#define MIN_ALIGN_MALLOC 2
|
|
//随机申请的最大内存
|
|
#define MAX_WANT_MALLOC 1024
|
|
//随机申请的最小内存
|
|
#define MIN_WANT_MALLOC 1
|
|
//随机申请内存最大次数
|
|
#define MAX_MALLOC_CNT 1000
|
|
|
|
typedef struct heap_region {
|
|
void *addr;
|
|
size_t mem_size;
|
|
} Mem_Region;
|
|
|
|
struct mem_heap_s g_userheap;
|
|
|
|
//生成指定范围的随机数
|
|
static inline unsigned int Get_Rand(unsigned int max, unsigned int min)
|
|
{
|
|
return random() % (max - min + 1) + min;
|
|
}
|
|
|
|
|
|
//生成一个随机的堆
|
|
Mem_Region *Mem_Manage_Generate_Rand_Heap(void)
|
|
{
|
|
size_t region_num;
|
|
Mem_Region *pRegion;
|
|
|
|
// region_num = Get_Rand(MAX_HEAP_REGION_NUM, MIN_HEAP_REGION_NUM);
|
|
region_num = 1;
|
|
pRegion = malloc(sizeof(Mem_Region) * (region_num + 1));
|
|
|
|
if (pRegion == NULL)
|
|
return NULL;
|
|
|
|
// for (size_t i = 0; i < region_num; i++) {
|
|
// size_t region_size = Get_Rand(MAX_HEAP_REGION, MIN_HEAP_REGION) * HEAP_BLOCK_SIZE;
|
|
size_t region_size = 50 * 1024;
|
|
size_t i = 0;
|
|
|
|
void *paddr = malloc(512); //确保内存不连续
|
|
|
|
pRegion[i].addr = malloc(region_size);
|
|
pRegion[i].mem_size = region_size;
|
|
free(paddr);
|
|
// }
|
|
|
|
// for (size_t i = 0; i < region_num; i++) { //按地址进行排序,从低到高
|
|
// for (size_t j = i + 1; j < region_num; j++) {
|
|
// if (pRegion[i].addr > pRegion[j].addr) {
|
|
// Mem_Region buf_region = pRegion[i];
|
|
// pRegion[i] = pRegion[j];
|
|
// pRegion[j] = buf_region;
|
|
// }
|
|
// }
|
|
// }
|
|
|
|
pRegion[region_num].addr = NULL;
|
|
pRegion[region_num].mem_size = 0;
|
|
|
|
return pRegion;
|
|
}
|
|
|
|
void Mem_Manage_Free_Rand_Heap(Mem_Region *const pHeap)
|
|
{
|
|
for (Mem_Region *buf_heap = pHeap; buf_heap->addr != NULL; buf_heap++) {
|
|
free(buf_heap->addr);
|
|
}
|
|
|
|
free(pHeap);
|
|
}
|
|
|
|
//打印堆的信息
|
|
void Mem_Manage_Show_Heap_Info(Mem_Region *pHeap)
|
|
{
|
|
printf("地址\t\t\t大小\r\n");
|
|
for (; pHeap->addr != NULL; pHeap++) {
|
|
printf("0x%08x\t\t%d\r\n", (size_t)pHeap->addr, pHeap->mem_size);
|
|
}
|
|
}
|
|
//打印当前内存剩余
|
|
size_t Mem_Manage_Show_Free_Heap(struct meminfo *info)
|
|
{
|
|
bflb_mem_usage(&g_userheap, info);
|
|
printf("剩余内存:%d\r\n", info->free_size);
|
|
printf("内存利用率:%.2f%%\r\n", (info->used_size) * 100.0 / info->total_size);
|
|
printf("最大内存块:%d\r\n", info->max_free_size);
|
|
// printf("最小内存块:%d\r\n", use_state.min_node_size);
|
|
printf("剩余内存块数:%d\r\n", info->free_node);
|
|
return info->free_node;
|
|
}
|
|
|
|
void memtest(void)
|
|
{
|
|
Mem_Region *pRegion;
|
|
struct meminfo info;
|
|
uint64_t max_time = 0;
|
|
float avr_time = 0.0;
|
|
uint64_t time;
|
|
uint64_t time_tmp;
|
|
|
|
// while (1) {
|
|
size_t heap_num;
|
|
printf("生成随机内存堆...\r\n");
|
|
printf("<---------内存堆信息------------>\r\n");
|
|
|
|
pRegion = Mem_Manage_Generate_Rand_Heap();
|
|
|
|
Mem_Manage_Show_Heap_Info(pRegion);
|
|
|
|
printf("<-------初始化内存堆--------->\r\n");
|
|
umem_init(&g_userheap, pRegion[0].addr, pRegion[0].mem_size);
|
|
|
|
// printf("start块:0x%08x,%d\r\n", (size_t)Mem_Handle.pStart, Mem_Handle.pStart->mem_size);
|
|
// printf("end 块:0x%08x,%d\r\n", (size_t)Mem_Handle.pEnd, Mem_Handle.pEnd->mem_size);
|
|
printf("总内存:%d\r\n", pRegion[0].mem_size);
|
|
printf("<---------初始空闲列表------------>\r\n");
|
|
|
|
heap_num = Mem_Manage_Show_Free_Heap(&info);
|
|
|
|
printf("<-------malloc测试------------>\r\n");
|
|
{
|
|
void **addr_buf = malloc(MAX_MALLOC_CNT * sizeof(void *));
|
|
size_t *want_size = malloc(MAX_MALLOC_CNT * sizeof(size_t));
|
|
void *buf_addr;
|
|
size_t malloc_cnt = 0;
|
|
size_t align_size;
|
|
size_t buf_size;
|
|
|
|
while (malloc_cnt < MAX_MALLOC_CNT) {
|
|
align_size = 1 << Get_Rand(MAX_ALIGN_MALLOC, MIN_ALIGN_MALLOC); //确保为2的指数次幂
|
|
want_size[malloc_cnt] = Get_Rand(MAX_WANT_MALLOC, MIN_WANT_MALLOC);
|
|
|
|
time_tmp = bflb_mtimer_get_time_us();
|
|
addr_buf[malloc_cnt] = bflb_malloc_align(&g_userheap, align_size, want_size[malloc_cnt]);
|
|
time = bflb_mtimer_get_time_us() - time_tmp;
|
|
|
|
if (max_time < time) {
|
|
max_time = time;
|
|
}
|
|
avr_time += (float)time;
|
|
printf("malloc time %lld us %p\r\n", time, addr_buf[malloc_cnt]);
|
|
|
|
if (addr_buf[malloc_cnt] == NULL) {
|
|
printf("malloc分配失败!\r\n");
|
|
printf("期望对齐:%d,期望大小:%d\r\n", align_size, want_size[malloc_cnt]);
|
|
break;
|
|
}
|
|
if ((size_t)addr_buf[malloc_cnt] % align_size) {
|
|
printf("malloc 对齐出错!\r\n");
|
|
}
|
|
|
|
memset(addr_buf[malloc_cnt], malloc_cnt, want_size[malloc_cnt]);
|
|
|
|
buf_size = Get_Rand(MAX_WANT_MALLOC, want_size[malloc_cnt]);
|
|
buf_addr = bflb_realloc(&g_userheap, addr_buf[malloc_cnt], buf_size);
|
|
|
|
if (buf_addr == NULL) {
|
|
printf("realloc分配失败!\r\n");
|
|
printf("期望大小:%d\r\n", buf_size);
|
|
break;
|
|
}
|
|
if ((size_t)buf_addr % align_size) {
|
|
printf("realloc 对齐出错!%p\r\n", buf_addr);
|
|
}
|
|
|
|
memset((uint8_t *)buf_addr + want_size[malloc_cnt], malloc_cnt, buf_size - want_size[malloc_cnt]);
|
|
addr_buf[malloc_cnt] = buf_addr;
|
|
want_size[malloc_cnt] = buf_size;
|
|
malloc_cnt++;
|
|
}
|
|
|
|
avr_time = avr_time / (float)malloc_cnt;
|
|
|
|
printf("共分配%d次, 平均malloc耗时%.02fus, 最大耗时%ldus\r\n", malloc_cnt, avr_time, max_time);
|
|
printf("<---------测试后空闲列表------------>\r\n");
|
|
Mem_Manage_Show_Free_Heap(&info);
|
|
|
|
printf("内存区检查...\r\n");
|
|
for (size_t i = 0; i < malloc_cnt; i++) {
|
|
for (size_t j = 0; j < want_size[i]; j++) {
|
|
if (((uint8_t *)addr_buf[i])[j] != (uint8_t)i) {
|
|
printf("校验出错!\r\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
printf("<---------free测试----------->\r\n");
|
|
for (size_t i = 0; i < malloc_cnt; i++) {
|
|
bflb_free(&g_userheap, addr_buf[i]);
|
|
}
|
|
|
|
free(addr_buf);
|
|
free(want_size);
|
|
}
|
|
|
|
// printf("start块:0x%08x,%d\r\n", (size_t)Mem_Handle.pStart, Mem_Handle.pStart->mem_size);
|
|
// printf("end 块:0x%08x,%d\r\n", (size_t)Mem_Handle.pEnd, Mem_Handle.pEnd->mem_size);
|
|
printf("总内存:%d\r\n", pRegion[0].mem_size);
|
|
printf("<---------内存释放后空闲列表------------>\r\n");
|
|
if (Mem_Manage_Show_Free_Heap(&info) != heap_num) {
|
|
printf("算法异常!\r\n");
|
|
}
|
|
|
|
Mem_Manage_Free_Rand_Heap(pRegion);
|
|
// }
|
|
}
|
|
|
|
int memheap_test(void)
|
|
{
|
|
char *ptr = NULL;
|
|
|
|
for (int i = 1;; i++) {
|
|
ptr = malloc(i * 128);
|
|
|
|
if (ptr != NULL) {
|
|
memcpy(ptr, "hello123456789123456789123456789", 33);
|
|
printf("ptr :%s\r\n", ptr);
|
|
printf("get memory :%d byte\r\n", i * 128);
|
|
free(ptr);
|
|
printf("free memory :%d byte\r\n", i * 128);
|
|
ptr = NULL;
|
|
bflb_mtimer_delay_ms(100);
|
|
} else {
|
|
printf("try to get %d byte memory failed!\r\n", i * 128);
|
|
|
|
return -1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
board_init();
|
|
|
|
memtest();
|
|
|
|
if (memheap_test() == -1) {
|
|
printf("memheap test fail\r\n");
|
|
while (1) {
|
|
}
|
|
}
|
|
printf("memheap test success\r\n");
|
|
while (1) {
|
|
bflb_mtimer_delay_ms(1000);
|
|
}
|
|
}
|