zoukankan      html  css  js  c++  java
  • Raw-OS源代码分析之idle任务

            分析的内核版本号截止到2014-04-15,基于1.05正式版,blogs会及时跟进最新版本号的内核开发进度,若源代码凝视出现”???”字样。则是未深究理解部分。

            Raw-OS官方站点:http://www.raw-os.org/

            Raw-OS托管地址:https://github.com/jorya/raw-os/

            这篇開始会连续几篇讲一讲Raw-OS的状态机编程那点破事。实际上来说,在实践上我并没实用过状态机编程这样的思想,可能使用过的某些库是状态机实现的我并不知道,可是在我写过的应用层代码至少没有涉及过状态机编程,可是确实这个也是非常非常好的思想,感觉理解起来非常easy。状态机编程的精髓是怎样依据须要设计合理的状态机,而并非状态机运行的过程。当然了~Raw-OS中的状态机模块就相当于QP-NANO的改写版本号,童鞋们能够去了解一下QP事件驱动框架。这也是水非常深的东西。

            今天就先再回想Raw-OS中IDLE任务这个东东

     

            在最開始我们讲Raw-OS初始化的代码的时候讲过,Raw-OS内核在初始化过程中,会建立一个系统最低优先级(255)的任务,这个任务称为IDLE任务,也就是所谓的“空暇任务”,IDLE任务是在系统没有实用任务运行的时候才运行,那么在Raw-OS中。当系统没什么事可做的时候,运行IDLE任务,而IDLE任务的详细内容,Raw-OS实现了两种操作:

     

            第一。在开发和调试用户业务逻辑代码的时候,使用实现1,即监控各个任务的任务堆栈使用情况,在开发阶段。监控任务堆栈的做法使得任务执行过程能够实时监控,各个任务所需的系统资源能够达到收敛的情况

    IDLE任务监控各个用户任务代码:

    /*
     * 当开启RAW_SYSTEM_CHECK宏时,idle任务事实上做的事情非常easy
     * 就是不断測试系统各个任务栈空间的剩余情况。在Raw-OS中。开启RAW_SYSTEM_CHECK宏后,
     * idle任务就当检測到不论什么任务的剩余栈空间少于12%时,系统就会down掉,打印哪个任务出现这样的情况
     * 是为了在用户应用层开发的时候避免系统产生不必要的无故down机的检測手段
     */
    #if (RAW_SYSTEM_CHECK > 0)
    RAW_VOID raw_idle_task(void *p_arg)
    {
    	LIST *iter;
    	RAW_TASK_OBJ						 *task_ptr;
    	PORT_STACK  *task_stack;
    
    	RAW_U32 free_stack;
    
    	RAW_SR_ALLOC();
    	p_arg = p_arg; /* Make compiler happy ^_^ */
    
    	/* 如今能够回头去看看task creat函数关于增加到系统debug链表的实现 */
    	iter = system_debug.task_head.next;
    
    	while (1) {
    
    		free_stack = 0u;
    		/*
    		 * 任务通过任务TCB的stack_check_list元素连接成系统debug链表
    		 * 这里通过存在debug链表的stack_check_list,逆计算出任务TCB地址
    		 */
    		task_ptr = list_entry(iter,RAW_TASK_OBJ, stack_check_list);
    
    		/*
    		 * 计算任务栈剩余空间时要注意CPU的栈空间生长的方向,低地址->高地址还是高地址->低地址
    		 */
    		#if (RAW_CPU_STACK_DOWN > 0)
    		task_stack = task_ptr->task_stack_base;
    		/* 假设堆栈是向下生成(高地址->低地址),那么栈顶在低地址,统计时往上计数 */
    		while (*task_stack++ == 0u) {
    			free_stack++;
    			/* 逻辑运算右移1位相当于/2,右移3位相当于/8。那么结果就是1/8*100% = 12% */
    			if (free_stack > (task_ptr->stack_size >> 3)) {
    				break;
    			}
    		}
    
    		#else
    		task_stack = (PORT_STACK *)(task_ptr->task_stack_base) + task_ptr->stack_size - 1;
    		/* 假设堆栈是向上生成(低地址->高地址),那么栈顶在低地址。统计时往下计数 */
    		while (*task_stack-- == 0) {
    			free_stack++;
    			/* 逻辑运算右移1位相当于/2,右移3位相当于/8,那么结果就是1/8*100% = 12% */
    			if (free_stack > (task_ptr->stack_size >> 3)) {
    				break;
    			}
    		}
    		#endif
    
    		TRACE_TASK_STACK_SPACE(task_ptr);
    		/* 统计idle任务执行次数 */
    		raw_idle_count++;
    
    		RAW_CPU_DISABLE();
    
    		if (task_ptr->task_state != RAW_DELETED) {
    
    			/* 这里就是推断任务栈空间的剩余大小。小于任务总堆栈空间的12%时,down掉信息打印 */
    			if (free_stack < (task_ptr->stack_size >> 3)) {
    				RAW_ASSERT(0);
    			}
    
    			/* 更新到系统debug的堆栈检查链表中的下一个任务,知道完整历遍一次stack_debug链表 */
    			iter = iter->next;
    			if (iter == (&(system_debug.task_head))) {
    				iter = system_debug.task_head.next;
    			}
    
    		}
    
    		/* 当在idle堆栈检查前任务已被删除。那么就立即跳过。再检索下下个堆栈检查链表任务 */
    		else {
    			iter = system_debug.after_delete_list;
    		}
    
    		RAW_CPU_ENABLE();
    	}
    }


            第二,当用户任务开发完毕时,一般会使用第二个实现。就是使用协程,可是这个协程是什么呢,这里只须要知道。IDLE使用协程。事实上就是调用一个钩子函数,这个钩子函数命名为“协程”而已。全然能够当做。就是IDLE任务的运行时,调用一个用户自己定义的钩子函数。这个钩子函数称为“协程的钩子”而已,完事

    #else
    
    /*
     * 未开启RAW_SYSTEM_CHECK宏时,idle任务事实上做的事情非常easy
     * 不过全局统计执行idle任务次数的raw_idle_count变量自加,能够检索系统执行多少次idle任务
     * 然后调用所谓的“协程”,“协程”事实上就是一个执行在idle任务的钩子函数
     *
     * 不过“协程”这个东西能够利用一些思想和编程技巧来实现比較有趣的东西
     * 在Raw-OS中就存在一个叫做“空暇事件编程”的东东,非常有意思
     */
    RAW_VOID raw_idle_task (void *p_arg)
    {
    	RAW_SR_ALLOC();
    
    	p_arg = p_arg; /* Make compiler happy ^_^ */
    
    	while (1) {
    
    		USER_CPU_INT_DISABLE();
    		/* 统计idle任务执行次数 */
    		raw_idle_count++;
    
    		USER_CPU_INT_ENABLE();
    		/* idle任务中的协程钩子函数 */
    		raw_idle_coroutine_hook();
    	}
    }
    
    #endif


  • 相关阅读:
    火车票起售时间
    java基础知识
    java运行
    123
    1233
    那些不能错过的XCode插件
    那些不能错过的XCode插件
    如何正确的在Android中存储特定应用文件
    如何正确的在Android中存储特定应用文件
    问题解决:listview多次调用addHeaderView和addFooterView
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7284713.html
Copyright © 2011-2022 走看看