【RK3588嵌入式Linux应用编程】-用户空间I2C通信

用户空间I2C通信

1、理解I2C协议

1.1 什么是I2C协议

I2C或IC间通信是嵌入式系统中非常常见的低速通信方法。I2C 的最大优势在于易于实现,被半导体制造商广泛采用,并且能够在同一总线上轻松添加多个节点,从而实现更高效的设计(甚至可能更具成本效益)。I2C由飞利浦半导体公司定义,后来被恩智浦半导体公司收购。I2C 基本上是主从总线,是纯粹的半双工。

I2C 是一种简单的低速 2 线总线,在嵌入式板上很常见,通常用于访问不在 SoC 上的外设,例如显示控制器、摄像头传感器、GPIO 扩展器等。在PC上可以找到一种称为系统管理总线(System Manager Bus,SMBus)的相关标准,用于访问温度和电压传感器。SMBus 是 I2C 的一个子集。

I2C 是一种主从协议,主设备是 SoC 上的一个或多个主机控制器。 从设备具有制造商分配的 7 位地址(阅读数据表),每条总线最多允许 128 个节点,但保留了 16 个节点,因此实际上只允许 112 个节点。主设备可以与其中一个从设备发起读取或写入事务。通常,第一个字节用于指定从机上的寄存器,其余字节是从该寄存器读取或写入该寄存器的数据。

### RK3588 实时内核串口编程概述 在嵌入式开发中,串口通信是一种常见的外设接口技术。对于基于 RK3588 的实时内核环境下的串口编程,通常涉及以下几个方面: #### 1. 配置串口设备 在 Linux 系统下,串口设备一般通过 `/dev/ttyS*` 或 `/dev/ttyUSB*` 进行访问。为了实现串口通信功能,需要先确认目标硬件对应的串口号及其配置参数。 ```bash ls /dev/tty* ``` 上述命令可以列出当前系统中的可用串口设备[^1]。 #### 2. 打开并初始化串口 打开串口文件描述符后,需设置波特率、数据位数、停止位等基本参数。以下是 C 语言的一个简单示例代码片段用于初始化串口: ```c #include <stdio.h> #include <stdlib.h> #include <string.h> #include <fcntl.h> /* File Control Definitions */ #include <errno.h> /* Error Number Definitions */ #include <termios.h> /* POSIX Terminal Control Definitions */ int setup_serial_port(const char *device, speed_t baud_rate) { int fd; struct termios options; // Open the serial port device. fd = open(device, O_RDWR | O_NOCTTY); if (fd == -1) { perror("open() failed"); return -1; } // Get current attributes of the port. tcgetattr(fd, &options); // Set input/output baud rate to desired value. cfsetispeed(&options, baud_rate); cfsetospeed(&options, baud_rate); // Configure other settings such as data bits, parity, stop bits etc. options.c_cflag &= ~PARENB; // No Parity bit options.c_cflag &= ~CSTOPB; // One Stop Bit options.c_cflag &= ~CSIZE; // Clear size mask options.c_cflag |= CS8; // Select 8 Data Bits // Enable receiver and set local mode. options.c_cflag |= (CLOCAL | CREAD); // Apply new configuration immediately without waiting for pending I/O operations. tcsetattr(fd, TCSANOW, &options); return fd; } ``` 此函数实现了对指定串口设备的基本配置操作[^2]。 #### 3. 数据读写处理 完成串口初始化之后,可以通过 `read()` 和 `write()` 函数分别执行数据接收与发送任务。下面展示了一个简单的循环过程来持续监听来自外部的数据输入情况: ```c void read_from_serial(int fd) { unsigned char buffer[256]; ssize_t bytes_read; while ((bytes_read = read(fd, buffer, sizeof(buffer))) > 0) { printf("Received %zd byte(s): ", bytes_read); fwrite(buffer, 1, bytes_read, stdout); putchar('\n'); } } // Example usage within main function or another thread context... if (serial_fd >= 0) { write(serial_fd, "Hello Serial Port!", strlen("Hello Serial Port!")); read_from_serial(serial_fd); } else { fprintf(stderr, "Failed to initialize serial communication.\n"); } ``` 以上部分展示了如何利用标准库 API 来管理实际的 IO 流程[^3]。 #### 4. 关闭资源释放 当不再需要使用某个特定端口时,请记得调用 close 方法关闭关联句柄以避免潜在泄漏风险: ```c close(serial_fd); ``` 这一步骤非常重要,在任何异常退出场景下都应妥善安排清理逻辑[^4]。 --- ### 注意事项 - **权限控制**: 访问某些特殊类型的字符型设备可能要求超级用户身份或者适当调整 SELinux 策略。 - **中断机制**: 如果希望获得更高效的响应速度,则考虑引入信号量或者其他同步原语配合异步通知模式工作。 - **错误检测**: 对于生产环境中部署的应用而言,完善的健壮性和容错设计必不可少。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

视觉与物联智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值