UCOS-II内存管理

2023-05-16

内存管理:
  我们知道,在 ANSI C 中可以用 malloc()和 free()两个函数动态地分配内存和释放内存。但是,在嵌入式实时操作系统中,多次这样做会把原来很大的一块连续内存区域,逐渐地分割成许多非常小而且彼此又不相邻的内存区域,也就是内存碎片。由于这些碎片的大量存在,使得程序到后来连非常小的内存也分配不到,我们讲到过用 malloc()函数来分配堆栈时,曾经讨论过内存碎片的问题。另外,由于内存管理算法的原因,malloc()和free()函数执行时间是不确定的。
  在µC/OS-II 中,操作系统把连续的大块内存按分区来管理。每个分区中包含有整数个大小相同的内存块。利用这种机制,µC/OS-II 对 malloc()和 free()函数进行了改进,使得它们可以分配和释放固定大小的内存块。这样一来,malloc()和 free()函数的执行时间也是固定的了。


内存控制块:
  为了便于内存的管理,在µC/OS-II 中使用内存控制块(memory control blocks)的数据结构来跟踪每一个内存分区,系统中的每个内存分区都有它自己的内存控制块。
typedef struct 
{
  //指向内存分区起始地址的指针 建立一个内存分区,OSMemCreate()时被初始化,在此之后就不能更改了。
  void *OSMemAddr;
  //指向下一个空闲内存控制块或者下一个空闲的内存块的指针
  void *OSMemFreeList;
  //内存分区中内存块的大小
  INT32U OSMemBlkSize;
  //内存分区中总的内存块数量
  INT32U OSMemNBlks;
  //内存分区中当前可以使用的空闲内存块的数量
  INT32U OSMemNFree;
} OS_MEM;


  在uC/OS-II中OS_MAX_MEM_PART(见文件 OS_CFG.H)定义了最大的内存分区数,该常数值至少应为 2。 每个内存分区必须含有至少两个内存块,每个内存块至少为一个指针的大小,因为同一分区中的所有空闲内存块是由指针串联起来的。


建立一个内存分区, OS_MEM *OSMemCreate ()
OS_MEM *OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err)
{
  OS_MEM *pmem;
  INT8U *pblk;
  void **plink;
  INT32U i;
  if (nblks < 2)//在ucos中内存分区中内存块的大小最小为2
  {
  *err = OS_MEM_INVALID_BLKS;
  return ((OS_MEM *)0);
  }
  if (blksize < sizeof(void *)) //每个内存块的大小至少为一个指针大小
  {
  *err = OS_MEM_INVALID_SIZE;
  return ((OS_MEM *)0);
  }
  OS_ENTER_CRITICAL();
  pmem = OSMemFreeList;
  if (OSMemFreeList != (OS_MEM *)0)//在空闲的内存控制块中取得一个内存控制块
  {
  OSMemFreeList = (OS_MEM *)OSMemFreeList->OSMemFreeList;
  }
  OS_EXIT_CRITICAL();
  if (pmem == (OS_MEM *)0) 
  {
  *err = OS_MEM_INVALID_PART;
  return ((OS_MEM *)0);
  }
  plink = (void **)addr;//指向内存分区的首地址
  pblk = (INT8U *)addr + blksize;//指向内存分区中下一个内存块的首地址
  for (i = 0; i < (nblks - 1); i++)//把内存分区中各个内存块链接成一个单向链表
  {
  *plink = (void *)pblk;//当前内存块的第一个元素存储下一个内存块的首地址
  plink = (void **)pblk;//plink指向下一个内存块
  pblk = pblk + blksize;//pblk指向下一个内存块
  }
  *plink = (void *)0;//最后一个内存块的第一个元素指向NULL
  OS_ENTER_CRITICAL();
  pmem->OSMemAddr = addr;
  pmem->OSMemFreeList = addr;
  pmem->OSMemNFree = nblks;
  pmem->OSMemNBlks = nblks;
  pmem->OSMemBlkSize = blksize;
  OS_EXIT_CRITICAL();
  *err = OS_NO_ERR;
  return (pmem);
}

分配一个内存块,OSMemGet()
void *OSMemGet (OS_MEM *pmem, INT8U *err)
{
  void *pblk;
  OS_ENTER_CRITICAL();
  if (pmem->OSMemNFree > 0) 
  {
  pblk = pmem->OSMemFreeList;
  pmem->OSMemFreeList = *(void **)pblk;
  pmem->OSMemNFree--;
  OS_EXIT_CRITICAL();
  *err = OS_NO_ERR;
  return (pblk);
  } 
  else 
  {
  OS_EXIT_CRITICAL();
  *err = OS_MEM_NO_FREE_BLKS;
  return ((void *)0);
  }
}
释放一个内存块,OSMemPut()
  注意不要把和“当前分区中内存块大小不同”的内存块释放到当前分区。否则会引起灾难性后果。
INT8U OSMemPut (OS_MEM *pmem, void *pblk)
{
  OS_ENTER_CRITICAL();
  if (pmem->OSMemNFree >= pmem->OSMemNBlks)
  {
  OS_EXIT_CRITICAL();
  return (OS_MEM_FULL);
  }
  *(void **)pblk = pmem->OSMemFreeList;
  pmem->OSMemFreeList = pblk;
  pmem->OSMemNFree++;
  OS_EXIT_CRITICAL();
  return (OS_NO_ERR);
}


查询一个内存分区的状态,OSMemQuery()
  在µC/OS-II 中,可以使用 OSMemQuery()函数来查询一个特定内存分区的有关消息。通过该函数可以知道特定内存分区中内存块的大小、可用内存块数和正在使用的内存块数等信息。所有这些信息都放在一个叫 OS_MEM_DATA 的数据结构中。


OS_MEM_DATA数据结构:
typedef struct 
{
  void *OSAddr; /* 指向内存分区首地址的指针 */
  void *OSFreeList; /* 指向空闲内存块链表首地址的指针 */
  INT32U OSBlkSize; /* 每个内存块所含的字节数 */
  INT32U OSNBlks; /* 内存分区总的内存块数 */
  INT32U OSNFree; /* 空闲内存块总数 */
  INT32U OSNUsed; /* 正在使用的内存块总数 */
} OS_MEM_DATA;
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

UCOS-II内存管理 的相关文章

  • Ubuntu终端命令详述

    一 基本终端命令 1 调整终端窗口的字体大小 34 ctrl 43 shift 43 61 34 放大终端窗口的字体 34 ctrl 43 34 缩小终端窗口的字体 2 Linux命令的基本使用 序号命令对应英文作用01lslist查看当前
  • Ubuntu安装并连接Mysql

    安装配置MySql sudo apt install mysql server XX 提示 xff1a 当输入mysql时便可连续按 tab 键两次便可得到提示信息 xff0c 根据信息选择安装 安装过程中会提示输入mysql服务密码 xf
  • vi的使用与基本命令

    vi的使用 一 初识vi 1 什么是vi vi xff0c 即终端中一款编辑器 2 vi的应用场景 当我们要通过远程连接到服务器时 xff0c 此时没有图形界面 xff0c 当我们要对服务器上的文件进行编辑时 xff0c 便可以使用vi进行
  • Ubuntu下安装并配置Redmine

    Redmine安装与使用 Redmine是什么 xff1f Redmine是用Ruby开发的基于web的项目管理软件 xff0c 是用ROR框架开发的一套跨平台项目管理系统 xff0c 支持多种数据库 xff0c 多项独特功能 这种 Web
  • Ubuntu下安装ReviewBoard

    ReviewBoard安装与使用 ReviewBoard是什么 xff1f ReviewBoard是个开源的 可扩展的 友好的基于Web的代码评审工具 xff0c 是用Python框架Django开发的 ReviewBoard是通过Pyth
  • Ubuntu安装redis,Docker下安装redis以及redis基本配置说明

    一 什么是redis redis是一个key value存储系统 和Memcached类似 xff0c 它支持的数据类型相对更多 xff0c 包括string 字符串 list 链表 set 集合 zset sorted set 有序集合
  • Ubuntu安装memcache

    一 什么是memcache memcache是一个高性能的分布式的内存对象缓存系统 xff0c 通过在内存里维护一个统一的巨大的hash表 xff0c 它能够用来存储各种格式的数据 xff0c 包括图像 视频 文件以及数据库检索的结果等 简
  • Ubuntu安装Apache+Svn+Submin

    安装之前建议先更新 sudo apt update sudo apt upgrade 一 安装配置Apache 1 安装apache sudo apt install apache2 2 开启apache2模块 a2enmod rewrit
  • ROS坐标系统,常见的坐标系和其含义

    原链接 运行测试平台 小强ROS机器人 常见的坐标系 在使用ROS进行定位导航等操作时 xff0c 我们经常会遇到各种坐标系 每种坐标系都有明确的含义 理论上坐标系的名称可以是随意的 xff0c 但是为了方便不同的软件间共享坐标信息 xff
  • ReviewBoard+SVN配置强制code review

    本文需要在svn与reviewboard安装成功之后开始进行配置 xff0c 详情参考如下两篇文章根据实际情况操作 xff1a Ubuntu安装Apache 43 Svn 43 Submin https blog csdn net qq 2
  • Ubuntu安装配置Maven私服Nexus

    1 简介 Maven是什么 xff1f Maven是一个采用纯Java编写的开源项目管理工具 Maven采用了一种被称之为Project Object Model POM 的概念来管理项目 xff0c 所有的项目配置信息都被定义在一个叫做P
  • Ubuntu安装配置Docker

    一 Docker简介 Docker 是一个开源的应用容器引擎 xff0c 可以轻松的为任何应用创建一个轻量级的 可移植的 自给自足的容器 xff0c 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中 xff0c 然后发布到任何流行的
  • Ubuntu安装ftp实现文件上传

    ftp服务安装与配置 sudo apt install vsftpd 外链图片转存失败 源站可能有防盗链机制 建议将图片保存下来直接上传 img UlscHRVo 1598855886357 https img blog csdn net
  • Docker安装Tomcat镜像并部署web项目简述

    一 安装Tomcat 1 查找Docker Hub上的tomcat镜像 docker search tomcat 2 拉取官方的镜像 docker pull tomcat 等待下载完毕 xff0c 需要一些时间 3 查看docker所有的镜
  • Docker删除镜像和容器

    删除docker中的镜像 xff0c 我们可以使用如下命令 xff1a docker rmi 镜像id 删除docker中的容器可以使用如下命令 xff1a docker rm 容器id 使用如下命令可以查看当前正在运行的容器 docker
  • ubuntu安装SonarQube实现代码质量检测

    一 ubuntu中安装jdk 下载并安装jdk 详细过程可参考 xff1a https blog csdn net qq 26709459 article details 80466239 二 ubuntu中安装mysql 详细过程可参考
  • springboot整合quartz(集群环境)

    使用quartz实现定时任务 xff0c 若是部署多台机器 xff0c 那么到了时间点 xff0c 多台服务器便会同时均开始执行定时任务 xff0c 这不符合我们的功能实现 quartz集群分为水平集群和垂直集群 xff0c 水平集群即将定
  • tomcat集群环境下实现负载均衡、session共享

    一 高可用 高可用HA High Availability 是分布式系统稳定运行必须考虑的因素之一 xff0c 它指的是通过处理减少系统不能提供服务的时间 比如说系统能够一直正常提供服务 xff0c 我们就说这个系统可用性为100 我们知道
  • 搭建RocketMq

    安装所需要的所有安装包 自己可以搜索源码自己打包 xff0c 也可以自己百度下载 xff0c 下面的是我的相关软件包 xff0c 有需要可以自己下载 xff1a https download csdn net download qq 267
  • ros launch中的节点工作空间路径

    原链接 运行测试平台 小强ROS机器人 在launch文件中启动节点 xff0c 那么这个节点的工作目录是什么呢 xff1f 在node程序中如果创建一个文件 xff0c 这个文件的默认位置在哪里 xff1f 在launch中node节点有

随机推荐

  • 搭建Git服务器并安装管理工具Gitblit

    一 安装Git服务 1 移除旧版git yum remove git 2 下载git 在如下链接中可以看到git所有版本 xff0c 选择自己需要的版本进行下载 xff0c 这里我选择最新版本 https github com git gi
  • FastDFS的安装配置及其使用

    一 fastDFS是什么 fastDFS是c语言编写的一款开源分布式文件系统 xff0c 使用fastDFS可以很方便搭建一套高性能的文件服务器集群提供文件上传 下载等服务 二 fastDFS工作原理 fastDFS包括Tracker se
  • centos编译hadoop源码包

    一 所需工具 JDK maven protobuf CMake ant hadoop 2 x x src 如下所示 xff1a 二 安装 1 安装jdk 2 安装maven 可以参考如下地址 xff1a https blog csdn ne
  • CentOs搭建Zookeeper

    下载地址 https mirrors tuna tsinghua edu cn apache zookeeper zookeeper 3 4 14 一 zookeeper环境搭建 安装jdk xff1a 略 本次我们在192 168 0 1
  • CensOs搭建Solr环境并配置

    下载地址 xff1a https mirrors tuna tsinghua edu cn apache lucene solr 8 1 1 注 xff1a 这里我使用的8 1 1版本 xff0c 可以根据自己需要选择版本 若是版本相差较大
  • Centos安装Docker

    Docker 是一个开源的应用容器引擎 xff0c 让开发者可以打包他们的应用以及依赖包到一个可移植的容器中 xff0c 然后发布到任何流行的 Linux 机器上 xff0c 也可以实现虚拟化 Docker 技术的三大核心概念 xff0c
  • Docker图形管理工具的安装与使用

    1 搜索Portainer镜像 docker search portainer 2 下载镜像 docker pull portainer portainer 3 启动 docker run d p 9000 9000 restart 61
  • PV3953L1光流定点激光定高四轴悬停模块说明书

    PV3953L1光流定点激光定高四轴悬停模块说明书 视频效果 xff1a STM32F103 270飞控 四轴飞行器大机架 DIY安装 视频教程 1 产品图片 型号 xff1a PV3953L1 接线标识 xff1a V xff1a 3 3
  • 【OpenCV3.2】Detection of ArUco Markers

    姿态估计 xff08 Pose estimation xff09 在 计算机视觉 领域扮演着十分重要的角色 xff1a 机器人 导航 增强现实以及其它 这一过程的基础是找到现实世界和图像投影之间的对应点 这通常是很困难的一步 xff0c 因
  • FreeRTOS学习之前后台系统存在的问题

    最近报了百问网7天物联网的训练营 https www 100ask net detail term 6216e88bc00cf 3clJb1 25 和在B站上学习的韦东山老师的freeRTOS做了下学习记录 1 什么是前后台系统 这是一个典
  • 速腾聚创16线激光雷达rslidar-16的ros驱动安装与rviz点云显示

    原链接 https community bwbot org topic 520 运行测试平台 小强ROS机器人 速腾聚创16线激光雷达rslidar 16的供电是直流12v 3A xff0c 通信接口是rs485网络接口 小强ros开发平台
  • freeRTOS滴答时钟相关源码分析

    最近学习白问网韦东山老师在B站开源的freeRTOS课程 xff0c 网址 xff1a 韦东山直播公开课 xff1a RTOS实战项目之实现多任务系统 第1节 xff1a 裸机程序框架和缺陷 哔哩哔哩 bilibili和7天物联网训练营 第
  • freeRTOS相对延时函数-vTaskDelay源码分析

    最近学习白问网韦东山老师在B站开源的freeRTOS课程 xff0c 网址 xff1a 韦东山直播公开课 xff1a RTOS实战项目之实现多任务系统 第1节 xff1a 裸机程序框架和缺陷 哔哩哔哩 bilibili和7天物联网训练营 第
  • freeRTOS绝对延时函数 vTaskDelayUntil源码分析

    最近学习白问网韦东山老师在B站开源的freeRTOS课程 xff0c 网址 xff1a 韦东山直播公开课 xff1a RTOS实战项目之实现多任务系统 第1节 xff1a 裸机程序框架和缺陷 哔哩哔哩 bilibili和7天物联网训练营 第
  • 北京邮电大学计算机考研信息汇总

    See you in BUPT 北京邮电大学计算机考研报考资料 复试资料汇总 for 2019 by 凝紫暮 CSDN xff1a 北京邮电大学计算机考研信息汇总 GitHub Pages 北京邮电大学计算机考研信息汇总 适用报考范围 xf
  • C++面向对象程序设计——类和对象(个人整理)

    对象 xff1a object 客观世界中任何一个事物都可以看成一个对象 xff0c 如自然物体 xff08 汽车 xff0c 房子 xff0c 班级 xff09 可以看到一个班级作为一个对象有两个要素 xff1a 1 班级所属系和专业 x
  • C++面向对象程序设计——类和对象的进一步讨论

    构造函数 xff1a 构造函数是一种特殊的成员函数 xff0c 它不需要用户来调用它 xff0c 而是在建立对象时自动执行 在一个类中定义了全部是默认参数的构造函数后 xff0c 则不再定义重载构造函数 xff08 否则容易出错 xff09
  • C++面向对象程序设计——继承与派生

    什么是继承与派生 xff1a 在C 43 43 中可重用性是通过 继承 这一机制来实现的 xff0c 因此继承是C 43 43 的一个重要的组成部分 声明派生类的一般形式为 xff1a class 派生类名 xff1a 继承方式 基类名 派
  • UCOS-II时间管理

    uC OS II时间管理 xff1a 任务延时函数 xff0c OSTimeDly INT16U ticks 申请该服务的任务可以延时一段时间 xff0c 这段时间的长短是用时钟节拍的数目来确定的 实现这个系统服务的函数叫做 OSTimeD
  • UCOS-II内存管理

    内存管理 xff1a 我们知道 xff0c 在 ANSI C 中可以用 malloc 和 free 两个函数动态地分配内存和释放内存 但是 xff0c 在嵌入式实时操作系统中 xff0c 多次这样做会把原来很大的一块连续内存区域 xff0c