荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: georgehill (佐治·希尔), 信区: Linux
标  题: RTLinux简介(2)
发信站: BBS 荔园晨风站 (Thu Jan 13 22:37:31 2000), 转信

发信人: 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;
}

--
※ 来源:·BBS 水木清华站 smth.org·[FROM: 39_38.xjtu.edu.]
--

     书山有路勤为径;
     学海无涯苦作舟!

         欢迎各位光临Linux版!
 我是来自大富翁的小美!^_^

※ 来源:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.115]


[回到开始] [上一篇][下一篇]

荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店