Continue reading notes today, "Challenge memory Management" (30-day homemade OS).
Why the interest in this piece of content, because once encountered such a problem. In the STM32 program to use the queue, not the FIFO, but the use of large memory space, but also want to do the sequential access management of the queue.
In this queue to use the malloc, the dynamic application of memory, the first is directly requested not to memory, and later in the startup script changed the address value of the set heap, you can apply for success, but found the application several times, but also to apply for memory.
Sure enough, the MCU-level program, the memory of this piece of processing will not be as free as the Windows program. Talk so much and get to the point.
1, the related data structure body
#defineMemman_frees 4000//can have up to 4,000 independent blocks of available memorystructfreeinfo{unsignedintaddr,size;};//This is the core data structure of memory management, and available memory is represented by its start address and memory size. //request memory is to find the appropriate size of memory in available memory, return the start address to the requester,//at the same time there is less memory available (this is the case that the application memory size is exactly equal to the available memory size, other cases look at the following code)structMemman//memory management Data Structures{ intfrees,maxfrees,lostsizes,losts; structfreeinfo[memman_frees];}//frees indicates the current number of independent memory blocks available//Maxfrees used to observe the maximum value of frees//Losts Indicates the number of failed requests for memory//lostsizes indicates the size of memory loss due to application memory failure
View Code
2, the initialization of memory management, that is, the initialization of related data structure
void memman_init (struct Memman *Mans) { man0; // not yet a piece of available memory 0 ; man0; // the number of failed releases is 0 0; // The total memory size of the failed release is also 0}
View Code
3. Get the total size of all available memory currently
int memman_total (struct Memman * man) { int i,t=0; for (i=0; i<man->frees;i++) { t+ =man-> free [i].size; // consider only the total memory size for all available memory, regardless of memory continuity (there is definitely a discontinuity). } return t;}
View Code
4. Memory management key Code 1-Request Memory
UnsignedintMemman_alloc (structmemman* man,unsignedintSize//The return value is the starting address of the requested memory{unsignedintI,a; for(i=0; i<man->frees;i++) { if(man-> Free[I].size > Size]//Traverse all available memory block information{a= man-> Free[I].addr;//Block I available memory meets requirementsMan-> Free[I].addr + =size; Mans- Free[I].size-= size;//change the memory used in block I information if(man-> Free[I].size = =0)//exactly the requested memory is the same as the available memory size of block I{Mans->frees--;//a piece of usable memory is missing for(; i<man->frees;i++) { man- Free[I] = man-> Free[i+1];//Back available memory information pre-push } } returnA//successful application, return to specified address } } return 0;//Not found, that is, the application of memory is unsuccessful}
View Code
5, Memory management key code 2-free memory
intMemman_free (structMemman *man,unsignedintaddr,unsignedintsize) { inti,j; /*for ease of management, the available blocks of memory are arranged in addr order, first finding where the available memory blocks should be located*/ for(i=0; i<man->frees;i++) { if(man-> Free[I].addr >addr) { Break; } } //In fact, there are many situations, the following analysis /*free[i-1].addr < addr < free[i].addr*/ if(i>0) { if(man-> Free[I1].addr +man-> Free[I1].size = =addr) { //The freed memory is combined with the previously available memory block.Man-> Free[I1].size + =size; if(i<man->frees)//consider freeing the memory with Free[i] can you fit in a piece { if(Addr+size = = man-> Free[I].ADDR]//with the back of the memory together.{Memman- Free[I1].size + = man-> Free[I].size; //This reduces the amount of available memory information by mergingMan->frees--; for(; i<man->frees;i++) { man- Free[I] = man-> Free[i+1];//Structure Iteration } } } return 0;//Release Success } } if(i<man->frees)//The above conditions are not valid and cannot be combined with the previous available memory block information { if(Addr+size = = man-> Free[I].ADDR]//can be combined with the memory block information in the back{Mans- Free[i].addr = addr;//adjust the available memory block information laterMan-> Free[I].size + =size; return 0;//Release Success } } /*Neither the front nor the back is together.*/ if(Man->frees < Memman_frees)//only one additional piece of information is available { for(j=man->frees;j>i;j--) { man- Free[j] = man-> Free[J-1]; } Mans->frees + +; if(Man->maxfrees < man->frees) {Mans->maxfrees = man->frees;//Update Maximum Value} Mans- Free[I].ADDR =addr; Mans- Free[I].size =size; return 0;//Release Success } /*can't move backwards .*/Mans->losts + +; Mans->lostsize + =size; return-1;}
View Code
How to use the above code:
1. Initialize the structure first
struct Memman *memman = (struct Memman *) malloc (struct memman);
2. Call Memman_init to initialize the data structure body
Memman_init (Memman);
3, first release the entire available memory (such as 64K RAM, after 30K is set to be dynamically requested memory)
Memman_free (memman,&34k,30k);
4. Memory request where memory is required
Char *buf = (char *) memman_alloc (memman,1000); Request 1000 bytes of space
5. The total size of available memory can be obtained in any suitable place
unsigned int memtotal = Memman_total (Memman);
All of the above source code completes a function to customize the functions of the class malloc and free to complete the management of the memory space.
Memory Management (30-Day homemade operating system – reading notes)