A40i使用笔记:编译驱动到内核中调用(ubuntu和A40i平台)

一、前言 

最近因个人需求和工作需求,准备入坑linux驱动篇,学习了几节课程,简单了解了linux驱动流程,本章前期现介绍开发linux驱动必备的工具,否则后续学习很困难

二、环境

notepadqq

source insight 4

window

Ubuntu16

三、正文

一个良好的开发工具,决定了开发者的心情,使用方便就很容易避免很多问题,这里我推荐使用source insight进行文件编辑,因为他能自动索引文件,到这里就需要介绍一下配置了,下载安装我就不介绍了,破解文件在这里https://download.csdn.net/download/qq_37603131/32673573https://download.csdn.net/download/qq_37603131/32673573

 破解完毕之后,需要添加索引资源,资源就是linux内核源码中的include函数,ubuntu下在/usr/include,在A40i的环境中,在/root/workspace/allwinner/A40i/bsp/lichee/linux-3.10中,把里面的include和fs文件夹拷贝出来放在一个文件夹中,这个文件夹任意放在一个位置,在source insight中去引用为所有工程,参照此贴介绍https://blog.csdn.net/zhuzitop/article/details/80310246?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242https://blog.csdn.net/zhuzitop/article/details/80310246?utm_medium=distribute.pc_relevant.none-task-blog-2~default~baidujs_title~default-0.no_search_link&spm=1001.2101.3001.4242

 到这里环境就搭建成了

之后就是驱动了,驱动是连接内核与设备的桥梁

扫描二维码关注公众号,回复: 13177244 查看本文章

驱动主要分为字符设备,块设备,网络设备,对应就是三种类型的驱动,开发难度也是由简变难。

 模块编写具备三要素:

1.入口module_init(入口函数)

2.出口module_exit(出口函数)

3.GPL协议申明  MODULE_LICENSE("GPL")

 下面就放置一个简单的驱动demo,申请设备号,初始化dev结构体,注册字符设备,释放

linux_test.c

#include <linux/init.h>		/* For init/exit macros */
#include <linux/module.h>	/* For MODULE_ marcros  */
#include <linux/cdev.h>
#include <linux/fs.h>


dev_t devno;
struct cdev *cdevp=NULL;



int demo_open(struct inode *inode, struct file *filp)
{
	printk(KERN_ALERT "demo_opennnnnnnnnnnn\n");
	return 0;
}

int demo_release(struct inode *inode, struct file *filp)
{
	printk(KERN_ALERT "demo_releaseeeeeeeeee\n");
	return 0;

}

struct file_operations fops = {
	.owner = THIS_MODULE,
	.open = demo_open,
	.release = demo_release,
};

static int __init hx711_init(void)
{
  int ret =0;
	
	ret = alloc_chrdev_region(&devno,0,3,"demo");
	if(ret<0){
		printk(KERN_ERR "alloc_chrdev_region err\n");
		goto err1;
	}
	printk(KERN_INFO "start major = %d\n",MAJOR(devno));
	

	cdevp = cdev_alloc();
	if(cdevp == NULL){
		printk(KERN_ERR "cdev_alloc err\n");
		ret = -ENOMEM;
		goto err2;		
	}
	

	cdev_init(cdevp,&fops);
	

	ret = cdev_add(cdevp,devno,3);
	if(ret<0){
		printk(KERN_ERR "cdev_add err\n");
		goto err2;
	}

	
  
	printk(KERN_ALERT "Hello, worldkkkkkkkbbbbbbbbbqqqqqqqq\n");
    return ret;
	
err2:
	unregister_chrdev_region(devno, 3);
	
err1:
	return ret;

	
}

static void __exit hx711_exit(void)
{
	cdev_del(cdevp);
	unregister_chrdev_region(devno, 3);
	printk(KERN_ALERT "Goodbye, cruel worldkkkkkkbbbbbbbqqqqqqq\n");
}
module_init(hx711_init);//三要素 必须有
module_exit(hx711_exit);//三要素 必须有
MODULE_LICENSE("GPL");//三要素 必须有
MODULE_AUTHOR("[email protected]");//模块作者的声明
MODULE_DESCRIPTION("HX711 Driver");//当前模块的功能描述

 Makefile

ifneq ($(KERNELRELEASE),)

    obj-m := linux_test.o

else

    PWD := $(shell pwd)
    KVER := $(shell uname -r)
    KDIR := /lib/modules/$(KVER)/build/

all: 

	$(MAKE) -C $(KDIR) M=$(PWD) modules 

clean: 

	rm -rf .*.cmd *.o *.mod.c *.ko .tmp_versions 

endif

 makefile的编写一定要注意格式,有些语句一定要以TAB按键开头

之后执行make,就编译驱动啦,生成ko文件

编写好测试驱动后就是用函数测试

  • modinfo linux_test.ko查看内核模块信息
  • lsmod查看当前已经加载的内核模块
  • insmod linux_test.ko加载内核模块到内核中
  • rmmod linux_test.ko卸载内核模块
  • dmesg查看日志信息
  • dmesg -c清除日志信息

以上的方式编译的驱动是利用Ubuntu的内核源码编译的,无法在a40i设备上加载

具体在Ubuntu中编译能在a40i中加载的驱动目前未实现使用makefile单独编译,可以随着全局编译附带这编译,也算是解决燃眉之急的一种方法,方法如下:

针对于A40i,其他平台没用过不知道
1.在/root/workspace/allwinner/A40i/bsp/lichee/linux-3.10/drivers路径下创建一个文件夹,放置自己写的驱动文件,我起的名字为0myself_driver,排在第一个寻找方便,管理不乱
2.修改同级文件makefile,打开makefile,在最后一行加入obj-m    += 0myself_driver/**/**.o  ,这里用的是obj-m,意思是单独编译模块,生成ko文件,而不是obj-y编译进入内核,生成o文件,**指的是自己写的某一个驱动文件夹,**.o指的是自己写的某一个驱动**.c
3.到/root/workspace/allwinner/A40i/bsp/lichee路径下打开控制台,执行全局编译./build.sh,不用等待到编译完毕,发现自己的驱动ko文件即生成完毕,拿去用就可以了

四、结语

本篇文章实际和全志a40i没有多大的关系,算是我在全志a40i平台上开始使用驱动开发的开篇吧

猜你喜欢

转载自blog.csdn.net/qq_37603131/article/details/120692436