• uC/OS-II 内存管理


    UC/OS-II  内存管理

    1. 简介
        uC/OS-II 不使用ANSI编译器的malloc(), free(),因为内存碎片,很可能获取不到一块连续的内存, 这在嵌入式系统中是很危险的。同时malloc()和free()的执行时间也是不确定的。
        uC/OS-II 把内存划分为固定长度的块,一定数量的块组成一个partition,分配和回收的函数的执行时间是固定的,即常量时间。
        可以有一个或多个分区(partition), 每个分区的块大小可以不一样,这样想获取不同size的块,就从不同的分区取。再者,从哪个分区获取的块,回收时要重新放回获取内存时的分区,即哪来哪去。

    2. 数据结构
        内存控制块:用于跟踪内存分区,每个分区使用自己的内存控制块

     typedef struct {
            void *OSMemAddr;
            void *OSMemFreeList;
            INT32U OSMemBlkSize;
            INT32U OSMemNBlks;
            INT32U OSMemNFree;
     } OS_MEM;

       OSMemAddr       : 内存分区的起始地址,分区建立时初始化,以后不再改变
       OSMemFreeList : 指针,两种用途:1.指向下一个空闲的内存控制块,2.指向下一个空闲的内存块,视情况定    ** 要注意区分内存控制块和内存块**
       OSMemBlkSize  : 分区中内存块的大小
       OSMemNBlks     : 分区内内存块总数,分区建立时指定
       OSMemNFree    : 内存块的可用数,就是还剩多少个块可以分配。

       两个选项:(OS_CFG.H)
       OS_MEM_EN               1  允许初始化内存管理器
       OS_MAX_MEM_PART   4  内存分区数,至少是2
      

       图:

      

             这个链表由OSMemInit()建立,而OSMemInit()由OSInit()自动调用


    3. 建立分区
        分区要先初始化才能使用, 建立分区由OSMemCreate()完成:

        OS_MEM OSMemCreate (void *addr, INT32U nblks, INT32U blksize, INT8U *err);

        算法描述:
           1. nblks >=2, blksize > sizeof(void *), 否则报错,返回(OS_MEM *)0;   
           2. 从OSMemFreeList取下一个内存控制块。因为一个分区需要一个内存控制块。
               验证一下不是空指针
               ** OSMemFreeList 是个全局变量 **, 指向上面图中的内存控制块链表头
           3.  将内存块连接起来,形成分区
           4.  初始化2中取出的内存控制块    

        简单点说, 这个函数的功能就是把空闲的内存块连接起来形成分区,再将分区相关信息放入内存控制块。
        代码这里就不粘出来了。 函数执行后, 内存分区如图:


        值得注意的是,这些内存块是通过每个块的前面几个字节作为连接地址的。这就是为什么blksize > sizeof(void *)

                                        
    4. 获取内存块
        void * OSMemGet(OS_MEM *pmem, INT8U *err) ;

        这个函数就是把内存控制块的OSMemFreeList所指向的内存块返回,然后OSMemFreeList(这个不是全局变量那个)指向下一个空闲内存块。

    5. 返还内存块
        INT8U OSMemPut(OS_MEM *pmem, void * pblk);

        用完了就返还内存块到链表里。 返还的位置还是OSMemFreeList.


    6. 获取内存分区的状态
       INT8U OSMemQuery(OS_MEM *pmem, OS_MEM_DATA *pdata);


       状态用一个结构来表示: 

    typedef struct {
            void *OSAddr;        /* 分区的起始地址 */
            void *OSFreeList;    /* 空闲块的起始地址 */
            INT32U OSBlkSize;    /* 内存块的size */
            INT32U OSNBlks;      /* 分区里块的总数 */
            INT32U OSNFree;      /* 空闲块的数量 */
            INT32U OSNUsed;      /* 使用块的数量 */
    } OS_MEM_DATA;

       
      将内存控制块的各字段,赋给OS_MEM_DATA的各字段,很简单。    

       

  • 相关阅读:
    Web端导出CSV
    dojo/dom-style样式操作学习笔记
    dojo/dom源码学习
    上层建筑——DOM元素的特性与属性(dojo/dom-prop)
    上层建筑——DOM元素的特性与属性(dojo/dom-attr)
    返本求源——DOM元素的特性与属性
    DOM扩展札记
    以代码爱好者角度来看AMD与CMD
    dojo事件驱动编程之事件绑定
    通过Web.config中的configSections配置自己系统的全局常量
  • 原文地址:https://www.cnblogs.com/bear129/p/8167600.html
Copyright © 2020-2023  润新知