论 SoC上的Linux如何拉动外部I/O
在MCU中(如classic autosr或其他RTOS),一般可以直接通过往对应的寄存器(地址转为指针)写值,
或者调用一些硬件抽象层或者驱动接口来拉动芯片提供的GPIO。
但是在Linux中,可能不会让应用层直接去访问底层的物理地址,而且配置GPIO或者其他什么IO,往往不只一个寄存器,可能是一组,比较复杂。
SoC中嵌入式Linux控制I/O需要关注的问题
SoC相较于单片机或者MCU,往往复杂得多。读芯片手册和电路板原理图的时候,需要关注很多问题,
I/O种类
目前我看到的I/O有两种,一种是SoC芯片直接提供的GPIO. 一种是通过i2c总线,挂一些I/O扩展器,来实现的外部I/O。
对于SoC板而言,可能这两种同时存在。但是他们的控制方法是不同的。
当使用了总线 I/O扩展芯片来实现外部 I/O, 那么还需要获取和阅读对应扩展芯片的手册。
设备树
需要查阅、核对、修正设备树的能力。
SoC内部的配置和体系各家各自成一套,所以才有设备树。设备树和开发板不配套,可能会造成很多问题,比如/dev下面东西不对。地址不对等等。
另外,要是内核裁剪的有问题,比如一些驱动或者文件系统没有放进来,就更麻烦了,要重新编译内核和内核模块。
GPIO
需要先确认我们需要使用的GPIO芯片,以及该端口位于该GPIO芯片的编号。
然后可以使用gpio文件系统去配置和控制对应的IO。
这里可能需要使用设备树文件来识别控制芯片和偏移。
偏移请参阅SOC的芯片手册。
下面都以TDA4论坛上的问答为例:
[FAQ] TDA4VM/DRA829/AM65xx: Linux: Configuring GPIOs
查询gpio控制芯片和设备树信息:
root@j7-evm:~# find /proc/device-tree/__symbols__/ | grep gpio
/proc/device-tree/__symbols__/main_gpio_intr
/proc/device-tree/__symbols__/main_gpio7
/proc/device-tree/__symbols__/main_gpio5
/proc/device-tree/__symbols__/wkup_gpio0
/proc/device-tree/__symbols__/main_gpio3
/proc/device-tree/__symbols__/main_gpio1
/proc/device-tree/__symbols__/gpio_keys
/proc/device-tree/__symbols__/wkup_gpio_intr
/proc/device-tree/__symbols__/main_gpio6
/proc/device-tree/__symbols__/wkup_gpio1
/proc/device-tree/__symbols__/main_gpio4
/proc/device-tree/__symbols__/main_gpio2
/proc/device-tree/__symbols__/main_gpio0root@j7-evm:~# cat /proc/device-tree/__symbols__/main_gpio0
/interconnect@100000/gpio@600000
然后对应地址来找驱动文件系统:
root@j7-evm:~# ls -la /sys/class/gpio/lrwxrwxrwx 1 root root 0 Feb 17 08:38 gpiochip84 -> ../../devices/platform/interconnect@100000/600000.gpio/gpio/gpiochip84
根据对应的地址我们发现,控制芯片是84
如果我们要控制gpio0_127。
就得到:84+127=211.
然后:
root@j7-evm:~# cd /sys/class/gpio/
root@j7-evm:/sys/class/gpio# echo 211 > export
root@j7-evm:/sys/class/gpio# cd gpio211
root@j7-evm:/sys/class/gpio/gpio211# echo out > direction
root@j7-evm:/sys/class/gpio/gpio100# echo 1 > value
Above should export the GPIO and you can do read/writes.
I2C扩展I/O
参考:
TDA4VMXEVM: USER_LED1 & USER_LED2 through I2C GPIO EXPANDER2 (TCA6424ARGJR) - Processors forum - Processors - TI E2E support forums
以TDA4通用开发板为例:

开发板原理图中包含GPIO扩展MAP表。
查表可知I2C0 总线,0x22芯片地址的P26 P27有两个灯(I/O)可以被用户使用。

从图中可知,这是一个IO扩展芯片,和SOC之间通过I2C扩展。
这里写了地址0x22。和芯片型号。
查询对应型号的芯片手册,
8.6.2 Register Descriptions

从datasheet中可知,寄存器0 1 2三个字节,表示各个io的读取结果。
4 5 6是配置输出内容的地方。
8 9 10,配置极性反转。目前用不到。
12 13 14,配置I/O的方向。1 是输入,0 是输出。
那我们需要点亮LED P26 P27。
就如下操作:
查看i2c地址和对应的总线号。
root@j7-evm:~# dmesg | grep i2c
[ 1.082853] i2c /dev entries driver
[ 1.235041] omap_i2c 40b00000.i2c: bus 0 rev0.12 at 100 kHz
[ 1.235521] omap_i2c 40b10000.i2c: bus 1 rev0.12 at 100 kHz
[ 1.239971] omap_i2c 42120000.i2c: bus 2 rev0.12 at 100 kHz
[ 1.265639] omap_i2c 2000000.i2c: bus 3 rev0.12 at 400 kHz
[ 1.266549] omap_i2c 2010000.i2c: bus 4 rev0.12 at 400 kHz
[ 1.267005] omap_i2c 2020000.i2c: bus 5 rev0.12 at 100 kHz
[ 1.292154] omap_i2c 2030000.i2c: bus 6 rev0.12 at 400 kHz
[ 1.295636] omap_i2c 2040000.i2c: bus 7 rev0.12 at 100 kHz
[ 1.296040] omap_i2c 2050000.i2c: bus 8 rev0.12 at 100 kHz
[ 1.319763] omap_i2c 2060000.i2c: bus 9 rev0.12 at 400 kHzroot@j7-evm:/proc/device-tree/__symbols__# cat main_i2c0
/bus@100000/i2c@2000000
可知i2c0 的总线号是 3.
后面使用i2c 工具来操作扩展芯片的寄存器:
#查看设备
root@j7-evm:~# i2cdetect -y -r 30 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: UU -- UU -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- 57 -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- 6d -- --
70: 70 71 -- -- -- -- 76 -- #UU似乎表示这里0x20 0x22是两个内核没有使用的设备,和手册里的i2c芯片地址对应了# 读取当前寄存器内容
root@j7-evm:~# i2cdump -f -y 3 0x22 b0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 0c 84 f1 XX 3f fd ff XX 00 00 00 XX 3b f9 ef XX ???X??.X...X;??X
10: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
20: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
30: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
50: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
80: 0c 84 f1 XX 3f fd ff XX 00 00 00 XX 3b f9 ef XX ???X??.X...X;??X
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
a0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
b0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
c0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
d0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
e0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
f0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX# 配置P26 为输出
#P27在14号寄存器上,现在是ef .P27配为0 输出后是6Froot@j7-evm:~# i2cset -y -f 3 0x22 0x0e 0x6f
root@j7-evm:~# i2cdump -f -y 3 0x22 b0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 0c 84 f1 XX 3f fd ff XX 00 00 00 XX 3b f9 6f XX ???X??.X...X;?oX
10: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
20: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
30: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
50: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
80: 0c 84 f1 XX 3f fd ff XX 00 00 00 XX 3b f9 6f XX ???X??.X...X;?oX
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
a0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
b0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
c0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
d0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
e0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
f0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX#再将P26输出数据配置为0 在6号寄存器上 改成7F
root@j7-evm:~# i2cset -f -y 3 0x22 0x06 0x7F
root@j7-evm:~# i2cdump -f -y 3 0x22 b0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 0c 84 71 XX 3f fd 7f XX 00 00 00 XX 3b f9 6f XX ??qX???X...X;?oX
10: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
20: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
30: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
40: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
50: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
60: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
70: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
80: 0c 84 71 XX 3f fd 7f XX 00 00 00 XX 3b f9 6f XX ??qX???X...X;?oX
90: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
a0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
b0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
c0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
d0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
e0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
f0: XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XX XXXXXXXXXXXXXXXX
可以看到一个灯亮了!!!
相关文章:
论 SoC上的Linux如何拉动外部I/O
在MCU中(如classic autosr或其他RTOS),一般可以直接通过往对应的寄存器(地址转为指针)写值, 或者调用一些硬件抽象层或者驱动接口来拉动芯片提供的GPIO。 但是在Linux中,可能不会让应用层直接去…...
SpringBoot项目如何部署SSL证书 (JKS格式)
1、SpringBoot项目如何部署SSL证书 (JKS格式) 1. 获取 SSL 证书和私钥 首先,你需要获取有效的 SSL 证书和私钥。SSL 证书是一种用于加密通信的数字证书,它可以通过购买商业 SSL 证书或使用免费的 Let’s Encrypt 证书获得。请确保你拥有证书文件和与之…...
成功解决:ValueError Cannot assign non-leaf Tensor to parameter ‘weight‘
成功解决:ValueError Cannot assign non-leaf Tensor to parameter ‘weight‘ 欢迎大家来到安静到无声的《模式识别与人工智能(程序与算法)》,如果对所写内容感兴趣请看模式识别与人工智能(程序与算法)系列讲解 - 总目录,同时这也可以作为大家学习的参考。欢迎订阅,优…...
面试之快速学习SQL-基础增删改查语句
1. SELECT SELECT column1,column2,column3 FROM table_name;SELECT * FROM table_name;2. SQL SELECT DISTINCT 语句 在表中,可能会包含重复值。这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值。 SE…...
nuxt脚手架创建项目
在初始化时遇到一个依赖找不到的问题,记录一下,如有遇到同样问题的小伙伴,希望能给你们一点指引。 从安装脚手架开始,首先 一:安装nuxt脚手架 1. C盘全局安装: npm i -g create-nuxt-app 安装后可creat…...
复现原型链污染漏洞
目录 一、复现原型链污染漏洞 hackit 2018 1、创建hackit_2018.js文件 2、运行hackit_2018.js文件 3、寻找原型链漏洞 4、污染原型链 hackit 2018 1、创建hackit_2018.js文件 const express require(express) var hbs require(hbs); var bodyParser require(body-par…...
.Net6 Web Core API 配置 Autofac 封装 --- 依赖注入
目录 一、NuGet 包导入 二、Autofac 封装类 三、Autofac 使用 四、案例测试 下列封装 采取程序集注入方法, 单个依赖注入, 也适用, 可<依赖注入>的地方配置 一、NuGet 包导入 Autofac Autofac.Extensions.DependencyInjection Autofac.Extras.DynamicProxy 二、Auto…...
鸿鹄工程项目管理系统em Spring Cloud+Spring Boot+前后端分离构建工程项目管理系统 em
Java版工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离 功能清单如下: 首页 工作台:待办工作、消息通知、预警信息,点击可进入相应的列表 项目进度图表:选择(总体或单个)项目…...
【搭建PyTorch神经网络进行气温预测】
import numpy as np import pandas as pd import matplotlib.pyplot as plt import torch import torch.optim as optim import warnings warnings.filterwarnings("ignore") %matplotlib inlinefeatures pd.read_csv(temps.csv)#看看数据长什么样子 features.head…...
.Net6 Web Core API --- AOP -- log4net 封装 -- MySQL -- txt
目录 一、引入 NuGet 包 二、配置log4net.config 三、编写Log4net封装类 四、编写日志记录类 五、AOP -- 拦截器 -- 封装 六、案例编写 七、结果展示 一、引入 NuGet 包 log4net Microsoft.Extensions.Logging.Log4Net.AspNetCore MySql.Data ---- MySQL…...
【论文阅读】对抗溯源图主机入侵检测系统的模仿攻击(NDSS-2023)
作者:伊利诺伊大学芝加哥分校-Akul Goyal、Gang Wang、Adam Bates;维克森林大学-Xueyuan Han、 引用:Goyal A, Han X, Wang G, et al. Sometimes, You Aren’t What You Do: Mimicry Attacks against Provenance Graph Host Intrusion Detect…...
微信小程序多图片上传实用代码记录
微信小程序多图片上传实用代码记录 由于在小程序中,wx.uploadFile 只能一次上传一张图片,因此在一次需要上传多张图片的应用场景中例如商品图片上传、评论图片上传等场景下,不得不使用for等循环上传每一张图片,多次调用wx.upload…...
android实现获取系统全局对象实例
无需Context获取系统常用全局对象:Application,Activity,PackageManager等。 import android.app.Activity; import android.app.Application; import android.app.Service; import android.content.Context; import android.content.pm.Pac…...
viewerjs 如何新增下载图片功能(npm包补丁)
文章目录 先实现正常的效果实现下载图片改变viewerjs的build函数源码改变之后,执行npm i 之后node_modules源码又变回了原样 1、viwerjs所有功能都很完善,但唯独缺少了图片的下载 2、需求:在用viwerjs旋转图片后,可以直接下载旋转…...
基于YOLOv7开发构建MSTAR雷达影像目标检测系统
MSTAR(Moving and Stationary Target Acquisition and Recognition)数据集是一个基于合成孔径雷达(Synthetic Aperture Radar,SAR)图像的目标检测和识别数据集。它是针对目标检测、机器学习和模式识别算法的研究和评估…...
关于c++中mutable、const、volatile这三个关键字及对应c++与汇编示例源码
这哥三之间的关系是有趣的,不妨看看这个: cv (const and volatile) type qualifiers - cppreference.com mutable permits modification of the class member declared mutable even if the containing object is declared const. 即便一个对象是con…...
把大模型装进手机,分几步?
点击关注 文 | 姚 悦 编 | 王一粟 大模型“跑”进手机,AI的战火已经从“云端”烧至“移动终端”。 “进入AI时代,华为盘古大模型将会来助力鸿蒙生态。”8月4日,华为常务董事、终端BG CEO、智能汽车解决方案BU CEO 余承东介绍,…...
c++游戏制作指南(三):c++剧情类文字游戏的制作
🍿*★,*:.☆( ̄▽ ̄)/$:*.★* 🍿 🍟欢迎来到静渊隐者的csdn博文,本文是c游戏制作指南的一部🍟 🍕更多文章请点击下方链接🍕 🍨 c游戏制作指南dz…...
Flutter系列文章-实战项目
在本篇文章中,我们将通过一个实际的 Flutter 应用来综合运用最近学到的知识,包括保存到数据库、进行 HTTP 请求等。我们将开发一个简单的天气应用,可以根据用户输入的城市名获取该城市的天气信息,并将用户查询的城市列表保存到本地…...
HCIA---TCP/UDP协议
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 目录 文章目录 一.UDP协议简介 UDP协议的特点: 二.TCP协议简介 TCP协议特点 三.TCP和UDP的区别 思维导图 一.UDP协议简介 UDP(User …...
iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘
美国西海岸的夏天,再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至,这不仅是开发者的盛宴,更是全球数亿苹果用户翘首以盼的科技春晚。今年,苹果依旧为我们带来了全家桶式的系统更新,包括 iOS 26、iPadOS 26…...
RocketMQ延迟消息机制
两种延迟消息 RocketMQ中提供了两种延迟消息机制 指定固定的延迟级别 通过在Message中设定一个MessageDelayLevel参数,对应18个预设的延迟级别指定时间点的延迟级别 通过在Message中设定一个DeliverTimeMS指定一个Long类型表示的具体时间点。到了时间点后…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
今日学习:Spring线程池|并发修改异常|链路丢失|登录续期|VIP过期策略|数值类缓存
文章目录 优雅版线程池ThreadPoolTaskExecutor和ThreadPoolTaskExecutor的装饰器并发修改异常并发修改异常简介实现机制设计原因及意义 使用线程池造成的链路丢失问题线程池导致的链路丢失问题发生原因 常见解决方法更好的解决方法设计精妙之处 登录续期登录续期常见实现方式特…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
