本文以 KickPi 开发板为目标硬件,围绕「用户按键读取」展开实战:解决开发板系统部署、WiFi/SSH 连接、电源键功能修改、按键设备识别与驱动编写、交叉编译环境搭建等问题。
过程中曾遇到两个核心阻碍:一是开发板内存有限,直接编译大型项目卡顿;二是按键设备文件识别不明确,导致读取失败。通过配置交叉编译链、逐行排查/dev/input设备属性,最终实现按键按下 / 松开事件的稳定读取,并掌握了跨平台文件传输技巧。本文将详细拆解每一步操作,适合嵌入式新手参考。
一、开发板初始化配置
1. 系统镜像烧录与启动
- 下载 KickPi 官方镜像,使用镜像烧录工具(如 BalenaEtcher)写入 SD 卡;
- 将 SD 卡插入开发板,接通电源,等待系统自动启动(首次启动约 3 分钟)。
2. 系统迁移至 eMMC(可选)
若开发板配备 eMMC,可将 SD 卡中的系统迁移至 eMMC,提升运行速度:
等待迁移完成后,拔掉 SD 卡,重启开发板即可从 eMMC 启动。
3. WiFi 连接与 SSH 配置
(1)WiFi 连接
在开发板终端输入以下命令,连接本地 WiFi:
验证:输入ip addr查看 WiFi 网卡(如 wlan0)是否获取到 IP 地址(如 192.168.3.186)。
(2)SSH 远程连接
在电脑(同一局域网)终端输入以下命令,远程登录开发板:
首次连接需输入yes确认,再输入开发板 root 密码即可登录。
连接方式很多,vscode开发也很方便,例如自动联想之类的。方法自己找~~
4. 禁用USER键默认功能
因为再默认情况下,此开发板的USER按键会触发关机,需修改配置禁用该功能,避免误触:
在文件中添加 / 修改以下 3 行:
保存退出后,重启 logind 服务生效:
二、用户按键开发
1. 识别按键设备文件
开发板的用户按键会被系统挂载到/dev/input/目录,以eventX(X 为数字)命名:
通过文件属性确认按键设备(字符设备类型,归属 input 组):
此处event1即为用户按键对应的设备文件(若不确定,可通过排除法测试:按下按键时,用cat /dev/input/eventX查看是否有数据输出)。
2. 编写按键读取 C 代码
通过linux/input.h提供的事件结构体,读取按键的按下 / 松开状态,代码如下(key_read.c):
3. 开发板本地编译测试(可选)
若开发板性能充足(内存≥512MB),可直接在开发板上编译运行:
三、交叉编译环境搭建与文件传输
1. 交叉编译的必要性
开发板多为 ARM 架构,而电脑(虚拟机)是 x86 架构,直接编译的程序无法在开发板运行;且开发板内存有限(可能仅 256MB/512MB),安装 GCC(约几十 MB)会占用大量资源,因此需在电脑上搭建交叉编译环境。
2. 安装交叉编译器
(1)准备工具链
从芯片原厂下载对应 ARM 架构的交叉编译器(示例:gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu.tar)。
(2)解压与配置环境变量
- 将编译器压缩包传送到虚拟机(如/home/lzj/目录),解压:
- 复制编译器 bin 目录路径(示例:
/home/lzj/gcc-arm-11.2-2022.02-x86_64-aarch64-none-linux-gnu/bin);
- 编辑用户环境变量文件,添加编译器路径:
在文件末尾添加:
- 生效环境变量:
- 验证:输入
aarch64-none-linux-gnu-gcc,中途如果可以补全指令则成功。
3. 交叉编译与文件传输
(1)交叉编译程序
在虚拟机中,使用交叉编译器编译需要编译的文件,这里以
helloworld.c为例:⚠️ 注意:该文件无法在虚拟机(x86 架构)运行,需传输到开发板。
(2)SCP 文件传输
通过 SSH 协议将编译后的文件传输到开发板(同一局域网 / 公网均可):
首次传输需输入yes确认,再输入开发板 root 密码,等待传输完成。
4. 开发板运行程序
在开发板终端输入以下命令,运行交叉编译后的程序:
四、第三方开源库的交叉编译(以 ALSA、JSON 为例)
1. 核心原理:为什么需要交叉编译开源库?
在嵌入式开发中,若程序需依赖第三方库(如音频开发用的libasound、视频播放用的Mplayer、以及JSON),直接用-lxxx(如-lasound)链接会报错 —— 开发板的 ARM 架构与虚拟机的 x86 架构不兼容,且开发板系统中默认没有预编译的 ARM 版库文件。
因此需先通过交叉编译器,将开源库编译为ARM 架构的库文件(.a 静态库 /.so 动态库) ,并指定安装目录;后续编译应用程序时,再通过-I(指定头文件路径)和-L(指定库文件路径)链接这些交叉编译后的库,才能生成可在开发板运行的程序。
通用原则:所有开源库的交叉编译,优先参考其自带的
INSTALL或README文档,核心是通过./configure指定目标架构(--host) 、交叉编译器(CC) 和安装目录(--prefix) 。2. ALSA 库(音频开发核心库)交叉编译
ALSA(Advanced Linux Sound Architecture)是 Linux 音频开发的基础库,以下基于其官方安装文档,实现 ARM 架构交叉编译。
(1)准备工作
- ALSA 库源码:
从ALSA 官网下载源码包(如
alsa-lib-1.2.12.tar.bz2),或通过 Git 克隆:git clone https://github.com/alsa-project/alsa-lib.git;- 确认交叉编译器已就绪:
确保前文配置的aarch64-none-linux-gnu-gcc可正常使用(输入
aarch64-none-linux-gnu-gcc -v验证版本)。(2)交叉编译步骤(以 tar 包源码为例)
- 解压源码并进入目录
2. 配置交叉编译参数并编译(关键)
此步骤可以在官方的INSTALL中查看(核心部分已标注颜色)
INSTALL
For platform names in the form cpu-vendor-os (or aliases for this)
you should look in 'config.guess' script. Target and all paths
used here are only examples and should not be directly applicable to
your system.
Configuration for machines without FPU
If your machine does not have FP unit, you should use '--with-softfloat'
option. This option disables usage of float numbers in PCM route plugin.
ALSA could then leave much more CPU cycles for your applications, but you
could still need some floating point emulator.
Thread-safety option
As default, major PCM functions of alsa-lib are built to be
thread-safe with pthread mutex (while this wasn't present in the
versions earlier than 1.1.2). If you want to build without this
thread-safety support but reduce the overhead, pass
--disable-thread-safety configure option.
Jack plugin
JACK plugin is moved to alsa-plugins package.
Trouble Shooting
- Install path on Fedora Core 3
FC3 installs its system ALSA library to /lib instead of /usr/lib.
Specify --libdir=/lib to configure to overwrite it with the new library,
or run like
ln -sf /usr/lib/libasound.so.2.0.0 /lib/libasound.so.2.0.0
to make symlink to the new path.
Note that /lib might be /lib64 on 64bit architecture.
- 为项目添加 Libtool 支持。
Libtool 是跨平台处理共享库(
.so/.dylib)和静态库(.a)的工具,能自动适配不同系统的库编译、链接、安装规则(比如 Linux 的 -fPIC、macOS 的 -dynamiclib 等)。参数介绍
-force:强制覆盖项目中已存在的 Libtool 相关文件(比如ltmain.sh、libtool.m4),避免旧文件冲突。
-copy:将 Libtool 的模板文件复制到项目目录(而非创建符号链接),确保项目分发时不依赖系统上的 Libtool 文件(更易移植)。
-automake:生成 Automake 工具所需的辅助文件(比如ltmain.sh),让后续automake能识别 Libtool 相关配置。
- 收集项目所需的 宏定义(macro),生成
aclocal.m4文件。
- 根据
configure.ac中的配置,生成config.h.in模板文件。
- 根据
Makefile.am文件,生成Makefile.in模板文件。
参数介绍
- 源代码文件(比如
SOURCES = main.c util.c);
- 目标文件(比如
bin_PROGRAMS = myapp表示要编译出myapp可执行文件);
- 依赖库(比如
LDADD = -lz表示链接 zlib)。
- 将
configure.ac和aclocal.m4中的宏展开,生成最终的configure脚本(这是用户实际执行的配置脚本)。
- 通过./configure指定目标架构、编译器和安装目录。
参数列表
CC:指定交叉编译器(需与开发板架构匹配,此处为aarch64-none-linux-gnu-gcc);
-host:指定目标架构(ARM 架构常用aarch64-linux或arm-linux,需与交叉编译器前缀一致);
-prefix:指定库的安装目录(建议自定义路径,如/home/lzj/alsa-arm,避免与系统 x86 库冲突);
- 开始编译
- 安装
- 验证安装
如果安装成功, 会在指定的目录下生成文件
例如在此例子中 输入查询目录列表,就能看到此文件下的目录
3 json-c 库(JSON 解析核心库)交叉编译
json-c(原名 json-cpp)是 Linux 平台常用的轻量级 JSON 数据解析 / 序列化库,完全兼容 C 语言标准,广泛应用于嵌入式设备的 JSON 数据处理场景。以下基于其官方编译文档,实现 ARM 架构交叉编译,保持与前文 ALSA 库一致的编译流程风格。
(1) 准备工作
- json-c 源码获取
从官方仓库下载:通过 json-c GitHub 地址 下载源码包(如
json-c-0.17.tar.gz),或通过 Git 克隆最新源码:git clone https://github.com/jehiah/json-c.git若输出编译器版本信息(如 GCC version 9.4.0 等),说明编译器就绪。
(2)交叉编译步骤
- 进入源码目录
- 生成 configure 脚本(关键步骤)
json-c 官方提供
autogen.sh 脚本,可自动完成 libtoolize、aclocal、autoheader、automake、autoconf 等一系列配置文件生成操作(无需手动执行单步命令,比 ALSA 更简化),命令如下:脚本作用说明:
- 自动调用
libtoolize:添加跨平台库编译支持(处理.so/.a库的适配);
- 自动生成
aclocal.m4(宏定义文件)、config.h.in(配置头文件模板)、Makefile.in(编译模板文件);
- 最终生成可执行的
configure脚本,用于后续编译参数配置。
- 配置交叉编译参数(核心)
参考 json-c 官方交叉编译规范,结合 ARM 架构需求,指定交叉编译器、目标平台和安装目录:
参数列表
CC:指定交叉编译器(需与开发板架构匹配,此处为aarch64-none-linux-gnu-gcc);
-host:指定目标架构(ARM 架构常用aarch64-linux或arm-linux,需与交叉编译器前缀一致);
-prefix:指定库的安装目录(建议自定义路径,如/home/lzj/alsa-arm,避免与系统 x86 库冲突);
- 编译
使用多线程加速编译(
-j4 表示 4 线程,根据 CPU 核心数调整,如 8 核心可改为 -j8):- 安装
将编译生成的头文件、库文件、工具程序安装到
--prefix 指定的目录:- 验证安装
若安装成功,在指定的安装目录(
/home/lzj/json-arm)下会生成标准的目录结构,执行以下命令验证:五、开发板部署完整流程(依赖适配与运行调试)
部署核心目标:将交叉编译后的应用程序、依赖库移植到开发板,适配硬件参数(声卡、控制单元等),解决库依赖问题,最终实现按键控制功能(如按键控制音频播放 / 音量)稳定运行。
1. 开发板环境预处理(安装必要工具)
Mplayer(音频播放工具)交叉编译耗时较长,优先在开发板直接安装(需联网)
(1)安装 Mplayer
2. 虚拟机修改 Makefile (关键:链接交叉编译库)
在虚拟机进行编译时需通过 Makefile(不用也可以,手动麻烦…) 指定交叉编译链、依赖库路径(即前文
--prefix指定的安装目录),避免编译时链接 x86 架构库。(1)Makefile 示例
(2)Makefile 关键说明
主要是添加了这两行, 这两行就是之前交叉编译然后make install安装的地址。分别I 找到其头文件,和L 链接其库文件。
-I/home/lzj/alsa-arm/include -I/home/lzj/json-arm/include
-L/home/lzj/alsa-arm/lib -L/home/lzj/json-arm/lib
(3)编译应用程序
在虚拟机中执行 Makefile,生成 ARM 架构可执行文件:
编译成功后,当前目录会生成目标文件。
3. 依赖库移植与链接(解决 “库找不到” 错误)
开发板默认没有交叉编译的 ARM 版 ALSA、json-c 库,需将虚拟机中编译好的库文件传输到开发板,并创建软链接(避免库路径错误)。
(1)传输依赖库到开发板
通过
scp (也可以通过其他方式)将交叉编译库的lib目录下所有文件传输到开发板工作目录的lib文件夹:(2)查看库依赖(关键:确认程序需要哪些库)
在开发板上,找到在虚拟机上移植过来的可运行程序,用
ldd命令查看可执行程序的依赖库(是否缺失、路径是否正确):示例输出(正常情况):
异常情况(库找不到):
(3)创建软链接(解决库版本匹配问题)
开发板上的库文件可能存在版本后缀(如
libasound.so.2.0.0),而程序默认查找libasound.so.2(无版本后缀),需通过软链接关联:(4)添加库路径到系统环境(可选,避免每次指定路径)
若不想每次运行程序都指定库路径,可将开发板的库目录添加到系统环境变量:
4. 硬件参数适配(关键:替换虚拟机调试参数)
虚拟机与开发板的硬件参数(声卡名、控制单元名)不同,需在代码中替换为开发板实际参数,否则功能失效(如音量控制无响应)。
(1)查询开发板声卡名(ALSA 音频场景)
示例输出(开发板实际情况):
- 声卡名:
audiocodec(替换代码中虚拟机的AudioPCI)。
(2)查询开发板音频控制单元名(音量调节场景)
示例输出(开发板实际情况):
- 控制单元名:
lineout volume(替换代码中虚拟机的Master)。
(3)修改代码中的硬件参数
以 ALSA 音量控制代码为例,替换关键参数:
5. 应用程序传输与运行
(1)传输可执行程序到开发板
(2)赋予执行权限(若需要)
(3)运行程序并测试功能
6. 常见问题排查
(1)库找不到错误(如libjson-c.so.5: cannot open shared object file)
- 排查步骤:
- 用
ldd key_audio_control确认缺失的库名; - 检查开发板
lib目录下是否有该库的实际文件(如libjson-c.so.5.2.0); - 重新创建软链接(
ln -sf 实际库文件名 缺失的库名); - 若仍报错,运行程序时手动指定库路径:
bash
LD_LIBRARY_PATH=/root/kickpi_project/lib ./key_audio_control(2)按键无响应(程序未检测到按键事件)
- 排查步骤:
- 确认
/dev/input/eventX设备文件正确(重新执行cat /dev/input/event1,按下按键看是否有数据输出); - 检查
logind.conf配置是否生效(systemctl status systemd-logind,确保 USER 键已禁用关机功能); - 代码中
ev.type == EV_KEY是否正确(未过滤按键事件)。
(3)音频无输出(Mplayer 播放失败)
- 排查步骤:
- 单独运行 Mplayer 测试:
mplayer test.mp3(确认音频文件存在且格式支持); - 检查声卡名是否正确(
aplay -l重新确认); - 检查音频控制单元是否开启(
amixer set "lineout volume" 20,手动调节音量)。
部署核心总结
- 依赖库必须与开发板架构一致(ARM),优先使用交叉编译(避免开发板资源占用);
- 硬件参数(声卡、控制单元、设备文件)必须通过
aplay/amixer/ls /dev/input查询,不可直接复用虚拟机参数;
- 库依赖问题核心是 “路径正确 + 软链接匹配”,
ldd命令是关键排查工具;

- 运行程序前,先单独测试依赖工具(如 Mplayer)和硬件(如按键、声卡),再整合测试。
通过以上步骤,即可完成从 “交叉编译” 到 “开发板稳定运行” 的全流程部署,实现用户按键的灵活控制(如音频播放、参数配置等扩展功能)。
Tips 开发板支持的U盘位exFAT格式,这个格式支持中文且不乱码。
插上U盘后,输入dmesg打印内核信息是可以看到变化的。
也就是 有一个sdabc1
例如设备文件在/dev/sdc1
要使用U盘内容,则需要将其挂载在某个挂载点。
mkdir /mnt/usb
mount -t exfat /dev/sdc1 /mnt/usb
ls /mnt/usb/
- 作者:L_Z_J
- 链接:https://www.mcoi.top/article/Post-KickPi2B
- 声明:本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。










