在alios things启动过程中,krhino_init中,做完memory堆初始化,就会初始化进程相关的东西。在分析的过程中,默认RHINO_CONFIG_KOBJ_LIST,RHINO_CONFIG_KOBJ_DYN_ALLOC,RHINO_CONFIG_SCHED_RR都使能,RHINO_CONFIG_CPU_NUM为1。RHINO_CONFIG_SCHED_RR表示高优先级会抢占低优先级,高优先级运行期间,低优先级没法抢占,只能等到高优先级主动退出,对于同等优先级的进程,各个进程会轮流运行一定的时间片。
我们先看下krhino_init初始化过程:
kstat_t krhino_init(void)
{
/*设置系统为RHINO_STOPPED状态*/
g_sys_stat = RHINO_STOPPED;
/*RHINO_CONFIG_CPU_NUM = 1跳过g_sys_lock和g_task_del_head初始化*/
#if (RHINO_CONFIG_CPU_NUM > 1)
krhino_spin_lock_init(&g_sys_lock);
klist_init(&g_task_del_head);
#endif
/*初始化就绪队列g_ready_queue*/
runqueue_init(&g_ready_queue);
/*初始化tick链表,这个也和进程切换相关*/
tick_list_init();
#if (RHINO_CONFIG_KOBJ_LIST > 0)
/*初始化kobj链表*/
kobj_list_init();
#endif
/*RHINO_CONFIG_USER_HOOK 当前先不开启,后续章节分析*/
#if (RHINO_CONFIG_USER_HOOK > 0)
krhino_init_hook();
#endif
/*堆内存初始化,前两章已经分析过*/
#if (RHINO_CONFIG_MM_TLF > 0)
k_mm_init();
#endif
#if (RHINO_CONFIG_KOBJ_DYN_ALLOC > 0)
/*初始化进程资源释放相关的链表, 信号量以及释放管理进程*/
klist_init(&g_res_list);
krhino_sem_create(&g_res_sem, "res_sem", 0);
/*dyn_mem_proc_task_start会创建一个dyn_mem_proc_task,调度器开始后就启动这个用来释放进程资源的进程
这是创建的第一个task*/
dyn_mem_proc_task_start();
#endif
/*RHINO_CONFIG_CPU_NUM = 1*/
#if (RHINO_CONFIG_CPU_NUM > 1)
for (uint8_t i = 0; i < RHINO_CONFIG_CPU_NUM; i++) {
krhino_task_cpu_create(&g_idle_task[i], "idle_task", NULL, RHINO_IDLE_PRI, 0,
&g_idle_task_stack[i][0], RHINO_CONFIG_IDLE_TASK_STACK_SIZE,
idle_task, i, 1u);
}
#else
/*创建idle进程,调度器开始后正式启动idle进程,这是创建的第二个task*/
krhino_task_create(&g_idle_task[0], "idle_task", NULL, RHINO_IDLE_PRI, 0,
&g_idle_task_stack[0][0], RHINO_CONFIG_IDLE_TASK_STACK_SIZE,
idle_task, 1u);
#endif
#if (RHINO_CONFIG_WORKQUEUE > 0)
/*初始化workqueue,这是创建的第三个task*/
workqueue_init();
#endif
#if (RHINO_CONFIG_TIMER > 0)
/*初始化时钟,比较重要,后面分析,这是创建的第四个task*/
ktimer_init();
#endif
/*用来检查栈溢出,目前没使能不分析*/
rhino_stack_check_init();
return RHINO_SUCCESS;
}
void runqueue_init(runqueue_t *rq)
{
uint8_t prio;
rq->highest_pri = RHINO_CONFIG_PRI_MAX;
for (prio = 0; prio < RHINO_CONFIG_PRI_MAX; prio++) {
rq->cur_list_item[prio] = NULL; //所有优先级的链表先置空
}
}
#define RHINO_CONFIG_PRI_MAX 62
#define NUM_WORDS ((RHINO_CONFIG_PRI_MAX + 31) / 32)
typedef struct {
klist_t *cur_list_item[RHINO_CONFIG_PRI_MAX]; //一共有62个进程链表, 每个链表挂不同优先级的进程
uint32_t task_bit_map[NUM_WORDS]; //每个bit位置1,代表一种优先级的进程存在。
uint8_t highest_pri; //队列上进程的最高优先级
} runqueue_t;
这里我们单独看下dyn_mem_proc_task这个进程:
void dyn_mem_proc_task(void *arg)
{
/*申明cpsr,后边RHINO_CRITICAL_ENTER/RHINO_CRITICAL_EXIT调用需要*/
CPSR_ALLOC();
size_t i;
kstat_t ret;
res_free_t *res_free;
res_free_t tmp;
(void)arg;
while (1) {
/*无限睡眠等待g_res_sem资源被释放*/
ret = krhino_sem_take(&g_res_sem, RHINO_WAIT_FOREVER);
if (ret != RHINO_SUCCESS) {
k_err_proc(RHINO_DYN_MEM_PROC_ERR);
}
while (1) {
/*保存当前中断状态,并关中断*/
RHINO_CRITICAL_ENTER();
/*查看g_res_list是否为空, 为空则跳出while(1),否则直到释放完g_res_list上的资源*/
if (!is_klist_empty(&g_res_list)) {
/*不为空,则将g_res_list上的对象取下来,放到res_free上*/
res_free = krhino_list_entry(g_res_list.next, res_free_t, res_list);
klist_rm(&res_free->res_list);

本文深入剖析AliOS Things操作系统内核启动流程,详细解读krhino_init函数中的关键步骤,包括进程初始化、调度器配置及核心组件如tick链表、kobj链表的初始化。同时,分析了task_create函数的实现细节,以及动态内存进程释放机制。
最低0.47元/天 解锁文章
1473

被折叠的 条评论
为什么被折叠?



