当前位置: 首页 > 工业电子产品 > 其他电子产品 > 开发板,套件,编程器 > 开发板

类型分类:
科普知识
数据分类:
开发板

移植OpenWRT下的ART驱动程序

发布日期:2022-10-14 点击率:34

For English speaking readers, please visit: https://www.witimes.com/openwrt-porting-art-en/

相信本站的大部分读者都知道OpenWRT与ART:OpenWRT是一款基于Linux的开源无线路由器系统,目前广泛应用于很多厂商的无线设备;ART是Atheros Radio Test的简写,用于测试各种基于Qualcomm Atheros芯片设备的射频指标。近期有朋友寻求OpenWRT中的ART驱动程序, 笔者费了九牛二虎之力终于将其搞定,在此做简要总结,以便后续查阅。

1. 基于已有经验,移植ART驱动程序必须指定相应的内核路径与Toolchain路径,修改makefile.artmod如下

KDIR := /home/tom/openwrt/trunk/build_dir/target-mips_34kc_uClibc-0.9.33.2/linux-ar71xx_generic/linux-3.18.7

PWD := $(shell pwd)

ROOTDIR := $(PWD)/modules

# Default architecture is MIPS

ARC :=mips

CROSS_CC :=/home/tom/openwrt/trunk/staging_dir/toolchain-mips_34kc_gcc-4.8-linaro_uClibc-0.9.33.2/bin/mips-openwrt-linux-uclibc-

2. 未作任何代码的更改情况下,开始编译。

3. 出现error: unknown field 'ioctl' specified in initializer,此前在移植i.MX6 ART驱动程序时已经遇到过类似问题,在https://www.witimes.com/imx6-porting-art/一文中有介绍,修改modules/dk_func.c中dk_fops结构体中的ioctl为compat_ioctl,再次编译未报出ioctl的错误。

3. 出现error: 'SPIN_LOCK_UNLOCKED' undeclared here (not in a function),修改modules/dk_event.c中的

spinlock_t driver_lock = SPIN_LOCK_UNLOCKED;

DEFINE_SPINLOCK(driver_lock);

4. 再次编译,顺利通过,在modules目录下出现了art.ko。

5. 将art.ko上传至web服务器,并使用wget命令下载至DUT中,并使用insmod art.ko命令插入内核模块并运行nart.out,未出现任何异常。

6. 使用artgui Load DUT,出现如下错误:

deviceInit devIndex=0 device_fn=0 pdkInfo=0

Opening device /dev/dk0

Error: get version ioctl failed !

< 6006 ERROR Anwi driver load error.

< 7502 CONTROL OFF

< 7504 INFO |set|devid||

< 7504 INFO |set|mac||

< 7504 INFO |set|customer||

< 7506 CONTROL DONE load devid=-1; caldata=auto;

截图如下

ioctl-Error

7. 又出现了可怕的错误“Error: get version ioctl failed !”,这个错误曾在我移植i.MX6 ART驱动程序时折磨了我很多天,同样记录在https://www.witimes.com/imx6-porting-art/一文中,当时更换为高版本ART后问题得到解决,然而这一次我采用同样方法却完全不奏效。既然无法避开,那就正面面对,彻查此问题。

8. 查看高版本ART代码modules/dk_func.c中的dk_fops结构体,如下

#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,31)
static long dk_ioctl_new(struct file *file, unsigned int cmd, unsigned long arg)
{
        struct inode *inode = file->f_path.dentry->d_inode;
        long ret;
        ret = dk_ioctl(inode, file, cmd, arg);
        return ret;
}
#endif

发现其定义了一个新的ioctl,在内核版本高于2.6.31时生效。

9. 此处引用自:http://blog.csdn.net/cbl709/article/details/7295772

今天调一个程序调了半天,发现应用程序的ioctl的cmd参数传送到驱动程序的ioctl发生改变。而根据《Linux设备驱动》这个cmd应该是不变的。因为在Kernel 2.6.36 中已经完全删除了struct file_operations 中的ioctl 函数指针,取而代之的是unlocked_ioctl ,所以我怀疑二者是不是兼容的。上网查了一些资料,很多文章只是泛泛谈了一下,说在应用程序中ioctl是兼容的,不必变化。而在驱动程序中这个指针函数变了之后最大的影响是参数中少了inode ,所以应用程序ioctl是兼容的,但驱动程序中我们的ioctl函数必须变化,否则就会发生cmd参数的变化。

10. 仿照这段代码,将低版本ART代码modules/dk_func.c中的dk_fops结构体作出修改,如下

static long dk_ioctl_new(struct file *file, unsigned int cmd, unsigned long arg)
{
        struct inode *inode = file->f_path.dentry->d_inode;
        long ret;
        ret = dk_ioctl(inode, file, cmd, arg);
        return ret;
}

static struct file_operations dk_fops = {
        owner:  THIS_MODULE,
        open:   dk_open,
        release: dk_release,
        mmap:   dk_mmap,
	unlocked_ioctl: dk_ioctl_new
};

11. 再次编译,下载至DUT,并使用artgui Load DUT,一切正常。

Final-OK

下一篇: PLC、DCS、FCS三大控

上一篇: Allegro PCB设计模板

推荐产品

更多