点击“嵌入式情报局”,选择“置顶/星标”
1、尽量不使用库自带的malloc和free。
malloc和free在PC编程中是很好用的一种内存分配手段。但是,其在嵌入式中,就未必好用了。由于嵌入式裸机编程中,无MMU,即内存管理单元。无法实现对内存进行动态映射(不明白什么叫动态映射的同学,可以参考网上的资料)。
也就是说,实际上,malloc和free并不能实现动态的内存的管理。这需要在启动阶段专门给其分配一段空闲的内存区域作为malloc的内存区。如STM32中的启动文件startup_stm32f10x_md.s中可见以下信息:
1Heap_Size EQU 0x00000800
2AREA HEAP, NOINIT, READWRITE, ALIGN=3
3__heap_base
4Heap_Mem SPACE Heap_Size
5__heap_limit
1#define Heap_Size 0x00000800
2unsigned char Heap_Mem[Heap_Size] = {0};
1__user_initial_stackheap
2LDR R0, = Heap_Mem ; 返回系统中堆内存起始地址
3LDR R1, =(Stack_Mem + Stack_Size)
4LDR R2, = (Heap_Mem + Heap_Size); 返回系统中堆内存的结束地址
5LDR R3, = Stack_Mem
6BX LR
而更为致命的是,有些malloc,free函数,由于工程人员的偷懒。实现甚至可能如下:
1unsigned char mem_buffer[512];
2unsigned char *mem_offset = & mem_buffer;
3void *malloc(int size)
4{
5 unsigned char *tmp = mem_offset;
6 mem_offset += size;
7 return (void *)tmp;
8}
9void free(void *mem)
10{
11 mem_offset = mem;
12}
2、不用malloc、free的原因
3、 更好的替代方案:内存池。
1#define MEM_BUFFER_LEN 5 //内存块的数量
2#define MEM_BUFFER_SIZE 256 //每块内存的大小
3
4//内存池的描述,使用联合体,体现穷人的智慧。就如,我一同学说的:一个字节,恨不得掰成8个字节来用。
5typedef union mem {
6 struct list_head list;
7 unsigned char buffer[MEM_BUFFER_SIZE];
8}mem_t;
9
10static union mem gmem[MEM_BUFFER_LEN];
11
12LIST_HEAD(mem_pool);
13
14//分配内存
15void *mem_pop()
16{
17 union mem *ret = NULL;
18 psr_t psr;
19
20 psr = ENTER_CRITICAL();
21 if(!list_empty(&mem_pool)) { //有可用的内存池
22 ret = list_first_entry(&mem_pool, union mem, list);
23 //printf("mem_pool = 0x%p ret = 0x%p\n", &mem_pool, &ret->list);
24 list_del(&ret->list);
25 }
26 EXIT_CRITICAL(psr);
27 return ret;//->buffer;
28}
29
30
31//回收内存
32void mem_push(void *mem)
33{
34 union mem *tmp = NULL;
35 psr_t psr;
36
37 tmp = (void *)mem;//container_of(mem, struct mem, buffer);
38 psr = ENTER_CRITICAL();
39 list_add(&tmp->list, &mem_pool);
40 //printf("free = 0x%p\n", &tmp->list);
41
42 EXIT_CRITICAL(psr);
43}
44
45//初始化内存池
46void mem_pool_init()
47{
48 int i;
49 psr_t psr;
50 psr = ENTER_CRITICAL();
51 for(i=0; i<MEM_BUFFER_LEN; i++) {
52 list_add(&(gmem[i].list), &mem_pool);
53 //printf("add mem 0x%p\n", &(gmem[i].list));
54 }
55 EXIT_CRITICAL(psr);
56}
小哥搜集了一些嵌入式学习资料,公众号内回复【1024】即可找到下载链接!
推荐好文 点击蓝色字体即可跳转







文章转载自嵌入式情报局,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




