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;
				}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值