📄 00000002.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER>发信人: xog (雪剑心), 信区: Linux <BR>标 题: RTLinux简介(2) <BR>发信站: BBS 水木清华站 (Thu Jan 13 19:45:43 2000) <BR> <BR>1.3 中断处理 <BR> RTLinux 中重写了Linux中断处理过程,当程序用cli屏蔽中断时,RTLinux只是清软 <BR>中断表的全局标志,并不影响中断的发生。当中断发生时,实时核心接收中断,进行实 <BR>时处理工作后,把中断控制权传给Linux核心,并产生软返回,如无其他软中断,则中 <BR>断返回,否则由Linux处理最高优先级中断。因此可以看出,Linux程序的屏蔽中断 <BR>(cli)并不能影响实时中断的发生,实时中断的延迟时间也完全由实时核心的处理速 <BR>度决定。 <BR>1.4 RTLinux 应用程序结构分析 <BR> 设计RTLinux的应用程序,应首先分析应用系统的特点,把应用中实时要求最高的部 <BR>分和普通的处理部分分开,前者代码应尽可能短,对系统资源要求少,可把此部分用实 <BR>时任务实现,剩余部分仍由普通Linux完成,可进行网络、图形界面等实时要求不高,占 <BR>用系统资源较大的工作。RTLinux的实时任务模块采用Linux的可装载模块(Loadable <BR>modules)技术实现,可实现动态的加载和删除。 <BR>1.4.1 RTLinux的实时进程和Linux普通进程的IPC机制 <BR> RTLinux的实时进程和Linux普通进程之间通过RT-fifo通信。 <BR> 以下例程中,共定义了三个fifo,其中两个为数据fifo,一个为控制命令fifo,两个 <BR>实时任务分别向两个fifo发送数据,而在主程序中由普通的进程接收数据并打印。实时 <BR>任务在可装载模块中实现,代码如下: <BR>#include <linux/module.h> <BR>#include <linux/kernel.h> <BR>#include <linux/version.h> <BR>#include <linux/errno.h> <BR>#include <linux/cons.h> <BR>#include <rtl_sched.h> /*所有的实时程序必须包含RTLinux的头文件*/ <BR>#include <rtl_fifo.h> <BR>#include "control.h" /*自定义的fifo消息结构和命令*/ <BR>RT_TASK tasks[2]; /*定义两个实时任务变量*/ <BR>static char *data[] = {"xgl_1 ", "xgl_2 "};/*定义实时任务要发送的数据*/ <BR> /*数据必须静态分配,实时任务不可访 <BR> <BR> 问动态内存*/ <BR>/* t -- the fifo number */ <BR>/*实时任务的程序代码,实现向fifo发送数据的功能*/ <BR>void fun(int t) { <BR> while (1) { <BR> rtf_put(t, data[t - 1], 6); <BR> rt_task_wait(); /*发送完数据后等待下次调度*/ <BR> } <BR>} <BR>/*每次向fifo写入数据时,可定义自动处理函数,由系统自动调用,当主程序向命令fi <BR>fo <BR>发送命令时,由系统自动调用以下处理函数处理命令*/ <BR>int my_handler(unsigned int fifo) <BR>{ <BR> struct my_msg_struct msg; <BR> int err; <BR> RTIME now; <BR> while ((err = rtf_get(3, &msg, sizeof(msg))) == sizeof(msg)) { <BR> switch (msg.command) { <BR> case START_TASK:/*启动实时任务*/ <BR> now = rt_get_time(); <BR> rt_task_make_periodic(&tasks[msg.task], now, msg.period); <BR> break; <BR> case STOP_TASK:/*停止实时任务*/ <BR> rt_task_suspend(&tasks[msg.task]); <BR> break; <BR> default: <BR> return -EINVAL; <BR> } <BR> } <BR> if (err != 0) { <BR> return -EINVAL; <BR> } <BR> return 0; <BR>} <BR>int init_module(void) /*可装载模块初始化,当装载时自动执行*/ <BR>{ <BR> int c[3]; <BR> rtf_destroy(1); /*删除旧的fifo*/ <BR> rtf_destroy(2); <BR> rtf_destroy(3); <BR> c[0] = rtf_create(1, 4000);/*初始化三个RT-fifo*/ <BR> c[1] = rtf_create(2, 4000); <BR> c[2] = rtf_create(3, 100); /* input control channel */ <BR> printk("Fifo return 1=%d 2=%d 3=%d\n",c[0],c[1],c[2]); <BR> rt_task_init(&tasks[0], fun, 1, 3000, 4);/*实时任务初始化*/ <BR> rt_task_init(&tasks[1], fun, 2, 3000, 5); <BR> rtf_create_handler(3, &my_handler); /*指定fifo处理函数*/ <BR> return 0; <BR>} <BR>void cleanup_module(void) /*模块删除处理*/ <BR>{ <BR> rtf_destroy(1); /*删除fifo*/ <BR> rtf_destroy(2); <BR> rtf_destroy(3); <BR> rt_task_delete(&tasks[0]);/*删除任务*/ <BR> rt_task_delete(&tasks[1]); <BR>} <BR>主程序代码如下: <BR>............ <BR>#include <rtl_fifo.h> <BR>#include <rtl_time.h> <BR>#include "control.h" <BR>#define BUFSIZE 70 <BR>char buf[BUFSIZE]; <BR>int main() <BR>{ <BR> fd_set rfds; <BR> struct timeval tv; <BR> int retval; <BR> int fd0, fd1, ctl; <BR> int n; <BR> int i; <BR> struct my_msg_struct msg; <BR> /*打开第一个fifo数据缓冲*/ <BR> if ((fd0 = open("/dev/rtf1", O_RDONLY)) < 0) { <BR> fprintf(stderr, "Error opening /dev/rtf1\n"); <BR> exit(1); <BR> } <BR> /*打开第二个fifo数据缓冲*/ <BR> if ((fd1 = open("/dev/rtf2", O_RDONLY)) < 0) { <BR> fprintf(stderr, "Error opening /dev/rtf2\n"); <BR> exit(1); <BR> } <BR> /*打开fifo控制缓冲*/ <BR> if ((ctl = open("/dev/rtf3", O_WRONLY)) < 0) { <BR> fprintf(stderr, "Error opening /dev/rtf3\n"); <BR> exit(1); <BR> } <BR> /* 发送启动实时任务命令 */ <BR> msg.command = START_TASK; <BR> msg.task = 0; <BR> msg.period = 500000; <BR> /*向控制fifo写入启动命令*/ <BR> if (write(ctl, &msg, sizeof(msg)) < 0) { <BR> fprintf(stderr, "Can't send a command to RT-task\n"); <BR> exit(1); <BR> } <BR> msg.task = 1; <BR> msg.period = 200000; <BR> if (write(ctl, &msg, sizeof(msg)) < 0) { <BR> fprintf(stderr, "Can't send a command to RT-task\n"); <BR> exit(1); <BR> } <BR> /*读取数据fifo中的数据并打印*/ <BR> for (i = 0; i < 100; i++) { <BR> FD_ZERO(&rfds); <BR> FD_SET(fd0, &rfds); <BR> FD_SET(fd1, &rfds); <BR> tv.tv_sec = 1; <BR> tv.tv_usec = 0; <BR> retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); <BR> if (retval > 0) { <BR> if (FD_ISSET(fd0, &rfds)) { <BR> n = read(fd0, buf, BUFSIZE - 1); <BR> buf[n] = 0; <BR> printf("FIFO 1: %s\n", buf); <BR> } <BR> if (FD_ISSET(fd1, &rfds)) { <BR> n = read(fd1, buf, BUFSIZE - 1); <BR> buf[n] = 0; <BR> printf("FIFO 2: %s\n", buf); <BR> } <BR> } <BR> } <BR> fprintf(stderr, "frank_app: now sending commands to stop RT-tasks\n"); <BR> /* 停止实时任务 */ <BR> msg.command = STOP_TASK; <BR> msg.task = 0; <BR> if (write(ctl, &msg, sizeof(msg)) < 0) { <BR> fprintf(stderr, "Can't send a command to RT-task\n"); <BR> exit(1); <BR> } <BR> msg.task = 1; <BR> if (write(ctl, &msg, sizeof(msg)) < 0) { <BR> fprintf(stderr, "Can't send a command to RT-task\n"); <BR> exit(1); <BR> } <BR> return 0; <BR>} <BR> <BR>-- <BR>※ 修改:·linuxrat 於 Jan 14 12:12:46 修改本文·[FROM: 202.112.168.253] <BR>※ 来源:·BBS 水木清华站 smth.org·[FROM: 39_38.xjtu.edu.] <BR><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -