📄 mem.c
字号:
#if !defined(__EBOS_H)
#include "ebos.h"
#endif
/*
#include "ebos.h"
/*
*********************************************************************************************************
* Mem module implement FILE
*********************************************************************************************************
*/
/*
*********************************************************************************************************
* Creates a Dyn_MEMory Mem pool and then places it on the list of created Mem pools.
*********************************************************************************************************
*/
static MEM_MCB *MemPoolTable[MAX_POOL_NUM];//存储池向量表
static void CleanupPool(void *information);//存储池清除函数
static MEM_MCB *FreePoolList; //可用存储池列表
/*
*********************************************************************************************************
* 获得一个可用的ID号
*********************************************************************************************************
*/
static SIGNED _NewPoolId()
{
static UNSIGNED Next_ID;
UNSIGNED id; /* process id to return */
EnLock();
if((id=Next_ID++)< MAX_POOL_NUM){
if (MemPoolTable[id] == NULL){
UnLock();
return(id);
}
}
else if(FreePoolList){
id=FreePoolList->id;
#if ENABLE_MEM
FreeBuff(FreePoolList);
#endif
FreePoolList=FreePoolList->next;
UnLock();
return(id);
}
UnLock();
return(NO_POOL_SPACE);
}
/*
*********************************************************************************************************
* 创建一个块存储池
*********************************************************************************************************
*/
SIGNED CreateBlockMemPool(MEM_MCB *pool_ptr, void *start_address,INT32U pool_size)
{
SIGNED pool_id;
struct BLOCK_STRUCT * pheader;
if (pool_ptr==NULL) return(ERR_INVALID_POOL);
if(start_address==NULL) return(ERR_INVALID_MEMORY);
if(pool_size<sizeof(struct BLOCK_STRUCT)) return(ERR_INVALID_SIZE);
if (MemPoolTable[pool_ptr->id]==pool_ptr)
return pool_ptr->id;
pool_id=_NewPoolId();
if(pool_id<0)
return (pool_id);
#if DEBUG
DebugLog(CREATE_BLOCK_POOL,pool_ptr->id);//在日志中记录操作,时间等信息
#endif
MemPoolTable[pool_id]=pool_ptr;
pool_ptr->id =pool_id ;
pool_ptr->current_protect=NULL;
pool_ptr->start_address=start_address;
pool_ptr->pool_size=pool_size;
pool_ptr->suspend_type=FIFO;
pool_ptr->task_wait_header=NULL;
pheader= (struct BLOCK_STRUCT *)start_address;
pheader->block_size=pool_size;
pheader->next= pheader;
pheader->prev= pheader;
pool_ptr->available_header=pheader;
return(pool_id);
}
/*
*********************************************************************************************************
* 创建一个分区存储池
*********************************************************************************************************
*/
SIGNED CreateEvenMemPool(MEM_MCB *pool_ptr,void *start_address,INT32U pool_size,UNSIGNED partition_size)
{
UNSIGNED pages,i;
struct BLOCK_STRUCT * pheader;
SIGNED pool_id;
if (pool_ptr==NULL) return(ERR_INVALID_POOL);
if(start_address==NULL) return(ERR_INVALID_MEMORY);
if(partition_size<sizeof(struct BLOCK_STRUCT) ||pool_size==0 ||partition_size>pool_size ) return(ERR_INVALID_SIZE);
if (MemPoolTable[pool_ptr->id]==pool_ptr)
return pool_ptr->id;
pool_id=_NewPoolId();
if(pool_id<0)
return (pool_id);
#if DEBUG
DebugLog(CREATE_EVEN_POOL,pool_ptr->pool_id);//在日志中记录操作,时间等信息
#endif
MemPoolTable[pool_id]=pool_ptr;
pages=pool_size/partition_size;
pool_ptr->id =pool_id ;
pool_ptr->current_protect=NULL;
pool_ptr->start_address=start_address;
pool_ptr->pool_size=pool_size;
pool_ptr->partition_size=partition_size;
pool_ptr->suspend_type=FIFO;
pool_ptr->task_wait_header=NULL;
pool_ptr->availables=pages;
pool_ptr->available_header=(struct BLOCK_STRUCT *)start_address;
pheader=pool_ptr->available_header;
for(i=0;i<pages;i++){
pheader->next=(struct BLOCK_STRUCT *)((INT8U *)start_address+(i+1)*partition_size);
pheader->block_size=partition_size;
pheader=pheader->next;
}
pheader->next=NULL;
return(pool_id);
}
/*
*********************************************************************************************************
* 删除一个存储池
*********************************************************************************************************
*/
STATUS DeleteMemPool(SIGNED pool_id)
{
STATUS state,oldstate;
MEM_MCB *pool_ptr;
if (pool_id<0 || pool_id >=MAX_POOL_NUM) { /* Not allowed to delete idle task */
return (ERR_INVALID_POOL);
}
pool_ptr=MemPoolTable[pool_id];
#if DEBUG
DebugLog(DELETE_MEMPOOL,pool_id);//在日志中记录操作,时间等信息
#endif
oldstate=0;
DoProtect(pool_ptr);
if (pool_ptr == NULL) /* Not allowed to delete idle pool */
return (ERR_INVALID_POOL);
if(pool_ptr->ref_count){ //如果有任务等待,肯定该池被其它任务占用,否则没有任务等待
UnProtect(pool_ptr); //在删除一个还在使用的池时是不安全的
return ERR_INVALID_DELETE;
}
// while(pool_ptr->task_wait_header){
// state=_ResumeTask(pool_ptr->task_wait_header->task_ptr,EVENT_SUSPEND);
// if(state==TRUE)
// oldstate =state;
// DelHead(&(void *)(pool_ptr->task_wait_header));
// }
MemPoolTable[pool_id]=NULL;
UnProtect(pool_ptr);
EnLock();
pool_ptr->next=FreePoolList;
FreePoolList=pool_ptr;
MemPoolTable[pool_id]=NULL;
UnLock();
if(oldstate==TRUE)
_ControlToSystem();
return (OK);
}
/*
*********************************************************************************************************
* 存储池参数设置函数
*********************************************************************************************************
*/
STATUS SysPoolCtl(SIGNED pool_id,INT8U cmd,INT8U param)
{
STATUS ret;
MEM_MCB *pool_ptr;
if (pool_id<0 || pool_id >=MAX_POOL_NUM) { /* Not allowed to delete idle task */
return (ERR_INVALID_POOL);
}
#if DEBUG
DebugLog(SYS_POOL_CTL,pool_id);//在日志中记录操作,时间等信息
#endif
pool_ptr=MemPoolTable[pool_id];
DoProtect(pool_ptr);
if (pool_ptr == NULL) {
return (ERR_INVALID_POOL); /* Not allowed is idle task */
}
switch(cmd){
case SUSPEND_TYPE:
pool_ptr->suspend_type=param;
ret=OK;
break;
default:
ret=ERR_INVALID_CMD;
break;
}
UnProtect(pool_ptr);
return(ret);
}
/*
*********************************************************************************************************
* 从块存储池分配一个存储块,
*********************************************************************************************************
*/
STATUS AllocMem(SIGNED pool_id,void **return_pointer,INT32U size,SIGNED suspend)
{
WAIT_QUEUE *suspend_list;
struct BLOCK_STRUCT *p,*leftover;
WAIT_QUEUE *task_suspend;
MEM_MCB *pool_ptr;
#if WAIT_QUEUE_ALLOC_MODE
task_suspend=WaitQueueFreeList;
WaitQueueFreeList=WaitQueueFreeList->queue_ptr;
#else
WAIT_QUEUE mem_wait_queue;
task_suspend=&mem_wait_queue;
#endif
if (return_pointer == NULL) /* Not allowed to delete idle pool */
return (ERR_INVALID_POINTER);
if (size<=0)
return (ERR_INVALID_SIZE);
if (pool_id<0 || pool_id >=MAX_POOL_NUM) { /* Not allowed to delete idle task */
return (ERR_INVALID_POOL);
}
pool_ptr=MemPoolTable[pool_id];
#if DEBUG
DebugLog(ALLOC_MEM,pool_id);//在日志中记录操作,时间等信息
#endif
DoProtect(pool_ptr);
if (pool_ptr == NULL) /* Not allowed to delete idle pool */
return (ERR_INVALID_POOL);
p=pool_ptr->available_header;
do{
if ( p->block_size == size) {
DelList(&(void *)(pool_ptr->available_header),p);
UnProtect(pool_ptr);
return (OK);
}
else if ( p->block_size > size ) {
*return_pointer= (void *)p;
leftover = (struct BLOCK_STRUCT *)( (INT8U *)p + size );
leftover->block_size = p->block_size - size;
p->prev->next = leftover;
leftover->prev=p->prev;
leftover->next = p->next;
p->next->prev=leftover;
if (p==pool_ptr->available_header) {
pool_ptr->available_header=leftover;
}
UnProtect(pool_ptr);
return (OK);
}
p=p->next;
}while (p!=pool_ptr->available_header);
if(suspend!=NO_SUSPEND){
if(((TASK_TCB *)KERNAL.current_thread)->type !=TASK) {
UnProtect(pool_ptr);
return(ERR_INVALID_SUSPEND);
}
pool_ptr->tasks_waiting++;
task_suspend->mem_request_size=size;
task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
task_suspend->mem_return_pointer=NULL;
task_suspend->priority=GetPriority(((TASK_TCB *)KERNAL.current_thread)->id);
AddList(&(void *)(pool_ptr->task_wait_header),task_suspend,pool_ptr->suspend_type);
UnProtect(pool_ptr);
_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,CleanupPool,pool_ptr,suspend);
_ControlToSystem();
Enlock();
#if WAIT_QUEUE_ALLOC_MODE
task_suspend->queue_ptr=WaitQueueFreeList;
WaitQueueFreeList=task_suspend;
#endif
if (task_suspend->mem_return_pointer==NULL){
Unlock();
return(ERR_TIMEOUT);
}
if(pool_ptr==NULL) {
Unlock();
return(ERR_POOL_DELETED);
}
pool_ptr->tasks_waiting--;
*return_pointer=task_suspend->mem_return_pointer;
DelList(&(void *)(pool_ptr->task_wait_header),task_suspend);
Unlock();
return (OK);
}
else
return(ERR_NO_MEMORY);
}
/*
*********************************************************************************************************
* 从一个分区存储池分配一个存储块,
*********************************************************************************************************
*/
STATUS AllocBuff(SIGNED pool_id,void **return_pointer,SIGNED suspend)
{
WAIT_QUEUE *suspend_list;
struct BLOCK_STRUCT *pheader;
WAIT_QUEUE *task_suspend;
MEM_MCB *pool_ptr;
UNSIGNED *buf;
#if WAIT_QUEUE_ALLOC_MODE
task_suspend=WaitQueueFreeList;
WaitQueueFreeList=WaitQueueFreeList->queue_ptr;
#else
WAIT_QUEUE mem_wait_queue;
task_suspend=&mem_wait_queue;
#endif
if (return_pointer == NULL) /* Not allowed to delete idle pool */
return (ERR_INVALID_POINTER);
if (pool_id<0 || pool_id >=MAX_POOL_NUM) { /* Not allowed to delete idle task */
return (ERR_INVALID_POOL);
}
pool_ptr=MemPoolTable[pool_id];
#if DEBUG
DebugLog(ALLOC_BUFF,pool_id);//在日志中记录操作,时间等信息
#endif
DoProtect(pool_ptr);
if (pool_ptr == NULL) /* Not allowed to delete idle pool */
return (ERR_INVALID_POOL);
if(pool_ptr->availables>0){
(pool_ptr->availables)--;
buf=(UNSIGNED *)(pool_ptr->available_header);
*buf++=pool_id;
*return_pointer=buf;
pool_ptr->available_header=(pool_ptr->available_header)->next;
++pool_ptr->ref_count;
UnProtect(pool_ptr);
return (OK);
}
else if(suspend!=NO_SUSPEND){
if(((TASK_TCB *)KERNAL.current_thread)->type!=TASK) {
UnProtect(pool_ptr);
return(ERR_INVALID_SUSPEND);
}
pool_ptr->tasks_waiting++;
task_suspend->task_ptr=((TASK_TCB *)KERNAL.current_thread);
task_suspend->mem_return_pointer=NULL;
task_suspend->priority=GetPriority(((TASK_TCB *)KERNAL.current_thread)->id);;
AddList(&(void *)(pool_ptr->task_wait_header),task_suspend,pool_ptr->suspend_type);
UnProtect(pool_ptr);
_SuspendTask(KERNAL.current_thread,EVENT_SUSPEND,CleanupPool,pool_ptr,suspend);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -