芯灵思Sinlinx A64 linux 通过设备树写LED
发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,开发平台 芯灵思Sinlinx A64内存: 1GB 存储: 4GB详细参数 https://m.tb.cn/h.3wMaSKm开发板交流群 641395230全志A64设备树结构体#include
千家信息网最后更新 2026年11月01日芯灵思Sinlinx A64 linux 通过设备树写LED
开发平台 芯灵思Sinlinx A64
内存: 1GB 存储: 4GB
详细参数 https://m.tb.cn/h.3wMaSKm
开发板交流群 641395230
全志A64设备树结构体
#include <linux/of.h> //设备树里的每个设备及每个设备子节点都用此结构体描述
struct device_node{ const char *name; const char *type; phandle phandle; const char *full_name; struct property *properties; //属性 struct property *deadprops; /* removed properties */ struct device_node *parent; //在设备子节点对象,指向属于的设备对象 struct device_node *child; //在设备对象,指向子节点 struct device_node *sibling; //指向同级的下一个对象. struct device_node *next; /* next device of same type */ //应是指向device_type是同样的对象 struct device_node *allnext; /* next in list of all nodes */ ...};//下面函数用于获取设备树里的设备节点及设备子节点extern struct device_node *of_find_node_by_name(struct device_node *from, const char *name);
//通过名字查找相应的设备节点static inline int of_get_child_count(const struct device_node *np);
//获取指定设备的子节点个数extern struct device_node *of_find_node_by_path(const char *path);
//通过路径来获取设备节点,可用于获取设备子节点extern struct device_node *of_find_node_by_type(struct device_node *from, const char *type); //通过指定的device_type来获取设备节点
//下面函数用于获取设备节点或设备子节点的属性
static inline int of_property_read_u32(const struct device_node *np, const char *propname, u32 *out_value)extern int of_property_read_u32_index(const struct device_node *np, const char *propname, u32 index, u32 *out_value);extern int of_property_read_u8_array(const struct device_node *np, const char *propname, u8 *out_values, size_t sz);extern int of_property_read_u16_array(const struct device_node *np, const char *propname, u16 *out_values, size_t sz);extern int of_property_read_u32_array(const struct device_node *np, const char *propname, u32 *out_values, size_t sz);extern int of_property_read_u64(const struct device_node *np, const char *propname, u64 *out_value);extern int of_property_read_string(struct device_node *np, const char *propname, const char **out_string)首先增加节点,修改dtsi文件。vim /lichee/linux-3.10/arch/arm64/boot/dts/sun50iw1p1-pinctrl.dtsi
驱动代码:
#include #include #include #include #include #include #include #include #include #include #include #include #define MY_DEVICE_NAME "my_led_device" // 获取到设备树中到节点 static int gpio = -1; int get_irqno_from_node(void) { struct gpio_config config; struct device_node *np = of_find_node_by_path("/leds"); if(np){ printk("find node ok\n"); } else{ printk("find node failed\n"); } gpio = of_get_named_gpio_flags(nd, "gpios", i, (enum of_gpio_flags *)&config);// 从设备树中读取gpios的GPIO配置编号和标志 if(!gpio_is_valid(gpio)){ //判断该 GPIO 编号是否有效,有效gpio_request 则申请占用该 GPIO。如果初始化过程出错,需要调用 gpio_free 来释放之前申请过且成功的 GPIO printk("gpio isn't valid\n"); return -1; } if(gpio_request(gpio, "leds") < 0) printk("gpio request failed %d\n", gpio); gpio_direction_output(gpio, 1); //关灯 return 0; } static int my_open (struct inode *node, struct file *filp) { if(gpio) { printk("open ok\n"); } else { return -EINVAL; } return 0; } static ssize_t my_write (struct file *filp, const char __user *buf, size_t size, loff_t *off) { unsigned char val; copy_from_user(&val, buf, 1); printk(" gpl_dat address 0x%x\n",gpl_dat); if (val) { gpio_direction_output(gpio, 0); //关灯 printk("led on\n"); } else { gpio_direction_output(gpio, 1); //关灯 printk("led off\n"); } return 1; } static const struct file_operations my_led_fops = { //step 1 :定义file_operations结构体 .open = my_open, .write = my_write, }; //step 1 : static struct class *led_class; static struct cdev *pcdev; //定义一个cdev指针 static dev_t n_dev; //第一个设备号(包含了主和次) static int __init led_device_init(void) {//step 2 :注册 int ret = -1; pcdev = cdev_alloc();//分配cdev结构空间 if(pcdev == NULL) { printk(KERN_EMERG" cdev_alloc error\n"); ret = -ENOMEM; /* 分配失败 */ return ret; } //2. 动态申请设备号 ret = alloc_chrdev_region(&n_dev, 0 , 2, MY_DEVICE_NAME); if(ret < 0 ) { //释放前面成功的资源 kfree(pcdev); /*释放cdev结构空间 */ printk(KERN_EMERG"alloc_chrdev_region error\n"); return ret; } cdev_init(pcdev, &my_led_fops); //初始化cdev结构 /* 建立cdev和file_operations之间的连接 */ /* 或这样初始化cdev结构 pcdev->owner = THIS_MODULE; pcdev->ops = &my_led_fops; */ ret = cdev_add(pcdev, n_dev, 2) ;// 向内核里面添加一个驱动,注册驱动 if(ret < 0 ) { //释放前面成功的资源 unregister_chrdev_region(n_dev, 2); /* 释放前面申请的调和号*/ kfree(pcdev); /* 释放cdev结构空间 */ printk(KERN_EMERG"alloc_chrdev_region error\n"); return ret; } /*自动创建设备节点/dev/SinlinxA64_LED*/ led_class = class_create(THIS_MODULE, "myled"); device_create(led_class, NULL, n_dev, NULL, "SinlinxA64_LED"); get_irqno_from_node(); printk(KERN_EMERG"cdev ok\n"); return 0; } static void __exit led_device_exit(void) { //step 2 :注销 //注销cdev结构 cdev_del(pcdev); //释放设备号 unregister_chrdev_region(n_dev, 2); /*起始设备号(主、次) 连续的次设备号数量*/ //释放cdev结构空间 kfree(pcdev); device_destroy(led_class, n_dev); class_destroy(led_class); gpio_free(gpio); printk(KERN_EMERG"cdev_del ok\n"); } module_init(led_device_init); module_exit(led_device_exit); MODULE_LICENSE("GPL"); 参考文章:https://blog.csdn.net/jklinux/article/details/82382066
设备
节点
结构
对象
指向
空间
驱动
有效
成功
函数
属性
分配
开发
个数
代码
内存
内核
动态
参数
同级
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
互联网金融科技
有格互联网科技
互联网科技公司排名
互联网科技行业发展
互联网是不是新科技
新华互联网科技学院
互联网 科技公司
中国 科技 互联网
互联网科技集团
西安互联网科技公司
狮子座互联网科技培训
中国科技创新与世界互联网大会
广东工业互联网大赛深圳学泰科技
互联网领先科技宣传片
互联网科技股为什么大涨
上海同邻互联网科技有限公司规模
上海万顺科技互联网有限公司招聘
唐山双旺合互联网科技产业园
河南商务圈互联网科技有限公司
互联网领先科技成果宣传视频
百单网互联网科技有限公司怎么样
互联网科技公司起名
蓝思科技飞鸽互联网
北京互联网科技公司
融势互联网科技
剑昆互联网络科技有限公司临桂
央行互联网金融科技公司
未来五年的互联网科技
美国五大互联网科技公司市值多少
现代互联网科技公司