首先要编写字符设备驱动,代码大同小异,随便复制粘贴就行了。 但是要注意了,一定要保护好寄存器,不要乱搞,要不然系统崩了可别怪老夫没提醒。led.c#include#include#include#include#include#include辣鸡 #include"led.h"#defineLED_MAJOR245//主设备号unsignedint*led_config;unsignedint*led_data;unsignedint*led_pull;structcdevcdev;dev_tdevno;intled_open(structinode*node,structfile*filp){uint32_tregister_dat;//000:Input001:Outputled_config=ioremap(PA_CFG1,4);//从datesheet里面查询你的寄存器这里用的是PA10register_dat=readl(led_config);//先读取寄存器值只操作你需要操作的位段不要干扰其他端口register_dat&=~(0x7<<8);//清空PA10的值writel(register_dat|0x1<<8,led_config);//PA10设置成输出//00:Pull-up/downdisable01:Pull-up10:Pull-down11:Reservedled_pull=ioremap(PA_PILL0,4);register_dat=readl(led_pull);//读取寄存器值register_dat&=~(0x3<<2*10);//清空PA10设置writel((register_dat|0x1<<2*10),led_pull);//PA10上拉led_data=ioremap(PA_DAT,4);return0;}longled_ioctl(structfile*filp,unsignedintcmd,unsignedlongarg){uint32_treg_dat;switch(cmd){caseLED_ON:reg_dat=readl(led_data);reg_dat&=~(1<<10);writel(reg_dat|0x0<<10,led_data);return0;caseLED_OFF:reg_dat=readl(led_data);reg_dat&=~(1<<10);writel(reg_dat|0x1<<10,led_data);return0;default:return-EINVAL;}}staticstructfile_operationsled_fops={.owner=THIS_MODULE,.open=led_open,.unlocked_ioctl=led_ioctl,};#defineDEVICE_NAME"myled"staticstructclass*leds_class;staticintled_init(void){intret;//注册LED设备为字符设备ret=register_chrdev(LED_MAJOR,DEVICE_NAME,&led_fops);if(ret<0){printk(DEVICE_NAME"majornumberregisterfalid!\n");returnret;}//注册一个类,使mdev可以在/dev/下面建立设备节点leds_class=class_create(THIS_MODULE,DEVICE_NAME);if(IS_ERR(leds_class)){printk("creatleds_classfailed!");return-1;}//创建一个设备节点,节点名字为DEVICE_NAMEdevice_create(leds_class,NULL,MKDEV(LED_MAJOR,0),NULL,DEVICE_NAME);printk(DEVICE_NAME"initialized!");return0;}staticvoidled_exit(void){//注销设备unregister_chrdev(LED_MAJOR,DEVICE_NAME);//删除设备节点device_destroy(leds_class,MKDEV(LED_MAJOR,0));//注销类class_destroy(leds_class);}module_init(led_init);module_exit(led_exit);MODULE_LICENSE("GPL");MODULE_AUTHOR("leo_learning");MODULE_DESCRIPTION("myleddriver");以下是led.h这里把所有的GPIO都列出来了#ifndef_LED_H#define_LED_H//GPIOA_10#defineGPIO_BASE0x01C20800#definePA_CFG0GPIO_BASE+0x0000+0*0x24//GPIOA0-7#definePA_CFG1GPIO_BASE+0x0004+0*0x24//GPIOA8-15#definePA_CFG2GPIO_BASE+0x0008+0*0x24//GPIOA17-21#definePA_CFG3GPIO_BASE+0x000C+0*0x24//GPIOA#definePA_DATGPIO_BASE+0x0010+0*0x24//GPIOA_DAT#definePA_DRV0GPIO_BASE+0x0014+0*0x24#definePA_DRV1GPIO_BASE+0x0018+0*0x24#definePA_PILL0GPIO_BASE+0x001C+0*0x24#definePA_PILL1GPIO_BASE+0x0020+0*0x24#definePC_CFG0GPIO_BASE+0x0000+1*0x24//GPIOC0-7#definePC_CFG1GPIO_BASE+0x0004+1*0x24//GPIOC8-15#definePC_CFG2GPIO_BASE+0x0008+1*0x24//GPIOC17-21#definePC_CFG3GPIO_BASE+0x000C+1*0x24//GPIOC#definePC_DATGPIO_BASE+0x0010+1*0x24//GPIOC_DAT#definePC_DRV0GPIO_BASE+0x0014+1*0x24#definePC_DRV1GPIO_BASE+0x0018+1*0x24#definePC_PILL0GPIO_BASE+0x001C+1*0x24#definePC_PILL1GPIO_BASE+0x0020+1*0x24#definePD_CFG0GPIO_BASE+0x0000+2*0x24//GPIOD0-7#definePD_CFG1GPIO_BASE+0x0004+2*0x24//GPIOD8-15#definePD_CFG2GPIO_BASE+0x0008+2*0x24//GPIOD17-21#definePD_CFG3GPIO_BASE+0x000C+2*0x24//GPIOD#definePD_DATGPIO_BASE+0x0010+2*0x24//GPIOD_DAT#definePD_DRV0GPIO_BASE+0x0014+2*0x24#definePD_DRV1GPIO_BASE+0x0018+2*0x24#definePD_PILL0GPIO_BASE+0x001C+2*0x24#definePD_PILL1GPIO_BASE+0x0020+2*0x24#definePE_CFG0GPIO_BASE+0x0000+3*0x24//GPIOE0-7#definePE_CFG1GPIO_BASE+0x0004+3*0x24//GPIOE8-15#definePE_CFG2GPIO_BASE+0x0008+3*0x24//GPIOE17-21#definePE_CFG3GPIO_BASE+0x000C+3*0x24//GPIOE#definePE_DATGPIO_BASE+0x0010+3*0x24//GPIOE_DAT#definePE_DRV0GPIO_BASE+0x0014+3*0x24#definePE_DRV1GPIO_BASE+0x0018+3*0x24#definePE_PILL0GPIO_BASE+0x001C+3*0x24#definePE_PILL1GPIO_BASE+0x0020+3*0x24#definePF_CFG0GPIO_BASE+0x0000+4*0x24//GPIOF0-7#definePF_CFG1GPIO_BASE+0x0004+4*0x24//GPIOF8-15#definePF_CFG2GPIO_BASE+0x0008+4*0x24//GPIOF17-21#definePF_CFG3GPIO_BASE+0x000C+4*0x24//GPIOF#definePF_DATGPIO_BASE+0x0010+4*0x24//GPIOF_DAT#definePF_DRV0GPIO_BASE+0x0014+4*0x24#definePF_DRV1GPIO_BASE+0x0018+4*0x24#definePF_PILL0GPIO_BASE+0x001C+4*0x24#definePF_PILL1GPIO_BASE+0x0020+4*0x24#definePG_CFG0GPIO_BASE+0x0000+5*0x24//GPIOG0-7#definePG_CFG1GPIO_BASE+0x0004+5*0x24//GPIOG8-15#definePG_CFG2GPIO_BASE+0x0008+5*0x24//GPIOG17-21#definePG_CFG3GPIO_BASE+0x000C+5*0x24//GPIOG#definePG_DATGPIO_BASE+0x0010+5*0x24//GPIOG_DAT#definePG_DRV0GPIO_BASE+0x0014+5*0x24#definePG_DRV1GPIO_BASE+0x0018+5*0x24#definePG_PILL0GPIO_BASE+0x001C+5*0x24#definePG_PILL1GPIO_BASE+0x0020+5*0x24#definePL_CFG0GPIO_BASE+0x0000+6*0x24//GPIOL0-7#definePL_CFG1GPIO_BASE+0x0004+6*0x24//GPIOL8-15#definePL_CFG2GPIO_BASE+0x0008+6*0x24//GPIOL17-21#definePL_CFG3GPIO_BASE+0x000C+6*0x24//GPIOL#definePL_DATGPIO_BASE+0x0010+6*0x24//GPIOL_DAT#definePL_DRV0GPIO_BASE+0x0014+6*0x24#definePL_DRV1GPIO_BASE+0x0018+6*0x24#definePL_PILL0GPIO_BASE+0x001C+6*0x24#definePL_PILL1GPIO_BASE+0x0020+6*0x24#definePA_INT_CFG00x0200+0x00+0*0x20#definePA_INT_CFG10x0200+0x04+0*0x20#definePA_INT_CFG20x0200+0x08+0*0x20#definePA_INT_CFG30x0200+0x0C+0*0x20#definePA_INT_CTL0x0200+0x10+0*0x20#definePA_INT_STA0x0200+0x14+0*0x20#definePA_INT_DEB0x0200+0x18+0*0x20#definePF_INT_CFG00x0200+0x00+1*0x20#definePF_INT_CFG10x0200+0x04+1*0x20#definePF_INT_CFG20x0200+0x08+1*0x20#definePF_INT_CFG30x0200+0x0C+1*0x20#definePF_INT_CTL0x0200+0x10+1*0x20#definePF_INT_STA0x0200+0x14+1*0x20#definePF_INT_DEB0x0200+0x18+1*0x20#definePG_INT_CFG00x0200+0x00+2*0x20#definePG_INT_CFG10x0200+0x04+2*0x20#definePG_INT_CFG20x0200+0x08+2*0x20#definePG_INT_CFG30x0200+0x0C+2*0x20#definePG_INT_CTL0x0200+0x10+2*0x20#definePG_INT_STA0x0200+0x14+2*0x20#definePG_INT_DEB0x0200+0x18+2*0x20#defineLED_MAGIC'L'#defineLED_ON_IO(LED_MAGIC,1)#defineLED_OFF_IO(LED_MAGIC,0)#endifMakefile把这里的KDIR改成你开发板内核源码对应目录,指定交叉编译工具链,如果没有什么问题,make会编译出led.ko,只要insmod led.ko就行了, so easyobj-m:=led.oKDIR:=/home/share/OrangePi_H5SDK/kernelall:make-C$(KDIR)M=$(PWD)modules\CROSS_COMPILE=/home/share/OrangePi_H5SDK/toolchain/gcc-linaro-aarch/bin/aarch64-linux-gnu-ARCH=arm64clean:rm-f*.ko*.o*.mod.o*.mod.c*.symvers*.bak*.order最后是应用软件,安装led.ko内核模块会产生一个/dev/myled的设备节点,现在我们需要打开它,并对其进行读写操作led_app.c#include#include#include#include#include #include"led.h"intmain(intargc,char*argv[]){intfd;intcmd;if(argc<2){printf("pleaseenterthesecondpara!\n");return0;}cmd=atoi(argv[1]);fd=open("/dev/myled",O_RDWR);if(cmd==1)ioctl(fd,LED_ON);elseioctl(fd,LED_OFF);return0;}aarch64-linux-gnu-gcc -o led_app led_app.c通过./led_app 0熄灭LED./led_app 1点亮然后随便浪吧