首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

linux任务响应模型&linux实时化&RTAI 3.2分析&Adeos分析(4)

linux任务响应模型&linux实时化&RTAI 3.2分析&Adeos分析(4)

---------------
RTAI中断处理
RTAI的中断处理入口是rtai_irq_trampoline,这是在RTAI的初始化过程中向Adeos注册的。它完成的功能很简单,就是根据中断号调用相应的RTAI中断处理程序,当RTAI没有注册某个中断的中断服务程序时,它会通过调用Adeos接口函数adeos_propagate将这个中断沿着Adeos中断管道传递到下一个低优先级的域。
RTAI的中断管理信息保存在结构变量rtai_realtime_irq中,其定义如下:

struct {
    rt_irq_handler_t handler;
    void *cookie;
    int retmode;
} rtai_realtime_irq[NR_IRQS]

每一个中断对应这数组rtai_realtime_irq中的一个元素,其中,handler用于保存中断处理函数,cookie用于保存传递给中断处理函数的特殊信息;retmode在基于ARM的实现中没有用到。
另外,RTAI提供三个函数用于中断请求、中断释放和cookie的设置,它们分别是rt_request_irq,rt_release_irq,rt_set_irq_cookie。

--------------------
时钟中断服务程序
RTAI的时钟中断服务程序rt_timer_handler位于文件rtai-3.2/base/sched/sched.c中,每当系统时钟中断发生的时候,它就处理RTAI中与时钟相关的信息,并有可能进行任务的调度,它类似于Linux中的do_timer函数。它完成的主要功能如下:
1.更新系统的时间信息,RTAI将系统的时间信息保存在结构变量rt_times中,它的结构定义如下:

struct rt_times {
        int linux_tick;
        int periodic_tick;
        RTIME tick_time;
        RTIME linux_time;
        RTIME intr_time;
};

其中,linux_tick表示Linux的一个系统周期(Linux每秒的系统周期数为HZ)所需的时钟的嘀嗒数;periodic_tick表示RTAI所设置的时钟(定时器)的的运行周期(也就是定时器每计数periodic_tick次就产生一次时钟中断);tick_time表示上一次时钟中断产生时系统所经过的时钟嘀嗒数;linux_time表示下次Linux时钟中断应该产生的时间(以时钟嘀嗒数为单位);intr_time表示下次RTAI时钟中断应该产生的时间。
2.调用wake_up_timed_tasks唤醒RTAI中的超时任务,并调用宏RR_YIELD和TASK_TO_SCHEDULE找到下一个应该被调度运行的任务。
3.根据时钟的运行模式(单触发模式或周期模式)更新系统时间信息,并对定时器进行相应的设置。
4.根据需要进行任务的重新调度。

-----------------
实时任务的管理
在RTAI中,一个实时任务的生成一般包括任务创建、设置定时器、启动时实任务几个阶段,下面就这几个方面进行分析。
1        实时任务创建
实时任务的创建主要完成对代表实时任务实体的任务结构变量的初始化操作,包括分配任务栈、初始化任务栈、初始化链表指针等。任务的初始化操作最终由函数int rt_task_init_cpuid(RT_TASK *task, void (*rt_thread)(int), int data,int stack_size, int priority, int uses_fpu, void(*signal)(void),unsigned intcpuid)来完成。参数列表中的task是指向任务结构变量的指针,这个结构变量应该在初始化任务之前由任务的创建者分配;rt_thread是一个函数指针,指向代表任务的函数,参数列表中的data则是传递给这个函数的参数;stack_size指明任务所需的任务栈大小,priority指明任务的优先级,uses_fpu指明任务是否使用FPU;signal是一个函数指针,它所指向的函数在任务切换的时候被调度,它的调用方式有点类似于Linux中的信号;而cpuid则指明在多处理器系统中优先考虑将任务放在某个处理器上运行。
函数rt_task_init_cpuid的定义在文件rtai-3.2/base/sched/sched.c中,它完成的主要功能如下:
1.调用sched_malloc分配任务栈;
2.初始化任务结构变量(task所指向的RT_TASK结构)内的字段;
3.调用init_arch_stack为任务的首次运行准备任务栈内容;
4.将任务加入实时任务列表;
一个实时任务的绝大部分属性都保存在实时任务的RT_TASK结构变量中,下面对这个结构进行简要的说明。

typedef struct rt_task_struct {

    int *stack __attribute__ ((__aligned__ (L1_CACHE_BYTES)));
    int uses_fpu;
    int magic;
    volatile int state, running;
    unsigned long runnable_on_cpus;
    int *stack_bottom;
    volatile int priority;
    int base_priority;
    int policy;
    int sched_lock_priority;
    struct rt_task_struct *prio_passed_to;
    RTIME period;
    RTIME resume_time;
    RTIME yield_time;
    int rr_quantum;
    int rr_remaining;
    int suspdepth;
    struct rt_queue queue;
    int owndres;
    struct rt_queue *blocked_on;
    struct rt_queue msg_queue;
    int tid;        /* trace ID */
    unsigned msg;
    struct rt_queue ret_queue;
    void (*signal)(void);
    FPU_ENV fpu_reg __attribute__ ((__aligned__ (L1_CACHE_BYTES)));
    struct rt_task_struct *prev;
    struct rt_task_struct *next;
    struct rt_task_struct *tprev;
    struct rt_task_struct *tnext;
    struct rt_task_struct *rprev;
    struct rt_task_struct *rnext;
继承事业,薪火相传
返回列表