Linux 设备树学习——基于i2c总线分析

I2C驱动实验:向设备树添加 I2C设备的设备节点信息 阅读详情

博客说明

撰写日期2019.11.18
完稿日期2019.11.20
最近维护暂无
本文作者multimicro
联系方式multimicro@qq.com
资料链接本文无附件资料
GitHubhttps://github.com/wifialan/drivers/tree/master/device_tree_i2c
原文链接https://blog.youkuaiyun.com/multimicro/article/details/103129546

开发环境

环境说明详细信息备注信息
操作系统Ubunut 18.04
开发板JZ2440-V3
u-bootuboot-2012.04.01
busyboxbusybox-1.22.1
u-boot和busybox编译器arm-linux-gcc (4.4.3)
Linux内核linux-4.19-rc3
Linux内核编译器arm-linux-gnueabi-gcc (4.9.4)

1. 如何使用设备树

设备树,顾名思义,是描述物理设备的文件,里面的节点包含特定设备下的硬件信息。使用设备树,需要做两方面工作:其一,开启u-boot支持设备树的功能;其二:使用支持设备树的内核版本。

1.1 u-boot支持设备树

  • 在u-boot工程中,增添一行命令在板级配置文件中:
    #define CONFIG_OF_LIBFDT
    我用的是S3C2440,所以应该在include/configs/smdk2440.h中增添上述命令行,然后重新编译即可得到支持设备树的u-boot。

  • 在u-boot启动过程中,在把控制权交给内核前,会对内存进行分区,那么因此,也需要让u-boot启动时,为设备树分配一定的内存空间,具体操作是:
    继续修改include/configs/smdk2440.h文件,在里面这个位置增加图示代码:

在这里插入图片描述
重新编译,烧录,在u-boot命令行中输入mtdparts即可查看分区情况

在这里插入图片描述
这就在之前的u-boot基础上得到了一个支持设备树的u-boot,可以在对应的内存空间中烧写相应的文件。

1.2 Linux内核支持设备树

我使用的是韦东山提供的Linux内核以及补丁包,采用Linux-4.19.3-rc内核版本。

打补丁:
patch -p1<../linux-4.19-rc3_device_tree_for_jz2440.patch
编内核:
cp config_ok .config
make ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/4.9.4/bin/arm-linux-gnueabi- menuconfig
make ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/4.9.4/bin/arm-linux-gnueabi- uImage -j8
make ARCH=arm CROSS_COMPILE=/opt/FriendlyARM/toolschain/4.9.4/bin/arm-linux-gnueabi- dtbs -j8

执行完后,会在arch/arm/boot/文件夹下得到uImage,在arch/arm/boot/dts/文件夹下得到*.dtb

1.3 如何在开发板中使用设备树

为了减少学习时对开发板的FLASH擦写,这里一直使用tftp服务将内核和设备树文件的直接传递给内存中运行,而u-boot和文件系统busybox则固化在FLASH中,从Linux-3.4.2过渡过来的busybox可以直接使用,但需要提醒一下,之前的busybox是在第三分区,而增加设备树分区后的busybox被挪到了第四分区:
在这里插入图片描述
因此,在bootargs命令中,应该修改root挂载到/dev/mtdblock4分区下

set bootargs console=ttySAC0,115200 root=/dev/mtdblock4 rw init=/linuxrc

现在开始通过tftp服务加载内核和设备树,tftp服务器搭建参考:在Linux系统下通过TFTP或NFS烧写内核
在u-boot命令行中输入:

tftp 31000000 uImage; tftp 32000000 jz2440_irq.dtb; bootm 31000000 - 32000000

bootm 命令介绍,若ramdisk没有,则用"-"号替代
bootm + uImage地址 + ramdisk地址 + 设备树镜像地址

在这里插入图片描述
可以看到,设备树已经成功被uImage加载。

2. 设备树介绍

  • Linux uses DT data for three major purposes:
    1) platform identification,
    2) runtime configuration, and
    3) device population.

  • 我用设备树主要是方便其加载硬件设备信息,不需要在内核中增加比如spi_register_board_info这样的设备注册函数,通过重新编译内核来实现device的注册。现在在利用设备树时,若增加某个设备,那么只需要修改设备树中的相关信息,那么重新编译设备树让内核重新加载,即可便捷的注册某device。非设备树注册device可参考spi_device的注册过程: 2.2 spi_device注册

  • 在根文件系统中查看设备树(有助于调试)
    a. /sys/firmware/fdt // 原始dtb文件
     hexdump -C /sys/firmware/fdt//查看dtb文件内容
    b. /sys/firmware/devicetree // 以目录结构程现的dtb文件, 根节点对应base目录, 每一个节点对应一个目录, 每一个属性对应一个文件
    c. /sys/devices/platform // 系统中所有的platform_device, 有来自设备树的, 也有来有.c文件中注册的
     对于来自设备树的platform_device, 可以进入 /sys/devices/platform/<设备名>/of_node 查看它的设备树属性
    d. /proc/device-tree是链接文件, 指向 /sys/firmware/devicetree/base

2.1 设备树中的设备驱动节点

  • sys/devices/platform/
    在sys/devices/platform/文件夹下面可以看到通过设备树注册进来的根设备(子设备都在根设备文件夹内的of_node文件夹下):

在这里插入图片描述
进入其中一个文件夹,如54000000.i2c可以看到一个文件夹of_node,里面包含了i2c节点下的子节点设备信息:

在这里插入图片描述
红框中of_node被链接到了/sys/firmware/devicetree/base/i2c@54000000/文件夹下(由此也验证,设备树中的所有信息都在/sys/firmware/devicetree/base文件夹里面),那么该文件夹中信息有那些呢?

  • sys/firmware/devicetree/base

tree命令: 将tree源码交叉编译后的文件放到busybox下的/bin/文件夹下方可使用

在这里插入图片描述
设备树中,i2c节点下的设备子节点信息如下:

在这里插入图片描述
通过上述两张图,可以看出eeprom设备节点被成功加载到了内核中去,其依附于i2c设备。现在想想,树状关系是不是有点雏形了,一个根设备(i2c)下面伸出了一个枝干(eeprom)。

  • sys/bus/i2c/

设备树注册进来的总线设备,可以在sys/bus/文件夹下找到,比如i2c、spi总线等

在sys/bus/i2c/目录下面可以看到i2c总线下面的device和driver信息

在这里插入图片描述
若内核中注册了相应的i2c drivers,那么通过名字匹配成功后(具体的匹配方式下面会写),会调用相应的probe函数将driver和device连在一起

在这里插入图片描述

2.2 设备树匹配流程

通过设备树注册进来的device,是如何匹配到对应的driver呢,本节仍然以i2c总线的匹配为例进行介绍。

spi总线和platform总线也是类似的,本节结尾我会贴出这两个总线的匹配程序供参考,会发现,这玩意儿,就是一通百通。

2.2.1 以i2c匹配为例

i2c中的匹配函数在如下文件内

drivers/i2c/i2c-core-base.c : line 101

static int i2c_device_match(struct device *dev, struct device_driver *drv)
{
	struct i2c_client	*client = i2c_verify_client(dev);
	struct i2c_driver	*driver;

	/* Attempt an OF style match */
	if (i2c_of_match_device(drv->of_match_table, client))
		return 1;

	/* Then ACPI style match */
	if (acpi_driver_match_device(dev, drv))
		return 1;

	driver = to_i2c_driver(drv);

	/* Finally an I2C match */
	if (i2c_match_id(driver->id_table, client))
		return 1;

	return 0;
}

从上述流程中可以得知,通过调用i2c_device_match函数实现i2c设备和驱动的匹配,匹配流程为:

下面也是匹配的优先顺序

  • 1st: /* Attempt an OF style match */

    设备树中i2c子设备节点下的compatible属性值和内核驱动程序中所定义的of_device_id结构体中的compatible属性值 是否完全相同,在linux-4.19-rc3内核版本中,采用of_compat_cmp函数(原型为strcasecmp函数,由drivers/of/base.c :line454: __of_device_is_compatible调用)来匹配两个值是否相同

  • 2nd: /* Then ACPI style match */

    设备树不涉及这种匹配方式,忽略

  • 3rd: /* Finally an I2C match */

    设备树不涉及这种匹配方式,但此种方式是在没有采用设备树时的匹配方式:platform_device结构体定义的.name 字段(至于怎么传入client先留个疑问)和 驱动程序中所定义的i2c_device_id结构体中的.name字段属性值是否完全相同,在linux-4.19-rc3内核版本中,采用i2c_match_id函数(drivers/i2c/i2c-core-base.c :line86)来匹配两个值是否相同


下面举例介绍一下设备树中驱动的匹配

  • /* Attempt an OF style match */

如下将at24_of_match定义为了一个of_device_id结构体,里面包含compatible属性,和设备树中子设备节点下的compatible属性值进行匹配。倘若设备树中子设备节点eeprom@50中compatible = "atmel,24c256",那么就会匹配成功,调用probe函数

driver端    内核程序

  static const struct of_device_id at24_of_match[] = {
	{ .compatible = "atmel,24c00",		.data = &at24_data_24c00 },
	{ .compatible = "atmel,24c01",		.data = &at24_data_24c01 },
	{ .compatible = "atmel,24cs01",		.data = &at24_data_24cs01 },
 		...	//此处省略了一部分
	{ .compatible = "atmel,24c256",		.data = &at24_data_24c256 },
	{ .compatible = "atmel,24c512",		.data = &at24_data_24c512 },
	{ .compatible = "atmel,24c1024",	.data = &at24_data_24c1024 },
	{ /* END OF LIST */ },
};

device端    设备树程序

在这里插入图片描述


  • /* Finally an I2C match */

    对比通过内核注册i2c device,匹配方式

driver端    内核程序

static const struct i2c_device_id at24_ids[] = {
	{ "24c00",	(kernel_ulong_t)&at24_data_24c00 },
	{ "24c01",	(kernel_ulong_t)&at24_data_24c01 },
	{ "24cs01",	(kernel_ulong_t)&at24_data_24cs01 },
		...	//此处省略了一部分
	{ "24c256",	(kernel_ulong_t)&at24_data_24c256 },
	{ "24c512",	(kernel_ulong_t)&at24_data_24c512 },
	{ "24c1024",	(kernel_ulong_t)&at24_data_24c1024 },
	{ "at24",	0 },
	{ /* END OF LIST */ }
};

device端    内核程序

static struct i2c_board_info __initdata da830_evm_i2c_devices[] = {
	{
		I2C_BOARD_INFO("24c256", 0x50),
		.platform_data	= &da830_evm_i2c_eeprom_info,
	},
};

  • 附spi总线和platform总线的匹配程序
  1. spi总线  drivers/spi/spi.c
static int spi_match_device(struct device *dev, struct device_driver *drv)
{
	const struct spi_device	*spi = to_spi_device(dev);
	const struct spi_driver	*sdrv = to_spi_driver(drv);

/* Attempt an OF style match */
if (of_driver_match_device(dev, drv))
	return 1;

/* Then try ACPI */
if (acpi_driver_match_device(dev, drv))
	return 1;

if (sdrv->id_table)
	return !!spi_match_id(sdrv->id_table, spi);

return strcmp(spi->modalias, drv->name) == 0;

}
  1. platform总线  drivers/base/platform.c
static int platform_match(struct device *dev, struct device_driver *drv)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct platform_driver *pdrv = to_platform_driver(drv);


	/* When driver_override is set, only bind to the matching driver */
	if (pdev->driver_override)
		return !strcmp(pdev->driver_override, drv->name);

	/* Attempt an OF style match first */
	if (of_driver_match_device(dev, drv))
		return 1;

	/* Then try ACPI style match */
	if (acpi_driver_match_device(dev, drv))
		return 1;

	/* Then try to match against the id table */
	if (pdrv->id_table)
		return platform_match_id(pdrv->id_table, pdev) != NULL;

	/* fall-back to driver name match */
	return (strcmp(pdev->name, drv->name) == 0);
}

韦东山在设备树视频里面讲解的匹配流程就是基于platform总线的,见下图(单击放大后观看),而i2c总线和spi总线的匹配优先级方式可以根据各自对应的源码分析。现在再看这张图,理解的会更上一层楼。i2c总线和spi总线的匹配结构也可以仿照这张图绘制出来
在这里插入图片描述

2.2.2 设备树匹配下的程序模板

下面梳理一下i2c总线的device注册和driver注册以及匹配程序流程,spi总线和platform总线流程也基本都是一个套路,学会一个,其他的就会很好理解了。

  • 设备树端

    代码在git上:jz2440_irq.dts

    在设备树dts文件中的i2c总线节点下面,创建一个新的子设备节点(eeprom@50),需要注意的是,通过设备树注册的i2c设备会转换为一个i2c client,不像spi设备会转换为一个spi device。

  1. compatible 的值是用于和driver匹配的
  2. reg 的值是相应的寄存器
  3. status = "okay"是启用该设备

dts文件:

	&i2c {
    status = "okay";
    samsung,i2c-max-bus-freq = <200000>;
    eeprom@50 {
        compatible = "atmel,24c256";
        reg = <0x50>;
        pagesize = <32>;
        status = "okay";
    };  
};

下面是上述dts文件中所包含的dtsi文件里面的i2c设备节点信息,之所以可以用&i2c,就是因为在dtsi文件(见下)中将i2c@54000000这个i2c节点前记了一个标识符i2c,这种标识符的格式为:i2c: i2c@54000000。采用此标识符下的属性信息可以覆盖原有的属性,并可以增加新的属性信息在其中。

dtsi文件

i2c: i2c@54000000 {
        compatible = "samsung,s3c2440-i2c";
        clocks = <&clocks PCLK_I2C>;
        clock-names = "i2c";
        pinctrl-names = "default";
        pinctrl-0 = <&i2c0_bus>;
    }; 
  • 内核driver端
static const struct of_device_id xxx_of_match[] = {
	{ .compatible = "atmel,24c256",		.data = &xxx_data },
	...		//还可以增加其他设备信息	.data字段暂时不知道作用,匹配是用不到这个属性了
	{ /* END OF LIST */ },
};
MODULE_DEVICE_TABLE(of, xxx_of_match);
static int xxx_probe(struct i2c_client * client, const struct i2c_device_id *id)
{
	...	//在这里可以将i2c设备注册为字符设备或者misc设备使用
}

static int xxx_remove(struct i2c_client *client)
{
    ...
}

static struct i2c_driver xxx_driver = {
    .driver     = {
        .name   = "at24c256",
        .owner  = THIS_MODULE,
        .of_match_table = xxx_of_match,	//设备树注册i2c device匹配方式选用
    },
    .probe      = xxx_probe,
    .remove     = xxx_remove,
    .id_table   = xxx_ids,		//内核注册i2c device匹配方式选用
};

static int __init xxx_init(void)
{
    return i2c_add_driver(&xxx_driver);
}

static void __exit xxx_exit(void)
{
    i2c_del_driver(&xxx_driver);c
}

module_init(xxx_init);
module_exit(xxx_exit);

2.3 设备树中的设备节点转换

文本内容较多,移步至github: device_tree_node_transfer

i2c节点和spi节点是如何转换为相应的i2c client和spi device的呢?

/i2c节点一般表示i2c控制器, 它会被转换为platform_device, 在内核中有对应的platform_driver;
/i2c/at24c02节点不会被转换为platform_device, 它被如何处理完全由父节点的platform_driver决定, 一般是被创建为一个i2c_client。

类似的也有/spi节点, 它一般也是用来表示SPI控制器, 它会被转换为platform_device, 在内核中有对应的platform_driver;
/spi/flash@0节点不会被转换为platform_device, 它被如何处理完全由父节点的platform_driver决定, 一般是被创建为一个spi_device。

详细流程参考github上文本内容

附录

  1. GitHub:device_tree_i2c

参考资料

  1. 让u-boot支持内核设备树dts
设备树中的i2c设备以及内核对i2c节点的处理过程 dtb文件中的i2c节点 &i2c2 { clock-frequency = <100000>; //时钟频率 pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c2>; //i2c使用的引脚 status = "okay"; //默认状态为使能状态 codec: wm8904@1a { compatible = "wlf,wm8904"; // 阅读详情

相关推荐

Linux I2C从设备树信息查看与添加方法

下面介绍如何查看一个i2c-adapter对应的设备树文件,i2c-client对应的设备树文件 我们知道I2C-client的信息和adapter的一些信息如寄存器等信息是放在设备树里面的,那么在设备树的什么位置呢?在arch/arm/boot/dts/xxx.dts 在默认的文件系统中查看默认只提供了一个,也是第0组的I2C,我们需要的其他组需要自己添加。   实际上,我们从S...

让一切变得简单 1万+

设备树解析 & i2c设备模型

1、基础概念 1、总线 2、手机启动流程 1、MTK启动流程 2、高通启动流程的差别 3、设备树解析 1、设备树相关 2、设备树解析 4、 i2c 设备初始化流程

chwit的博客 2754

linux的I2C总线框架

IIC的全称是Inter-Integrated Circuit,由Philips公司推出,是近年来在微电子通信控制制领域广泛采用的一种新型总线标准。它是同步通信的一种特殊形式,仅需两根线(SLC、SDA)即可完成信息传输,并且通信速率较高。在主从通信中,可以有多个IIC设备同时接到IIC总线上,通过地址来识别通信对象。Linux的IIC体系结构分为3个组成部分,分别是IIC核心、IIC总线驱动和IIC设备驱动!

yumiano0的博客 1482

TP驱动——I2C驱动,细节分析——dts设备树

外设触屏,i2c总线与dts,pinctrl分析

蓝冰露的博客 3802

基于i2c子系统的驱动分析

和i2c有关的代码都在源码drivers/i2c目录下。内核提供了两种i2c的实现方法: 第一种叫i2c_dev,对应drivers/i2c/i2c-dev.c,这种方法仅仅封装了soc的i2c控制器操作,并向应用层提供操作接口。其本质是为应用层提供了一个库,驱动功能由应用层实现,不是主流的做法 第二种是驱动层实现所有驱动功能,是比较主流的做法

XiaoBaWu的博客 4666

设备树I2C设备节点配置:图解说明流程

通过图文详解在设备树中如何正确配置I2C设备节点,帮助开发者理解设备树的结构与设备挂载关系,提升嵌入式开发效率。

weixin_42589700的博客 927

linux i2c总线分析使用设备树

linux i2c总线分析使用设备树 i2c总线简要说明 I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。分别为时钟线SCL和数据线SDA,这里不重点分析i2c的物理特性,我们主要是分析linux下的i2c的软件框架,在MCU用过i2c的读者应该知道,i2c在MCU里面属于一个外设控制器,用户设置好时钟,从机地址,和数据搬运到读写寄存器外设控制器就可以把数据在i2c总线上发送出去。 linux下i2c的总线模型 linux是一个支

qq_27809619的博客 2692

NVIDIA之获取设备序列号代码加密

jetson上代码加密的方法

ZONGXP的博客 3326

Linux驱动学习—I2C总线

I2C是很常见的一种总线协议,I2C是NXP公司设计的,I2C使用两条线在主控制器和从机之间进行数据通信。一条是SCL(串行时钟线),另外一条是SDA(串行数据线),因为I2C这两条数据线是开漏输出的,所以需要接上拉电阻,总线空闲的时候SCL和SDA处于高电平。I2C总线标准模式下速度可以达到100Kb/s,快速模式下可以达到400kb/s。

suifen_的博客 3535

Linux——Linux驱动之玩转I2C(中)自己实现一个I2C总线client设备(Linux下I2C驱动框架、非设备树下的client、设备树下添加I2C设备节点)

0 引言 上一次博文讲解了怎么在应用层操作I2C设备(我们用的是触摸芯片作为I2C设备),前提是你已经有了一个对应的驱动,上一博文我们也是用的现成的驱动。那么,本次博文,我们进一步看下如何自己写一个I2C设备,这里还是以触摸芯片ft5x06为例。 1非设备树下实现I2C的client Linux下的I2C其实也是按照平台总线模型platform的概念设计的,在讲设备树之前,我们写设备驱动也是使用platform框架进行的,需要两个文件,device.c和driver.c,

数字世界 万物互联 805

Node.js内存溢出?一招搞定JavaScript heap out of memory错误(附永久配置方案)

本文深入解析Node.js内存溢出问题,提供从临时调整到永久配置的完整解决方案。重点介绍通过设置`max-old-space-size`参数和`NODE_OPTIONS`环境变量来扩展JavaScript堆内存限制,适用于Webpack、Vite等构建工具的大型项目场景,并涵盖Windows、Linux/macOS多平台配置方法。

cake8的博客 1056

Linux总线之I2C

(1)i2c几根线? (2)几种信号? (3)i2c读写时序 (4)i2c总线的特点 (5)i2c总线速率(控制器) 1.2i2c总线驱动框架结构 1.4i2c总线驱动的实例 2.i2c总线驱动 2.1si7006(sht20)设备树的编写 2.1.1画出硬件连接图 stm32mp151.dtsi 2.1.3编写自己的设备树 2.2i2c中相关的结构体 i2c_client结构体:当驱动进入到probe函数之前,内核会创建i2c_client,这个i2c_client是用来记录数据的。比如i2c_ad

KnowHowNewhaoran的博客 1637

VS Code ESP-IDF无法找到源文件、头文件波浪线解决

背景:想要编译小智AI项目,可以正常编译。但是一些头文件,例如#include <nvs.h>等无法找到。

Hot_Ant的博客 1490

Linux i2c 设备树或者平台总线配置和Linux i2c 调用原理

i2c 设备树或者平台总线配置和Linux i2c 调用原理 1设备树配置 代码编写过程 1.在对应的.dts中的i2c中写入设备数据即i2c(硬件模块)设备名和i2c设备(硬件)地址 2.在自己的驱动代码中填入i2c设备信息名字即可 3.在自己的驱动代码中添加i2c_add_driver代码即可,再通过驱动代码的proe添加设备号来实现文件操作符初始化 4.在字符驱动read,write或者ioctl中填入i2c_transfer(client->adapter, &msg, num);来读

weixin_39658481的博客 2687

STM32H723ZGT6-单ADC极限采样率实战与分辨率权衡

本文通过实战测试,深入探讨了STM32H723ZGT6微控制器中单ADC模块的极限性能。文章详细展示了如何通过CubeMX配置时钟树、ADC参数、定时器触发与DMA,实测得出在16位分辨率下最高稳定采样率约为4.6MHz,而将分辨率降至8位后,采样率可提升至约6.2MHz,并分析了速度与分辨率之间的关键权衡,为高速数据采集项目提供选型与优化参考。

weixin_29240711的博客 297

开源滑翔伞升降速度表:基于STM32与传感器融合的DIY飞行仪表

传感器融合是现代嵌入式系统与物联网设备中的核心技术,它通过整合多个传感器的数据,利用滤波与估计算法,获得比单一传感器更精确、更可靠的环境感知能力。其技术价值在于提升系统的鲁棒性、精度和上下文理解能力,广泛应用于无人机导航、可穿戴设备、工业监测及智能驾驶等领域。本文聚焦于一个具体的工程实践案例——开源多功能滑翔伞升降速度表(Open-Vario),该项目巧妙地运用了**卡尔曼滤波器**进行气压与GNSS数据的融合,以精确计算升降率,并基于**FreeRTOS**实时操作系统构建了一个稳定、可扩展的嵌入式平台,

weixin_33657398的博客 176

【嵌入式环境下linux内核及驱动学习笔记-(15)linux总线、设备、驱动模型之I2C总线】

define I2C_CLASS_HWMON (1

weixin_45499326的博客 3991

IWR6843ISK+DCA1000EVM 本人遇到的所有报错和解决方案

本文详解了初次使用DCA1000EVM和mmave studio遇到的一系列的问题以及解决方法

2301_77883976的博客 3301

使用GPIO模拟I2C的驱动程序分析:i2c-gpio.c

GPIO模拟I2C是一种利用GPIO引脚模拟I2C总线的方法,适用于I2C接口不够用的场景。I2C协议通过SDA和SCL两根线实现双向数据传输,并通过开漏结构和上拉电阻实现设备间的通信。使用GPIO模拟时,需要将引脚设置为开漏输出并配置相应的时序。Linux内核提供了I2C-GPIO驱动,支持通过设备树或平台数据配置SDA和SCL引脚。驱动通过i2c_algo_bit_data结构体设置I2C的操作函数,注册到I2C子系统,实现基于GPIO的I2C通信功能,适合无硬件I2C控制器的场景。

caiji0169的博客 2426

英伟达NVIDIA数字IC后端笔试真题(ASIC Physical Design Engineer)

英伟达NVIDIA数字IC后端笔试真题(ASIC Physical Design方向)

weixin_37584728的博客 3915

RT-Thread与ROS2通信:micro-ROS在STM32上的移植实践

本文详细介绍了在STM32平台上使用RT-Thread实时操作系统移植micro-ROS实现与ROS2通信的实践方案。通过对比rosserial方案,重点阐述了micro-ROS基于XRCE-DDS协议栈在数据可靠性(丢包率低于1%)、双模式通信(UDP/串口)以及C/C++混合编程方面的优势,为嵌入式设备与ROS2的高效通信提供了完整解决方案。

emacs5lisp的博客 327

Linux之I2C驱动

在 Linux 内核中 I2C 的体系结构分为 3 个部分:①: I2C 核心提供了I2C 总线驱动和设备驱动的注册、 注销方法②: I2C 总线驱动是对I2C 硬件体系结构中适配器端的实现, 适配器可由CPU 控制, 甚至可以直接集成在 CPU 内部。I2C 总线驱动就是 SOC 的,也叫做。③: I2C 设备驱动是对,设备一般挂接在受 CPU 控制的 I2C 适配器上, 通过 I2C 适配器与 CPU 交换数据。

风间琉璃的博客 5678

基于方差分解分析气象/水文干旱驱动因素(含MATLAB全代码)

简介基于方差分解方法分析气象/水文干旱驱动因素

WW、forever的博客 801

Linux I2C设备分析2

Linux I2C设备分析2(基于Linux6.6)---i2c bus介绍

ListQ的博客 1239

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

I2C总线式驱动开发

Linux I2C驱动

weixin_44681745的博客 2282

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

ZYNQ Linux I2C总线框架笔记

Linux I2C驱动

qq_41478801的博客 1563

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

上一篇: Linux SPI驱动学习——调用SPI读写函数
下一篇: Linux I2C驱动架构
multimicro
博客等级 码龄10年 93粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值