Linux内核驱动开发-符设备开发-001Led驱动

/************************************************************************* > File Name: led.c > Author: yas > Mail: rage_yas@hotmail.com > Created Time: 2024年04月21日 星期日 16时20分42秒 ************************************************************************/ #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> #include <linux/fs.h> #include <asm/uaccess.h> #include <asm/io.h> #if 0 /*数据类型重定义*/ typedef unsigned char u8; typedef unsigned int u32; #endif #define DEVICE_MAJOR 200 #define DEVICE_NAME "led_device" /*寄存器地址映射*/ #define GPBCON (0x56000010) #define GPBDAT (0x56000014) /**/ unsigned int *regGPBCON; unsigned int *regGPBDAT; /*led函数声明*/ void led_init(void); void led_off(void); void led_on(u8 n); void led_on_off(u8 n); void delay_nms(u32 t); /*驱动函数声明*/ void r_ioremap(void); static int __init led_driver_init(void); ssize_t led_driver_write(struct file *fp, const char __user *user_buffer, size_t len, loff_t *offset); static void __exit led_driver_exit(void); int led_driver_open(struct inode *node, struct file *fp); ssize_t led_driver_read(struct file *fp, char __user *user_buffer, size_t len, loff_t *offset); int led_driver_close(struct inode *node, struct file *fp); /*定义结构体变量*/ static struct file_operations fops = { .owner = THIS_MODULE, .open = led_driver_open, .read = led_driver_read, .write = led_driver_write, .release = led_driver_close }; #if 1 /******************************************************************************* * 函 数 名 : r_ioremap * 函数功能 : 寄存器映射 * 输 入 :无 * 输 出 :无 *******************************************************************************/ void r_ioremap(void) { /*寄存器映射*/ regGPBCON = ioremap(GPBCON, 4);//【源地址】【需要映射的地址大小】<返回目标地址> regGPBDAT = ioremap(GPBDAT, 4); } #endif #if 0 static int __init led_driver_init(void) { unsigned int t; /*注册字符设备*/ register_chrdev(DEVICE_MAJOR, DEVICE_NAME, &fops); /*寄存器映射*/ regGPBCON = ioremap(GPBCON, 4);//【源地址】【需要映射的地址大小】<返回目标地址> regGPBDAT = ioremap(GPBDAT, 4); t = *regGPBCON; t &= ~((3 << 10) | (3 << 12) | (3 << 14) | (3 << 16)); t |= (1 << 10) | (1 << 12) | (1 << 14) | (1 << 16); *regGPBCON = t; printk("led_driver_init OK\n"); return 0; } #endif #if 1 /******************************************************************************* * 函 数 名 : led_driver_init * 函数功能 : led驱动初始化 * 输 入 :无 * 输 出 :无 *******************************************************************************/ static int __init led_driver_init(void) { /*注册字符设备*/ register_chrdev(DEVICE_MAJOR, DEVICE_NAME, &fops); /*寄存器映射*/ r_ioremap();//每次调用led函数都要先调用寄存器映射函数? /*led初始化*/ led_init(); printk("led_driver_init OK\n"); return 0; } #endif #if 1 int led_driver_open(struct inode *node, struct file *fp) { return 0; } #endif #if 1 ssize_t led_driver_read(struct file *fp, char __user *user_buffer, size_t len, loff_t *offset) { return 0; } #endif #if 0 ssize_t led_driver_write(struct file *fp, const char __user *user_buffer, size_t len, loff_t *offset) { char n; unsigned int t; copy_from_user(&n, user_buffer, 1); n &= 0x0F; t = *regGPBDAT; t &= ~(0x0F << 5); t |= n << 5; *regGPBDAT = t; return 1; } #endif #if 1 /******************************************************************************* * 函 数 名 : led_driver_write * 函数功能 : led驱动写数据 * 输 入 : * fp: * user_buffer: * offset: * 输 出 :无 *******************************************************************************/ ssize_t led_driver_write(struct file *fp, const char __user *user_buffer, size_t len, loff_t *offset) { char n; copy_from_user(&n, user_buffer, 1); led_on(n); return 1; } #endif #if 1 int led_driver_close(struct inode *node, struct file *fp) { return 0; } #endif #if 1 /******************************************************************************* * 函 数 名 : led_driver_exit * 函数功能 : 退出led驱动 * 输 入 : 无 * 输 出 : 无 *******************************************************************************/ static void __exit led_driver_exit(void) { unregister_chrdev(DEVICE_MAJOR, DEVICE_NAME); printk("led_driver_exit OK\n"); } #endif /*=========================led配置函数=========================*/ /******************************************************************************* * 函 数 名 : led_init * 函数功能 : LED初始化 * 输 入 :无 * 输 出 :无 *******************************************************************************/ //LED1-GPB5,LED2-GPB6,LED3-GPB7,LED4-GPB8 void led_init(void) { u32 t=0; t=*regGPBCON;//思考点:这里为何要使用中间变量配置寄存器? t&=~((3<<10)|(3<<12)|(3<<14)|(3<<16));//LED控制引脚清0 t|=(1<<10|1<<12|1<<14|1<<16);//LED控制引脚配置-输出状态 *regGPBCON=t;//配置端口B引脚 led_off();//初始化LED为关闭 } /******************************************************************************* * 函 数 名 : led_on * 函数功能 : 打开指定的LED * 输 入 : n:打开第几个LED * 输 出 : 无 *******************************************************************************/ void led_on(u8 n) { u8 i=0; for(i=0;i<n;i++) { *regGPBDAT&=~(1<<(4+n));//配置端口B的数据寄存器 } // *regGPBDAT&=~(1<<5);//配置端口B的数据寄存器 } /******************************************************************************* * 函 数 名 : led_on_off * 函数功能 : 指定的LED闪烁 * 输 入 : n:第几个LED闪烁 * 输 出 : 无 *******************************************************************************/ void led_on_off(u8 n) { led_on(n); delay_nms(2000); led_off(); delay_nms(2000); } /******************************************************************************* * 函 数 名 : led_off * 函数功能 : 关闭LED * 输 入 :无 * 输 出 :无 *******************************************************************************/ void led_off(void) { *regGPBDAT|=(1<<5|1<<6|1<<7|1<<8);//配置端口B的数据寄存器 } /******************************************************************************* * 函 数 名 : delay_nms * 函数功能 : 延时nms * 输 入 : * t:延时时间 * 输 出 : 无 *******************************************************************************/ void delay_nms(u32 t) { u32 i=0; u32 j=0; for(i=0;i<t;i++) { for(j=0;j<100;j++); } } module_init(led_driver_init); module_exit(led_driver_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("XXX");
上一篇:Https网站接口被黑被恶意调取


下一篇:如何在本地创建一个贪吃蛇小游戏node.js服务并实现无公网IP远程游玩