首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

ucos内存管理(3)

ucos内存管理(3)


释放一个内存块,OSMemPut()当用户应用程序不再使用一个内存块时,必须及时地把它释放并放回到相应的内存分区中。这个操作由OSMemPut()函数完成。必须注意的是,OSMemPut()并不知道一个内存块是属于哪个内存分区的。例如,用户任务从一个包含32字节内存块的分区中分配了一个内存块,用完后,把它返还给了一个包含120字节内存块的内存分区。当用户应用程序下一次申请120字节分区中的一个内存块时,它会只得到32字节的可用空间,其它88字节属于其它的任务,这就有可能使系统崩溃。
程序清单 L7.5是OSMemPut()函数的源代码。它的第一个参数pmem是指向内存控制块的指针,也即内存块属于的内存分区[L7.5(1)]。OSMemPut()首先检查内存分区是否已满[L7.5(2)]。如果已满,说明系统在分配和释放内存时出现了错误。如果未满,要释放的内存块被插入到该分区的空闲内存块链表中[L7.5(3)]。最后,将分区中空闲内存块总数加1[L7.5(4)]。


  程序清单 L7.5 OSMemPut()
  
  INT8U  OSMemPut (OS_MEM  *pmem, void  *pblk)                              (1)
  
  {
  
      OS_ENTER_CRITICAL();
  
      if (pmem->OSMemNFree  >= pmem->OSMemNBlks) {                         (2)
  
           OS_EXIT_CRITICAL();
  
           return (OS_MEM_FULL);
  
      }
  
      *(void **)pblk      =  pmem->OSMemFreeList;                          (3)
  
      pmem->OSMemFreeList =  pblk;
  
      pmem->OSMemNFree++;                                                 (4)
  
      OS_EXIT_CRITICAL();
  
      return (OS_NO_ERR);
  
  }
  



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


  程序清单 L7.6 OS_MEM_DATA数据结构
  
  typedef  struct {
  
      void  *OSAddr;     /* 指向内存分区首地址的指针 */
  
      void  *OSFreeList; /* 指向空闲内存块链表首地址的指针 */
  
      INT32U OSBlkSize;  /* 每个内存块所含的字节数 */
  
      INT32U OSNBlks;    /* 内存分区总的内存块数 */
  
      INT32U OSNFree;    /* 空闲内存块总数 */
  
      INT32U OSNUsed;    /* 正在使用的内存块总数 */
  
  }  OS_MEM_DATA;
  


程序清单 L7.7是OSMemQuery()函数的源代码,它将指定内存分区的信息复制到OS_MEM_DATA定义的变量的对应域中。在此之前,代码首先禁止了外部中断,防止复制过程中某些变量值被修改[L7.7(1)]。由于正在使用的内存块数是由OS_MEM_DATA中的局部变量计算得到的,所以,可以放在(criticalsection中断屏蔽)的外面。


  程序清单 L7.7 OSMemQuery()
  
  INT8U  OSMemQuery (OS_MEM *pmem, OS_MEM_DATA *pdata)
  
  {
  
      OS_ENTER_CRITICAL();
  
      pdata->OSAddr     =  pmem->OSMemAddr;                               (1)
  
      pdata->OSFreeList =  pmem->OSMemFreeList;
  
      pdata->OSBlkSize  = pmem->OSMemBlkSize;
  
      pdata->OSNBlks    = pmem->OSMemNBlks;
  
      pdata->OSNFree    = pmem->OSMemNFree;
  
      OS_EXIT_CRITICAL();
  
      pdata->OSNUsed    = pdata->OSNBlks -  pdata->OSNFree;               (2)
  
      return (OS_NO_ERR);
  
  }
  



Using Memory Partitions图 F7.5是一个演示如何使用µC/OS-II中的动态分配内存功能,以及利用它进行消息传递[见第6章]的例子。程序清单L7.8是这个例子中两个任务的示意代码,其中一些重要代码的标号和图 F7.5中括号内用数字标识的动作是相对应的。
第一个任务读取并检查模拟输入量的值(如气压、温度、电压等),如果其超过了一定的阈值,就向第二个任务发送一个消息。该消息中含有时间信息、出错的通道号和错误代码等可以想象的任何可能的信息。
错误处理程序是该例子的中心。任何任务、中断服务子程序都可以向该任务发送出错消息。错误处理程序则负责在显示设备上显示出错信息,在磁盘上登记出错记录,或者启动另一个任务对错误进行纠正等。


























  
  









继承事业,薪火相传
返回列表