linux任务响应模型&linux实时化&RTAI 3.2分析&Adeos分析(5)
- UID
- 1029342
- 性别
- 男
|
linux任务响应模型&linux实时化&RTAI 3.2分析&Adeos分析(5)
/* Appended for calls from LINUX. */
int *fun_args, *bstack;
struct task_struct *lnxtsk;
long long retval;
char *msg_buf[2];
int max_msg_size[2];
char task_name[16];
void *system_data_ptr;
struct rt_task_struct *nextp;
struct rt_task_struct *prevp;
/* Added to support user specific trap handlers. */
RT_TRAP_HANDLER task_trap_handler[RTAI_NR_TRAPS];
/* Added from rtai-22. */
void (*usp_signal)(void);
volatile unsigned long pstate;
unsigned long usp_flags;
unsigned long usp_flags_mask;
unsigned long force_soft;
volatile int is_hard;
void *trap_handler_data;
struct rt_task_struct *linux_syscall_server;
/* For use by watchdog. */
int resync_frame;
/* For use by exit handler functions. */
XHDL *ExitHook;
RTIME exectime[2];
struct mcb_t mcb;
/* Real time heaps. */
struct rt_heap_t heap[2];
} RT_TASK __attribute__ ((__aligned__ (L1_CACHE_BYTES)));
其中,stack用于保存实时任务的当前堆栈指针;uses_fpu表示任务是否使用FPU;magic用于标识这个结构是否是RT_TASK数据结构;字段state,running用于表示任务所处的状态;字段runnable_on_cpus用于表示任务当前运行的CPU;stack_bottom指向任务对栈的栈底;priority表示任务的当前优先级,由于优先级继承的机制存在,这个字段的指有可能会和base_prority的值不同;base_prority表示任务本身的优先级;字段prio_passed_to表示这个任务在优先级继承机制中将优先级传给了那个任务;字段period,resume_time,yield_time用于任务的调度;rr_quantum,rr_remaining用于同等优先级任务的时间片轮转调度;字段suspdepth用于记录任务被挂起的次数;字段signal保存任务的一个类似于Linux下的信号处理函数,这个函数在任务调度的时候会被调用;字段prev,next,tprev,tnext,rprev,rnext用于任务的队列管理;
2 实时任务定时器设置
在创建实时任务的过程中,主要通过3个函数对定时器进行设置,它们分别是:rt_set_oneshot_mode,rt_set_periodic_mode和start_rt_timer,下面分别对这3个函数进行分析。
rt_set_oneshot_mode用于将定时器设置为单触发模式,所谓单触发模式,就是说,每当定时器产生一次中断后,系统都要根据目前系统任务对时间精度的要求情况对定时器重新进行编程,设定下一次触发的时间。rt_set_oneshot_mode完成的功能如下:
1.调用stop_rt_timer停止定时器的运行;
2.设置全局变量oneshot_timer的值为1;在时钟中断函数中,系统会检查oneshot_timer的值,判断定时器的工作模式,然后根据定时器的模式对定时器进行相应的操作。
rt_set_periodic_mode的操作与rt_set_oneshot_mode的类似,只不过它将oneshot_timer的值设为0,表示定时器应工作在周期模式;当定时器工作在周期模式下时,系统只要对定时器进行一次初始化,指定定时器产生中断的周期,以后就不再需要对定时器进行编程了。
start_rt_timer根据设定的定时器运行模式对定时器进行初始化,它完成的主要功能如下:
1.调用函数rt_request_timer注册时钟中断服务程序rt_timer_handler;
2.初始化系统用于保存时间信息的结构rt_smp_times(就是前面所说的rt_times);
3.调用rt_request_linux_irq注册一个Linux下的中断服务程序recover_jiffies,这个中断程序和Linux的时钟中断服务程序共享时钟中断,recover_jiffies用于补偿Linux所丢失的时钟中断(因为可能由于实时任务的运行,使Linux很长一段时间得不到运行的机会,无法响应时钟中断)。
3 实时任务调度
实时任务的调度是通过函数rt_schedule完成的,这个函数完成的功能与rt_timer_handler完成的功能类似,它的定义在文件rtai-3.2/base/sched/sched.c中,它的主要功能如下:
1.通过调用函数wake_up_timed_tasks唤醒超时的任务;
2.调用宏RR_YIELD()和TASK_TO_SCHEDULE()找到下一个优先级最高的任务;
3.更新系统的时间相关信息rt_times;
4.根据需要,如果定时器工作在单触发模式,则根据系统时间要求对定时器进行编程;
5.如果下一个最高优先级的任务不是当前运行的任务,则进行任务切换; |
|
|
|
|
|