1. k_buf_queue
1.1 功能
1.2 结构体
typedef struct {
blk_obj_t blk_obj;
void *buf;
k_ringbuf_t ringbuf;
size_t max_msg_size;
size_t cur_num;
size_t peak_num;
size_t min_free_buf_size;
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
klist_t buf_queue_item;
#endif
uint8_t mm_alloc_flag;
} kbuf_queue_t;
成员名称 | 功能 |
---|---|
blk_obj | buf queue的任务链表 |
buf | |
ringbuf | |
max_msg_size | |
cur_num | |
peak_num | |
min_free_buf_size | |
buf_queue_item | |
mm_alloc_flag |
1.3 函数
kstat_t krhino_buf_queue_create(kbuf_queue_t *queue, const name_t *name,
void *buf, size_t size, size_t max_msg);
kstat_t krhino_fix_buf_queue_create(kbuf_queue_t *queue, const name_t *name,
void *buf, size_t msg_size, size_t msg_num);
kstat_t krhino_buf_queue_del(kbuf_queue_t *queue);
kstat_t krhino_buf_queue_dyn_create(kbuf_queue_t **queue, const name_t *name,
size_t size, size_t max_msg);
kstat_t krhino_buf_queue_dyn_del(kbuf_queue_t *queue);
kstat_t krhino_buf_queue_send(kbuf_queue_t *queue, void *msg, size_t size);
kstat_t krhino_buf_queue_recv(kbuf_queue_t *queue, tick_t ticks, void *msg,
size_t *size);
kstat_t krhino_buf_queue_flush(kbuf_queue_t *queue);
kstat_t krhino_buf_queue_info_get(kbuf_queue_t *queue, kbuf_queue_info_t *info);
1.4 参考链接
2. k_dyn_mem_proc
3. k_err
4. k_event
5. k_idle
6. k_mm
6.1 功能
6.2 结构体
typedef struct {
#if (RHINO_CONFIG_MM_REGION_MUTEX > 0)
kmutex_t mm_mutex;
#else
kspinlock_t mm_lock;
#endif
k_mm_region_info_t *regioninfo;
#if (RHINO_CONFIG_MM_BLK > 0)
void *fix_pool;
#endif
#if (K_MM_STATISTIC > 0)
size_t used_size;
size_t maxused_size;
size_t free_size;
/* number of times for each TLF level */
size_t alloc_times[MM_BIT_LEVEL];
#endif
/* msb (MM_BIT_LEVEL-1) <-> lsb 0, one bit match one freelist */
uint32_t free_bitmap;
/* freelist[N]: contain free blks at level N,
2^(N + MM_MIN_BIT) <= level N buffer size < 2^(1 + N + MM_MIN_BIT) */
k_mm_list_t *freelist[MM_BIT_LEVEL];
} k_mm_head;
6.3 函数
kstat_t krhino_init_mm_head(k_mm_head **ppmmhead, void *addr, size_t len );
kstat_t krhino_deinit_mm_head(k_mm_head *mmhead);
kstat_t krhino_add_mm_region(k_mm_head *mmhead, void *addr, size_t len);
void *k_mm_alloc(k_mm_head *mmhead, size_t size);
void k_mm_free(k_mm_head *mmhead, void *ptr);
void *k_mm_realloc(k_mm_head *mmhead, void *oldmem, size_t new_size);
/**
* This function is wrapper of mm allocation
* @param[in] size size of the mem to malloc
* @return the operation status, NULL is error, others is memory address
*/
void *krhino_mm_alloc(size_t size);
/**
* This function is wrapper of mm free
* @param[in] ptr address point of the mem
*/
void krhino_mm_free(void *ptr);
/**
* This function is wrapper of mm rallocation
* @param[in] oldmem oldmem address
* @param[in] size size of the mem to malloc
* @return the operation status, NULL is error, others is realloced memory address
*/
void *krhino_mm_realloc(void *oldmem, size_t newsize);
6.4 参考链接
[1]. Alios-things, https://github.com/chengshuyi/AliOS-Things/blob/master/kernel/rhino/core/k_mm.c
7. k_mm_blk
7.1 功能
提供内存池,内存池里面内存按块分配。
7.2 结构体
typedef struct {
const name_t *pool_name;
void *pool_end; /* end address */
void *pool_start; /* start address */
size_t blk_size;
size_t blk_avail; /* num of available(free) blk */
size_t blk_whole; /* num of all blk */
uint8_t *avail_list;
kspinlock_t blk_lock;
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
klist_t mblkpool_stats_item;
#endif
} mblk_pool_t;
成员名称 | 功能 |
---|---|
pool_name | pool的名字 |
pool_end | pool的尾地址 |
pool_start | pool的头地址 |
blk_size | pool中一个blk的大小 |
blk_avail | pool中blk的可用数目 |
blk_whole | pool中一共有多少个blk |
avail_list | 第一个可用的blk地址 |
blk_lock | pool的锁 |
mblkpool_stats_item | pool的双向链表 |
7.3 函数
内存池的初始化,内存块分配和释放。
kstat_t krhino_mblk_pool_init(mblk_pool_t *pool, const name_t *name,
void *pool_start,
size_t blk_size, size_t pool_size);
kstat_t krhino_mblk_alloc(mblk_pool_t *pool, void **blk);
kstat_t krhino_mblk_free(mblk_pool_t *pool, void *blk);
部分函数解析:
- krhino_mblk_alloc:在分配给用户一个block后,需要更新avail(可用的block的地址)的指针,使其指向下一个block的地址。
avail_blk = pool->avail_list; pool->avail_list = *(uint8_t **)(avail_blk);
avail_blk是当前block的地址(已经分配给用户),但是avail_blk地址的前四位包含着下一个block的地址。在源码里面,是将avail_blk强制转换成(uint8_t*)类型(指向uint8_t的指针的指针)。那么(uint8_t )(avail_blk)即 avail_blk,取avail_blk地址的值一次得到uint8_t类型,即是32(sizeof(uint8_t *))位的。故得到了avail_blk地址的前四位,即下一个block的地址。
7.4 参考链接
[1]. Alios-things, https://github.com/chengshuyi/AliOS-Things/blob/master/kernel/rhino/core/k_mm_blk.c
k_pend
功能
任务阻塞时的状态转换,即实现了阻塞的有限状态机。
函数
主要是任务阻塞、任务唤醒两个操作。
void pend_task_wakeup(ktask_t *task);
void pend_to_blk_obj(blk_obj_t *blk_obj, ktask_t *task, tick_t timeout);
void pend_task_rm(ktask_t *task);
void pend_list_reorder(ktask_t *task);
kstat_t pend_state_end_proc(ktask_t *task);
RHINO_INLINE void pend_list_add(klist_t *head, ktask_t *task)
部分函数解析:
- pend_to_blk_obj:当有申请的资源(比如buf queue、sem、event等等)被阻塞时,则将该task依据优先级插入到该资源阻塞列表,并设置超时。
参考链接
[1]. FreeRTOS中的任务状态, https://blog.csdn.net/peakzuo/article/details/60132640
[2]. Alios-things, https://github.com/chengshuyi/AliOS-Things/blob/master/kernel/rhino/core/k_pend.c
k_queue
功能
提供消息队列,供进程间通信。
结构体
typedef struct queue_s {
blk_obj_t blk_obj;
k_ringbuf_t ringbuf;
msg_q_t msg_q;
#if (RHINO_CONFIG_SYSTEM_STATS > 0)
klist_t queue_item;
#endif
uint8_t mm_alloc_flag;
} kqueue_t;
成员名称 | 功能 |
---|---|
blk_obj_t | 阻塞任务列表 |
k_ringbuf_t | ring buffer |
msg_q_t | msg结构信息,包括:起始地址、大小、msg的数目、msg数目的顶峰 |
klist_t | 双向链表 |
uint8_t | kernel动态分配还是user分配 |
函数
对消息队列的基本操作。
kstat_t krhino_queue_create(kqueue_t *queue, const name_t *name, void **start,
size_t msg_num);
kstat_t krhino_queue_del(kqueue_t *queue);
kstat_t krhino_queue_dyn_create(kqueue_t **queue, const name_t *name,
size_t msg_num);
kstat_t krhino_queue_dyn_del(kqueue_t *queue);
kstat_t krhino_queue_back_send(kqueue_t *queue, void *msg);
kstat_t krhino_queue_all_send(kqueue_t *queue, void *msg);
kstat_t krhino_queue_recv(kqueue_t *queue, tick_t ticks, void **msg);
kstat_t krhino_queue_is_full(kqueue_t *queue);
kstat_t krhino_queue_flush(kqueue_t *queue);
kstat_t krhino_queue_info_get(kqueue_t *queue, msg_info_t *info);
部分函数解析:
- krhino_queue_del:要删除时,唤醒被阻塞的task。
- krhino_queue_recv:当前task接收msg,如果queue里面msg的数目大于0,说明可以接收。不然,task则调用pend_to_blk_obj进入阻塞状态。
参考链接
[1]. Alios-things, https://github.com/chengshuyi/AliOS-Things/blob/master/kernel/rhino/core/k_queue.c
[2]. 消息队列和管道的区别, https://blog.csdn.net/wuhenyouyuyouyu/article/details/53888805
13. k_ringbuf
功能
提供环状缓冲区的操作。在kernel里面,只有buf queue和queue有用到。
ringbuf_init函数called by结构体
typedef struct {
uint8_t *buf;
uint8_t *end;
uint8_t *head;
uint8_t *tail;
size_t freesize;
size_t type;
size_t blk_size;
} k_ringbuf_t;
成员名称 | 功能 |
---|---|
buf | 指向buf的头 |
end | 指向buf的尾 |
head | 指向data的头 |
tail | 指向data的尾 |
freesize | buf可用的空间 |
type | data的长度是固定长度/不定长度 |
blk_size | 每一个data的固定长度 |
函数
主要有六个函数都是ringbuf的基本操作。对于data是固定长度的操作比较简单,但是不定长度需要注意的有:
- 不定长度和固定长度都需要考虑,data在ringbuf->end被切断。
- 不定长度的data pop时,要注意data的长度信息可能在ringbuf->end被切断。
kstat_t krhino_ringbuf_init (k_ringbuf_t *p_ringbuf, void *buf, size_t len,
size_t type, size_t block_size);
kstat_t krhino_ringbuf_reset(k_ringbuf_t *p_ringbuf);
kstat_t krhino_ringbuf_push(k_ringbuf_t *p_ringbuf, void *data, size_t len);
kstat_t krhino_ringbuf_pop(k_ringbuf_t *p_ringbuf, void *pdata, size_t *plen);
uint8_t krhino_ringbuf_is_full(k_ringbuf_t *p_ringbuf);
uint8_t krhino_ringbuf_is_empty(k_ringbuf_t *p_ringbuf);
部分函数解析:
- krhino_ringbuf_is_full 如果是固定长度且freesize小于blk_size,则full。如果是不定长度且freesize小于sizeof(size_t)+1(因为ringbuf里面每一个data第一个字段都为len(uint32_t),所以至少得能放得下长度+一个byte),则full。
参考链接
[1]. Alios-things, https://github.com/chengshuyi/AliOS-Things/blob/master/kernel/rhino/core/k_ringbuf.c
网友评论