NanoPi M2 gpio驱动编写

来源:互联网 发布:虚拟机ubuntu如何分区 编辑:程序博客网 时间:2024/05/15 07:04

     作为一个新手第一个程序应该是hello world,第一个驱动肯定就是流水灯了哈,但是啊前两天虚拟机爆炸了。重装了一个64位的ubuntu,耽误了两天,今天下午刚装完开始写驱动,找资料又找了好久,各种心酸。觉得今天再不发帖子太对不起论坛和友善之臂的抬爱了,所以这一篇完成度有点低。
     比起来啊,看s5p4418的datesheet简直虐心,英文小白,一句一句度娘翻译的。今天刚写完驱动吧,还不知道对错,如果有错的地方明天试验之后回来改正,希望大家多指正。
    当然了,第一部是安装交叉编译环境,本来应该是很容易的事情哈,然而我整了整整1天多,已经哭晕了,借用一下友善的wiki
git clone https://github.com/friendlyarm/prebuilts.gitsudo mkdir -p/opt/FriendlyARM/toolchainsudo tar xf prebuilts/gcc-x64/arm-cortexa9-linux-gnueabihf-4.9.3.tar.xz-C /opt/FriendlyARM/toolchain/

然后将编译器的路径加入到PATH中,用vi编辑vi ~/.bashrc,在末尾加入以下内容:
export PATH=/opt/FriendlyARM/toolchain/4.9.3/bin:$PATHexport GCC_COLORS=auto


       这些大家都知道吧,然而我就不知道。。好了擦擦眼泪。。进入心碎的看手册环节。
       看一下盒子吧,谁让我蠢得都找不到m2的原理图呢,盒子上gpioc还是比较多的,当时我的想法就是,嗯先把gpioc都整成高电平,插个灯不就亮了么,好想法,就这么干。
 
然后开始懵逼的看原理图环节,似乎下面两个图就已经可以解决我的所有问题了呢(偷工减料就是方便,然而我蠢得把所有配置注册表看了一遍)
 
这个大概的意思好像是GPIOXOUT是管配置输入输出的,1输入0输出。GPIOXOUTENB是管初始状态高低电平的,0是低电平,1是高电平。(巴拉巴拉的,具体对不对我也不知道,而且这个基地址加偏移量我真的蒙了,等明天具体做出结果之后会在下一篇补充的)
这么一看好像明了的许多,我们的目的很简单,让GPIOCOUT和GPIOCOUTENB都等于0xffffffff。好像很简单的样子,不过我想说我之前用的是linux内核是2.6.22.6.你先让我哭一会,冷不丁换这么高版本的linux心贼慌。先包一堆头文件,管他有没有用呢,礼多人不怪。。
 
然后把协议写上,把大框弄出来,在往里加东西,对不对。
module_init(second_drv_init);

module_exit(second_drv_exit);

MODULE_LICENSE("GPL");


这样 有了入口函数和出口函数,就可以快乐的玩耍了。我们来先完善一下入口函数,在入口函数里我们先注册一个字符设备,告诉内核我有个东西要往你那里接一下
major = register_chrdev(0, "second_drv", &sencod_drv_fops);
然后一会在入口函数外面弄一个结构体,告诉内核,我这个设备都能干啥
static struct file_operations sencod_drv_fops = {
    .owner  =   THIS_MODULE,    /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
    .open   =   second_drv_open,     
        .read        =        second_drv_read,           
};

其实我这个驱动呢,我不想用读写的,没办法写上了就这样吧。告诉内核我这个设备啊,能打开,还能读取(实际上read函数并没有写完,就一个return 0.)
 
返回值major是这个设备的主设备号。
然后我们要创建一个类,把我们注册的这个设备加进去,告诉这个设备的所有者,这个设备的爸爸妈妈儿子闺女啥的,没有我们直接就NULL,最后比较重要的就是给他起个名字,方便在应用程序里找到他
seconddrv_class_dev = device_create(seconddrv_class, NULL, MKDEV(major, 0), NULL, "led")
这样我们就可以通过打开/dev/led/来打开我们的设备了。
然后映射一下物理地址,用ioremap喽。。好像我写的基地址加偏移量有问题,同学们,如果我错了,麻烦告诉我一下,谢谢大家。申请一个大点的空间,然后我们的GPIOXOUTENB就可以直接地址+1了。
剩下的呢就很简单了,我很偷懒,直接在open函数里把gpioc拉高了。当然后面我会更加规范的,今天真的是有点太着急了,希望大家见谅。
 最后在尾巴的地方加个出口函数,把注册的都注销掉,申请的空间都释放掉
 
这样啊。在应用程序里我们直接写一个简单的打开/dev/led/应该就能点亮个灯了、、理想是这样的,实际可能相去甚远,敬请期待明天更新的改邪归正篇。。
0 0