AliOS-Things+STM32 (七) 进程管理(上)

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

在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);
         
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值