在同事的帮助下,第一次尝试了STM32程序的编写. 当然仅仅是C语言的部分, 并没有涉及到电子/硬件的操作. 相关操作还是同事实现的.
当时使用了STM32 自带的 malloc, 后来发现程序运行久了会导致卡死. 其原因至今没有查清楚, 一来是因为能力不够,二是因为时间不足.
最终是写了一个超级简陋的内存分配器, 当然了,肯定是不能用在多线程了. 而且分配次数还是有限的. 也请不要吐槽诸如使用了冒泡排序等.
本文仅是简单地记录一下.
头文件
#ifndef __MY_MEM_H #define __MY_MEM_H #include <stdint.h> //一共可以申请的内存字节数 #define MAMORY_SIZE 0x800 //最多可以申请的次数 #define MAX_MALLOC_CNT 10 void Assert(int a); void InitMyMemory(void); void* Malloc(uint32_t size); void Free(void*); #endif
代码
#include "MyMem.h" //#ifndef Assert //#define Assert(a) // do{ // while(!(a)){ // } // }while(0) //#endif #ifndef NULL #define NULL 0 #endif typedef struct { uint8_t * ptr; // uint32_t size; uint8_t * end; }MyMallocInfo; typedef struct { uint8_t MEMORY[MAMORY_SIZE]; MyMallocInfo Info[MAX_MALLOC_CNT]; uint32_t count; }MyMemory;
static MyMemory mem;
//断言 void Assert(int a){ int x=0; while(!a){ x++; } }
//根据申请的内存地址
//对MallocInfo进行排序 void SortMallocInfo(){ uint32_t i,j; MyMallocInfo *ii; MyMallocInfo *ij; MyMallocInfo temp; for(i=0;i<mem.count;++i){ ii = &mem.Info[i]; for(j=i+1;j<mem.count;++j){ ij = &mem.Info[j]; if(ii->ptr > ij->ptr){ temp = *ii; *ii = *ij; *ij = temp; } } } } void InitMyMemory(){ mem.count = 0; } uint8_t * FindMemory(uint32_t size) { // [start, end) uint8_t * start = mem.MEMORY; uint8_t * end = mem.MEMORY + MAMORY_SIZE;// not include
uint32_t i; MyMallocInfo info; Assert(size > 0); for(i=0;i<mem.count;++i){ info = mem.Info[i];
// 在 info间寻找没被分配的内存区域
// 如果有没被分配的区域并且此区域字节大于申请的字节的话
// 那就返回此区域给外部 if(start < info.ptr){ if(info.ptr - start >= size){ return start; } } //否则 就查询下一个区域 start = info.end; }
//最后一个memInfo后还有足够的空间(或者根本就没有memInfo,即mem.count = 0) if(end - start >= size){ return start; } return NULL; } //申请内存 void* Malloc(uint32_t size){ uint8_t * ptr; SortMallocInfo();
//超过申请次数了, 返回NULL if(mem.count >= MAX_MALLOC_CNT){ return NULL; } ptr = FindMemory(size); if(ptr){ mem.Info[mem.count].ptr = ptr; mem.Info[mem.count].end = ptr + size; mem.count++; return ptr; } return NULL; }
//释放内存 void Free(void* ptr){ int32_t i; int32_t idx = -1;
//找出对应的 memInfo 索引 for(i=0;i<mem.count;++i){ if(mem.Info[i].ptr == ptr){ idx = i; break; } }
//没有找到证明外部指针被修改了,直接让程序 crash更好 Assert(idx >= 0);
//删除对应的 memInfo, 让后面的memInfo前置 for(i=idx+1;i<mem.count;++i){ mem.Info[i-1] = mem.Info[i]; } mem.count--; //Assert(mem.count >= 0 && mem.count <= MAX_MALLOC_CNT); }