设备树中的标准属性
1、compatible属性
描述“兼容性”,非常重要的属性。
gpio_spi:reg由spi4来决定的。address-cells 和size-cells 影响的是子节点reg属性而不是本节点。
#address-cells = <1>; //表示地址
#size-cells = <0>; //表示地址大小
表示reg里面只有一个address-cell。
解释说明:
2022.5.23 根节点下compatible属性作用
类型是字符串,根节点下的compatible,内核启动的时候会检查是否支持该平台或者机器。不使用设备树的情况下,根据machine id来判断是否支持此机器。
使用设备树之后,不使用机器ID,而是使用根节点/下的compatible属性。
正是因为 字符串匹配 所以可以启动内核。
和设备树中的内容可以匹配。
of函数
1、驱动如何获取设备树中的信息。在驱动中使用of函数获取设备树属性内容。
2、驱动要获取设备树节点内容,首先要找到节点。
如何使用of函数获取设备信息。
P6.9左忠凯手撕代码
/\*\*
\*my first driver
\*
\*/
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of\_address.h>
#include <linux/of\_irq.h>
#define LED\_MAJOR 200 //主设备号
#define LED\_NAME "LED" //驱动名称
#define NEWCHRLED\_NAME "newchrled"
#define NEWCHRLED\_COUNT 1
struct newchrled\_dev {
struct cdev cdev;
struct class \*class;/\*类:为了自动创建节点\*/
struct device \*device;/\*设备:为了自动创建节点\*/
dev\_t devid; //设备号
int major; //主设备号
int minor; //次设备号
};
struct newchrled\_dev newchrled; //led设备
#if 0
backlight {
compatible = "pwm-backlight";
pwms = <&pwm1 0 5000000>;
brightness-levels = <0 4 8 16 32 64 128 255>;
default-brightness-level = <7>;
status = "okay";
};
#endif
static int __init dtsof\_init(void)
{
int ret = 0; //
/\*1、找到backlight节点,/路径是:/backlight /\*/
struct device\_node \*bl_nd = NULL;/\*节点\*/
struct property \*comppro = NULL;
const char \*\*str = NULL;
u32 def_value = 0;
/\*内核动态申请内存\*/
u32 \*brival;
u32 elemsize = 0;
bl_nd = of\_find\_node\_by\_path("/backlight");
if (bl_nd == NULL){ /\*失败\*/
ret = -EINVAL;
goto fail_findnd;
}
/\*2、获取属性\*/
comppro = of\_find\_property(bl_nd,"compatible",NULL);
if (comppro == NULL){ /\*失败\*/
ret = -EINVAL;
goto fail_findpro;
}else{
printk("compatible = %s",(char\*)comppro->value);
}
ret = of\_property\_read\_string(bl_nd,"status",str);
if (ret < 0){
goto fail_rs;
}
/\*3、获取数字属性值\*/
ret = of\_property\_read\_u32(bl_nd,"default-brightness-level",&def_value);
if (ret<0){
goto fail_read32;
}else{
printk("default-brightness-level = %d \r\n",def_value);
}
/\*4、获取数组类型的属性\*/
elemsize = of\_property\_count\_elems\_of\_size(bl_nd,"brightness-levels",sizeof(u32));
if (elemsize<0){
ret = -ENAVAIL;
goto fail_readele;
}else{
printk("brightness-levels = %d \r\n",ret);
}
/\*申请内存\*/
brival = kmalloc(elemsize \* sizeof(u32),GFP_KERNEL);
if(!brival){
ret = -EINVAL;
goto fail_mem;
}
/\*获取数组\*/
ret = of\_property\_read\_u32\_array(bl_nd,"brightness-levels",brival,elemsize);
if (ret<0){
ret = -EINVAL;
goto fail_read32array;
} else {
u8 i = 0;
for (i = 0; i < elemsize; i++){
printk("brightness-levels[%d] = %d \r\n",i,\*(brival+i));
}
}
kfree(brival);
return 0;
fail_read32:
fail_findnd:
fail_findpro:
fail_rs:
fail_readele:
fail_mem:
fail_read32array:
return ret;
}
static void __exit dtsof\_exit(void)
{
}
//模块加载函数
module\_init(dtsof_init);
//模块卸载
module\_exit(dtsof_exit);
MODULE\_LICENSE("GPL");
MODULE\_AUTHOR("qhy");
出了一点小问题,编译的驱动和加载的驱动不匹配,搞了不少时间,外加网络配置也出现一点问题。
设备树下的led驱动
设备节点最好添加到好区分的节点。添加到1级节点。
设备树添加如下信息。
/\*qhy 2022.5.24\*/
alphaled {
#address-cells = <1>;
#size-cells = <1>;
compatible = "atkalpha-led";
status = "okay";
reg = < 0X020C406C 0X04 /\* CCM\_CCGR1\_BASE \*/
0X020E0068 0X04 /\* SW\_MUX\_GPIO1\_IO03\_BASE \*/
0X020E02F4 0X04 /\* SW\_PAD\_GPIO1\_IO03\_BASE \*/
0X0209C000 0X04 /\* GPIO1\_DR\_BASE \*/
0X0209C004 0X04 >; /\* GPIO1\_GDIR\_BASE \*/
};
复制设备树到tftp目录下
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年嵌入式&物联网开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新!!
g-u7Zg0TlZ-1715757233445)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上嵌入式&物联网开发知识点,真正体系化!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新!!