1 /* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
4 * 2019/7/20 - ROBIN KRENS
8 * Fixed-sized memory pool allocation. A so called * memory-pool
9 * (i.e. 4kB * 12 blocks) can be initialized. Note: this allocator
10 * is for use on processors without an MMU (memory management
11 * unit). A MPU (memory protection unit), if available can be used
12 * to protect certain zones.
14 * This work is based on an article of Ben Kenwright.
16 * Blocks are fixed size. In some situations ideal, in some situation
17 * may be not. It's fast.
19 * Preconditions: programmer should make sure the SRAM entry point
20 * + (blocks * blocksize) is free.
23 * KERNEL: initialize one (or multiple!) fixed memory-sized
26 * USER TASKS/PROCESS: can use this to dynamically allocate their
27 * own memory (i.e. heap). You might argue that a fixed size memory
28 * pool is not ideal, but you would be amazed that many programs
29 * use structs of more or less similar size.
39 #include <lib/tinyprintf.h>
40 #include <lib/string.h>
43 void pool_init(mem_pool_t * pool, size_t size_arg, unsigned int blocks_arg, unsigned char* entry_SRAM) {
45 pool->blocks = blocks_arg;
46 pool->block_size = size_arg;
47 pool->blocks_init = 0;
48 pool->SRAM_entry = entry_SRAM;
49 memset(entry_SRAM, 0x00, (sizeof(char) * (size_arg * blocks_arg)));
50 pool->free_blocks = blocks_arg;
51 pool->m_next = pool->SRAM_entry;
54 /* void deletepool() {
55 pool->SRAM_entry = NULL;
58 /* Helper functions */
59 unsigned char* AddrFromIndex(mem_pool_t * pool, unsigned int i) {
60 return pool->SRAM_entry + ( i * pool->block_size );
64 unsigned int IndexFromAddr(mem_pool_t * pool, const unsigned char* p) {
65 return (((unsigned int)(p - pool->SRAM_entry)) / pool->block_size);
70 void * alloc(void * s) {
71 mem_pool_t * pool = (mem_pool_t *) s;
72 if (pool->blocks_init < pool->blocks ) {
73 unsigned int * p = (unsigned int *)AddrFromIndex(pool, pool->blocks_init );
74 *p = pool->blocks_init + 1;
79 if ( pool->free_blocks > 0 ) {
80 ret = (void*)pool->m_next;
82 if (pool->free_blocks!=0) {
83 pool->m_next = AddrFromIndex(pool, *((unsigned int*)pool->m_next) );
93 void free(void * s, void* p) {
95 mem_pool_t * pool = (mem_pool_t *) s;
96 if (pool->m_next != NULL) {
97 (*(unsigned int *)p) = IndexFromAddr(pool, pool->m_next );
98 pool->m_next = (unsigned char*)p;
101 *((unsigned int*)p) = pool->blocks;
102 pool->m_next = (unsigned char*) p;
108 /* Heap info helper functions */
110 void heap_info(void * s) {
112 mem_pool_t * pool = (mem_pool_t *) s;
114 printf("HEAP INFO:\n");
115 printf("BLOCKS FREE: %d\n", pool->free_blocks);
117 unsigned char* curr_addr = pool->SRAM_entry;
119 // Loop over heap blocks
120 for (int i = 0; i < pool->blocks; i++) {
121 printf("\nBLOCK %d", i+1);
122 for (int j = 0; j < (pool->block_size-1); j++) {
125 printf("\n%x ", curr_addr);
126 printf("%#x ", *curr_addr);