零开始学ESP32:个人笔记记录:
芯片型号: ESP32
网络环境支持:LWIP
IDF.PY-SDK: ESP-IDF v4.3
芯片功能: freeRTOS系统
声明: 当前内存池参考 Linux / rttthreadOS 两个套系统,自己写成的。
内存池的创建:
头文件:
#include <stdint.h>
内存池主体结构
#define MP_ALIGN_SIZE 4
#define MP_ALIGN(size, align) (((size) + (align) - 1) & ~((align) - 1))
typedef struct ST_MEMORY_POOL__ {
void* startA_address;
size_t size ;
size_t block_size;
uint8_t* block_lisk;
size_t block_total_count;
size_t block_free_count;
}st_memoryPool , *st_mp_t;
void* T_mp_create(size_t block_count , size_t block_size)
{
uint8_t* block_chr = NULL;
register size_t offset = 0;
st_memoryPool* mp = (st_memoryPool * )pvPortMalloc ( sizeof( st_memoryPool ) );
if( mp == NULL )
{
return NULL;
}
block_size = MP_ALIGN( block_size , MP_ALIGN_SIZE );
mp->block_size = block_size;
mp->size = (block_size + sizeof(uint8_t * ) ) * block_count ;
mp->startA_address = pvPortMalloc( mp->size );
if( !mp->startA_address )
{
goto Err_startAdd;
}
mp->block_total_count = block_count;
mp->block_free_count = block_count;
block_chr = mp->startA_address ;
for(offset = 0 ; offset < mp->block_total_count ; offset ++ )
{
*( uint8_t **)( block_chr + offset * (block_size + sizeof(uint8_t *)))
= block_chr + ( offset + 1) * ( block_size + sizeof( uint8_t *) );
}
*( uint8_t **)( block_chr + (offset -1) * (block_size + sizeof(uint8_t *))) = NULL;
mp->block_lisk = block_chr;
return mp;
Err_startAdd: vPortFree( mp );
return NULL;
}
在内存池里面申请内存
void* T_mp_malloc( st_memoryPool* mp )
{
uint8_t* block_chr = NULL;
vTaskSuspendAll();
if( mp->block_free_count == 0 )
{
xTaskResumeAll();
return NULL;
}
mp->block_free_count --;
block_chr = mp->block_lisk;
assert( block_chr != NULL );
mp->block_lisk = *(uint8_t **)block_chr;
*( uint8_t **)block_chr = (uint8_t *)mp;
xTaskResumeAll();
return ( uint8_t * )( block_chr + sizeof( uint8_t *) );
}
// 释放归还内存块回给内存池里面
void T_mp_free( void * block )
{
uint8_t** block_str = NULL;
st_memoryPool* mp = NULL;
vTaskSuspendAll();
block_str = (uint8_t **)( (uint8_t*) block - (sizeof( uint8_t * )));
mp = (st_memoryPool *)*block_str;
*block_str = mp->block_lisk;
mp->block_lisk = ( uint8_t* )block_str;
mp->block_free_count ++;
xTaskResumeAll();
}
//释放整个内存块
void T_mp_free( void * block )
{
uint8_t** block_str = NULL;
st_memoryPool* mp = NULL;
vTaskSuspendAll();
block_str = (uint8_t **)( (uint8_t*) block - (sizeof( uint8_t * )));
mp = (st_memoryPool *)*block_str;
*block_str = mp->block_lisk;
mp->block_lisk = ( uint8_t* )block_str;
mp->block_free_count ++;
xTaskResumeAll();
}
在当前这个版本内存池里面存在尚未解决的问题,在使用时候必须要考虑到:
一、当前任务向内存池申请内存是(T_mp_malloc),没有实现一个超时等待,或者阻塞等待直至有空闲内存块
当前内存池空闲内存为零时, 应该将当前任务挂起并且放到一个任务里面,等待内存到来。
二、在T_mp_malloc 函数里面使用到vTaskSuspendAll()和 xTaskResumeAll(),FREERTOS内存API ,尚未明确会不会
存在一些危险操作和与之相关的问题
三、当多任务都在同时等待当前内存池时候而被第三方任务将整个内存池删除,应该要实现一个操作, 唤醒当前所有等待的任务,并且告
知当前内存池一已经被释放。
要是碰巧看到这边博文的工程师,并且有想法或者是对freeRTOS比较熟系的,希望您路过的时候不设赐教。
当前用上你的想法或者对应的方案,博文也会明确表示当您的身份和对应的贡献。
感谢。
关注微信公众号 一起学习 ( 技术Code城 )
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)