框架基本上已经搭好了,需要补充的就是硬件相关的操作了。
想要操作GPIO,肯定要配置寄存器。看原理图可知,当输出低电平时,led会发光。led分别接在GPIOB的5、6、7pin上。所以需要配置的寄存器是gpbcon和gpbdat。因此定义:volatile unsigned int gpbcon =NULL;volatile unsigned long *gpbdat = NULL;与裸板程序不同,驱动程序操作的不是物理地址而是虚拟地址,因此需要用到ioremap这个函数。我们在入口函数中完成对gpbcon和gpbdat的地址映射。gpbcon = (volatile unsigned long )ioremap(0x56000010,16);
gpbdat = gpbcon + 1;同时在出口函数中取消映射iounmap(gpbcon);然后,可以在open函数中完成对gpbcon的设置,由于01表示输出所以对寄存器要先清零再置1: *gpbcon &= ~((0x3<<(5*2)) | (0x3<<(6*2)) | (0x3<<(7*2)));*gpbcon |= ((0x1<<(5*2)) | (0x1<<(6*2)) | (0x1<<(7*2)));
在read函数中完成对gpbdat的设置,打开led即为清零:*gpbdat &= ~((1<<5) | (1<<6) | (1<<7));关闭led即为置1:*gpbdat |= ((1<<5) | (1<<6) | (1<<7));
问题在于,如何判断让led点亮或者熄灭呢?当然是从应用程序传参数了!所以要用到copy_from_user(&val,buf,count),*buf即为传来的参数,val可作为判断的条件。
到此为止,led驱动程序就算是完成了,下面还需要写一个测试程序。
测试程序的要求是输入test on就亮灯,test off就灭灯。关键还是在于判断第二个参数,所以要对argv[1]进行判断。
if (strcmp(argv[1],”on”) == 0)
{
val=1;
}
else
{
val=0;
}
然后把val的值写到驱动程序里,write(fd,&val,4);这样实现有一个不足之处,就是如果输入的第二个参数除了“on”之外都可以熄灭led。
这样就完成了。