分享一个香橙派PC2的C语言点亮LED程序

xiaoxiao2021-02-28  51

首先要编写字符设备驱动,代码大同小异,随便复制粘贴就行了。 但是要注意了,一定要保护好寄存器,不要乱搞,要不然系统崩了可别怪老夫没提醒。

led.c

#include <linux/module.h> #include <linux/init.h> #include <linux/cdev.h> #include <linux/fs.h> #include <linux/io.h> #include<linux/device.h> #include "led.h" #define LED_MAJOR 245 //主设备号 unsigned int *led_config; unsigned int *led_data; unsigned int *led_pull; struct cdev cdev; dev_t devno; int led_open(struct inode *node, struct file *filp) { uint32_t register_dat; //000:Input 001: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/down disable 01: Pull-up 10: Pull-down 11: 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); return 0; } long led_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { uint32_t reg_dat; switch (cmd) { case LED_ON: reg_dat = readl(led_data); reg_dat &= ~(1<<10); writel(reg_dat|0x0<<10,led_data); return 0; case LED_OFF: reg_dat = readl(led_data); reg_dat &= ~(1<<10); writel(reg_dat|0x1<<10,led_data); return 0; default: return -EINVAL; } } static struct file_operations led_fops = { .owner= THIS_MODULE, .open = led_open, .unlocked_ioctl = led_ioctl, }; #define DEVICE_NAME "myled" static struct class*leds_class; static int led_init(void) { int ret; //注册LED设备为字符设备 ret = register_chrdev(LED_MAJOR, DEVICE_NAME, &led_fops); if(ret< 0) { printk(DEVICE_NAME" major number register falid!\n"); return ret; } //注册一个类,使mdev可以在/dev/下面建立设备节点 leds_class= class_create(THIS_MODULE, DEVICE_NAME); if(IS_ERR(leds_class) ) { printk("creatleds_class failed!"); return-1; } //创建一个设备节点,节点名字为DEVICE_NAME device_create(leds_class,NULL, MKDEV(LED_MAJOR, 0), NULL, DEVICE_NAME); printk(DEVICE_NAME"initialized!"); return 0; } static void led_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("myled driver");

以下是led.h  这里把所有的GPIO都列出来了

#ifndef _LED_H #define _LED_H //GPIOA_10 #define GPIO_BASE 0x01C20800 #define PA_CFG0 GPIO_BASE+0x0000+0*0x24 //GPIOA0-7 #define PA_CFG1 GPIO_BASE+0x0004+0*0x24 //GPIOA8-15 #define PA_CFG2 GPIO_BASE+0x0008+0*0x24 //GPIOA17-21 #define PA_CFG3 GPIO_BASE+0x000C+0*0x24 //GPIOA #define PA_DAT GPIO_BASE+0x0010+0*0x24 //GPIOA_DAT #define PA_DRV0 GPIO_BASE+0x0014+0*0x24 #define PA_DRV1 GPIO_BASE+0x0018+0*0x24 #define PA_PILL0 GPIO_BASE+0x001C+0*0x24 #define PA_PILL1 GPIO_BASE+0x0020+0*0x24 #define PC_CFG0 GPIO_BASE+0x0000+1*0x24 //GPIOC0-7 #define PC_CFG1 GPIO_BASE+0x0004+1*0x24 //GPIOC8-15 #define PC_CFG2 GPIO_BASE+0x0008+1*0x24 //GPIOC17-21 #define PC_CFG3 GPIO_BASE+0x000C+1*0x24 //GPIOC #define PC_DAT GPIO_BASE+0x0010+1*0x24 //GPIOC_DAT #define PC_DRV0 GPIO_BASE+0x0014+1*0x24 #define PC_DRV1 GPIO_BASE+0x0018+1*0x24 #define PC_PILL0 GPIO_BASE+0x001C+1*0x24 #define PC_PILL1 GPIO_BASE+0x0020+1*0x24 #define PD_CFG0 GPIO_BASE+0x0000+2*0x24 //GPIOD0-7 #define PD_CFG1 GPIO_BASE+0x0004+2*0x24 //GPIOD8-15 #define PD_CFG2 GPIO_BASE+0x0008+2*0x24 //GPIOD17-21 #define PD_CFG3 GPIO_BASE+0x000C+2*0x24 //GPIOD #define PD_DAT GPIO_BASE+0x0010+2*0x24 //GPIOD_DAT #define PD_DRV0 GPIO_BASE+0x0014+2*0x24 #define PD_DRV1 GPIO_BASE+0x0018+2*0x24 #define PD_PILL0 GPIO_BASE+0x001C+2*0x24 #define PD_PILL1 GPIO_BASE+0x0020+2*0x24 #define PE_CFG0 GPIO_BASE+0x0000+3*0x24 //GPIOE0-7 #define PE_CFG1 GPIO_BASE+0x0004+3*0x24 //GPIOE8-15 #define PE_CFG2 GPIO_BASE+0x0008+3*0x24 //GPIOE17-21 #define PE_CFG3 GPIO_BASE+0x000C+3*0x24 //GPIOE #define PE_DAT GPIO_BASE+0x0010+3*0x24 //GPIOE_DAT #define PE_DRV0 GPIO_BASE+0x0014+3*0x24 #define PE_DRV1 GPIO_BASE+0x0018+3*0x24 #define PE_PILL0 GPIO_BASE+0x001C+3*0x24 #define PE_PILL1 GPIO_BASE+0x0020+3*0x24 #define PF_CFG0 GPIO_BASE+0x0000+4*0x24 //GPIOF0-7 #define PF_CFG1 GPIO_BASE+0x0004+4*0x24 //GPIOF8-15 #define PF_CFG2 GPIO_BASE+0x0008+4*0x24 //GPIOF17-21 #define PF_CFG3 GPIO_BASE+0x000C+4*0x24 //GPIOF #define PF_DAT GPIO_BASE+0x0010+4*0x24 //GPIOF_DAT #define PF_DRV0 GPIO_BASE+0x0014+4*0x24 #define PF_DRV1 GPIO_BASE+0x0018+4*0x24 #define PF_PILL0 GPIO_BASE+0x001C+4*0x24 #define PF_PILL1 GPIO_BASE+0x0020+4*0x24 #define PG_CFG0 GPIO_BASE+0x0000+5*0x24 //GPIOG0-7 #define PG_CFG1 GPIO_BASE+0x0004+5*0x24 //GPIOG8-15 #define PG_CFG2 GPIO_BASE+0x0008+5*0x24 //GPIOG17-21 #define PG_CFG3 GPIO_BASE+0x000C+5*0x24 //GPIOG #define PG_DAT GPIO_BASE+0x0010+5*0x24 //GPIOG_DAT #define PG_DRV0 GPIO_BASE+0x0014+5*0x24 #define PG_DRV1 GPIO_BASE+0x0018+5*0x24 #define PG_PILL0 GPIO_BASE+0x001C+5*0x24 #define PG_PILL1 GPIO_BASE+0x0020+5*0x24 #define PL_CFG0 GPIO_BASE+0x0000+6*0x24 //GPIOL0-7 #define PL_CFG1 GPIO_BASE+0x0004+6*0x24 //GPIOL8-15 #define PL_CFG2 GPIO_BASE+0x0008+6*0x24 //GPIOL17-21 #define PL_CFG3 GPIO_BASE+0x000C+6*0x24 //GPIOL #define PL_DAT GPIO_BASE+0x0010+6*0x24 //GPIOL_DAT #define PL_DRV0 GPIO_BASE+0x0014+6*0x24 #define PL_DRV1 GPIO_BASE+0x0018+6*0x24 #define PL_PILL0 GPIO_BASE+0x001C+6*0x24 #define PL_PILL1 GPIO_BASE+0x0020+6*0x24 #define PA_INT_CFG0 0x0200 + 0x00 + 0*0x20 #define PA_INT_CFG1 0x0200 + 0x04 + 0*0x20 #define PA_INT_CFG2 0x0200 + 0x08 + 0*0x20 #define PA_INT_CFG3 0x0200 + 0x0C + 0*0x20 #define PA_INT_CTL 0x0200 + 0x10 + 0*0x20 #define PA_INT_STA 0x0200 + 0x14 + 0*0x20 #define PA_INT_DEB 0x0200 + 0x18 + 0*0x20 #define PF_INT_CFG0 0x0200 + 0x00 + 1*0x20 #define PF_INT_CFG1 0x0200 + 0x04 + 1*0x20 #define PF_INT_CFG2 0x0200 + 0x08 + 1*0x20 #define PF_INT_CFG3 0x0200 + 0x0C + 1*0x20 #define PF_INT_CTL 0x0200 + 0x10 + 1*0x20 #define PF_INT_STA 0x0200 + 0x14 + 1*0x20 #define PF_INT_DEB 0x0200 + 0x18 + 1*0x20 #define PG_INT_CFG0 0x0200 + 0x00 + 2*0x20 #define PG_INT_CFG1 0x0200 + 0x04 + 2*0x20 #define PG_INT_CFG2 0x0200 + 0x08 + 2*0x20 #define PG_INT_CFG3 0x0200 + 0x0C + 2*0x20 #define PG_INT_CTL 0x0200 + 0x10 + 2*0x20 #define PG_INT_STA 0x0200 + 0x14 + 2*0x20 #define PG_INT_DEB 0x0200 + 0x18 + 2*0x20 #define LED_MAGIC 'L' #define LED_ON _IO(LED_MAGIC,1) #define LED_OFF _IO(LED_MAGIC,0) #endif

Makefile,把这里的KDIR改成你开发板内核源码对应目录,指定交叉编译工具链,如果没有什么问题,make会编译出led.ko,只要insmodled.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 <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <sys/ioctl.h> #include <stdlib.h> #include "led.h" int main(int argc, char *argv[]) { int fd; int cmd; if (argc <2 ) { printf("please enter the second para!\n"); return 0; } cmd = atoi(argv[1]); fd = open("/dev/myled",O_RDWR); if (cmd == 1) ioctl(fd,LED_ON); else ioctl(fd,LED_OFF); return 0; }

aarch64-Linux-gnu-gcc-o led_app led_app.c

通过

./led_app 0 

熄灭LED

./led_app 1 

点亮

然后随便浪吧
转载请注明原文地址: https://www.6miu.com/read-82757.html

最新回复(0)