本帖最后由 renshengrumeng 于 2017-6-28 21:13 编辑
前几篇,搞了根文件系统,也分享了nfs网络挂载根文件系统,同时还搞了个256M的小镜像可以通过友善提供的工具下载到nanopi M1 Plus中。 这次弄的是模块加载驱动程序,入门驱动编程的第二个程序程序(也可以是第一个)。驱动源码如下 #include
#include
#include
#include
#include static struct class *firstdrv_class;
static struct device *firstdrv_dev;
static int first_drv_open(struct inode *inode, struct file *file)
{
printk(KERN_INFO "first_drv_openn");
/* 配置GPF4,5,6为输出 */ return 0;
} static ssize_t first_drv_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{ printk(KERN_INFO "first_drv_writen"); return 0;
} static struct file_operations first_drv_fops =
{
.owner = THIS_MODULE, /* 这是一个宏,推向编译模块时自动创建的__this_module变量 */
.open = first_drv_open,
.write = first_drv_write,
};
int major;
static int first_drv_init(void)
{
printk(KERN_INFO "first_drv_initn");
major = register_chrdev(0, "first_drv", &first_drv_fops); // 注册, 告诉内核 firstdrv_class = class_create(THIS_MODULE, "firstdrv");
firstdrv_dev = device_create(firstdrv_class, NULL, MKDEV(major, 0), NULL, "xyz"); /* /dev/xyz */ return 0;
} static void first_drv_exit(void)
{
printk(KERN_INFO "first_drv_exitn");
unregister_chrdev(major, "first_drv"); // 卸载 device_unregister(firstdrv_dev);
class_destroy(firstdrv_class);
} module_init(first_drv_init);
module_exit(first_drv_exit); MODULE_LICENSE("GPL"); 由于我们使用的是3.x的内核不是平时教学视频里的2.6的内核所以要使用device_create这个函数替代class_device_create函数返回结构体指针也要改否者会编译不过的。 编译需要的Makefile 如下 obj-m :=first_drv.o CROSS_COMPILE = ARM-linux-
CC = $(CROSS_COMPILE)gcc KDIR :=/root/program/lichee/linux-3.4/
PWD :=$(shell pwd) default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.o* .*.cmd *.ko *.mod.c *~ core .depend
rm -rf .tmp_versions/
rm -rf *.symvers 有了这两个文件我们就可以通过执行make指令编译驱动模块了。 编译模块,终端打印的日志和生成的文件如图所示
驱动模块这就做好了可以通过 make clean 清除make编译产生的文件。 接下来我们需要个应用程序,应用程序如下
#include
#include
#include
#include
/* firstdrvtest on
* firstdrvtest off
*/
int main(int argc, char **argv)
{
int fd;
int val = 1;
fd = open("/dev/xyz", O_RDWR);
if (fd < 0)
{
printf("can't open!n");
}
if (argc != 2)
{
printf("Usage :n");
printf("%s n", argv[0]);
return 0;
} if (strcmp(argv[1], "on") == 0)
{
val = 1;
}
else
{
val = 0;
}
write(fd, &val, 4);
return 0;
}
程序为点灯所写,由于这样会增加难道所以驱动程序去掉控制小灯部分。 编译arm-linux-gcc -o xx xx.c -static 这样我们就可以复制到我们的板子上测试了。 通过命令insmod xx.ko 挂载效果如图
通过指令cat /proc/devices 可以查看是否产生来了xx设备。 通过lsmod可以查看都挂载了哪写模块,运行应用程序如图所示。
卸载驱动成功rmmod 这里注意卸载时只写文件名效果如图
最后在来个板子的照片一直没有晒板子。希望我以后会在板子上添加多谢外设。
|