From 179b5fe33f0c95e32e2ef12eb54c31240afeee87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E6=B2=BB=E4=B8=9E?= <16113360+chen-zhichengzzz@user.noreply.gitee.com> Date: Sun, 23 Aug 2026 16:32:41 +0000 Subject: [PATCH] =?UTF-8?q?Day4=EF=BC=9A=E6=8F=90=E4=BA=A4=20PIN=20?= =?UTF-8?q?=E8=AE=BE=E5=A4=87=E5=AF=B9=E6=8E=A5=E4=B8=8E=20test=5Fdev=20?= =?UTF-8?q?=E9=A9=B1=E5=8A=A8=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: 陈治丞 <16113360+chen-zhichengzzz@user.noreply.gitee.com> --- .../README.md" | 43 ++++++ .../test_dev.c" | 128 ++++++++++++++++++ 2 files changed, 171 insertions(+) create mode 100644 "2026/\347\254\2541\347\273\204/\351\231\210\346\262\273\344\270\236/\347\254\254\345\233\233\345\244\251\344\275\234\344\270\232/README.md" create mode 100644 "2026/\347\254\2541\347\273\204/\351\231\210\346\262\273\344\270\236/\347\254\254\345\233\233\345\244\251\344\275\234\344\270\232/test_dev.c" diff --git "a/2026/\347\254\2541\347\273\204/\351\231\210\346\262\273\344\270\236/\347\254\254\345\233\233\345\244\251\344\275\234\344\270\232/README.md" "b/2026/\347\254\2541\347\273\204/\351\231\210\346\262\273\344\270\236/\347\254\254\345\233\233\345\244\251\344\275\234\344\270\232/README.md" new file mode 100644 index 0000000..3ba8240 --- /dev/null +++ "b/2026/\347\254\2541\347\273\204/\351\231\210\346\262\273\344\270\236/\347\254\254\345\233\233\345\244\251\344\275\234\344\270\232/README.md" @@ -0,0 +1,43 @@ +# 【DAY4】RT-Thread PIN 设备对接与 test_dev 驱动框架 + +- 姓名:陈治丞 +- 组别:第 1 组 +- 开发板:STM32F407 星火一号 + +## 一、作业说明 + +本次作业围绕 RT-Thread PIN 设备对接和自定义设备框架展开。源码文件为 `test_dev.c`,使用星火一号的板载红灯和按键作为测试对象:红灯对应 `PF12`,`KEY_UP` 对应 `PC5`。 + +本版本暂不填写串口截图和实测数值,避免把未实际运行的结果当作实验数据。完成烧录后,可根据真实输出补充实验现象。 + +## 二、PIN 设备对接 + +RT-Thread 通过 PIN 设备接口屏蔽底层 GPIO 寄存器差异。应用层使用 `rt_pin_mode()` 配置引脚方向,使用 `rt_pin_write()` 输出电平,使用 `rt_pin_read()` 读取输入电平。 + +| 功能 | 引脚 | 配置 | +| --- | --- | --- | +| `test_dev` 输出 | PF12 | 推挽输出,低电平点亮 LED_R | +| `test_dev` 输入 | PC5 | 上拉输入,按下 KEY_UP 时读取低电平 | + +## 三、test_dev 设备框架 + +源码定义静态 `struct rt_device`,并通过 `rt_device_register()` 注册为 `test_dev`。设备操作函数包括初始化、打开、关闭、读取、写入和控制。`read` 读取按键电平,`write` 设置 LED 状态,`control` 提供状态读取和 LED 翻转。 + +初始化函数使用 `INIT_APP_EXPORT(test_dev_register)` 自动执行,不需要在 `main.c` 中手动调用。 + +## 四、MSH 测试命令 + +下载程序并进入 FinSH 后,在 `msh >` 后输入: + +```text +test_dev read +test_dev on +test_dev off +test_dev toggle +``` + +`read` 读取 KEY_UP,`on` 点亮 LED_R,`off` 熄灭 LED_R,`toggle` 翻转 LED_R。 + +## 五、编译与验证 + +将 `test_dev.c` 放入 `applications` 目录,重新构建并下载。打开 `COM13`、`115200` 串口,逐条执行上述命令。按下和松开 KEY_UP 后再次执行 `test_dev read`,根据真实串口输出补充实验结果和截图。 diff --git "a/2026/\347\254\2541\347\273\204/\351\231\210\346\262\273\344\270\236/\347\254\254\345\233\233\345\244\251\344\275\234\344\270\232/test_dev.c" "b/2026/\347\254\2541\347\273\204/\351\231\210\346\262\273\344\270\236/\347\254\254\345\233\233\345\244\251\344\275\234\344\270\232/test_dev.c" new file mode 100644 index 0000000..da41ff0 --- /dev/null +++ "b/2026/\347\254\2541\347\273\204/\351\231\210\346\262\273\344\270\236/\347\254\254\345\233\233\345\244\251\344\275\234\344\270\232/test_dev.c" @@ -0,0 +1,128 @@ +/* Day4: a small RT-Thread PIN-backed device framework. */ +#include +#include +#include + +#define TEST_DEV_NAME "test_dev" +#define TEST_OUT_PIN GET_PIN(F, 12) /* RT-Spark LED_R */ +#define TEST_IN_PIN GET_PIN(C, 5) /* RT-Spark KEY_UP */ + +struct test_dev_data +{ + struct rt_device device_object; + rt_device_t device; + rt_base_t out_pin; + rt_base_t in_pin; + rt_uint8_t out_value; +}; + +static struct test_dev_data test_data; + +static rt_err_t test_dev_init(rt_device_t dev) +{ + struct test_dev_data *data = (struct test_dev_data *)dev->user_data; + rt_pin_mode(data->out_pin, PIN_MODE_OUTPUT); + rt_pin_write(data->out_pin, PIN_HIGH); + rt_pin_mode(data->in_pin, PIN_MODE_INPUT_PULLUP); + data->out_value = 0; + return RT_EOK; +} + +static rt_err_t test_dev_open(rt_device_t dev, rt_uint16_t oflag) +{ + RT_UNUSED(dev); RT_UNUSED(oflag); return RT_EOK; +} + +static rt_err_t test_dev_close(rt_device_t dev) +{ + RT_UNUSED(dev); return RT_EOK; +} + +static rt_size_t test_dev_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + struct test_dev_data *data = (struct test_dev_data *)dev->user_data; + rt_uint8_t value; + RT_UNUSED(pos); + if (buffer == RT_NULL || size < 1) return 0; + value = (rt_uint8_t)rt_pin_read(data->in_pin); + *(rt_uint8_t *)buffer = value; + return 1; +} + +static rt_size_t test_dev_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + struct test_dev_data *data = (struct test_dev_data *)dev->user_data; + RT_UNUSED(pos); + if (buffer == RT_NULL || size < 1) return 0; + data->out_value = *(const rt_uint8_t *)buffer ? 1 : 0; + rt_pin_write(data->out_pin, data->out_value ? PIN_LOW : PIN_HIGH); + return 1; +} + +static rt_err_t test_dev_control(rt_device_t dev, int cmd, void *args) +{ + struct test_dev_data *data = (struct test_dev_data *)dev->user_data; + if (cmd == 0) /* read output latch */ + { + if (args == RT_NULL) return -RT_EINVAL; + *(rt_uint8_t *)args = data->out_value; + return RT_EOK; + } + if (cmd == 1) /* toggle output */ + { + rt_uint8_t value = data->out_value ? 0 : 1; + return test_dev_write(dev, 0, &value, 1) == 1 ? RT_EOK : -RT_ERROR; + } + return -RT_ENOSYS; +} + +static int test_dev_register(void) +{ + rt_err_t result; + rt_memset(&test_data, 0, sizeof(test_data)); + test_data.out_pin = TEST_OUT_PIN; + test_data.in_pin = TEST_IN_PIN; + test_data.device = &test_data.device_object; + test_data.device->type = RT_Device_Class_Miscellaneous; + /* RT-Thread 4.1.x stores the operations directly in rt_device. */ + test_data.device->init = test_dev_init; + test_data.device->open = test_dev_open; + test_data.device->close = test_dev_close; + test_data.device->read = test_dev_read; + test_data.device->write = test_dev_write; + test_data.device->control = test_dev_control; + test_data.device->user_data = &test_data; + result = rt_device_register(test_data.device, TEST_DEV_NAME, RT_DEVICE_FLAG_RDWR); + if (result != RT_EOK) { rt_kprintf("register %s failed: %d\n", TEST_DEV_NAME, result); return result; } + result = rt_device_init(test_data.device); + if (result != RT_EOK) { rt_kprintf("init %s failed: %d\n", TEST_DEV_NAME, result); return result; } + rt_kprintf("%s registered: OUT=PF12, IN=PC5\n", TEST_DEV_NAME); + return RT_EOK; +} +INIT_APP_EXPORT(test_dev_register); + +static int test_dev(int argc, char **argv) +{ + rt_device_t dev = rt_device_find(TEST_DEV_NAME); + rt_uint8_t value, input; + if (dev == RT_NULL) { rt_kprintf("%s not found\n", TEST_DEV_NAME); return -RT_ENOSYS; } + if (argc < 2 || !rt_strcmp(argv[1], "read")) + { + rt_device_open(dev, RT_DEVICE_FLAG_RDWR); + rt_device_read(dev, 0, &input, 1); + rt_kprintf("test_dev read: KEY_UP=%u\n", input); + rt_device_close(dev); return RT_EOK; + } + if (!rt_strcmp(argv[1], "on") || !rt_strcmp(argv[1], "off")) + { + value = !rt_strcmp(argv[1], "on"); + rt_device_open(dev, RT_DEVICE_FLAG_RDWR); rt_device_write(dev, 0, &value, 1); rt_device_close(dev); + rt_kprintf("test_dev output %s\n", argv[1]); return RT_EOK; + } + if (!rt_strcmp(argv[1], "toggle")) + { + rt_device_control(dev, 1, RT_NULL); rt_kprintf("test_dev toggled\n"); return RT_EOK; + } + rt_kprintf("usage: test_dev [read|on|off|toggle]\n"); return -RT_EINVAL; +} +MSH_CMD_EXPORT(test_dev, test PIN-backed device: read/on/off/toggle); -- Gitee