移植Linux的外围设备驱动到QNX系统中
花了半年时间在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;
}