Android怎么开发第一个驱动程序
创始人
2024-12-24 02:04:10
0次

1.驱动程序

frist_driver.c

#include #include #include #include #include #include #include #include #include #include #include #include #define HELLOON               1#define HELLOOFF              0        #define HELLO_CNT             1#define HELLO_NAME           "hello driver"static char readbuf[100];static char writebuf[100];static char kerneldata[] = {"hello my first driver"};static char mybuf[100]   ="1234";struct hello_driver{dev_t           devid;            /*设备号*/struct cdev     cdev;             /*cdev*/struct class    *class;           /*类*/struct device   *device;          /*设备*/int             major;            /*主设备号*/int             minor;            /*次设备号*/atomic_t        atomic_lock;      /*原子变量*/ };struct hello_driver hello_driver_dev;static ssize_t show_my_device(struct device *dev,struct device_attribute *attr, char *buf){return sprintf(buf, "%s\n", mybuf);}static ssize_t set_my_device(struct device *dev,struct device_attribute *attr, const char *buf, size_t len)//echo命令时,将会调用该函数{sprintf(mybuf, "%s", buf);return len;}static DEVICE_ATTR(my_device_test, S_IWUSR|S_IRUSR, show_my_device, set_my_device);//定义一个名字为my_device_test的设备属性文件static int hello_driver_open(struct inode *inode, struct file *filp){
   if(!atomic_dec_and_test(&hello_driver_dev.atomic_lock))
   {   atomic_inc(&hello_driver_dev.atomic_lock);   return -EBUSY;           
   }filp->private_data = &hello_driver_dev;return 0;}static ssize_t hello_driver_read(struct file *filp, char __user *buf, size_t cnt, loff_t *offt){int ret = 0;memcpy(readbuf,kerneldata,sizeof(kerneldata));ret = copy_to_user(buf,readbuf,cnt);if(ret == 0){printk("kernel senddata ok!\n");}else{printk("kernel senddata failed\n");}return 0;}static ssize_t hello_driver_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt){int ret = 0;ret = copy_from_user(writebuf,buf,cnt);if(ret == 0){printk("kernel recvdata %s\n",writebuf);}else{printk("kernel recvdata failed\n");}return 0;}static long hello_driver_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg){switch(cmd){case HELLOON:  printk("Open hello driver\n");break;case HELLOOFF:   printk("Close hello driver\n");break;default:break;}return 0;}static int hello_driver_release(struct inode *inode, struct file *filp){struct hello_driver *dev = filp->private_data;atomic_inc(&dev->atomic_lock);return 0;}static struct file_operations hello_driver_fops= {.owner             = THIS_MODULE,.open              = hello_driver_open, .read              = hello_driver_read,.write             = hello_driver_write,.unlocked_ioctl    = hello_driver_unlocked_ioctl,.release           = hello_driver_release,};static int __init hello_driver_init(void){int ret;/*1.设置原子变量,保证同一时刻只能有一个应用程序使用该驱动*/atomic_set(&hello_driver_dev.atomic_lock,1);/*2.分配设备号*//*2.1 之前分配了主设备号*/if(hello_driver_dev.major){/*注册设备号*/hello_driver_dev.devid = MKDEV(hello_driver_dev.major,0);ret = register_chrdev_region(hello_driver_dev.devid, HELLO_CNT, HELLO_NAME);if(ret < 0){printk("can't register major\n");  return ret; }}else/*2.2 之前未分配设备号,向内核申请设备号*/{   alloc_chrdev_region(&hello_driver_dev.devid, 0, HELLO_CNT, HELLO_NAME); }printk(KERN_ERR"hello_driver_dev major = %d, minor = %d\n", hello_driver_dev.major,hello_driver_dev.minor);hello_driver_dev.cdev.owner = THIS_MODULE;cdev_init(&hello_driver_dev.cdev,&hello_driver_fops);ret = cdev_add(&hello_driver_dev.cdev, hello_driver_dev.devid,HELLO_CNT);if(ret){printk("Error cdev_add\n");  goto fail_to_cdev_add;}hello_driver_dev.class = class_create(THIS_MODULE,HELLO_NAME);if(IS_ERR(hello_driver_dev.class)){goto fail_to_class_create;}hello_driver_dev.device = device_create(hello_driver_dev.class , NULL, hello_driver_dev.devid, NULL, HELLO_NAME);if(IS_ERR(hello_driver_dev.device)){goto fail_to_device_create;}

 if(sysfs_create_file(&hello_driver_dev.device ->kobj), &dev_attr_my_device_test.attr)){    
     //在mytest_device设备目录下创建一个my_device_test属性文件   return -1;}return 0;fail_to_cdev_add:unregister_chrdev_region(hello_driver_dev.devid, HELLO_CNT); 
	return -1;fail_to_class_create:cdev_del(&hello_driver_dev.cdev);unregister_chrdev_region(hello_driver_dev.devid, HELLO_CNT);return -1;	fail_to_device_create:cdev_del(&hello_driver_dev.cdev);unregister_chrdev_region(hello_driver_dev.devid, HELLO_CNT); class_destroy(hello_driver_dev.class);return -1;}static void __exit hello_driver_exit(void){cdev_del(&hello_driver_dev.cdev);unregister_chrdev_region(hello_driver_dev.devid, HELLO_CNT); device_destroy(hello_driver_dev.class, hello_driver_dev.devid); class_destroy(hello_driver_dev.class);}module_init(hello_driver_init);module_exit(hello_driver_exit);MODULE_DESCRIPTION("my hello driver");MODULE_AUTHOR("Kong Lingze");MODULE_LICENSE("GPL");

2.加载驱动程序编译到内核

添加文件夹

在kernel/driver目录下添加新的文件夹frist_driver,在frist_driver中添加文件Kconfig,Makefile,frist_driver.c

Android怎么开发第一个驱动程序
frist_driver/Kconfig中的内容:
Android怎么开发第一个驱动程序

frist_driver/Makefile中的内容:
Android怎么开发第一个驱动程序
在driver/Kconfig添加内容:
Android怎么开发第一个驱动程序
在driver/Makefile添加内容:
Android怎么开发第一个驱动程序

  • 在kernel/driver下执行make menuconfig,选择First Android Driver

  • 在安卓源码目录目录下source build/envsetup.sh

  • lunch  xx xxxx (可选择)

  • make bootimage -j32

测试:

执行fastboot flash boot boot.img将内核烧写到开发板,在开发板目录找到sys/class/hello driver/hello driver或者下图目录,执行如图的命令
Android怎么开发第一个驱动程序
测试成功

3.用c程序进行测试

首先在android源码的packages目录下新建一个helloapp目录,该目录下新建hello_app.c和Android.mk两个文件。

hello_app.c

#include #include  #include  #include #include #include  #include #include #define READ           3#define WRITE          4#define HELLO_ON       1#define HELLO_OFF      0// ./app /dev/hello\driver  static unsigned char cUserData[] = {"User data"};int main(int argc, char **argv){int  iFd;int  iRet;char *cFilename;unsigned int  arg = 0;unsigned char cReadBuf[100];unsigned char cWriteBuf[100];if(argc!=3){Printf(“Usage:%s  ”,argv[0]);}//打开设备结点cFilename = argv[1];iFd = open(cFilename, O_RDWR);if(iFd < 0){printf(" open %s failed\n", cFilename);return -1;}/*读取驱动中的数据*/if(atoi(argv[2]) == READ){memset(cReadBuf,sizeof(cReadBuf),sizeof(cReadBuf));iRet = read(iFd,cReadBuf,sizeof(cReadBuf));if(iRet < 0){printf("read %s data failed\n",cFilename);return -1;}else{printf("read data is:%s\n",cReadBuf);}}else if(atoi(argv[2]) == WRITE)//向驱动中写数据{memset(cWriteBuf,sizeof(cWriteBuf),sizeof(cWriteBuf));memcpy(cWriteBuf,cUserData,sizeof(cUserData));iRet = write(iFd,cWriteBuf,sizeof(cWriteBuf));if(iRet < 0){printf("write %s data failed\n",cFilename);return -1;}}else if(atoi(argv[2]) == HELLO_ON)//给驱动发送HELLO_ON命令{ioctl(iFd,HELLO_ON,arg);}else if(atoi(argv[2]) == HELLO_OFF)//给驱动发送HELLO_OFF命令{ioctl(iFd,HELLO_OFF,arg);}
    iRet = close(iFd);if(iFd < 0){printf("close %s failed",cFilename);return -1;}return 0;}

Andoird.mk

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := hellotest
LOCAL_SRC_FILES := $(call all-subdir-c-files)
include $(BUILD_EXECUTABLE)

编译

完成之后在安卓源码目录,输入source build\envser.up.sh,再进入packages/helloapp目录执行mm命令,生成可执行文件,编译后的文件在out/target/product/xxx/obj/EXECUTABLES/hellotapp_intermediates/中
Android怎么开发第一个驱动程序

测试

adb shell
adb push hello_app /data把hello_app推送到android设备的data目录下,
chmod +x helloapp添加可执行权限。
执行./helloapp /dev/hello driver 1

打印如下:
Open hello driver
可见测试成功。

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...