OneNET NB 学习笔记二 内存管理 memb fifo ringbuf

本文分析基于固件OneNET-Demo_v5(适配M5310sp3)

#define CC_CONCAT2(s1, s2) s1##s2   //将s1和s2连接
#define CC_CONCAT(s1, s2) CC_CONCAT2(s1, s2)

#define MEMB(name, structure, num) \
        static char CC_CONCAT(name,_memb_count)[num]; \
        static structure CC_CONCAT(name,_memb_mem)[num]; \
        static struct memb name = {sizeof(structure), num, \
                                   CC_CONCAT(name,_memb_count), \
                                   (void *)CC_CONCAT(name,_memb_mem)}

struct memb {
  unsigned short size;
  unsigned short num;
  char *count;
  void *mem;
};

#define FIFO(name, queuelen, buflen) \
      struct name##_fifo{\
         uint16_t datalen;\
         uint8_t  databuf[buflen];\
      };\
     MEMB(name, struct name##_fifo, queuelen)

例如:

FIFO(dl_buf, 8, 512);

可以分解为:

struct dl_buf_fifo{
    uint16_t datalen;
    uint8_t databuf[512];
};
static char dl_buf_memb_count[8];
static struct dl_buf_fifo dl_buf_memb_mem[8];   // 结构体 dl_buf_fifo 数组

static struct memb dl_buf = 
{
    sizeof(struct dl_buf_fifo),
    8,  // dl_buf_memb_count数组和dl_buf_memb_mem结构体数组元素的个数
    dl_buf_memb_count,// 指示dl_buf_memb_mem的某一空间是否被占用
    (void*)dl_buf_memb_mem// 存储dl_buf_fifo的数组缓存
}

以上也就是FIFO(dl_buf, 8, 512) 定义了一个类型为struct memb的变量dl_buf,并将成员变量初始化。
这里写图片描述
如图,其中struct memb dl_buf成员变量 char *count 指向 dl_buf_memb_count[8],当第 i 个成员为1的时候,表征对应的dl_buf_memb_mem[i]的内存空间已经被占用。void *mem指向sturct dl_buf_fifo dl_buf_memb_mem[8]dl_buf_memb_mem每一个空间都可以存放一个dl_buf_fifo的结构体变量。

fifo.c

    typedef struct{
      uint8_t used;
      struct memb *mem_b;
    }pipe_t;

pipe_t pipe[pipe_num] = {0};

int8_t fifo_init(struct memb *ptr)
{
   int8_t i = 0;
   for(i = 0; i < pipe_num; i++)
     if(pipe[i].used == 0){
        pipe[i].used = 1;
        pipe[i].mem_b = ptr;
        memb_init(ptr);
        return i;
     }
   return -1;
}

在USART3.c中 dl_buf_id = fifo_init(&dl_buf); 也就是pipe[dl_buf_id ]指向dl_buf

ringbuf

ringbuf用于最底层USART接收缓存

struct ringbuf {
  uint8_t *data;
  uint16_t mask;

  /* XXX these must be 8-bit quantities to avoid race conditions. */
  uint16_t put_ptr, get_ptr;
};

void ringbuf_init (struct ringbuf *r, uint8_t *dataptr, uint16_t size)  
{
    r->data = dataptr;
    r->mask = size - 1;
    r->put_ptr = 0;
    r->get_ptr = 0;
}
struct ringbuf ring_fifo;
static uint8_t rx_fifo[512];

在USART3.c 中调用 ringbuf_init(&ring_fifo, rx_fifo, sizeof(rx_fifo));,并且DMA接收内存设置为rx_fifo ,也就是ring_fifo->data指向rx_fifo缓存。一帧数据接收完成之后触发总线空闲中断点此详解),在中断服务函数中,如果是平台发来的read write execute等请求,则将数据放到FIFO中

//如果是平台发来的 +MIPLREAD +MIPLWRITE +MIPLEXECUTE 等等
if((msg_p = strstr((const char *)ring_fifo.data, "+MIPL")) != NULL)
    fifo_put(dl_buf_id, ringbuf_elements(&ring_fifo), ring_fifo.data);

将ringbuf中的数据放入到FIFO中,待netif_rx()取出处理。

*read = fifo_get(dl_buf_id, ptr);//从FIFO中读数据,放到 ptr 中,*read 为数据长度

以上,字丑,整理的还有点乱,见谅。有理解错误的地方恳请指正,谢谢。

猜你喜欢

转载自blog.csdn.net/Hola_ya/article/details/81529770