全志A33 linux led驱动编程(附实测参考代码)
发表于:2025-12-02 作者:千家信息网编辑
千家信息网最后更新 2025年12月02日,开发平台开发平台* 芯灵思SinlinxA33开发板淘宝店铺: https://sinlinx.taobao.com/嵌入式linux 开发板交流 QQ:641395230#实验原理在芯灵思开发板上
千家信息网最后更新 2025年12月02日全志A33 linux led驱动编程(附实测参考代码)
开发平台

开发平台
* 芯灵思SinlinxA33开发板淘宝店铺: https://sinlinx.taobao.com/
嵌入式linux 开发板交流 QQ:641395230
#实验原理
在芯灵思开发板上,没有led灯模块,只能通过引脚电平观察: 这里我选择LS-INT引脚。
全志A33一共有10组IO口,每组IO有9个相关功能控制器,LS-INT属于PB7,相关寄存器如图
本次实验只用到这两个寄存器,在程序中命名为gpio_con,gpio_dat ,设置为输出引脚。
- 1)注册 class_register(class) 将class注册到内核中。调用前,必须手动分配class内存;调用后必须设置class的name等参数注册 class_create(owner,name) 创建class并将class注册到内核中。返回值为class结构体指针。注销 void class_unregister(struct class cls) 注销class,与class_register()配对使用。注销void class_destroy(struct class cls) 注销class,与class_create()配对使用内核中定义了struct class结构体顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用device_create(…)函数来在/dev目录下创建相应的设备节点。这样,加载模块的时候,用户空间中的udev会自动响应device_create(…)函数,去/sysfs下寻找对应的类从而创建设备节点.
- 2)void ioremap(unsigned long phys_addr , unsigned long size , unsigned long flags)用mmap映射一个设备意味着使用户空间的一段地址关联到设备内存上,这使得只要程序在分配的地址范围内进行读取或写入实际上就是对设备的访问。解除映射void iounmap(void addr)//取消ioremap所映射的IO地址
- 3)register_chrdev(unsigned int major, const char name,const struct file_operations fops);
但其实这个函数是linux版本2.4之前的注册方式,它的原理是:- (1)确定一个主设备号,如果major=0,则会自动分配设备号
- (2)构造一个file_operations结构体, 然后放在chrdevs数组中
- (3)注册:register_chrdev,cat /proc/devices查看内核中已经注册过的字符设备驱动(和块设备驱动),注意这里并不是驱动文件设备节点!
- 4) Linux使用file_operations结构访问驱动程序的函数,这个结构的每一个成员的名字都对应着一个调用
- 5) class_device_create() 调用class_create为该设备创建一个class,再为每个设备调用 class_device_create创建对应的设备。大致用法如下:struct class *myclass = class_create(THIS_MODULE, "my_device_driver");class_device_create(myclass, NULL, MKDEV(major_num, 0), NULL, "my_device");这样的module被加载时,udev daemon就会自动在/dev下创建my_device设备件。
总体代码框架
1)先要有file_operations先要有引脚初始化函数myled_init(void),在myled_init里面注册class并将class类注册到内核中创建设备节点,初始化引脚已经将寄存器地址映射到虚拟内存中,最后调用module_init(myled_init)驱动的加载就靠它2)创建这个file_operations结构体 static struct file_operations myled_oprs = { .owner = THIS_MODULE, .open = led_open, .write = led_write, .release = led_release, }; 下面就围绕这个结构体写函数led_write() led_open() led_release()3)最后要注销设备附实测代码,参考下
LED驱动代码:
#include #include #include #include #include #include #include #include #include #include #include static int major;static struct class *led_class;volatile unsigned long *gpio_con = NULL;volatile unsigned long *gpio_dat = NULL;static int led_open (struct inode *node, struct file *filp){ /* PB7 - 0x01C20824 */ if (gpio_con) { printk("ioremap 0x%x\n", gpio_con); } else { return -EINVAL; } return 0;}static ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *off){ unsigned char val; copy_from_user(&val, buf, 1); if (val) { *gpio_dat |= (1<<7); } else { *gpio_dat &= ~(1<<7); } return 1; }static int led_release (struct inode *node, struct file *filp){ printk("iounmap(0x%x)\n", gpio_con); iounmap(gpio_con); return 0;}static struct file_operations myled_oprs = { .owner = THIS_MODULE, .open = led_open, .write = led_write, .release = led_release,};static int myled_init(void){ major = register_chrdev(0, "myled", &myled_oprs); led_class = class_create(THIS_MODULE, "myled"); device_create(led_class, NULL, MKDEV(major, 0), NULL, "ledzzzzzzzz"); gpio_con = (volatile unsigned long *)ioremap(0x01C20824, 1); //0x01C20824 gpio_dat = gpio_con + 4; //0x01C20834 *gpio_con &= ~(7<<28); *gpio_con |= (1<<28); *gpio_dat &= ~(1<<7); return 0;} APP代码:
#include #include #include #include #include #include #include #include #include #include #include static int major;static struct class *led_class;volatile unsigned long *gpio_con = NULL;volatile unsigned long *gpio_dat = NULL;static int led_open (struct inode *node, struct file *filp){ /* PB7 - 0x01C20824 */ if (gpio_con) { printk("ioremap 0x%x\n", gpio_con); } else { return -EINVAL; } return 0;}static ssize_t led_write (struct file *filp, const char __user *buf, size_t size, loff_t *off){ unsigned char val; copy_from_user(&val, buf, 1); if (val) { *gpio_dat |= (1<<7); } else { *gpio_dat &= ~(1<<7); } return 1; }static int led_release (struct inode *node, struct file *filp){ printk("iounmap(0x%x)\n", gpio_con); iounmap(gpio_con); return 0;}static struct file_operations myled_oprs = { .owner = THIS_MODULE, .open = led_open, .write = led_write, .release = led_release,};static int myled_init(void){ major = register_chrdev(0, "myled", &myled_oprs); led_class = class_create(THIS_MODULE, "myled"); device_create(led_class, NULL, MKDEV(major, 0), NULL, "ledzzzzzzzz"); gpio_con = (volatile unsigned long *)ioremap(0x01C20824, 1); //0x01C20824 gpio_dat = gpio_con + 4; //0x01C20834 *gpio_con &= ~(7<<28); *gpio_con |= (1<<28); *gpio_dat &= ~(1<<7); return 0;} Makefile代码:
#include #include #include /* ledtest on * * ledtest off * */int main(int argc, char **argv){ int fd; unsigned char val = 1; fd = open("/dev/ledzzzzzzzz", O_RDWR); if (fd < 0) { printf("can't open!\n"); } if (argc != 2) { printf("Usage :\n"); printf("%s \n", argv[0]); return 0; } if (strcmp(argv[1], "on") == 0) { val = 1; } else { val = 0; } write(fd, &val, 1); return 0;}
设备
结构
函数
驱动
内核
代码
开发
地址
节点
内存
寄存器
程序
分配
原理
平台
开发平台
模块
用户
空间
设备驱动
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
数据库的四个对象
特朗普网络安全规划
云服务器拿来做啥
昆山富士康软件开发
福建华兴软件开发有限公司
卫生行业数据库安全解决方案
网络安全地方立法
网络技术路由交换
青浦区正规软件开发哪家好
广州东信达软件开发有限公司
合肥慧通网络技术有限公司
梦幻古龙数据库
mc网易版能玩速建的服务器
浏览器和服务器交互哪个方式好
西青区咨询网络技术售后服务
打印服务器恢复出厂之后
网络安全法宣传文案
配置文件存数据库优劣
网络安全指南和安全评估文档
nist标准质谱数据库
大学生网络安全报告
庭瑞网络技术有限公司招聘
建行的软件开发岗
ios 线程 数据库
学网络技术等基础
怎么访问阿里云数据库
不属于关系数据库的范畴
apex 服务器不同步
山东商业软件开发市场报价
医院网络安全责任落实情况