移植Linux的外围设备驱动到QNX系统中

RopenYuan 2013-04-11

花了半年时间在QNX系统上,这是一个RTOS,这个系统是高安全级别的系统,在核物理站/天文空间站/电站/地铁/交通运输(飞机/汽车/地铁)等工业系统领域占有70%以上的市场份额。

背景:本文将我个人在QNX上移植内核和开发驱动以及应用程序的部分经验记录在此,因公司商业机密,部分源码不便公开。我会框架性的讲解开发思路。为了简化文章复杂性,我只讨论相同板子的平台驱动转移,我手中是at91sam9260-ek的板子。外部设备是公司硬件部单独添加的。

目的:利用已有的Linux驱动,简化QNX的驱动编写。

大致思路:Linux的驱动是基于模块的,每个驱动作为内核的扩展放进内存中,QNX的驱动就是一个进程,需要将模块改为一个应用程序。调整内核与驱动的通信机制。

以RTC驱动为例子:

Linux的驱动开发框架为:

1.填充read/write/ioctl/probe等驱动回调函数,设置对应的接口。

static struct file_operations rtc8025_fops = {
    .owner  = THIS_MODULE,
    .open    = rtc_open,
    .release = rtc_release,
    .read    = rtc_read,
    .write  = rtc_write,
    .ioctl  = rtc_ioctl,
 };
 2.编写每个部分的硬件相关代码。以write为例:
 
static ssize_t rtc_write(struct file *filp, __user const char  *buf,
                          size_t len,loff_t *ppos){
    char buff[16];
    VR_TIME *tm;
 
    tm = kmalloc(sizeof(VR_TIME),GFP_KERNEL);
    if ( NULL == tm ){
        printk("Memory error!\n");
        return -1;
    }
   
    if ( copy_from_user(buff, buf, len) )
        return -EFAULT;
    buff[len] = '\0';
   
    set_time_value(tm, buff);
    set_sys_time(tm);
    kfree(tm);
 
    return len;
 }