BBS水木清华站∶精华区

发信人: xog (雪剑心), 信区: Linux        
标  题: RTLinux简介(2) 
发信站: BBS 水木清华站 (Thu Jan 13 19:45:43 2000) 
 
1.3 中断处理 
   RTLinux 中重写了Linux中断处理过程,当程序用cli屏蔽中断时,RTLinux只是清软 
中断表的全局标志,并不影响中断的发生。当中断发生时,实时核心接收中断,进行实 
时处理工作后,把中断控制权传给Linux核心,并产生软返回,如无其他软中断,则中 
断返回,否则由Linux处理最高优先级中断。因此可以看出,Linux程序的屏蔽中断 
(cli)并不能影响实时中断的发生,实时中断的延迟时间也完全由实时核心的处理速 
度决定。 
1.4 RTLinux 应用程序结构分析 
   设计RTLinux的应用程序,应首先分析应用系统的特点,把应用中实时要求最高的部 
分和普通的处理部分分开,前者代码应尽可能短,对系统资源要求少,可把此部分用实 
时任务实现,剩余部分仍由普通Linux完成,可进行网络、图形界面等实时要求不高,占 
用系统资源较大的工作。RTLinux的实时任务模块采用Linux的可装载模块(Loadable  
modules)技术实现,可实现动态的加载和删除。 
1.4.1 RTLinux的实时进程和Linux普通进程的IPC机制 
   RTLinux的实时进程和Linux普通进程之间通过RT-fifo通信。 
   以下例程中,共定义了三个fifo,其中两个为数据fifo,一个为控制命令fifo,两个 
实时任务分别向两个fifo发送数据,而在主程序中由普通的进程接收数据并打印。实时 
任务在可装载模块中实现,代码如下: 
#include <linux/module.h> 
#include <linux/kernel.h> 
#include <linux/version.h> 
#include <linux/errno.h> 
#include <linux/cons.h> 
#include <rtl_sched.h> /*所有的实时程序必须包含RTLinux的头文件*/ 
#include <rtl_fifo.h> 
#include "control.h"  /*自定义的fifo消息结构和命令*/ 
RT_TASK tasks[2];    /*定义两个实时任务变量*/ 
static char *data[] = {"xgl_1 ", "xgl_2 "};/*定义实时任务要发送的数据*/ 
                                           /*数据必须静态分配,实时任务不可访 
 
                                            问动态内存*/ 
/* t -- the fifo number */ 
/*实时任务的程序代码,实现向fifo发送数据的功能*/ 
void fun(int t) { 
 while (1) { 
  rtf_put(t, data[t - 1], 6); 
  rt_task_wait();           /*发送完数据后等待下次调度*/ 
 } 

/*每次向fifo写入数据时,可定义自动处理函数,由系统自动调用,当主程序向命令fi 
fo 
发送命令时,由系统自动调用以下处理函数处理命令*/ 
int my_handler(unsigned int fifo) 

 struct my_msg_struct msg; 
 int err; 
 RTIME now; 
        while ((err = rtf_get(3, &msg, sizeof(msg))) == sizeof(msg)) { 
         switch (msg.command) { 
   case START_TASK:/*启动实时任务*/ 
          now = rt_get_time(); 
   rt_task_make_periodic(&tasks[msg.task], now, msg.period); 
   break; 
   case STOP_TASK:/*停止实时任务*/ 
          rt_task_suspend(&tasks[msg.task]); 
   break; 
   default: 
   return -EINVAL; 
  } 
 } 
 if (err != 0) { 
  return -EINVAL; 
 } 
 return 0; 

int init_module(void) /*可装载模块初始化,当装载时自动执行*/ 

 int c[3]; 
 rtf_destroy(1); /*删除旧的fifo*/ 
 rtf_destroy(2); 
 rtf_destroy(3); 
  c[0] = rtf_create(1, 4000);/*初始化三个RT-fifo*/ 
 c[1] = rtf_create(2, 4000); 
 c[2] = rtf_create(3, 100);  /* input control channel */ 
 printk("Fifo return 1=%d 2=%d 3=%d\n",c[0],c[1],c[2]); 
 rt_task_init(&tasks[0], fun, 1, 3000, 4);/*实时任务初始化*/ 
 rt_task_init(&tasks[1], fun, 2, 3000, 5); 
 rtf_create_handler(3, &my_handler); /*指定fifo处理函数*/ 
 return 0; 

void cleanup_module(void) /*模块删除处理*/ 

 rtf_destroy(1);   /*删除fifo*/ 
 rtf_destroy(2); 
 rtf_destroy(3); 
 rt_task_delete(&tasks[0]);/*删除任务*/ 
 rt_task_delete(&tasks[1]); 

主程序代码如下: 
............ 
#include <rtl_fifo.h> 
#include <rtl_time.h> 
#include "control.h" 
#define BUFSIZE 70 
char buf[BUFSIZE]; 
int main() 

 fd_set rfds; 
        struct timeval tv; 
        int retval; 
 int fd0, fd1, ctl; 
 int n; 
 int i; 
 struct my_msg_struct msg; 
 /*打开第一个fifo数据缓冲*/ 
 if ((fd0 = open("/dev/rtf1", O_RDONLY)) < 0) { 
  fprintf(stderr, "Error opening /dev/rtf1\n"); 
  exit(1); 
 } 
       /*打开第二个fifo数据缓冲*/ 
 if ((fd1 = open("/dev/rtf2", O_RDONLY)) < 0) { 
  fprintf(stderr, "Error opening /dev/rtf2\n"); 
  exit(1); 
 } 
       /*打开fifo控制缓冲*/ 
 if ((ctl = open("/dev/rtf3", O_WRONLY)) < 0) { 
  fprintf(stderr, "Error opening /dev/rtf3\n"); 
  exit(1); 
 } 
 /* 发送启动实时任务命令 */ 
 msg.command = START_TASK; 
 msg.task = 0; 
 msg.period = 500000; 
        /*向控制fifo写入启动命令*/ 
 if (write(ctl, &msg, sizeof(msg)) < 0) { 
  fprintf(stderr, "Can't send a command to RT-task\n"); 
  exit(1); 
 } 
 msg.task = 1; 
 msg.period = 200000; 
 if (write(ctl, &msg, sizeof(msg)) < 0) { 
  fprintf(stderr, "Can't send a command to RT-task\n"); 
  exit(1); 
 } 
        /*读取数据fifo中的数据并打印*/ 
 for (i = 0; i < 100; i++) { 
  FD_ZERO(&rfds); 
  FD_SET(fd0, &rfds); 
  FD_SET(fd1, &rfds); 
  tv.tv_sec = 1; 
  tv.tv_usec = 0; 
  retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); 
  if (retval > 0) { 
   if (FD_ISSET(fd0, &rfds)) { 
    n = read(fd0, buf, BUFSIZE - 1); 
    buf[n] = 0; 
    printf("FIFO 1: %s\n", buf); 
   } 
   if (FD_ISSET(fd1, &rfds)) { 
    n = read(fd1, buf, BUFSIZE - 1); 
    buf[n] = 0; 
    printf("FIFO 2: %s\n", buf); 
   } 
  } 
 } 
 fprintf(stderr, "frank_app: now sending commands to stop RT-tasks\n"); 
 /* 停止实时任务 */ 
 msg.command = STOP_TASK; 
 msg.task = 0; 
 if (write(ctl, &msg, sizeof(msg)) < 0) { 
  fprintf(stderr, "Can't send a command to RT-task\n"); 
  exit(1); 
 } 
 msg.task = 1; 
 if (write(ctl, &msg, sizeof(msg)) < 0) { 
  fprintf(stderr, "Can't send a command to RT-task\n"); 
  exit(1); 
 } 
 return 0; 

 
-- 
※ 修改:·linuxrat 於 Jan 14 12:12:46 修改本文·[FROM: 202.112.168.253] 
※ 来源:·BBS 水木清华站 smth.org·[FROM: 39_38.xjtu.edu.] 

BBS水木清华站∶精华区