linux下的dnw for 6410
一直还在6410上做裸机程序LCD,AC97,ucos做好可以烧到flash启动,这几天在做SD卡,winsow下的RVDS真是很垃圾,经常出错,以前搞LCD的时候就碰到过,把图片数组放到一个头文件编译没错,下载到内存就出错了,放到和主函数一起也没错,还有很多其他的问题一怒之下转战到linux下的gcc,但是这也出现一个麻烦问题,就是调试的时候不能像windows这么方便的用dnw下载到内存直接运行,本人电脑配置低了点所以没有装虚拟机而是装了双系统,这样来回转战两个系统之间很麻烦,刚开始就想到找linux版本的dnw,无奈都是2440的不能用,所以放弃了,串口下载好像也有问题。SD卡裸机是在windows下做的,搞了好几天现在又发现是编译器出问题了,同样的程序一会可以读一会不能读,写SD卡倒是后没出现问题,把中间的几个调试才用到的函数注释掉后也出现问题,被彻底激怒了,准备放弃windows平台而再次转入linux,第一个要解决的问题就是把程序如何下载到内存调试,还是找linux下的dnw再次实验还是失败,今天仔细想想,这个程序分为PC端驱动和应用程序,也因该和arm-linux上的驱动结构差不多的,所以想一探究竟改造一下。刚好这几天翻了翻linux下的驱动编写对驱动有了一点点认识,再结合dnw for linux里面的程序(其实就一个文件)里面有几个模块,几个模块都见过。static struct file_operations secbulk_fops = {
.owner = THIS_MODULE,
.read = secbulk_read,
.write = secbulk_write,
.open = secbulk_open,
.release= secbulk_release,
};无非就是这个文件结构体。还多了一个secbulk_probe(struct usb_interface *interface, const struct usb_device_id *id)
首先说一个出现的问题,编译后加载模块成功,但是运行dnw的时候却报错can't open /dev/seculk0,到dev下看看确实没有建立相应的设备节点,关于创建设备节点可以手动方法也可以自动,一般教程上都是手动方法,但是本人本着机器可以自动我就不手动的原则(说实话我是不知道这个设备应该归结到linux的那个里面去,所以不好手动创建)所以要改造一下源程序,刚好这几天看驱动编写的时候有一种方法可以在驱动加载的时候自动创建对应的文件节点,
定义一个struct class my_class
在初始化init函数中加上
my_class = class_create(THIS_MODULE, "my_class");
if(IS_ERR(my_class)) {
printk("Err: failed in creating class.\n");
return -1;
}
class_device_create(my_class, NULL, MKDEV(major_num, 0), NULL, “char_dev”);
注意的地方是major_num为主设备号char_dev为设备名后面补0,因为linux按照设备数量一次曾加命名的比如tty0,tty1在这里就是secbulk0
当然,在exit函数中要把创建的class移除:
class_destory(&xxx_dev->cdev);
class_device_desotry(my_class,MKDEV(major_num,0));
这样就不会出现can't open /dev/seculk0了。改造玩了就试试表面看一切还行可以加载dmesg也能看到信息。但是就是传不了数据,奇了怪了,继续看看源程序发现还有一个地方与我们平时写的驱动不同的是还多了一个结构
static struct usb_driver secbulk_driver= {
.name= "secbulk",
.probe= secbulk_probe,
.disconnect= secbulk_disconnect,
.id_table= secbulk_table,
.supports_autosuspend=0,
};(问题就是在这个结构体上)
还有一个static struct usb_device_id secbulk_table[]= {
{ USB_DEVICE(0x5345, 0x1234)},
{ }
};很眼熟,好像在移植u-boot的时候见到过,不同的flash要在那个表单中加入一些设备相关的信息类似ID号,在程序加载的时候自动读取芯片内部ID和这个相比较,没有注册的设备是不会被系统支持的,赶紧看看相关的资料发现确实有这么回事,linux上lsusb看到了SAMSUNG字样 ID出来了0xe48 0x1234,
改成这个,激动ing再编译,再加载(先把刚才那个卸载了)开两个终端,一个串口,一个用于加载,哈哈 看到熟悉的加载提示了 但是又出现问题了校验失败?dnw下的校验为0,跟板子上的不一样。再看看程序去,这个在驱动里面没有,找到应用软件的源程序发现有这么一行
for(i=8; i<file_stat.st_size+8; i++)
{
sum += file_buffer;
}
校验和在这,但是没发现有把这个校验值添加到文件中发出去的地方,这到底添加到哪儿又麻烦了,去找接受次文件的源程序看看在哪儿校验,果然找到了地方
void s3c_usb_verify_checksum(void)
{
u8 *cs_start, *cs_end;
u16 dnCS;
u16 checkSum;
printf("Checksum is being calculated.");
/* checksum calculation */
cs_start = (u8*)otg.dn_addr;
cs_end = (u8*)(otg.dn_addr+otg.dn_filesize-10);
checkSum = 0;
while(cs_start < cs_end) {
checkSum += *cs_start++;
if(((u32)cs_start&0xfffff)==0) printf(".");
}
dnCS = *(u16 *)cs_end;
if (checkSum == dnCS)
{
printf("\nChecksum O.K.\n");
}
else
{
printf("\nChecksum Value => MEM:%x DNW:%x\n",checkSum,dnCS);
printf("Checksum failed.\n\n");
}
}
我们看到的信息不就是这出来的吗Checksum O.K.\这是正常信息 ,Checksum failed这是错误信息dnCS = *(u16 *)cs_end;这就是校验值的位置,不在最前面而是放到最后面了,而且只给了两个字节,不知道是不是程序员偷懒,呵呵所以赶紧哪把dnw客户端的sum加到文件最后去看看。终于熟悉的界面有了
至此改造成功以后可以专心在linux下做了,不用来回折腾。源程序今天没传上去,有兴趣的可以借鉴着自己动手试试,如果没成功可以站内或者QQ联系我给你发一份(136687007)我也是新手慢慢学习中,一点点的成绩都能高兴一阵子,高手不要拍砖:lol
页:
[1]