本文分析基于固件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的结构体变量。
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用于最底层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 为数据长度
以上,字丑,整理的还有点乱,见谅。有理解错误的地方恳请指正,谢谢。