木子剑
生命不熄,学习不止!

请在网上先了解:什么是内存管理?有什么作用?为它这么重要?再继续下文阅读。。。。

因为在OS里面,每一个组件都有它存在原因和价值,当你不了解这些时,会是一头雾水。

 

在contiki-ng-release-v4.6\os\lib内,有俩种内存管理是静态内存和动态内存。

就是memb.c;   memb.hheapmem.c;  heapmem.h

 

要了解和掌握它们,我们最好先学习C下的基本方法:

 1 #include <stdio.h>
 2 #include <stdlib.h>//利用malloc()进行动态内存分配
 3 
 4 typedef struct{//定义一个结构体类刑,关于书的数据
 5     char title[64];
 6     int  price;
 7     char isbn[32];
 8 }BookData;
 9 
10 BookData *bok_dat_p;//定义个指针
11 
12 int main()
13 {    
14    printf("test1:%p \n", bok_dat_p->title);    //未分配时??
15     
16    bok_dat_p = malloc(sizeof(BookData));//为bok_dat_p分配内存区域    
17    if(!bok_dat_p){  //检查是不是分配成功      
18     printf("err:no RAM\n");
19     return 0;
20   }
21     printf("test2:%p \n", bok_dat_p->title);//正常分配后??
22     
23     printf("bok_dat_p:%d \n", sizeof(bok_dat_p));//指针自己的大小
24     printf("bok_dat_p-max:%d \n", sizeof(*bok_dat_p));//指向内存区域的总大小
25     printf("bok_dat_title:%d \n", sizeof(bok_dat_p->title));
26     printf("bok_dat_price:%d \n", sizeof(bok_dat_p->price));
27     printf("bok_dat_isbn:%d \n", sizeof(bok_dat_p->isbn));
28     
29     free(bok_dat_p);//释放内存    
30     return 0;
31 }

你可以复制到   https://www.runoob.com/try/runcode.php?filename=helloworld&type=c   进行在线测试。

 

当然,下面这个更简单,是不是真的很简单呢?(从教材读到,会产生大量的内存碎片,这些碎片是无法被系统使用的,大问题!,而CONTIKI很好处理了这些问题)

#include <stdio.h>
#include <stdlib.h>//利用malloc()进行动态内存分配
int main()
{
    int *int_p;
int_p
= malloc(sizeof(int));//为int_p分配内存区域,int一般是4字节吧,看系统情况 if(!int_p)return 0;//如果申请失败就直接退出
*int_p = 0x0f0f0f0f;//向内存块写入值 free(int_p);//释放内存

return 0; }

在OS里面,内存是有限的  宝贵的公共资源,只有在任务运行的时候,动态分配才是可行方案;举个例子,当你有100进程,但是只有30个进程在运行,

如果100个都分配好的话,是不是白白浪费SRAM了?话说占着毛坑不拉X,就是这个道理!!

 

时间:2021-01-12

把\os\lib内的memb.h进行爆光:

/**
 * Declare a memory block.声明内存块
* * \param:name给内存块取个名字, memb_init(), memb_alloc() and memb_free()使用. * * \param:structure内存块保存的结构的名称 * * \param:num内存块总数,以字节为单位 *
*/ #define MEMB(name, structure, num) \ static bool CC_CONCAT(name,_memb_used)[num]; \ static structure CC_CONCAT(name,_memb_mem)[num]; \ static struct memb name = {sizeof(structure), num, \ CC_CONCAT(name,_memb_used), \ (void *)CC_CONCAT(name,_memb_mem)} struct memb { unsigned short size; unsigned short num; bool *used; void *mem; }; /** * 初始化用MEMB()声明的内存块。 * * \param 一组先前用MEMB()声明的内存块。. */ void memb_init(struct memb *m); /** * 从用MEMB()声明的内存块中分配一个内存块。 * * \param 一组先前用MEMB()声明的内存块。. */ void *memb_alloc(struct memb *m); /** * 从先前用MEMB()声明的内存块中释放内存块。 * * \param 一组先前用MEMB()声明的内存块。 * * \param ptr指向要释放的内存块的指针。 * * \return 如果成功释放,错误代码应为 0,如果指针"ptr"未指向合法内存块,则为 -1。 */ int memb_free(struct memb *m, void *ptr); /** * 检查给定地址是否在先前用MEMB()声明的存储区之内。 * * \param 一组先前用MEMB()声明的内存块。 * * \param ptr指向要检查的地址的指针 * * \return 如果地址是存储块的一部分,则为1;否则为0。 否则为0 */ int memb_inmemb(struct memb *m, void *ptr); /** * 计数可用内存块 * * \param 一组先前用MEMB()声明的内存块。 * * \return 空闲(可用)内存块的数量 */ int memb_numfree(struct memb *m);

哈哈,看到这里,好像知道怎么使用CONTIKI NG的MEMB内存分配了。要好好试验加以掌握它!

 

接下来,让我们测试一下,CONTIKI NG的MEMB静态内存分配:

/*------------------------MEMB应用--------------------------------------------*/
#include "lib/memb.h"//加载静态内存库
PROCESS(MEMB_process, "MEMB process");

struct connection{ // 结构体,只有2个成员socket,实际应用中可能是多个
  char ID;
  int socket;
};

MEMB(connections, struct connection, sizeof(struct connection)/4);  // 申请一块connections内存 ,附合struct connection的大小

PROCESS_THREAD(MEMB_process, ev, data)//MEMB的process实现
{

  PROCESS_BEGIN();
  struct connection *pr; //对应的指针

  while(1)
  {
  memb_init(&connections);  //初化内存块,就是SET为0值,不能是垃圾值或以前旧值

  pr =  memb_alloc(&connections);  //给pr分配内存
  if(pr == NULL){  //检查是不是分配成功
    return NULL;  //不成功,返回NULL
  }
   pr->socket = 0xffff;//成功就附值进行测试

   printf("conn-socket:0x%x \n", pr->socket);//CONN的值是:??测试一个成员socket,实际应用中可能是多个
   printf("memb_numfree1:%d \n",  memb_numfree(&connections));//connections内存块,还有多少可用数量??

   memb_free(&connections, pr);//释放内存
   pr = NULL; //pr为空指针。
   printf("memb_numfree2:%d \n",  memb_numfree(&connections));//释放后,还有多少可用数量??

   PROCESS_EXIT(); //退出进程,释放资源
  }

  PROCESS_END();
}

/*------------------------所有自启动的测试PROCESSES---------------------------*/
AUTOSTART_PROCESSES(
                    &MEMB_process
                    );

测试效果如下:

从执行效果来看是正常的。在32位单片机中,一份内存块就是32BIT的,就是四个字节,我们可以看到,

为了内容对齐,一个char也是按照32BIT来分配的。

 

  关于heapmem.h动态分配器的,来看看CONTIKI 作者的原话:

 * \note This module does not contain a corresponding function to the
 *       standard C function calloc().
 *
 * \note Dynamic memory should be used carefully on
 *       memory-constrained, embedded systems, because fragmentation
 *       may be induced through various allocation/deallocation
 *       patterns, and no guarantees are given regarding the
 *       availability of memory.

如果你是在PC端,跑LINUX系统,可以用一下heapmem分配器,但是受限的嵌入式系统中,不建议使用的。

哪么明白了(内存碎片是个麻烦事),这个heapmem只作少量了解,直接跳过它就好了。

 

   

posted on 2021-01-11 22:58  木子剑  阅读(330)  评论(0编辑  收藏  举报