UCOSIII存储管理

Posted 想成为大师啊

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UCOSIII存储管理相关的知识,希望对你有一定的参考价值。

1.1、存储管理

作为一个RTOS操作系统,内存管理是必备的功能,因此UCOSIII也就内存管理能力。通常应用程序可以调用ANSI C编译器的 malloc()和free()函数 来动态的分配和释放内存,但是在嵌入式实时操作系统中最好不要这么做,多次这样的操作会把原来很大的一块连续存储区域逐渐地分割成许多非常小并且彼此不相邻的存储区域,这就是存储碎片

UCOSIII中提供了一种替代 malloc()和free() 函数的方法,UCOSIII中将存储空间分成,每个存储区有数量不等大小相同的存储块,在一个系统中可以有多个存储区

一般存储区是固定的,在程序中可以用数组来表示一个存储区,比如 u8 buffer[20][10],就表示一个拥有20个存储块,每个存储块10个字节的存储区。


1.2、存储控制块

UCOSIII中用来存储控制块来表示存储区,存储控制块为 OS_MEM

struct os_mem                                              /* MEMORY CONTROL BLOCK                                   */
    OS_OBJ_TYPE          Type;                              /* Should be set to OS_OBJ_TYPE_MEM                       */
    void                *AddrPtr;                           /* Pointer to beginning of memory partition               */
    CPU_CHAR            *NamePtr;
    void                *FreeListPtr;                       /* Pointer to list of free memory blocks                  */
    OS_MEM_SIZE          BlkSize;                           /* Size (in bytes) of each block of memory                */
    OS_MEM_QTY           NbrMax;                            /* Total number of blocks in this partition               */
    OS_MEM_QTY           NbrFree;                           /* Number of memory blocks remaining in this partition    */
#if OS_CFG_DBG_EN > 0u
    OS_MEM              *DbgPrevPtr;
    OS_MEM              *DbgNextPtr;
#endif
;

创建好的存储区如下图:


2.1、存储管理相关API函数

函数名作用
OSMemCreate()创建一个存储分区
OSMemGet()从存储分区中获得一个存储块
OSMemPut()将一个存储块归还到存储分区中

OSMemCreate() : 创建一个存储分区

void  OSMemCreate (OS_MEM       *p_mem,	// 定义一个存储控制块
                   CPU_CHAR     *p_name, // 给存储区命名
                   void         *p_addr, // 存储区原始的内存地址
                   OS_MEM_QTY    n_blks, // 存储区有多少存储块
                   OS_MEM_SIZE   blk_size, // 存储块的大小
                   OS_ERR       *p_err)

OSMemGet() :从存储分区中获得一个存储块

void  *OSMemGet (OS_MEM  *p_mem, // 定义一个存储控制块
                 OS_ERR  *p_err)

OSMemPut() : 将一个存储块归还到存储分区中

void  OSMemPut (OS_MEM  *p_mem, // 定义一个存储控制块
                void    *p_blk, // 存储区有多少存储块
                OS_ERR  *p_err)

定义一个存储区

OS_MEM INTERNAL_MEM;	

存储区中存储块数量

#define INTERNAL_MEM_NUM		5

每个存储块大小由于一个指针变量占用4字节所以块的大小一定要为4的倍数,而且必须大于一个指针变量(4字节)占用的空间,否则的话存储块创建不成功

#define INTERNAL_MEMBLOCK_SIZE	100  

存储区的内存池,使用内部RAM

CPU_INT08U Internal_RamMemp[INTERNAL_MEM_NUM][INTERNAL_MEMBLOCK_SIZE];

存储区的创建要先于开始任务的创建

//创建一个存储分区
	OSMemCreate((OS_MEM*	)&INTERNAL_MEM,
				(CPU_CHAR*	)"Internal Mem",
				(void*		)&Internal_RamMemp[0][0],
				(OS_MEM_QTY	)INTERNAL_MEM_NUM,
				(OS_MEM_SIZE)INTERNAL_MEMBLOCK_SIZE,
				(OS_ERR*	)&err);
	//创建开始任务
	OSTaskCreate((OS_TCB 	* )&StartTaskTCB,		//任务控制块
				 (CPU_CHAR	* )"start task", 		//任务名字
                 (OS_TASK_PTR )start_task, 			//任务函数
                 (void		* )0,					//传递给任务函数的参数
                 (OS_PRIO	  )START_TASK_PRIO,     //任务优先级
                 (CPU_STK   * )&START_TASK_STK[0],	//任务堆栈基地址
                 (CPU_STK_SIZE)START_STK_SIZE/10,	//任务堆栈深度限位
                 (CPU_STK_SIZE)START_STK_SIZE,		//任务堆栈大小
                 (OS_MSG_QTY  )0,					//任务内部消息队列能够接收的最大消息数目,为0时禁止接收消息
                 (OS_TICK	  )0,					//当使能时间片轮转时的时间片长度,为0时为默认长度,
                 (void   	* )0,					//用户补充的存储区
                 (OS_OPT      )OS_OPT_TASK_STK_CHK|OS_OPT_TASK_STK_CLR, //任务选项
                 (OS_ERR 	* )&err);				//存放该函数错误时的返回值
	OS_CRITICAL_EXIT();	//退出临界区	 
	OSStart(&err);      //开启UCOSIII

一定要向内存申请使用!!!!!

if(err == OS_ERR_NONE) //内存申请成功
				
					printf("internal_buf内存申请之后的地址为:%#x\\r\\n",(u32)(internal_buf));
					LCD_ShowString(30,155,200,16,16,"Memory Get success!  ");
					internal_memget_num++;
					POINT_COLOR = BLUE;
					sprintf((char*)internal_buf,"INTERNAL_MEM Use %d times",internal_memget_num);
					LCD_ShowString(30,175,200,16,16,internal_buf); 
					POINT_COLOR = RED;
				

以上是关于UCOSIII存储管理的主要内容,如果未能解决你的问题,请参考以下文章

UCOSIII中断和时间管理

UCOSIII任务管理

ucosiii几个常用的时间管理函数

UCOSiii源码分析——os_task.c任务管理函数分析

uCOs 学习:0-有关概念

zynq7000 中断系统及在UCOSIII中的中断处理接口