Keil RTX 是免版税的确定性实时操作系统,适用于 ARM 和 Cortex-M 设备。使用该系统可以创建同时执行多个功能的程序,并有助于创建结构更好且维护更加轻松的应用程序。关于Keil  RTX不多说了,使用KEil软件作为开发的用到RTX的不少吧。
  RTX系统配合KeilMDK软件使用起来还是比较简单的,开发也很方便。RTX系统中的各个模块都是比较独立的,这点很方便学习。其中的内存管理部分在rt_MemBox.c函数中。RTX的动态内存管理,其实是事先分配了一个全局变量的大数组,只不过把这部分连续内存用指针链表的形式加以灵活管理。可以把RTX这部分内存管理代码摘出来单独为以后自己的应用使用。
  看一下代码中的宏两个宏
/* Memory pool for TCB allocation    */
_declare_box (mp_tcb, OS_TCB_SIZE, OS_TASKCNT);
U16 const mp_tcb_size = sizeof(mp_tcb);
/* Memory pool for System stack allocation (+ os_idle_demon). */
_declare_box8 (mp_stk, OS_STKSIZE*4, OS_TASKCNT-OS_PRIVCNT+1);
  其中的任务控制块mp_tcb和堆栈mp_stk都用到了动态内存管理。因为这样管理起来很方便,比如创建任务和删除任务,要是用数组的话,你必须知道现在处于哪个索引位置,添加任务和删除任务时又处于数组的哪个索引位置。有这种链表的方式,无需关心这些。
  找到这个宏的定义出,看到了它的真面目,分配了一个大数组,叫它内存池吧。
#define BOX_ALIGN_8                   0x80000000
#define _declare_box(pool,size,cnt)   U32 pool[(((size)+3)/4)*(cnt) + 3]
#define _declare_box8(pool,size,cnt)  U64 pool[(((size)+7)/8)*(cnt) + 2]
#define _init_box8(pool,size,bsize)   _init_box (pool,size,(bsize) | BOX_ALIGN_8)
/* Variables */
extern U32 mp_tcb[];
extern U64 mp_stk[];
extern U32 os_fifo[];
extern void *os_active_TCB[];
  至于#define BOX_ALIGN_8                   0x80000000,这涉及到对齐,
  对齐难免造成内存资源浪费,但是也给操作增加了方便,至少访问不会出错吧。
  mp_tcb和mp_stk定义了数组的地址,和*mp_tcb差不多吧,但是两者却是有区别的,数组名不等于指针,举个简单例子说,指针变量可以任意给其赋值,但是数组名,能给它赋一个另一个地址吗?数组名指向的地址是确定的。指针是一个变量,变量的值是另外一个变量的地址。那么,既然指针是变量,那么指针必然有自己的存储空间,只不过是该存储空间内的值是一个地址值,而不是别的内容。定义指针是要占一个空间的,因为它是个变量,定义成mp_tcb[]实际是不占空间的。数组名只是一个符号。它们取指运算的效果相同但是不是相等。可以把数组名看做常量指针吧,只是看做但并不是。
  使用RTX的内存管理模块之前,先是要定义一个大数组分配内存池,然后是初始化了。把各个小分区链接起来。
  看一下链接用的链表结构:
  typedef struct OS_BM {
  void *free;                     /* Pointer to first free memory block      */
  void *end;                      /* Pointer to memory block end             */
  U32  blk_size;                  /* Memory block size                       */
  } *P_BM;
  是这么个双向链表,把小块的内存链接起来,共用一个内存池。