首先要编写字符设备驱动,代码大同小异,随便复制粘贴就行了。
但是要注意了,一定要保护好寄存器,不要乱搞,要不然系统崩了可别怪老夫没提醒。
led.c
#include
#include
#include
#include
#include
#include
辣鸡
![](https://img.haomeiwen.com/i5735521/65250f7c1bd93aec.png)
#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:Output
led_config=ioremap(PA_CFG1,4);//从datesheet里面查询你的寄存器这里用的是PA10
register_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:Reserved
led_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_NAME
device_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)
#endif
Makefile
把这里的KDIR改成你开发板内核源码对应目录,指定交叉编译工具链,如果没有什么问题,make会编译出led.ko,只要insmod led.ko就行了, so easy
obj-m:=led.o
KDIR:=/home/share/OrangePi_H5SDK/kernel
all:
make-C$(KDIR)M=$(PWD)modules\
CROSS_COMPILE=/home/share/OrangePi_H5SDK/toolchain/gcc-linaro-aarch/bin/aarch64-linux-gnu-ARCH=arm64
clean:
rm-f*.ko*.o*.mod.o*.mod.c*.symvers*.bak*.order
最后是应用软件,安装led.ko内核模块会产生一个/dev/myled的设备节点,现在我们需要打开它,并对其进行读写操作
led_app.c
#include
#include
#include
#include
#include
![](https://img.haomeiwen.com/i5735521/e7b07640774ef4b1.png)
网友评论