RuyiSDK 外设控制示例
- 安装ruyi包管理器
sudo apt update; sudo apt install wget
wget https://mirror.iscas.ac.cn/ruyisdk/ruyi/tags/0.49.0/ruyi-0.49.0.riscv64
chmod +x ./ruyi-0.49.0.riscv64
sudo cp -v ./ruyi-0.49.0.riscv64 /usr/local/bin/ruyi- 安装工具链
ruyi update
ruyi install gnu-plct llvm-plctCanaan K510 CRB-V1.2 KIT GPIO KEYS Demo
-
示例描述和硬件环境准备
- 示例功能:基于 Linux input 子系统,读取 K510 开发板上的物理按键(
KEY0、KEY1)事件,打印按键码、按下/释放动作及持续时长。 - 硬件环境:Canaan K510 CRB-V1.2 KIT 开发板。
- 软件环境:K510 Buildroot 2020.02.11 (Linux 4.17),已联网可访问外部仓库(或使用主机交叉编译方式)。
-
创建并激活 ruyi 虚拟环境
ruyi venv --toolchain gnu-plct generic gcc-env . gcc-env/bin/ruyi-activate -
使用 ruyi 工具链编译 GPIO KEYS 测试代码
-
创建测试代码目录并编写代码
mkdir demo && cd demo nano gpio_keys_demo.c将以下代码粘贴进
gpio_keys_demo.c:#include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <fcntl.h> #include <errno.h> #include <linux/input.h> #include <sys/time.h> /* 按键状态 */ #define KEY_PRESSED 1 #define KEY_RELEASED 0 /* 按键动作描述 */ static const char *get_key_action(int value) { if (value == KEY_PRESSED) return "PRESSED"; else if (value == KEY_RELEASED) return "RELEASED"; else return "UNKNOWN"; } int main(int argc, char *argv[]) { int fd; struct input_event ev; struct timeval start_time, end_time; long duration_ms; int key_down = 0; unsigned int last_key_code = 0; /* 参数检查:需要指定 input 设备路径 */ if (argc != 2) { fprintf(stderr, "Usage: %s <input_device>\n", argv[0]); fprintf(stderr, "Example: %s /dev/input/event0\n", argv[0]); fprintf(stderr, "\nHint: Run 'cat /proc/bus/input/devices' to find the correct event node.\n"); return -1; } /* 打开 input 设备 */ fd = open(argv[1], O_RDONLY); if (fd == -1) { perror("open"); fprintf(stderr, "Failed to open %s. Please check device path and permissions.\n", argv[1]); return -1; } printf("GPIO_KEYS Demo started. Monitoring %s ...\n", argv[1]); printf("Press any key on the board. Press Ctrl+C to exit.\n\n"); /* 主循环:阻塞式读取按键事件 */ while (1) { memset(&ev, 0, sizeof(ev)); /* 阻塞读取一个 input 事件 */ if (read(fd, &ev, sizeof(ev)) < 0) { perror("read"); close(fd); return -1; } /* 只处理 EV_KEY 类型事件(按键事件) */ if (ev.type == EV_KEY) { /* 记录按键按下时间 */ if (ev.value == KEY_PRESSED) { gettimeofday(&start_time, NULL); key_down = 1; last_key_code = ev.code; printf("[%ld.%06ld] KEY CODE: %-4u ACTION: %s\n", start_time.tv_sec, start_time.tv_usec, ev.code, get_key_action(ev.value)); } /* 按键释放时计算持续时间 */ else if (ev.value == KEY_RELEASED && key_down && ev.code == last_key_code) { gettimeofday(&end_time, NULL); duration_ms = (end_time.tv_sec - start_time.tv_sec) * 1000 + (end_time.tv_usec - start_time.tv_usec) / 1000; printf("[%ld.%06ld] KEY CODE: %-4u ACTION: %s DURATION: %ld ms\n", end_time.tv_sec, end_time.tv_usec, ev.code, get_key_action(ev.value), duration_ms); key_down = 0; } /* 其他情况(如重复事件) */ else if (ev.value == 2) { /* 长按重复事件,可选择打印 */ /* printf("[*] KEY CODE: %u REPEAT\n", ev.code); */ } } } close(fd); return 0; } -
使用 RuyiGCC 编译
riscv64-plct-linux-gnu-gcc -static -o gpio_keys gpio_keys_demo.c -
剥离属性段
riscv64-plct-linux-gnu-objcopy --remove-section=.riscv.attributes gpio_keys gpio_keys_stripped
-
-
传输并运行测试
-
获取主板IP
ip addr show # 一般在eno1中的inet有:如10.13.21.160 -
PC端传输
python3 -m http.server 8000 -
另起一终端窗口进入开发板
sudo minicom -
下载并运行测试
wget http://10.13.21.160:8000/gpio_keys_stripped -O /root/gpio _keys_stripped chmod +x /root/gpio_keys_stripped # 查看 GPIO 按键对应的 input 事件节点 cat /proc/bus/input/devices # 找到含有 "gpio-keys" 的条目,记下对应的 event 编号(如 event1) # 运行测试程序(指定事件节点) /root/gpio_keys_stripped /dev/input/event1输出结果
[root@canaan ~ ]$ wget http://10.13.21.160:8000/gpio_keys_stripped -O /root/gpio _keys_stripped Connecting to 10.13.21.160:8000 (10.13.21.160:8000) saving to '/root/gpio_keys_stripped' gpio_keys_stripped 100% |********************************| 3191k 0:00:00 ETA '/root/gpio_keys_stripped' saved [root@canaan ~ ]$ chmod +x /root/gpio_keys_stripped [root@canaan ~ ]$ cat /proc/bus/input/devices I: Bus=0018 Vendor=0416 Product=038f Version=1060 N: Name="Goodix Capacitive TouchScreen" P: Phys=input/ts S: Sysfs=/devices/platform/99900000.noc_bus/99900000.noc_bus:apb_bus/99900000.noc_bus:apb_0 U: Uniq= H: Handlers=kbd event0 B: PROP=2 B: EV=b B: KEY=400 0 0 0 2000000000000000 0 B: ABS=265800000000003 I: Bus=0019 Vendor=0001 Product=0001 Version=0100 N: Name="99900000.noc_bus:gpio-keys" P: Phys=gpio-keys/input0 S: Sysfs=/devices/platform/99900000.noc_bus/99900000.noc_bus:gpio-keys/input/input1 U: Uniq= H: Handlers=kbd event1 B: PROP=0 B: EV=3 B: KEY=1000040000000 [root@canaan ~ ]$ /root/gpio_keys_stripped /dev/input/event1 GPIO_KEYS Demo started. Monitoring /dev/input/event1 ... Press any key on the board. Press Ctrl+C to exit. [1291173014.801218] KEY CODE: 48 ACTION: PRESSED [1291173014.986088] KEY CODE: 48 ACTION: RELEASED DURATION: 184 ms [1291173019.298035] KEY CODE: 30 ACTION: PRESSED [1291173019.515556] KEY CODE: 30 ACTION: RELEASED DURATION: 217 ms
-
-
退出环境
cd
ruyi-deactivate