基于Linux的嵌入式工业测控系统
1、前言 随着嵌入式工业测控系统/linux网络控制技术的快速发展,工业以太网得到逐步完善,在工业控制领域获得越来越广泛的应用。工业以太网使用了tcp/ip协议,便于联网,并具有高速控制网络的嵌入式工业测控系统/linux优点。随着32位嵌入式cpu价格的下降,性能指标的提高,为嵌入式系统的广泛应用和linux在嵌入式系统中的发展提供了广阔的空间。由于linux的高度灵活性,可以容易地根据应用领域的特点对它进行定制开发,以满足实际应用需要。 2、基于linux的嵌入式系统在测控系统中的设计 计算机测控系统本质上嵌入式工业测控系统/linux就是计算机控制系统,为了对被控对象实施控制,对其参数和状态进行检测是必不可少的。 2.1 测控系统整体设计 测控系统以基于linux的嵌入式嵌入式工业测控系统/linux系统为核心,应用程序可通过网络进行更新,通过键盘进行人机对话,数据可通过lcd现场显示。重要数据可以件形式保存在flash存储器中,数据和报警信息还可通过串口向上位机传输,也可通过以太网口向inernet发布信息。用户通过显示界面查看设备状态,设置设备参数,实现远程嵌入式工业测控系统/linux监控、远程维护。 2.2 总体框图
图2-1 嵌入式系统总体框图 2.3 嵌入式系统硬件设计 2.3.1 硬件框图 考虑一般测控系统对嵌入式系统嵌入式工业测控系统/linux要求比较多的功能有:键盘接口、显示接口、a/d(或d/a)转换单元、可扩展的uo接口、打印机接口、与pc机通信的串行接口、以太网口等。实现的嵌入式系统硬件框图如图2-2所示:
图2-2 嵌入式系统硬件框图 2.3.2 linux下设备驱动程序的开发 linux系统中,内核提供保护机制,用户空间的进程一般不能直接访问硬件。linux设备被抽象出来,所有设备都看成文件。用户进程通过文件系统的接口嵌入式工业测控系统/linux访问设备驱动程序,设备驱动程序主要完成如下功能: ①探测设备和初始化设备;②从设备接受数据并提交给内核;③从内核接受数据送到设备;④检测和处理设备错误。 3、基于 rtai-linux的嵌入式系统的软件实现 3.1 rtai实时硬件抽象层的实现机理 引入嵌入式工业测控系统/linux新的数据结构rt_hal,形成了实时硬件抽象层rthal(real time hardware abatract layer),rt_hal结构体的定义如下: struct rt_hal { struct desc_struct*idt table; void(*disint)(void); void(*enint)(void); unsigned int(*getflags)(void); void(*setflags)(unsigned int flags); void(*mask_and_ack_8259a)(unsigned int irq); void(*unmask_8259a_irq)(unsigned int irq); void(*ack_apic_irq)(void); void(*mask_io_apic_irq)(unsigned int irq); void(*unmask_i0_apic_irq)(unsigned int irq); unsigned long *io_apic_irgs; void*irq_controller_lock; void*irq_desc; int *irq_vector; void *irq_2_pin; void* ret_from_intr; struct desc_struct *gdt_table; volatile int*idle_weight; void (*lxrt_cli)(void); }; 在usr/src/linux/arch/i386/kernel/irq.c中初始化为rthal: struct rt_hal rthal { idt_table, /*中断向量表*/ linux_cli, /*关中断函数*/ linux_sti, /*开中断函数*/ linux_save_flags, /*保存中断前的标志*/ linux_restore_flags, /*恢复中断前的标志*/ task_and_ack_8259a, /*中断屏蔽*/ enable_8259a_irq, /*中断使能*/ linux_ack_apic_irq, (), /*在io_apic.c文件中设置*/ &io_apic_irgs, &irq_controller_lock, irq_desc, irq_vector, (), /*在io_apic.c文件中设置*/ &ret_from_imr, gdt_table, /*全局描述符表*/ &idle_weight, () }; 初始化rthal时,指向函数的指针变量指向实现原来标准linux中开、关中断等功能的函数如下: static void linux_cli(void) { hard_cli(); } static void linux_sti(void) { hard_sti(); } static unsigned int linux_save_flags(void) { int flags; hard_save_flags(flags) turn flags } static void linux_restore_flags(unsigned int flags) { hard_restore_flags(flags); } 当加载rtai模块时,执行rt_mount_rtai函数如下: void rt_mountes_rtai(void) { rthal.disint=linux_cli; rthal.enint=linux_sti; rthal.getflags=linux_save_flags; rthal.setflags=linux_restore_flags; rthal.mask_and_ack_8259a=trpd_mask_and_ack_irq; rthal.unmask_8259a_irq=trpd_unmask_irq; } rthal中指向函数的指针变量指向了rtai中实现的同名函数,在rtai中实现的关中断函数如下: static void linux_cli(void) { processor[hard_cpu_id()].intr_flag=0; } 在rtai中引入新的数据结构processor,描述和中断有关的处理器的状态: static struct cpu_own_status { volatile unsigned int intr_flag; volatile unsigned int linux_intr_flag; volatile unsigned int pending_irqs; volatile unsigned int activ_irqs; } processor[nr_rt_cpus]; 当嵌入式工业测控系统/linux执行关中断时,只是将数据结构processor中的中断标志位intr_flag设为0,而不是真正的清除eflags寄存器的if标志来关中断,解决了linux中长期关中断的问题。 3.2 采用rtai增强linux实时性的实现 通过修改linux内核相关的源文件,形成实时硬件抽象层。执行insmod命令,挂载上提供实时服务的rtai,rtai_sched,rtai_fifos模块,得到如下信息: linux tick at 100hz calibrated cpu frequency 551268530hz calibrated 8254-timer-interrupt-to-scheduler latency 8000ns calibrated one shot setup time 3000ns module size used by rtai_sched 16608 0 unused rtai_fifos 33468 0 unused rtai 20728 1 (rati_sched rtai-fifos) 加载上应用程序需要的rtai模块后,就可以在rtai-linux环境下开发应用程序。 3.3 基于rtai-linux的应用程序的开发 针对工业测控系统的数据采集、数据处理、控制、通信等具体应用,将应用程序分为实时任务和非实时任务。实时任务利用rtai提供的api来开发,编写嵌入式工业测控系统/linux成内核模块,工作在linux的核心态。用户进程可利用linux操作系统提供的大量资源,进行tcp/ip网络通信,开发图形用户界面程序等。实时任务之间、实时任务和非实时任务之间可通过fifo队列和共享内存等方法通信。rtai-linux应用程序结构如图3-1所示。
图3-1 rtai-linux应用程序结构图 数据采集任务的实现在rt_process.c中的主要函数如下: static void data_collect() { rtf_put(fifo,&data_value,sizeof(data_value);/*将采集的数据放入实时fifo中*/ rt_task_wait_period(); } int int_module(void) rtime tick_period; rt_set_periodic_mode(); /*将定时器设置为周期模式*/ rt_task_init(&rt_task,data_collect,l,stack_size,task_priority,1,0);/*初始化数据采集任务*/ return () } void cleanup_module(void) { stop_rt_timer(); rtf_destroy(fifo); rt_task_de-lete(&rt_task); return; } 数据显示程序的实现在disaplay.c中的主要函数: int main(void) { if((fifo=open("/dev/rtf()",()_rdonly))<0) { fprintf(stderr,"error opening/dev/rtf()\n"); exit(1); } read(fifo,&data_value,sizeof(data_value));/*用户进程从实时fifo中读取数据*/ printf("data%f\n",data_value) }
4、结论 本文给出了一种应用于测控系统的基于linux的嵌入式系统的设计方案,能保证测控任务完成的实时性、可靠性,可以嵌入式工业测控系统/linux连到工业以太网,实现远程监控,在工业控制领域有很好的应用前景。 |


