本帖最后由 jlass 于 2013-5-9 15:32 编辑
硬件整完了,开始整软件了,这里我只说一下GPMC的测试,其他类似的直接参考就是了。
这是网上某个大牛的**,很有参考意义。
http://blog.chinaunix.net/uid-730738-id-3266709.html
废话不多说,开始吧,先是内核的改动
1、函数释出
在arch/arm/mach-omap2/gpmc.c文件里的gpmc_cs_write_reg与gpmc_cs_read_reg函数之后分别加上
EXPORT_SYMBOL(gpmc_cs_write_reg);
EXPORT_SYMBOL(gpmc_cs_read_reg);
这样的话你的驱动就可以调用他们了。如果你还想调用其他函数的话,请参考这两个函数的处理,另外,不要忘了去arch/arm/plat-omap/include/plat/gpmc.h文件里声明一下。
2、引脚定义
比如定义gpmc_ad10,写法如下
{"gpmc_ad10.gpmc_ad10", OMAP_MUX_MODE0 | AM33XX_PIN_INPUT_PULLUP},
当内核加载时出现错误,显示"gpmc_ad10.gpmc_ad10"不存在时,请去arch/arm/mach-omap2/mux33xx.c文件里完善一下下面的语句。
_AM33XX_MUXENTRY(GPMC_AD10, 0, "gpmc_ad10", "lcd_data18", "mmc1_dat2", "mmc2_dat6", NULL, NULL, NULL, "gpio0_26"),
很明显gpmc_ad10已经存在了,但是还有三个NULL,如果你刚好使用到的话就会报错,请花点时间去完善一下。
引脚定义完成后请使用setup_pin_mux设定,并放到init函数里自动执行。
3、驱动部分
因为我以前一直使用的是2.6的核,所以简单说明一下3.0以上版本的核与2.6的区别,具体的可以去网上查看
ioctl变成unlocked_ioctl,并且inode参数省去了
init_MUTEX(******)变成sema_init(******,1)
4、测试代码
反正每个公司都有自己的风格,具体的代码我直接放附件好了,这里说一下遇到的问题
问题一:驱动加载时显示XXX函数没定义,编译的时候也报XXX函数没定义
在内核里把需要使用的函数前面的static删除,再在其后加上EXPORT_SYMBOL(***),并在gpmc.h文件里声明成extern。
重新编译内核,把新编译的内核烧到板子里去
问题二:驱动加载时显示XXX函数没定义,但是编译的时候却没报
在驱动文件里添加这一句
MODULE_LICENSE("Dual BSD/GPL");
问题三:想查看0x10000000地址的数据,使用(*((volatile unsigned int*)(0x100000000)))语句直接返回段错误。
估计3.0以上版本的内核已近不允许直接的地址读写了,要使用gpmc_cs_request申请一块内存,然后用ioremap重映射一下。我这里映射之后的地址为0xD2020000,然后使用(*((volatile unsigned int*)(0xD2020000)))语句就可以了。当然,你也可以调用readb,readw,readl函数,效果是一样的。
问题四:地址线A0~A11有效,A12以上的无效。
GPMC_CONFIG的bit2位的限制,默认是1,写成0就可以了
问题五:驱动加载第一次可以,第二次就不行了
每次request之后,记得要用free释放一下
问题六:使用wait线写数据,芯片卡死
经过多次测试后发现当使用intel模式的时候是可以的,但是使用motorola模式时,芯片会卡死,也就是说使用wait线时,片选必须比写要宽,否则芯片就会卡死。
所以,当要和motorola模式连接时,不能使用片选线直连,而应该使用ADV线与对端的片选线相连,AM335x的片选线可以悬空。(注:由于环境所限,我没有测试过,但应该是可行的)
因为motorola模式是不连接RD线的,所以读没有影响。
(问题七由热心网友yi215415提供)
问题七:调用gpmc_write_reg等函数时,显示段错误
由于内核初始化时omap_init_gpmc函数未调用所致,加入即可。
注:如果支持nand的板子,这个函数在nand的初始化中已经调用了,对于不支持nand的板子,需要特别注意此问题。
声明:附件中的代码仅为测试使用,由于个人环境的不同需要自己做一些修改,如果由于代码写的太烂而引起的不快,不爽,甚至不举,本人不负任何责任。
|