蚂蚁S9矿板PS 蜂鸣器驱动

发布时间:2026/7/28 22:21:23
蚂蚁S9矿板PS 蜂鸣器驱动 参考蚂蚁S9矿板引脚定义.csdn蚂蚁S9矿板PS led驱动的四个实验-第1课 字符设备驱动.csdn蚂蚁S9矿板PS led驱动的四个实验-第2课 设备树下的led驱动.csdn蚂蚁S9矿板PS led驱动的四个实验-第3课 gpio子系统下的led驱动.csdn蚂蚁S9矿板PS led驱动的四个实验-第4课 设备驱动框架下的led驱动.csdn设备树system-user.dtsi#include dt-bindings/gpio/gpio.h#include dt-bindings/input/input.h#include dt-bindings/media/xilinx-vip.h#include dt-bindings/phy/phy.h/{modelz7 Board ant111;compatiblexlnx,zynq-zc702,xlnx,zynq-7000;chosen{bootargsconsolettyPS0,115200 earlyconcdns,mmio,0xe0000000,115200n8 keep_bootcon earlyprintk root/dev/mmcblk0p2 rw rootwait;stdout-pathserial0:115200n8;};beeper{compatibleming,beeper;statusokay;default-stateoff;beeper-gpiogpio037GPIO_ACTIVE_HIGH;};};驱动 beeper.kobeeper.c#includelinux/types.h#includelinux/kernel.h#includelinux/delay.h#includelinux/ide.h#includelinux/init.h#includelinux/module.h#includelinux/errno.h#includelinux/gpio.h#includeasm/mach/map.h#includeasm/uaccess.h#includeasm/io.h#includelinux/cdev.h#includelinux/of.h#includelinux/of_address.h#includelinux/of_gpio.h#defineBEEPER_CNT1/* 设备号个数 */#defineBEEPER_NAMEbeeper/* 名字 *//* dtsled设备结构体 */structbeeper_dev{dev_tdevid;/* 设备号 */structcdevcdev;/* cdev */structclass*class;/* 类 */structdevice*device;/* 设备 */intmajor;/* 主设备号 */intminor;/* 次设备号 */structdevice_node*nd;/* 设备节点 */intgpio;/* LED所使用的GPIO编号 */};staticstructbeeper_devbeeper;/* led设备 *//* * description : 打开设备 * param – inode : 传递给驱动的inode * param – filp : 设备文件file结构体有个叫做private_data的成员变量 * 一般在open的时候将private_data指向设备结构体。 * return : 0 成功;其他 失败 */staticintbeeper_open(structinode*inode,structfile*filp){return0;}/* * description : 从设备读取数据 * param – filp : 要打开的设备文件(文件描述符) * param – buf : 返回给用户空间的数据缓冲区 * param – cnt : 要读取的数据长度 * param – offt : 相对于文件首地址的偏移 * return : 读取的字节数如果为负值表示读取失败 */staticssize_tbeeper_read(structfile*filp,char__user*buf,size_tcnt,loff_t*offt){return0;}/* * description : 向设备写数据 * param – filp : 设备文件表示打开的文件描述符 * param – buf : 要写给设备写入的数据 * param – cnt : 要写入的数据长度 * param – offt : 相对于文件首地址的偏移 * return : 写入的字节数如果为负值表示写入失败 */staticssize_tbeeper_write(structfile*filp,constchar__user*buf,size_tcnt,loff_t*offt){charvalue;printk(KERN_INFObeeper_write: cnt%zu\n,cnt);/* 只接受 1 个字节 */if(cnt!1){printk(KERN_ERRinvalid count%zu\n,cnt);return-EINVAL;}/* 从用户空间读取 1 字节 */if(copy_from_user(value,buf,1)){printk(KERN_ERRcopy_from_user failed\n);return-EFAULT;}printk(KERN_INFObeeper_write: value%d\n,value);gpio_set_value(beeper.gpio,value?1:0);/* 返回实际写入的字节数 */return1;}/* * description : 关闭/释放设备 * param – filp : 要关闭的设备文件(文件描述符) * return : 0 成功;其他 失败 */staticintbeeper_release(structinode*inode,structfile*filp){return0;}/* 设备操作函数 */staticstructfile_operationsbeeper_fops{.ownerTHIS_MODULE,.openbeeper_open,.readbeeper_read,.writebeeper_write,.releasebeeper_release,};staticint__initbeeper_init(void){constchar*str;intret;/* 1.获取beeper设备节点 */beeper.ndof_find_node_by_path(/beeper);if(NULLbeeper.nd){printk(KERN_ERRbeeper: Failed to get beeper node\n);return-EINVAL;}/* 2.读取status属性 */retof_property_read_string(beeper.nd,status,str);if(!ret){if(strcmp(str,okay))return-EINVAL;}/* 2、获取compatible属性值并进行匹配 */retof_property_read_string(beeper.nd,compatible,str);if(0ret){printk(KERN_ERRbeeper: Failed to get compatible property\n);returnret;}if(strcmp(str,ming,beeper)){printk(KERN_ERRbeeper: Compatible match failed\n);return-EINVAL;}printk(KERN_INFObeeper: device matching successful!\r\n);/* 4.获取设备树中的beeper-gpio属性得到蜂鸣器所使用的GPIO编号 */beeper.gpioof_get_named_gpio(beeper.nd,beeper-gpio,0);if(!gpio_is_valid(beeper.gpio)){printk(KERN_ERRbeeper: Failed to get beeper-gpio\n);return-EINVAL;}printk(KERN_INFObeeper: beeper-gpio num %d\r\n,beeper.gpio);/* 5.向gpio子系统申请使用GPIO */retgpio_request(beeper.gpio,Beeper gpio);if(ret){printk(KERN_ERRbeeper: Failed to request gpio num %d\n,beeper.gpio);returnret;}/* 6.将gpio管脚设置为输出模式 */gpio_direction_output(beeper.gpio,0);/* 7.设置蜂鸣器的初始状态 */retof_property_read_string(beeper.nd,default-state,str);if(!ret){if(!strcmp(str,on))gpio_set_value(beeper.gpio,1);elsegpio_set_value(beeper.gpio,0);}elsegpio_set_value(beeper.gpio,0);/* 8.注册字符设备驱动 *//* 创建设备号 */if(beeper.major){beeper.devidMKDEV(beeper.major,0);retregister_chrdev_region(beeper.devid,BEEPER_CNT,BEEPER_NAME);if(ret)gotoout1;}else{retalloc_chrdev_region(beeper.devid,0,BEEPER_CNT,BEEPER_NAME);if(ret)gotoout1;beeper.majorMAJOR(beeper.devid);beeper.minorMINOR(beeper.devid);}printk(beeper: major%d,minor%d\r\n,beeper.major,beeper.minor);/* 初始化cdev */beeper.cdev.ownerTHIS_MODULE;cdev_init(beeper.cdev,beeper_fops);/* 添加一个cdev */retcdev_add(beeper.cdev,beeper.devid,BEEPER_CNT);if(ret)gotoout2;/* 创建类 */beeper.classclass_create(THIS_MODULE,BEEPER_NAME);if(IS_ERR(beeper.class)){retPTR_ERR(beeper.class);gotoout3;}/* 创建设备 */beeper.devicedevice_create(beeper.class,NULL,beeper.devid,NULL,BEEPER_NAME);if(IS_ERR(beeper.device)){retPTR_ERR(beeper.device);gotoout4;}return0;out4:class_destroy(beeper.class);out3:cdev_del(beeper.cdev);out2:unregister_chrdev_region(beeper.devid,BEEPER_CNT);out1:gpio_free(beeper.gpio);returnret;}staticvoid__exitbeeper_exit(void){/* 注销设备 */device_destroy(beeper.class,beeper.devid);/* 注销类 */class_destroy(beeper.class);/* 删除cdev */cdev_del(beeper.cdev);/* 注销设备号 */unregister_chrdev_region(beeper.devid,BEEPER_CNT);/* 释放GPIO */gpio_free(beeper.gpio);}/* 驱动模块入口和出口函数注册 */module_init(beeper_init);module_exit(beeper_exit);MODULE_AUTHOR(ming);MODULE_DESCRIPTION(ZYNQ GPIO LED Driver);MODULE_LICENSE(GPL);测试rootant:~# insmod beeper.kobeeper: loading out-of-tree module taints kernel. beeper: device matching successful!beeper: beeper-gpio num943beeper:major244,minor0rootant:~# ls /dev/beeper/dev/beeper rootant:~# printf \x01 /dev/beeperbeeper_write:cnt1beeper_write:value1rootant:~# printf \x00 /dev/beeperbeeper_write:cnt1rootant:~# rmmod beeperrootant:~# ls /dev/beeperls: /dev/beeper: No suchfileor directory