diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000000000000000000000000000000000..f9128470529fe73acd7e953ee3d0c420f14c5149 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x86", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "C:/MinGW/bin/gcc.exe", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x86", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..b3b2db064e2ce1aea2ebe8e5cd1a79aff41ed6e3 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,24 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "C/C++ Runner: Debug Session", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "externalConsole": true, + "cwd": "d:/2025-RSOC/rsoc-rtt/2025/第2组(RA8D1-Vision-Board)/林庆安/作业/DAY3", + "program": "d:/2025-RSOC/rsoc-rtt/2025/第2组(RA8D1-Vision-Board)/林庆安/作业/DAY3/build/Debug/outDebug", + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000000000000000000000000000000000000..bb879da5a0774e5e3a4e5e90dba7a0770370c0f7 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,59 @@ +{ + "C_Cpp_Runner.cCompilerPath": "gcc", + "C_Cpp_Runner.cppCompilerPath": "g++", + "C_Cpp_Runner.debuggerPath": "gdb", + "C_Cpp_Runner.cStandard": "", + "C_Cpp_Runner.cppStandard": "", + "C_Cpp_Runner.msvcBatchPath": "C:/Program Files/Microsoft Visual Studio/VR_NR/Community/VC/Auxiliary/Build/vcvarsall.bat", + "C_Cpp_Runner.useMsvc": false, + "C_Cpp_Runner.warnings": [ + "-Wall", + "-Wextra", + "-Wpedantic", + "-Wshadow", + "-Wformat=2", + "-Wcast-align", + "-Wconversion", + "-Wsign-conversion", + "-Wnull-dereference" + ], + "C_Cpp_Runner.msvcWarnings": [ + "/W4", + "/permissive-", + "/w14242", + "/w14287", + "/w14296", + "/w14311", + "/w14826", + "/w44062", + "/w44242", + "/w14905", + "/w14906", + "/w14263", + "/w44265", + "/w14928" + ], + "C_Cpp_Runner.enableWarnings": true, + "C_Cpp_Runner.warningsAsError": false, + "C_Cpp_Runner.compilerArgs": [], + "C_Cpp_Runner.linkerArgs": [], + "C_Cpp_Runner.includePaths": [], + "C_Cpp_Runner.includeSearch": [ + "*", + "**/*" + ], + "C_Cpp_Runner.excludeSearch": [ + "**/build", + "**/build/**", + "**/.*", + "**/.*/**", + "**/.vscode", + "**/.vscode/**" + ], + "C_Cpp_Runner.useAddressSanitizer": false, + "C_Cpp_Runner.useUndefinedSanitizer": false, + "C_Cpp_Runner.useLeakSanitizer": false, + "C_Cpp_Runner.showCompilationTime": false, + "C_Cpp_Runner.useLinkTimeOptimization": false, + "C_Cpp_Runner.msvcSecureNoWarnings": false +} \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY2/Day2\344\275\234\344\270\232.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY2/Day2\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..190ef5790a57de2b743daf18367e7c239d60eaa8 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY2/Day2\344\275\234\344\270\232.md" @@ -0,0 +1,16 @@ +【课后作业DAY2】 + +1️⃣整理和提交课堂笔记(Git PR): +将今日课程内容进行整理,形成清晰的笔记。使用 Git 将整理好的笔记以 Pull Request (PR) 的形式提交到https://gitee.com/rtthread/rsoc-rtt笔记仓库。 + +2️⃣论坛发文(分享笔记): +在课程论坛发表整理好的课堂笔记,论坛链接https://club.rt-thread.org/ +➡️文章标题格式: 【RSOC25】笔记标题(如 XXX) + +3️⃣编写代码上传至git仓库,创建至少3个线程,能体现抢占与时间片轮转,在今天的工程的mian.c中实现,其他同学拿到该文件可以直接运行。 + +4️⃣自行研究:ARM函数调用规范 + +PR链接:https://gitee.com/lin-arc/rsoc-rtt/commit/74c660b38dc5766ad4852d191cc5ef301dd4fd23 + +文章链接:https://club.rt-thread.org/ask/article/4087d927de746667.html \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY2/main.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY2/main.c" new file mode 100644 index 0000000000000000000000000000000000000000..8a840aa958b91c4eef47f2e200637b2bf8d1cb6d --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY2/main.c" @@ -0,0 +1,80 @@ +#include +#include +#include + +// 线程控制块指针声明 +rt_thread_t thread1 = RT_NULL; +rt_thread_t thread2 = RT_NULL; +rt_thread_t thread3 = RT_NULL; + +/** + * 线程1入口函数 + * 功能:循环打印"thread1_run,count:%d\n",并在计数 + */ +void thread1_entry(void *parameter) +{ + int count=0; + while(1) // 线程主循环,持续运行 + { + if(count<10) + { + rt_kprintf("thread1_run,count:%d\n",count); // 打印线程1运行信息 + count++; + rt_thread_mdelay(15); + } + } +} + +/** +* 线程2入口函数 +* 功能:循环打印"thread2_run\n" +*/ +void thread2_entry(void *parameter) +{ + while(1) // 线程主循环,持续运行 + { + + rt_kprintf("thread2_run\n"); // 打印线程2运行信息 + + } +} + +/** +* 线程3入口函数 +* 功能:循环打印"thread3_run\n" +*/ +void thread3_entry(void *parameter) +{ + while(1) // 线程主循环,持续运行 + { + + rt_kprintf("thread3_run\n"); // 打印线程3运行信息 + } +} + +int main(void) +{ + // 创建线程1:名称"thread1",入口函数_thread1,无参数,栈大小1024,优先级9,时间片5 + thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 1024, 9, 5); + // 创建线程2:名称"thread2",入口函数_thread2,无参数,栈大小1024,优先级11,时间片5 + thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, 1024, 11, 10); + // 创建线程3:名称"thread3",入口函数_thread3,无参数,栈大小1024,优先级11,时间片5 + thread3 = rt_thread_create("thread3", thread3_entry, RT_NULL, 1024, 11, 5); + + // 若线程1创建成功,则启动线程1 + if(thread1 != RT_NULL) + { + rt_thread_startup(thread1); + } + // 若线程2创建成功,则启动线程1 + if(thread2 != RT_NULL) + { + rt_thread_startup(thread2); + } + // 若线程3创建成功,则启动线程1 + if(thread3 != RT_NULL) + { + rt_thread_startup(thread3); + } + return 0; // 主函数返回(RT-Thread中主函数退出后仍会运行线程) +} diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/Day3\344\275\234\344\270\232.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/Day3\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..69e3f2b707e5ab0aa0460d4446072c52e1b5f279 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/Day3\344\275\234\344\270\232.md" @@ -0,0 +1,14 @@ +【课后作业DAY3】 + +1️⃣整理和提交课堂笔记(Git PR): +将今日课程内容进行整理,形成清晰的笔记。使用 Git 将整理好的笔记以 Pull Request (PR) 的形式提交到https://gitee.com/rtthread/rsoc-rtt笔记仓库。 + +2️⃣论坛发文(分享笔记): +在课程论坛发表整理好的课堂笔记,论坛链接https://club.rt-thread.org/ +➡️文章标题格式: 【RSOC25】笔记标题(如 【RSOC25】Day1 课程笔记:XXX) + +3️⃣编写代码上传至git仓库,程序需要体现出信号量、互斥量、事件集、邮箱、消息队列、信号的作用(上传6个C文件,每个文件体现一种功能)。 + +PR链接:https://gitee.com/rtthread/rsoc-rtt/commit/ea4e15688939695e2d840e36b63a727af769188f + +文章链接:https://club.rt-thread.org/ask/article/e9f15358ab7f0465.html \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/even3.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/even3.c" new file mode 100644 index 0000000000000000000000000000000000000000..a2021726066bda0e67315bc117555850cdc0659e --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/even3.c" @@ -0,0 +1,126 @@ +#include + +#define THREAD_PRIORITY 9 +#define THREAD_TIMESLICE 5 + +#define EVENT_FLAG1 (1 << 1) +#define EVENT_FLAG2 (1 << 2) +#define EVENT_FLAG3 (1 << 3) +/* 事件控制块 */ +static struct rt_event event; + +ALIGN(RT_ALIGN_SIZE) +static char thread1_stack[1024]; +static struct rt_thread thread1; + +/* 线程 1 入口函数 */ +static void thread1_recv_event(void *param) +{ + rt_uint32_t e; + + /* 第一次接收事件,事件 1 或事件 2 任意一个可以触发线程 1,接收完后清除事件标志 */ + if (rt_event_recv(&event, (EVENT_FLAG1 | EVENT_FLAG2), + RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, + RT_WAITING_FOREVER, &e) == RT_EOK) + { + rt_kprintf("thread1: OR recv event 0x%x\n", e); + } + + rt_kprintf("thread1: delay 1s to prepare the second event\n"); + rt_thread_mdelay(1000); + + /* 第二次接收事件,事件 1 和事件 2 均发生时才可以触发线程 1,接收完后清除事件标志 */ + if (rt_event_recv(&event, (EVENT_FLAG1 | EVENT_FLAG2), + RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, + RT_WAITING_FOREVER, &e) == RT_EOK) + { + rt_kprintf("thread1: AND recv event 0x%x\n", e); + } + rt_kprintf("thread1: delay 1s to prepare the thrid event\n"); + rt_thread_mdelay(1000); + /* 第三次接收事件,事件 1 和 事件 2 和 事件3 均发生时才可以触发线程 1,接收完后清除事件标志 */ + if (rt_event_recv(&event, ( EVENT_FLAG1 | EVENT_FLAG2 | EVENT_FLAG3 ), + RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, + RT_WAITING_FOREVER, &e) == RT_EOK) + { + rt_kprintf("thread1: AND recv event 0x%x\n", e); + } + /* 执行完该事件集后进行事件集的脱离,事件集重复初始化会导致再次运行时,出现重复初始化的问题 */ + rt_event_detach(&event); + rt_kprintf("thread1 leave.\n"); +} + + +ALIGN(RT_ALIGN_SIZE) +static char thread2_stack[1024]; +static struct rt_thread thread2; + +/* 线程 2 入口 */ +static void thread2_send_event(void *param) +{ + //第一次发送 + rt_kprintf("thread2: send event1\n"); + rt_event_send(&event, EVENT_FLAG1); + rt_thread_mdelay(1000); + + //第二次发送 + rt_kprintf("thread2: send event2\n"); + rt_event_send(&event, EVENT_FLAG2); + rt_thread_mdelay(200); + + rt_kprintf("thread2: send event1\n"); + rt_event_send(&event, EVENT_FLAG1); + rt_thread_mdelay(1000); + + //第三次发送 + rt_kprintf("thread2: send event1\n"); + rt_event_send(&event, EVENT_FLAG1); + rt_thread_mdelay(200); + + rt_kprintf("thread2: send event2\n"); + rt_event_send(&event, EVENT_FLAG2); + rt_thread_mdelay(200); + + rt_kprintf("thread2: send event3\n"); + rt_event_send(&event, EVENT_FLAG3); + rt_thread_mdelay(200); + + rt_kprintf("thread2 leave.\n"); + +} + +int event3(void) +{ + rt_err_t result; + + /* 初始化事件对象 */ + result = rt_event_init(&event, "event", RT_IPC_FLAG_PRIO); + if (result != RT_EOK) + { + rt_kprintf("init event failed.\n"); + return -1; + } + + rt_thread_init(&thread1, + "thread1", + thread1_recv_event, + RT_NULL, + &thread1_stack[0], + sizeof(thread1_stack), + THREAD_PRIORITY - 1, THREAD_TIMESLICE); + rt_thread_startup(&thread1); + + rt_thread_init(&thread2, + "thread2", + thread2_send_event, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(&thread2); + + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(event3, event3); diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/mailbox4.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/mailbox4.c" new file mode 100644 index 0000000000000000000000000000000000000000..7d63e304341d027c51a3e5fe92926341f0059f2b --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/mailbox4.c" @@ -0,0 +1,113 @@ +#include + +#define THREAD_PRIORITY 10 +#define THREAD_TIMESLICE 5 + +/* 邮箱控制块 */ +static struct rt_mailbox mb; +/* 用于放邮件的内存池 */ +static char mb_pool[128]; + +static char mb_str1[] = "first_mail"; +static char mb_str2[] = "return_mail"; +static char mb_str3[] = "end"; + +ALIGN(RT_ALIGN_SIZE) +static char thread1_stack[1024]; +static struct rt_thread thread1; + +/* 线程 1 入口 */ +static void thread1_entry(void *parameter) +{ + char *str; + + while (1) + { + rt_kprintf("thread1: try to recv a mail\n"); + + /* 从邮箱中收取邮件 */ + if (rt_mb_recv(&mb, (rt_uint32_t *)&str, RT_WAITING_FOREVER) == RT_EOK) + { + rt_kprintf("thread1: get a mail from mailbox, the content: %s\n", str); + if (str == mb_str3) + break; + + /* 延时 100ms */ + rt_thread_mdelay(100); + } + } + /* 执行邮箱对象脱离 */ + rt_mb_detach(&mb); +} + +ALIGN(RT_ALIGN_SIZE) +static char thread2_stack[1024]; +static struct rt_thread thread2; + +/* 线程 2 入口 */ +static void thread2_entry(void *parameter) +{ + rt_uint8_t count; + + count = 0; + while (count < 10) + { + count ++; + if (count & 0x1) + { + /* 发送 mb_str1 地址到邮箱中 */ + rt_mb_send(&mb, (rt_uint32_t)&mb_str1); + } + else + { + /* 发送 mb_str2 地址到邮箱中 */ + rt_mb_send(&mb, (rt_uint32_t)&mb_str2); + } + + /* 延时 200ms */ + rt_thread_mdelay(200); + } + + /* 发送邮件告诉线程 1,线程 2 已经运行结束 */ + rt_mb_send(&mb, (rt_uint32_t)&mb_str3); +} + +int mailbox4(void) +{ + rt_err_t result; + + /* 初始化一个 mailbox */ + result = rt_mb_init(&mb, + "mbt", /* 名称是 mbt */ + &mb_pool[0], /* 邮箱用到的内存池是 mb_pool */ + sizeof(mb_pool) / 4, /* 邮箱中的邮件数目,因为一封邮件占 4 字节 */ + RT_IPC_FLAG_FIFO); /* 采用 FIFO 方式进行线程等待 */ + if (result != RT_EOK) + { + rt_kprintf("init mailbox failed.\n"); + return -1; + } + + rt_thread_init(&thread1, + "thread1", + thread1_entry, + RT_NULL, + &thread1_stack[0], + sizeof(thread1_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(&thread1); + + rt_thread_init(&thread2, + "thread2", + thread2_entry, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(&thread2); + +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(mailbox4, mailbox4); + diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/mutex2.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/mutex2.c" new file mode 100644 index 0000000000000000000000000000000000000000..120768a485d3d798333568bf08c0c4b59028872b --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/mutex2.c" @@ -0,0 +1,97 @@ +#include + +#define THREAD_PRIORITY 8 +#define THREAD_TIMESLICE 5 + +/* 指向互斥量的指针 */ +static rt_mutex_t dynamic_mutex = RT_NULL; +static rt_uint8_t number1=10, number2 = 20; +/* 线程退出标志 */ +static rt_bool_t thread_exit_flag = RT_FALSE; + +ALIGN(RT_ALIGN_SIZE) +static char thread1_stack[1024]; +static struct rt_thread thread1; + +static void rt_thread_entry1(void *parameter) +{ + while (1) + { + /* 获取互斥量并进行操作 */ + if (rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER) == RT_EOK) + { + number1++; + rt_kprintf(" number1 = %d\n", number1); + rt_mutex_release(dynamic_mutex); + rt_thread_mdelay(10); + if (number1 >= 50) + { + thread_exit_flag = RT_TRUE; + + /* 删除互斥量 */ + rt_mutex_delete(dynamic_mutex); + dynamic_mutex = RT_NULL; + + break; /* 退出线程 */ + } + } + } +} + +ALIGN(RT_ALIGN_SIZE) +static char thread2_stack[1024]; +static struct rt_thread thread2; +static void rt_thread_entry2(void *parameter) +{ + while (1) + { + /* 获取互斥量 */ + if (rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER) == RT_EOK) + { + rt_kprintf(" number2 is %d\n", number2); + number2++; + rt_mutex_release(dynamic_mutex); + /* 判断是否达到退出条件 */ + if (number2 >= 50) + { + break; /* 退出线程 */ + } + } + } +} + +int mutex2(void) +{ + /* 创建一个动态互斥量 */ + dynamic_mutex = rt_mutex_create("dmutex", RT_IPC_FLAG_PRIO); + if (dynamic_mutex == RT_NULL) + { + rt_kprintf("create dynamic mutex failed.\n"); + return -1; + } + rt_thread_init(&thread2, + "thread2", + rt_thread_entry2, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY - 1, THREAD_TIMESLICE); + rt_thread_startup(&thread2); + + rt_thread_init(&thread1, + "thread1", + rt_thread_entry1, + RT_NULL, + &thread1_stack[0], + sizeof(thread1_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(&thread1); + + + + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(mutex2, mutex2); + diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/queue5.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/queue5.c" new file mode 100644 index 0000000000000000000000000000000000000000..ba5cfe567b3cddf081dc0cbf501e67c843304f84 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/queue5.c" @@ -0,0 +1,134 @@ +#include + +#define THREAD1_PRIORITY 25 +#define THREAD1_STACK_SIZE 512 +#define THREAD1_TIMESLICE 5 + +#define THREAD2_PRIORITY 25 +#define THREAD2_STACK_SIZE 512 +#define THREAD2_TIMESLICE 5 + +/* 消息队列控制块 */ +static struct rt_messagequeue mq; +/* 消息队列中用到的放置消息的内存池 */ +static rt_uint8_t msg_pool[2048]; + +static rt_thread_t tid1 = RT_NULL; +/* 线程 1 入口函数 */ +static void thread1_entry(void *parameter) +{ + char buf = 0; + rt_uint8_t cnt = 0; + + while (1) + { + /* 从消息队列中接收消息 */ +#if defined(RT_VERSION_CHECK) && (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 1)) + if (rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) > 0) +#else + if (rt_mq_recv(&mq, &buf, sizeof(buf), RT_WAITING_FOREVER) == RT_EOK) +#endif + { + rt_kprintf("thread1: recv msg from msg queue, the content:%c\n", buf); + if (cnt == 19) + { + break; + } + } + /* 延时 50ms */ + cnt++; + rt_thread_mdelay(50); + } + rt_kprintf("thread1: detach mq \n"); + rt_mq_detach(&mq); +} + + +static rt_thread_t tid2 = RT_NULL; +/* 线程 2 入口 */ +static void thread2_entry(void *parameter) +{ + int result; + char buf = 'A'; + rt_uint8_t cnt = 0; + + while (1) + { + if (cnt == 8) + { + /* 发送紧急消息到消息队列中 */ + result = rt_mq_urgent(&mq, &buf, 1); + if (result != RT_EOK) + { + rt_kprintf("rt_mq_urgent ERR\n"); + } + else + { + rt_kprintf("thread2: send urgent message - %c\n", buf); + } + } + else if (cnt>= 20)/* 发送 20 次消息之后退出 */ + { + rt_kprintf("message queue stop send, thread2 quit\n"); + break; + } + else + { + /* 发送消息到消息队列中 */ + result = rt_mq_send(&mq, &buf, 1); + if (result != RT_EOK) + { + rt_kprintf("rt_mq_send ERR\n"); + } + + rt_kprintf("thread2: send message - %c\n", buf); + } + buf++; + cnt++; + /* 延时 5ms */ + rt_thread_mdelay(5); + } +} + +/* 消息队列示例的初始化 */ +int msgq_sample(void) +{ + rt_err_t result; + + /* 初始化消息队列 */ + result = rt_mq_init(&mq, + "mqt", + &msg_pool[0], /* 内存池指向 msg_pool */ + 1, /* 每个消息的大小是 1 字节 */ + sizeof(msg_pool), /* 内存池的大小是 msg_pool 的大小 */ + RT_IPC_FLAG_PRIO); /* 如果有多个线程等待,优先级大小的方法分配消息 */ + + if (result != RT_EOK) + { + rt_kprintf("init message queue failed.\n"); + return -1; + } + + /* 动态创建线程1 */ + tid1 = rt_thread_create("thread1", + thread1_entry, RT_NULL, + THREAD1_STACK_SIZE, + THREAD1_PRIORITY, THREAD1_TIMESLICE); + + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + + /* 动态创建线程2 */ + tid2 = rt_thread_create("thread2", + thread2_entry, RT_NULL, + THREAD2_STACK_SIZE, + THREAD2_PRIORITY, THREAD2_TIMESLICE); + + if (tid2 != RT_NULL) + rt_thread_startup(tid2); + + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(msgq_sample, msgq sample); diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/sign1.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/sign1.c" new file mode 100644 index 0000000000000000000000000000000000000000..d4418b06ecb28654b87caa9235d5e6ae9b3ebe56 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/sign1.c" @@ -0,0 +1,108 @@ +#include + +#define THREAD_PRIORITY 25 +#define THREAD_TIMESLICE 5 + +/* 信号量退出标志 */ +static rt_bool_t sem_flag = 0; +/* 指向信号量的指针 */ +static rt_sem_t dynamic_sem = RT_NULL; + +ALIGN(RT_ALIGN_SIZE) +static char thread1_stack[1024]; +static struct rt_thread thread1; + +// +static void rt_thread1_entry(void *parameter) +{ + static rt_uint8_t count = 0; + + while (1) + { + if (count <= 20) + { + count++; + } + else + { + rt_kprintf("thread1_stop\n"); + sem_flag = 1; + rt_sem_release(dynamic_sem); + count = 0; + return; + } + + /* count 小于20,就释放一次信号量 */ + if (count <= 20) + { + rt_kprintf("thread1_send \n",count); + rt_sem_release(dynamic_sem); + } + } +} + +ALIGN(RT_ALIGN_SIZE) +static char thread2_stack[1024]; +static struct rt_thread thread2; +static void rt_thread2_entry(void *parameter) +{ + static rt_err_t result; + static rt_uint8_t number = 0; + while (1) + { + /* 永久方式等待信号量,获取到信号量,则执行 number 自加的操作 */ + result = rt_sem_take(dynamic_sem, RT_WAITING_FOREVER); + if (sem_flag && result == RT_EOK) + { + rt_kprintf("thread2_stop \n"); + rt_sem_delete(dynamic_sem); + sem_flag = 0; + number = 0; + return; + } + else + { + number++; + rt_kprintf("thread2_rev \n"); + } + } +} + +/* 信号量示例的初始化 */ +int sign1(void) +{ + /* 创建一个动态信号量,初始值是 0 */ + dynamic_sem = rt_sem_create("dsem", 0, RT_IPC_FLAG_PRIO); + if (dynamic_sem == RT_NULL) + { + rt_kprintf("create dynamic semaphore failed.\n"); + return -1; + } + else + { + rt_kprintf("create done. dynamic semaphore value = 0.\n"); + } + + rt_thread_init(&thread1, + "thread1", + rt_thread1_entry, + RT_NULL, + &thread1_stack[0], + sizeof(thread1_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); + rt_thread_startup(&thread1); + + rt_thread_init(&thread2, + "thread2", + rt_thread2_entry, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY - 1, THREAD_TIMESLICE); + rt_thread_startup(&thread2); + + return 0; +} +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(sign1, sign1); + diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/signal6.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/signal6.c" new file mode 100644 index 0000000000000000000000000000000000000000..1a707578a36e62c1f2a1d96716e7bcb8b599473a --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY3/signal6.c" @@ -0,0 +1,58 @@ +#include + +#define THREAD_PRIORITY 25 +#define THREAD_STACK_SIZE 512 +#define THREAD_TIMESLICE 5 + +static rt_thread_t thread1 = RT_NULL; + +/* 线程 1 的信号处理函数 */ +void thread1_signal_handler(int sig) +{ + rt_kprintf("thread1 received signal %d\n", sig); +} + +/* 线程 1 的入口函数 */ +static void thread1_entry(void *parameter) +{ + int cnt = 0; + char buf= 'A'; + /* 安装信号 */ + rt_signal_install(SIGUSR1, thread1_signal_handler); + rt_signal_unmask(SIGUSR1); + + /* 运行 24 次 */ + while (cnt < 26) + { + /* 线程 1 采用低优先级运行,一直打印计数值 */ + rt_kprintf("thread1 count : %c\n", buf); + + cnt++; + buf++; + rt_thread_mdelay(100); + } +} + +/* 信号示例的初始化 */ +int signal6(void) +{ + /* 创建线程 1 */ + thread1 = rt_thread_create("thread1", + thread1_entry, RT_NULL, + THREAD_STACK_SIZE, + THREAD_PRIORITY, THREAD_TIMESLICE); + + if (thread1 != RT_NULL) + rt_thread_startup(thread1); + + rt_thread_mdelay(300); + + /* 发送信号 SIGUSR1 给线程 1 */ + rt_thread_kill(thread1, SIGUSR1); + + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(signal6, signal6); + diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/Day4\344\275\234\344\270\232.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/Day4\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..e26f5333f1f06bbf796d981d6e3f2d0dd51e5e77 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/Day4\344\275\234\344\270\232.md" @@ -0,0 +1,14 @@ +【课后作业DAY4】 + +1️⃣整理和提交课堂笔记(Git PR): +将今日课程内容进行整理,分析PIN设备如何对接的。使用 Git 将整理好的笔记以 Pull Request (PR) 的形式提交到https://gitee.com/rtthread/rsoc-rtt笔记仓库。 + +2️⃣论坛发文(分享笔记): +在课程论坛发表整理好的课堂笔记,论坛链接https://club.rt-thread.org/ +➡️文章标题格式: 【RSOC25】笔记标题(如 【RSOC25】Day1 课程笔记:XXX) + +3️⃣自己设计一个虚拟的设备驱动框架层。 + + PR链接:https://gitee.com/rtthread/rsoc-rtt/commit/dd334941f64616c78a508f113895f41a7727fcab + +文章链接:https://club.rt-thread.org/ask/article/5155c388e89364f9.html \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/drv_vir.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/drv_vir.c" new file mode 100644 index 0000000000000000000000000000000000000000..148ebd1b34c6099e50db8fa58705e9677c330764 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/drv_vir.c" @@ -0,0 +1,35 @@ +#include + +#if defined(RT_USING_VIR) + +struct vir_test vir; +void printfinfo(struct rt_device * device,rt_uint8_t * str) +{ + rt_kprintf("vir info :%s\n",str); +} +void vir_set_val(struct rt_device * device,rt_uint32_t val) +{ + vir.val = val; +} +void vir_get_val(struct rt_device * device,rt_uint32_t *val) +{ + *val = vir.val; +} +struct rt_vir_ops ops = +{ + printfinfo, + vir_set_val, + vir_get_val, +}; + +static int vir_init(void) +{ + vir.val = 0; + vir.info = "test_vir"; + rt_hw_vir_register(&vir.parent,"vir",&ops,(void*)vir.info); +} +INIT_APP_EXPORT(vir_init); + +#endif + + diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/drv_vir.h" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/drv_vir.h" new file mode 100644 index 0000000000000000000000000000000000000000..fdd0d8df5dc4d9464558fabc0005dcaaa1fce38b --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/drv_vir.h" @@ -0,0 +1,16 @@ +#ifndef __DRV_VIR_H__ +#define __DRV_VIR_H__ +#include +#include + + +struct vir_test +{ + + struct rt_vir_device parent; + rt_uint32_t val; + char * info; +}; + +#endif + diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/main.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/main.c" new file mode 100644 index 0000000000000000000000000000000000000000..9a0c252483bff316a778a2df99325825ce7e1bc2 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/main.c" @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-07-06 Supperthomas first version + * 2023-12-03 Meco Man support nano version + */ + +#include +#include +#include +#ifndef RT_USING_NANO +#include +#endif /* RT_USING_NANO */ + +int main(void) +{ + rt_device_t vir = rt_device_find("vir"); + if(vir == RT_NULL) + { + rt_kprintf("find vir dev err\n"); + return -RT_ERROR; + } + rt_uint32_t val = 1234; //写入数据 + rt_uint32_t ret = 0; //承接数据 + rt_device_open(vir,RT_DEVICE_FLAG_RDWR);//读写操作 + rt_device_write(vir,0,&val,4); + rt_device_read(vir,0,&ret,4); + rt_kprintf("ret :%d\n",ret);//打印承接的数据 + rt_device_close(vir);//关闭设备 +} diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/vir.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/vir.c" new file mode 100644 index 0000000000000000000000000000000000000000..e3c39b90376cebe2c8917f8c3184f9a2a09f051b --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/vir.c" @@ -0,0 +1,90 @@ +#include +#include + +#if defined(RT_USING_VIR) + +rt_err_t _vir_init(rt_device_t dev) +{ + rt_kprintf("vir init \n"); + return RT_EOK; +} +rt_err_t _vir_open(rt_device_t dev, rt_uint16_t oflag) +{ + rt_kprintf("vir open\n"); + return RT_EOK; +} +rt_err_t _vir_close (rt_device_t dev) +{ + rt_kprintf("vir close\n"); + return RT_EOK; +} +rt_ssize_t _vir_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) +{ + rt_vir_device_t device = (rt_vir_device_t)dev; + if(device->ops->vir_get_val) + { + device->ops->vir_get_val(dev,(rt_uint32_t*)buffer); + return RT_EOK; + } + return -RT_ERROR; +} + +rt_ssize_t _vir_wirte(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) +{ + rt_vir_device_t device = (rt_vir_device_t)dev; + if(device->ops->vir_set_val) + { + device->ops->vir_set_val(dev,*(rt_uint32_t*)buffer); + return RT_EOK; + } + return -RT_ERROR; +} +rt_err_t _vir_control(rt_device_t dev, int cmd, void *args) +{ + rt_kprintf("vir control %d\n",cmd); + return RT_EOK; +} + +rt_err_t rt_hw_vir_register(rt_vir_device_t device, const char *name, const struct rt_vir_ops *ops, const void *user_data) +{ + RT_ASSERT(ops != RT_NULL); + rt_err_t result; + device->ops = ops; + device->parent.init = _vir_init; + device->parent.open = _vir_open; + device->parent.close = _vir_close; + device->parent.read = _vir_read; + device->parent.write = _vir_wirte; + device->parent.control = _vir_control; + result = rt_device_register(&device->parent, name, RT_DEVICE_FLAG_RDWR); + return result; +} + +rt_err_t rt_vir_read(rt_vir_device_t device,rt_uint32_t * val) +{ + RT_ASSERT(device != RT_NULL && device->ops != RT_NULL); + rt_device_t dev = (rt_device_t)device; + + if(device->ops->vir_get_val) + { + device->ops->vir_get_val(dev,val); + return RT_EOK; + } + return -RT_ERROR; + +} + +rt_err_t rt_vir_wirte(rt_vir_device_t device,rt_uint32_t val) +{ + RT_ASSERT(device != RT_NULL && device->ops != RT_NULL); + rt_device_t dev = (rt_device_t)device; + if(device->ops->vir_set_val) + { + device->ops->vir_set_val(dev,val); + return RT_EOK; + } + return -RT_ERROR; +} + + +#endif \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/vir.h" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/vir.h" new file mode 100644 index 0000000000000000000000000000000000000000..12563f6e74aa0a513a3a12dc1a05a1795dddc4c4 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY4/vir_usr/vir.h" @@ -0,0 +1,28 @@ + +#ifndef __VIR_H__ +#define __VIR_H__ + +#include +#include +struct rt_vir_ops +{ + void (*printfinfo)(struct rt_device * device,rt_uint8_t * str); +void (*vir_set_val)(struct rt_device * device,rt_uint32_t val); +void (*vir_get_val)(struct rt_device * device,rt_uint32_t *val); +}; +/** + * @brief adc device + */ +struct rt_vir_device +{ + struct rt_device parent; + const struct rt_vir_ops *ops; +}; +typedef struct rt_vir_device *rt_vir_device_t; + +rt_err_t rt_hw_vir_register(rt_vir_device_t device, const char *name, const struct rt_vir_ops *ops, const void *user_data); +rt_err_t rt_vir_read(rt_vir_device_t device,rt_uint32_t * val); +rt_err_t rt_vir_wirte(rt_vir_device_t device,rt_uint32_t val); + + +#endif diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY5/Day5 \344\275\234\344\270\232.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY5/Day5 \344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..be55a8a0bc32e0a94f33900fda2ccf4b9f5adb56 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY5/Day5 \344\275\234\344\270\232.md" @@ -0,0 +1,18 @@ +作业1: + +将今日的学习内容整理文章到RT-Thread论坛 + +添加一个MQTT软件包:通过MQTT协议上传姓名+每个人今天的学习收获 +使用JSON软件包封装JSON数据格式,按照以下格式: +{ +name: “xiaoming”, +study:“Keep up the good work!” +} + +注意:使用 Kconfig 语法配置字段名称和内容(name,study)MQTT服务端订阅相关主题,当收到上述信息后回传:“辛苦了,下周的比赛加油!”并打印到终端 + +作业2:搭建好各自开发板平台的软件环境,为比赛做好准备 + +PR链接:https://gitee.com/rtthread/rsoc-rtt/commit/730f5b81ad6ced976338e1da2c71dcec2d31d02f + +文章链接:https://club.rt-thread.org/ask/article/0f6860c175d2e9b6.html \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY5/Kconfig" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY5/Kconfig" new file mode 100644 index 0000000000000000000000000000000000000000..bc4986b8d3d5b1889fe9736d841e0de87a7e322f --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY5/Kconfig" @@ -0,0 +1,6 @@ + config PUB_NAME + string "name" + default "LinQingAn" + config PUB_STUDY + string "study" + default "Keep up the good work" \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY5/text.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY5/text.c" new file mode 100644 index 0000000000000000000000000000000000000000..8cdf635d7bd506f950cb2c814be18438c177dda9 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/DAY5/text.c" @@ -0,0 +1,23 @@ + +#ifndef PUB_NAME +#define PUB_NAME "LinQingAn" +#endif +#ifndef PUB_STUDY +#define PUB_STUDY "keep up the good work" +#endif + +static int mqtt_publish_handle1(mqtt_client_t *client) +{ + mqtt_message_t msg; + memset(&msg, 0, sizeof(msg)); + msg.qos = QOS0; +// 拼接修改后的JSON字符串(修正语法并调整键值对) +static const char *json_data = "{" \ + "\"name\": \"" PUB_NAME "\"," \ + "\"study\": \""PUB_STUDY "\"" +"}"; + // 赋值给msg.payload + msg.payload = (void *)json_data; + msg.payloadlen = strlen(json_data); + return mqtt_publish(client, KAWAII_MQTT_PUBTOPIC, &msg); +} diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/Day1 \344\275\234\344\270\232.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/Day1 \344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..32280c4236f0f0a3bfb4cf8cbbdb73992f29b175 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\344\275\234\344\270\232/Day1 \344\275\234\344\270\232.md" @@ -0,0 +1,19 @@ +【课后作业DAY1】 + +1️⃣整理课堂笔记: + +将今日课程内容进行整理,形成清晰的笔记。 + +2️⃣提交笔记(Git PR): + +使用 Git 将整理好的笔记以 Pull Request (PR) 的形式提交到https://gitee.com/rtthread/rsoc-rtt笔记仓库。 + +3️⃣论坛发文(分享笔记): + +在课程论坛发表整理好的课堂笔记,论坛链接https://club.rt-thread.org/ + +➡️文章标题格式: 【RSOC25】笔记标题(如 【RSOC25】Day1 课程笔记:XXX) + +PR链接:https://gitee.com/rtthread/rsoc-rtt/pulls/73 + +文章链接:https://club.rt-thread.org/ask/article/1b45fc4602719cfd.html \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day1 \350\257\276\347\250\213\347\254\224\350\256\260.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day1 \350\257\276\347\250\213\347\254\224\350\256\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..dab990feebec71fb68310c5efdf86f4ba193d55d --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day1 \350\257\276\347\250\213\347\254\224\350\256\260.md" @@ -0,0 +1,58 @@ +# Day1 配置环境变量 +## git安装 +git安装网址:https://git-scm.com/downloads/win +![git安装图片说明](image_1/image.png) +安装完成后可以在空白地方点击鼠标右键->git Bash(有些需要点击“显示更多) +![git](image_1/image-2.png) +![git Bash界面](image_1/image-1.png) +## 拉取rt-thread代码 +新建文件夹用于储存拉取的代码 +直接在新建的文件夹中,点击鼠标右键启动git Bash +输入:`git clone https://gitee.com/rtthread/rt-thread.git`命令进行拉取 +![拉取](image_1/image-3.png) +![拉去结果](image_1/image-4.png) + +## 搭建env环境 +进入rt-thread官网进行下载 +![官网](image_1/image-5.png) +解压到文件夹中 +![文件夹](image_1/image-6.png) +进行下列操作进行配置 +![文件夹](image_1/image-7.png) +完成之后进入拉取rt-thread代码的文件夹右击鼠标打开env +输入:`pkgs --upgrade` +![env界面](image_1/image-8.png) +详细可以参照:https://www.bookstack.cn/read/RT-Thread-tool/1.md +## git仓库的使用 + +初始化Git仓库:`git init` + +添加到暂存区:`git add ` + +提交代码: `git commit -m "本次提交声明"` + +查看当前工作区和暂存区的状态:`git status` + +查看历史commit:`git log` + +查看当前所有分支:`git branch -a` + +管理分支:`git branch` + +切换分支:`git switch master` + +创建分支:`git checkout -b test` + +硬重置:`git reset --hard HEAD~` + +软重置:`git reset --soft HEAD~` + +管理远程仓库:`git remote` + +推送远程仓库:`git push origin 分支` + +推送至远程仓库的代码如何修改:`git push origin 分支 --force` + +修改上游仓库:`git remote set-url origin 地址` + +详细可以参考:`https://mp.weixin.qq.com/s/raSGv-aLHjK1HUcLZvQBeA` \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day2 \350\257\276\347\250\213\347\254\224\350\256\260.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day2 \350\257\276\347\250\213\347\254\224\350\256\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..96ceb3d083827bdec219c5c65b31035ebe7bb009 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day2 \350\257\276\347\250\213\347\254\224\350\256\260.md" @@ -0,0 +1,49 @@ +# Day2 RT-Thread启动流程、线程管理、调度器与RT-Thread Studio使用 +## 1.RT-Thread启动流程 +RT-Thread 支持多种平台和多种编译器,而 rtthread_startup() 函数是 RT-Thread 规定的统一启动入口。一般执行顺序是:系统先从启动文件开始运行,然后进入 RT-Thread 的启动函数 rtthread_startup() ,最后进入用户入口函数 main(),如下图所示: +![启动流程](image_2/image.png) +详细可以参考官方文档:https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/basic/basic?id=rt-thread-%e5%90%af%e5%8a%a8%e6%b5%81%e7%a8%8b +## 2.线程管理 +在日常生活中,我们要完成一个大任务,一般会将它分解成多个简单、容易解决的小问题,小问题逐个被解决,大问题也就随之解决了。在多线程操作系统中,也同样需要开发人员把一个复杂的应用分解成多个小的、可调度的、序列化的程序单元,当合理地划分任务并正确地执行时,这种设计能够让系统满足实时系统的性能及时间的要求。例如让嵌入式系统执行这样的任务,系统通过传感器采集数据,并通过显示屏将数据显示出来,在多线程实时系统中,可以将这个任务分解成两个子任务,如下图所示,一个子任务不间断地读取传感器数据,并将数据写到共享内存中,另外一个子任务周期性的从共享内存中读取数据,并将传感器数据输出到显示屏上。 +![线程管理](image_2/image-1.png) +### 2.1线程优先级 +RT-Thread 线程的优先级是表示线程被调度的优先程度。每个线程都具有优先级,线程越重要,赋予的优先级就应越高,线程被调度的可能才会越大。 + +RT-Thread 最大支持 256 个线程优先级 (0~255),数值越小的优先级越高,0 为最高优先级。在一些资源比较紧张的系统中,可以根据实际情况选择只支持 8 个或 32 个优先级的系统配置;对于 ARM Cortex-M 系列,普遍采用 32 个优先级。最低优先级默认分配给空闲线程使用,用户一般不使用。在系统中,当有比当前线程优先级更高的线程就绪时,当前线程将立刻被换出,高优先级线程抢占处理器运行。 +### 2.2时间片 +每个线程都有时间片这个参数,但时间片仅对优先级相同的就绪态线程有效。系统对优先级相同的就绪态线程采用时间片轮转的调度方式进行调度时,时间片起到约束线程单次运行时长的作用,其单位是一个系统节拍(OS Tick),详见《时钟管理》章节。假设有 2 个优先级相同的就绪态线程 A 与 B,A 线程的时间片设置为 10,B 线程的时间片设置为 5,那么当系统中不存在比 A 优先级高的就绪态线程时,系统会在 A、B 线程间来回切换执行,并且每次对 A 线程执行 10 个节拍的时长,对 B 线程执行 5 个节拍的时长,如下图。 +![时间片](image_2/image-2.png) +### 2.3线程状态切换 +RT-Thread 提供一系列的操作系统调用接口,使得线程的状态在这五个状态之间来回切换。几种状态间的转换关系如下图所示: +![状态切换图](image_2/image-3.png) +线程通过调用函数 rt_thread_create/init() 进入到初始状态(RT_THREAD_INIT);初始状态的线程通过调用函数 rt_thread_startup() 进入到就绪状态(RT_THREAD_READY);就绪状态的线程被调度器调度后进入运行状态(RT_THREAD_RUNNING);当处于运行状态的线程调用 rt_thread_delay(),rt_sem_take(),rt_mutex_take(),rt_mb_recv() 等函数或者获取不到资源时,将进入到挂起状态(RT_THREAD_SUSPEND);处于挂起状态的线程,如果等待超时依然未能获得资源或由于其他线程释放了资源,那么它将返回到就绪状态。挂起状态的线程,如果调用 rt_thread_delete/detach() 函数,将更改为关闭状态(RT_THREAD_CLOSE);而运行状态的线程,如果运行结束,就会在线程的最后部分执行 rt_thread_exit() 函数,将状态更改为关闭状态。 +## 3.调度器 +在系统中,调度器相当于指挥官,按照一定的规则,使系统有秩序的运行。 +调度器最主要的工作:1.决定任务运行顺序 2.执行任务切换 + +### 3.1 决定任务运行顺序:根据调度规则决定 + +优先级抢占:保证一个最高优先级的任务运行(抢占式调度器则需要立刻运行)从就绪链表中查找最高优先级任务。 +![优先级](image_2/1753343800389.png) +时间片轮转:相同优先级状态下根据时间片大小轮转运行。 +![时间片轮转](image_2/image-4.png) +### 3.2执行任务切换:任务切换方式: + +正常状态下:任务到任务的切换。 + +中断状态下:若中断服务程序唤醒了高优先级任务,在中断完成时,被中断的线程挂起,优先级高的线程开始运行。 + +## 4.RT-Thread Studio使用 +前往[RTT官网](https://www.rt-thread.org/download.html#download-rt-thread-studio)下载RT-studio工具最新版本。 +![下载网页](image_2/image-5.png) +安装完毕之后打开RT-Thread Studio,下载支持包。 +![下载支持包](image_2/image-6.png) +![下载支持包](image_2/image-7.png) +![下载支持包](image_2/image-8.png) +完成之后新建工程,顺序如下:文件 -> 新建 -> RT-Thread项目。 +![工程](image_2/image-9.png) +完成软件包的勾选之后按下 Ctrl+s进行保存,保存完成之后就可以从左侧资源项目管理中找到相对应示例的文件进行测试。 +![软件包](image_2/image-10.png) +![编译](image_2/image-11.png) +![第一个示例](image_2/image-12.png) +![第二个示例](image_2/image-13.png) \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day3 \350\257\276\347\250\213\347\254\224\350\256\260.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day3 \350\257\276\347\250\213\347\254\224\350\256\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..5f4b0bec70fab1e00f4ff9582d964a896bf84d89 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day3 \350\257\276\347\250\213\347\254\224\350\256\260.md" @@ -0,0 +1,110 @@ +# Day3 线程间同步和通信 +本篇笔记简短概述相关内容,需要查看详细的各个控制块和示例代码请参考官方文档:https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/ipc1/ipc1 +## 1、线程间同步 + +同步是指按预定的先后次序进行运行,线程同步是指多个线程通过特定的机制(如互斥量,事件对象,临界区)来控制线程之间的执行顺序,也可以说是在线程之间通过同步建立起执行顺序的关系,如果没有同步,那线程之间将是无序的。 + +线程的同步方式有很多种,其核心思想都是:在访问临界区的时候只允许一个 (或一类) 线程运行。进入 / 退出临界区的方式有很多种: + +1)调用 rt_hw_interrupt_disable() 进入临界区,调用 rt_hw_interrupt_enable() 退出临界区;详见《中断管理》的全局中断开关内容。 + +2)调用 rt_enter_critical() 进入临界区,调用 rt_exit_critical() 退出临界区。 + +### 1.1 信号量 +信号量是一种轻型的用于解决线程间同步问题的内核对象,线程可以获取或释放它,从而达到同步或互斥的目的。 + +信号量工作示意图如下图所示,每个信号量对象都有一个信号量值和一个线程等待队列,信号量的值对应了信号量对象的实例数目、资源数目,假如信号量值为 5,则表示共有 5 个信号量实例(资源)可以被使用,当信号量实例数目为零时,再申请该信号量的线程就会被挂起在该信号量的等待队列上,等待可用的信号量实例(资源)。 + +![信号](image_3/image-1.png) + +信号量控制块中含有信号量相关的重要参数,在信号量各种状态间起到纽带的作用。信号量相关接口如下图所示,对一个信号量的操作包含:创建 / 初始化信号量、获取信号量、释放信号量、删除 / 脱离信号量。 + +![控制块](image_3/image-2.png) + +### 1.2 互斥量 + +互斥量又叫相互排斥的信号量,是一种特殊的二值信号量。互斥量类似于只有一个车位的停车场:当有一辆车进入的时候,将停车场大门锁住,其他车辆在外面等候。当里面的车出来时,将停车场大门打开,下一辆车才可以进入。 + +互斥量和信号量不同的是:拥有互斥量的线程拥有互斥量的所有权,互斥量支持递归访问且能防止线程优先级翻转;并且互斥量只能由持有线程释放,而信号量则可以由任何线程释放。 + +互斥量的状态只有两种,开锁或闭锁(两种状态值)。当有线程持有它时,互斥量处于闭锁状态,由这个线程获得它的所有权。相反,当这个线程释放它时,将对互斥量进行开锁,失去它的所有权。当一个线程持有互斥量时,其他线程将不能够对它进行开锁或持有它,持有该互斥量的线程也能够再次获得这个锁而不被挂起,如下图时所示。这个特性与一般的二值信号量有很大的不同:在信号量中,因为已经不存在实例,线程递归持有会发生主动挂起(最终形成死锁)。 +![ 互斥](image_3/image-3.png) + +使用信号量会导致的另一个潜在问题是线程优先级翻转问题。所谓优先级翻转,即当一个高优先级线程试图通过信号量机制访问共享资源时,如果该信号量已被一低优先级线程持有,而这个低优先级线程在运行过程中可能又被其它一些中等优先级的线程抢占,因此造成高优先级线程被许多具有较低优先级的线程阻塞,实时性难以得到保证。如下图所示:有优先级为 A、B 和 C 的三个线程,优先级 A> B > C。线程 A,B 处于挂起状态,等待某一事件触发,线程 C 正在运行,此时线程 C 开始使用某一共享资源 M。在使用过程中,线程 A 等待的事件到来,线程 A 转为就绪态,因为它比线程 C 优先级高,所以立即执行。但是当线程 A 要使用共享资源 M 时,由于其正在被线程 C 使用,因此线程 A 被挂起切换到线程 C 运行。如果此时线程 B 等待的事件到来,则线程 B 转为就绪态。由于线程 B 的优先级比线程 C 高,且线程B没有用到共享资源 M ,因此线程 B 开始运行,直到其运行完毕,线程 C 才开始运行。只有当线程 C 释放共享资源 M 后,线程 A 才得以执行。在这种情况下,优先级发生了翻转:线程 B 先于线程 A 运行。这样便不能保证高优先级线程的响应时间。 +![互斥 1](image_3/image-4.png) + +在 RT-Thread 操作系统中,互斥量可以解决优先级翻转问题,实现的是优先级继承协议 (Sha, 1990)。优先级继承是通过在线程 A 尝试获取共享资源而被挂起的期间内,将线程 C 的优先级提升到线程 A 的优先级别,从而解决优先级翻转引起的问题。这样能够防止 C(间接地防止 A)被 B 抢占,如下图所示。优先级继承是指,提高某个占有某种资源的低优先级线程的优先级,使之与所有等待该资源的线程中优先级最高的那个线程的优先级相等,然后执行,而当这个低优先级线程释放该资源时,优先级重新回到初始设定。因此,继承优先级的线程避免了系统资源被任何中间优先级的线程抢占。 +![互斥 2](image_3/image-5.png) + +互斥量控制块中含有互斥相关的重要参数,在互斥量功能的实现中起到重要的作用。互斥量相关接口如下图所示,对一个互斥量的操作包含:创建 / 初始化互斥量、获取互斥量、释放互斥量、删除 / 脱离互斥量。 +![互斥 3](image_3/image-6.png) +### 1.3 事件集 + +事件集主要用于线程间的同步,与信号量不同,它的特点是可以实现一对多,多对多的同步。即一个线程与多个事件的关系可设置为:其中任意一个事件唤醒线程,或几个事件都到达后才唤醒线程进行后续的处理;同样,事件也可以是多个线程同步多个事件。这种多个事件的集合可以用一个 32 位无符号整型变量来表示,变量的每一位代表一个事件,线程通过 “逻辑与” 或“逻辑或”将一个或多个事件关联起来,形成事件组合。事件的 “逻辑或” 也称为是独立型同步,指的是线程与任何事件之一发生同步;事件 “逻辑与” 也称为是关联型同步,指的是线程与若干事件都发生同步。 + +RT-Thread 定义的事件集有以下特点: + +1)事件只与线程相关,事件间相互独立:每个线程可拥有 32 个事件标志,采用一个 32 bit 无符号整型数进行记录,每一个 bit 代表一个事件; + +2)事件仅用于同步,不提供数据传输功能; + +3)事件无排队性,即多次向线程发送同一事件 (如果线程还未来得及读走),其效果等同于只发送一次。 + +在 RT-Thread 中,每个线程都拥有一个事件信息标记,它有三个属性,分别是 RT_EVENT_FLAG_AND(逻辑与),RT_EVENT_FLAG_OR(逻辑或)以及 RT_EVENT_FLAG_CLEAR(清除标记)。当线程等待事件同步时,可以通过 32 个事件标志和这个事件信息标记来判断当前接收的事件是否满足同步条件。 +![事件集](image_3/image-7.png) + +事件集控制块中含有与事件集相关的重要参数,在事件集功能的实现中起重要的作用。事件集相关接口如下图所示,对一个事件集的操作包含:创建 / 初始化事件集、发送事件、接收事件、删除 / 脱离事件集。 + +![事件集控制块](image_3/image-8.png) + +## 2、线程间通信 +### 2.1 邮箱 +RT-Thread 操作系统的邮箱用于线程间通信,特点是开销比较低,效率较高。邮箱中的每一封邮件只能容纳固定的 4 字节内容(针对 32 位处理系统,指针的大小即为 4 个字节,所以一封邮件恰好能够容纳一个指针)。典型的邮箱也称作交换消息,如下图所示,线程或中断服务例程把一封 4 字节长度的邮件发送到邮箱中,而一个或多个线程可以从邮箱中接收这些邮件并进行处理。 + +非阻塞方式的邮件发送过程能够安全的应用于中断服务中,是线程、中断服务、定时器向线程发送消息的有效手段。通常来说,邮件收取过程可能是阻塞的,这取决于邮箱中是否有邮件,以及收取邮件时设置的超时时间。当邮箱中不存在邮件且超时时间不为 0 时,邮件收取过程将变成阻塞方式。在这类情况下,只能由线程进行邮件的收取。 + +当一个线程向邮箱发送邮件时,如果邮箱没满,将把邮件复制到邮箱中。如果邮箱已经满了,发送线程可以设置超时时间,选择等待挂起或直接返回 - RT_EFULL。如果发送线程选择挂起等待,那么当邮箱中的邮件被收取而空出空间来时,等待挂起的发送线程将被唤醒继续发送。 + +当一个线程从邮箱中接收邮件时,如果邮箱是空的,接收线程可以选择是否等待挂起直到收到新的邮件而唤醒,或可以设置超时时间。当达到设置的超时时间,邮箱依然未收到邮件时,这个选择超时等待的线程将被唤醒并返回 - RT_ETIMEOUT。如果邮箱中存在邮件,那么接收线程将复制邮箱中的 4 个字节邮件到接收缓存中。 + +![邮箱](image_3/image-9.png) + +邮箱控制块是一个结构体,其中含有事件相关的重要参数,在邮箱的功能实现中起重要的作用。邮箱的相关接口如下图所示,对一个邮箱的操作包含:创建 / 初始化邮箱、发送邮件、接收邮件、删除 / 脱离邮箱。 +![邮箱控制块](image_3/image-10.png) +### 2.2 消息队列 +消息队列是另一种常用的线程间通讯方式,是邮箱的扩展。可以应用在多种场合:线程间的消息交换、使用串口接收不定长数据等。 + +消息队列能够接收来自线程或中断服务例程中不固定长度的消息,并把消息缓存在自己的内存空间中。其他线程也能够从消息队列中读取相应的消息,而当消息队列是空的时候,可以挂起读取线程。当有新的消息到达时,挂起的线程将被唤醒以接收并处理消息。消息队列是一种异步的通信方式。 + +如下图所示,线程或中断服务例程可以将一条或多条消息放入消息队列中。同样,一个或多个线程也可以从消息队列中获得消息。当有多个消息发送到消息队列时,通常将先进入消息队列的消息先传给线程,也就是说,线程先得到的是最先进入消息队列的消息,即先进先出原则 (FIFO)。 + +RT-Thread 操作系统的消息队列对象由多个元素组成,当消息队列被创建时,它就被分配了消息队列控制块:消息队列名称、内存缓冲区、消息大小以及队列长度等。同时每个消息队列对象中包含着多个消息框,每个消息框可以存放一条消息;消息队列中的第一个和最后一个消息框被分别称为消息链表头和消息链表尾,对应于消息队列控制块中的 msg_queue_head 和 msg_queue_tail;有些消息框可能是空的,它们通过 msg_queue_free 形成一个空闲消息框链表。所有消息队列中的消息框总数即是消息队列的长度,这个长度可在消息队列创建时指定。 +![消息队列](image_3/image-11.png) + +消息队列控制块是一个结构体,其中含有消息队列相关的重要参数,在消息队列的功能实现中起重要的作用。消息队列的相关接口如下图所示,对一个消息队列的操作包含:创建消息队列 - 发送消息 - 接收消息 - 删除消息队列。 + +![消息队列控制块](image_3/mage-12.png) +### 2.3 信号 + +信号(又称为软中断信号),在软件层次上是对中断机制的一种模拟,在原理上,一个线程收到一个信号与处理器收到一个中断请求可以说是类似的。 + +信号在 RT-Thread 中用作异步通信,POSIX 标准定义了 sigset_t 类型来定义一个信号集,然而 sigset_t 类型在不同的系统可能有不同的定义方式,在 RT-Thread 中,将 sigset_t 定义成了 unsigned long 型,并命名为 rt_sigset_t,应用程序能够使用的信号为 SIGUSR1(10)和 SIGUSR2(12)。 + +信号本质是软中断,用来通知线程发生了异步事件,用做线程之间的异常通知、应急处理。一个线程不必通过任何操作来等待信号的到达,事实上,线程也不知道信号到底什么时候到达,线程之间可以互相通过调用 rt_thread_kill() 发送软中断信号。 + +收到信号的线程对各种信号有不同的处理方法,处理方法可以分为三类: + +第一种是类似中断的处理程序,对于需要处理的信号,线程可以指定处理函数,由该函数来处理。 + +第二种方法是,忽略某个信号,对该信号不做任何处理,就像未发生过一样。 + +第三种方法是,对该信号的处理保留系统的默认值。 + +如下图所示,假设线程 1 需要对信号进行处理,首先线程 1 安装一个信号并解除阻塞,并在安装的同时设定了对信号的异常处理方式;然后其他线程可以给线程 1 发送信号,触发线程 1 对该信号的处理。 + +![消息](image_3/image-13.png) + +当信号被传递给线程 1 时,如果它正处于挂起状态,那会把状态改为就绪状态去处理对应的信号。如果它正处于运行状态,那么会在它当前的线程栈基础上建立新栈帧空间去处理对应的信号,需要注意的是使用的线程栈大小也会相应增加。 + +对于信号的操作,有以下几种:安装信号、阻塞信号、阻塞解除、信号发送、信号等待。信号的接口详见下图: +![消息控制块](image_3/image-14.png) \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day4 \350\257\276\347\250\213\347\254\224\350\256\260.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day4 \350\257\276\347\250\213\347\254\224\350\256\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..23759fe2b402f83f9f51c5ab2d96bc0fffb6e0ab --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day4 \350\257\276\347\250\213\347\254\224\350\256\260.md" @@ -0,0 +1,190 @@ +# Day4 设备和驱动:I/O 设备模型 +绝大部分的嵌入式系统都包括一些 I/O(Input/Output,输入 / 输出)设备,例如仪器上的数据显示屏、工业设备上的串口通信、数据采集设备上用于保存数据的 Flash 或 SD 卡,以及网络设备的以太网接口等,都是嵌入式系统中容易找到的 I/O 设备例子。 +## I/O 设备模型框架 +RT-Thread 提供了一套简单的 I/O 设备模型框架,如下图所示,它位于硬件和应用程序之间,共分成三层,从上到下分别是 I/O 设备管理层、设备驱动框架层、设备驱动层。 +![模型框架](image_4/image.png) +应用程序通过 I/O 设备管理接口获得正确的设备驱动,然后通过这个设备驱动与底层 I/O 硬件设备进行数据(或控制)交互。 + +I/O 设备管理层实现了对设备驱动程序的封装。应用程序通过图中的"I/O设备管理层"提供的标准接口访问底层设备,设备驱动程序的升级、更替不会对上层应用产生影响。这种方式使得设备的硬件操作相关的代码能够独立于应用程序而存在,双方只需关注各自的功能实现,从而降低了代码的耦合性、复杂性,提高了系统的可靠性。 + +设备驱动框架层是对同类硬件设备驱动的抽象,将不同厂家的同类硬件设备驱动中相同的部分抽取出来,将不同部分留出接口,由驱动程序实现。 + +设备驱动层是一组驱使硬件设备工作的程序,实现访问硬件设备的功能。它负责创建和注册 I/O 设备,对于操作逻辑简单的设备,可以不经过设备驱动框架层,直接将设备注册到 I/O 设备管理器中,使用序列图如下图所示,主要有以下 2 点: + +设备驱动根据设备模型定义,创建出具备硬件访问能力的设备实例,将该设备通过 rt_device_register() 接口注册到 I/O 设备管理器中。 + +应用程序通过 rt_device_find() 接口查找到设备,然后使用 I/O 设备管理接口来访问硬件。 +![模型框架2](image_4/image-1.png) + +对于另一些设备,如看门狗等,则会将创建的设备实例先注册到对应的设备驱动框架中,再由设备驱动框架向 I/O 设备管理器进行注册,主要有以下几点: + +看门狗设备驱动程序根据看门狗设备模型定义,创建出具备硬件访问能力的看门狗设备实例,并将该看门狗设备通过 rt_hw_watchdog_register() 接口注册到看门狗设备驱动框架中。 + +看门狗设备驱动框架通过 rt_device_register() 接口将看门狗设备注册到 I/O 设备管理器中。 + +应用程序通过 I/O 设备管理接口来访问看门狗设备硬件。 + +看门狗设备使用序列图: +![看门狗设备](image_4/image-2.png) + +## I/O 设备模型 + +RT-Thread 的设备模型是建立在内核对象模型基础之上的,设备被认为是一类对象,被纳入对象管理器的范畴。每个设备对象都是由基对象派生而来,每个具体设备都可以继承其父类对象的属性,并派生出其私有属性,下图是设备对象的继承和派生关系示意图。 + +![设备模型](image_4/image-3.png) +``` +struct rt_device +{ + struct rt_object parent; /* 内核对象基类 */ + enum rt_device_class_type type; /* 设备类型 */ + rt_uint16_t flag; /* 设备参数 */ + rt_uint16_t open_flag; /* 设备打开标志 */ + rt_uint8_t ref_count; /* 设备被引用次数 */ + rt_uint8_t device_id; /* 设备 ID,0 - 255 */ + + /* 数据收发回调函数 */ + rt_err_t (*rx_indicate)(rt_device_t dev, rt_size_t size); + rt_err_t (*tx_complete)(rt_device_t dev, void *buffer); + + const struct rt_device_ops *ops; /* 设备操作方法 */ + + /* 设备的私有数据 */ + void *user_data; +}; +typedef struct rt_device *rt_device_t; +``` + +## I/O 设备类型 +RT-Thread 支持多种 I/O 设备类型,主要设备类型如下所示: +``` +RT_Device_Class_Char /* 字符设备 */ +RT_Device_Class_Block /* 块设备 */ +RT_Device_Class_NetIf /* 网络接口设备 */ +RT_Device_Class_MTD /* 内存设备 */ +RT_Device_Class_RTC /* RTC 设备 */ +RT_Device_Class_Sound /* 声音设备 */ +RT_Device_Class_Graphic /* 图形设备 */ +RT_Device_Class_I2CBUS /* I2C 总线设备 */ +RT_Device_Class_USBDevice /* USB device 设备 */ +RT_Device_Class_USBHost /* USB host 设备 */ +RT_Device_Class_SPIBUS /* SPI 总线设备 */ +RT_Device_Class_SPIDevice /* SPI 设备 */ +RT_Device_Class_SDIO /* SDIO 设备 */ +RT_Device_Class_Miscellaneous /* 杂类设备 */ +``` + +其中字符设备、块设备是常用的设备类型,它们的分类依据是设备数据与系统之间的传输处理方式。字符模式设备允许非结构的数据传输,即通常数据传输采用串行的形式,每次一个字节。字符设备通常是一些简单设备,如串口、按键。 + +块设备每次传输一个数据块,例如每次传输 512 个字节数据。这个数据块是硬件强制性的,数据块可能使用某类数据接口或某些强制性的传输协议,否则就可能发生错误。因此,有时块设备驱动程序对读或写操作必须执行附加的工作,如下图所示: + +![设备类型](image_4/image-4.png) + +当系统服务于一个具有大量数据的写操作时,设备驱动程序必须首先将数据划分为多个包,每个包采用设备指定的数据尺寸。而在实际过程中,最后一部分数据尺寸有可能小于正常的设备块尺寸。如上图中每个块使用单独的写请求写入到设备中,头 3 个直接进行写操作。但最后一个数据块尺寸小于设备块尺寸,设备驱动程序必须使用不同于前 3 个块的方式处理最后的数据块。通常情况下,设备驱动程序需要首先执行相对应的设备块的读操作,然后把写入数据覆盖到读出数据上,然后再把这个 “合成” 的数据块作为一整个块写回到设备中。例如上图中的块 4,驱动程序需要先把块 4 所对应的设备块读出来,然后将需要写入的数据覆盖至从设备块读出的数据上,使其合并成一个新的块,最后再写回到块设备中。 + +## 创建、注册I/O设备 +本文简略说明I/O设备所使用的API,详细参考官方文档: +https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/programming-manual/device/device?id=%e5%88%9b%e5%bb%ba%e5%92%8c%e6%b3%a8%e5%86%8c-io-%e8%ae%be%e5%a4%87 + +``` +rt_device_t rt_device_create(int type, int attach_size); + +struct rt_device_ops + +void rt_device_destroy(rt_device_t device); + +rt_err_t rt_device_register(rt_device_t dev, const char* name, rt_uint8_t flags); + +rt_err_t rt_device_unregister(rt_device_t dev); +``` + +flags 参数支持下列参数 (可以采用或的方式支持多种参数): +``` +#define RT_DEVICE_FLAG_RDONLY 0x001 /* 只读 */ +#define RT_DEVICE_FLAG_WRONLY 0x002 /* 只写 */ +#define RT_DEVICE_FLAG_RDWR 0x003 /* 读写 */ +#define RT_DEVICE_FLAG_REMOVABLE 0x004 /* 可移除 */ +#define RT_DEVICE_FLAG_STANDALONE 0x008 /* 独立 */ +#define RT_DEVICE_FLAG_SUSPENDED 0x020 /* 挂起 */ +#define RT_DEVICE_FLAG_STREAM 0x040 /* 流模式 */ +#define RT_DEVICE_FLAG_INT_RX 0x100 /* 中断接收 */ +#define RT_DEVICE_FLAG_DMA_RX 0x200 /* DMA 接收 */ +#define RT_DEVICE_FLAG_INT_TX 0x400 /* 中断发送 */ +#define RT_DEVICE_FLAG_DMA_TX 0x800 /* DMA 发送 */ +``` + +## 访问I/O设备 +应用程序通过 I/O 设备管理接口来访问硬件设备,当设备驱动实现后,应用程序就可以访问该硬件。I/O 设备管理接口与 I/O 设备的操作方法的映射关系下图所示: + +![访问设备](image_4/image-6.png) +查找设备: +``` +rt_device_t rt_device_find(const char* name); +``` +初始化设备: +``` +rt_err_t rt_device_init(rt_device_t dev); +``` +打开和关闭设备: +``` +rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags); + +rt_err_t rt_device_close(rt_device_t dev); +``` +控制设备: +``` +rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg); + +``` +读写设备: +``` +rt_size_t rt_device_read(rt_device_t dev, rt_off_t pos,void* buffer, rt_size_t size); + +rt_size_t rt_device_write(rt_device_t dev, rt_off_t pos,const void* buffer, rt_size_t size); +``` +数据收发回调: +``` +rt_err_t rt_device_set_rx_indicate(rt_device_t dev, rt_err_t (*rx_ind)(rt_device_t dev,rt_size_t size)); + +rt_err_t rt_device_set_tx_complete(rt_device_t dev, rt_err_t (*tx_done)(rt_device_t dev,void *buffer)); +``` + +oflags 支持以下的参数: +``` +#define RT_DEVICE_OFLAG_CLOSE 0x000 /* 设备已经关闭(内部使用)*/ +#define RT_DEVICE_OFLAG_RDONLY 0x001 /* 以只读方式打开设备 */ +#define RT_DEVICE_OFLAG_WRONLY 0x002 /* 以只写方式打开设备 */ +#define RT_DEVICE_OFLAG_RDWR 0x003 /* 以读写方式打开设备 */ +#define RT_DEVICE_OFLAG_OPEN 0x008 /* 设备已经打开(内部使用)*/ +#define RT_DEVICE_FLAG_STREAM 0x040 /* 设备以流模式打开 */ +#define RT_DEVICE_FLAG_INT_RX 0x100 /* 设备以中断接收模式打开 */ +#define RT_DEVICE_FLAG_DMA_RX 0x200 /* 设备以 DMA 接收模式打开 */ +#define RT_DEVICE_FLAG_INT_TX 0x400 /* 设备以中断发送模式打开 */ +#define RT_DEVICE_FLAG_DMA_TX 0x800 /* 设备以 DMA 发送模式打开 */ +``` + +参数 cmd 的通用设备命令可取如下宏定义: +``` +#define RT_DEVICE_CTRL_RESUME 0x01 /* 恢复设备 */ +#define RT_DEVICE_CTRL_SUSPEND 0x02 /* 挂起设备 */ +#define RT_DEVICE_CTRL_CONFIG 0x03 /* 配置设备 */ +#define RT_DEVICE_CTRL_SET_INT 0x10 /* 设置中断 */ +#define RT_DEVICE_CTRL_CLR_INT 0x11 /* 清中断 */ +#define RT_DEVICE_CTRL_GET_INT 0x12 /* 获取中断状态 */ + +``` +## I/O 设备模型框架补充图 +I/O 设备模型框架补充图是对 I/O 设备模型框架图的解释和补充说明,如下图所示。 +![补充](image_4/image-5.png) + +图中各类里的c文件是各类对应的管理接口所在,比如设备基类rt_device的管理接口在device.c中。 + +图中设备驱动框架层有很多 RT-Thread 写好的类,图中只列出2类,其他类用 “xxx” 来表示,这些省略的类及其管理接口可以在 RT-Thread 源码 components/drivers 目录下找寻,比如该目录下可以找到serial/i2c/spi/sensor/can 等等相关目录。 + +图中设备驱动层的 “xxx” ,是 RT-Thread 支持的各 BSP 平台,在源码的 src/bsp 目录下找寻,比如stm32/gd32/at32/avr32/k210 等等。各个平台各自实现各个设备类型的硬件驱动能力,比如 STM32分别实现了 stm32_uart 类/stm32_adc 类等及其对应的管理接口;同样的,其他平台也分别各自实现了诸多对应类别及管理接口。 + +图中设备驱动层的各类里的c文件路径和名字只是示意,具体名字和路径由各BSP开发维护者自己定的。且随着 RT-Thread 版本的变化,各 BSP 的驱动路径和名字可能会发生变化。比如图中画的 STM32 串口设备类的管理接口所在路径是 bsp/stm32/drv_usart.c ,但实际路径是在 RT-Thread 源码下的 bsp/stm32/libraries/HAL_Drivers 下 。比如有的名字叫 drv_uart.c 等等。 + +该图横向看是分层思想,纵向看是各类派生继承关系。从下到上不断抽象、屏蔽下层差异,体现了面向对象的抽象的思想。子类受到父类的接口约束,子类各自实现父类提供的统一接口,又体现了面向接口编程的思想。比如从驱动层到驱动框架层,由不同厂商的相同硬件模块创建了很多子类对象,然后对接到同一个父类接口上,多对一,体现面向对象的抽象的威力。以串口设备为例,不管下层是 STM32、GD32 还是别的平台的,只要都是串口设备,都对接到 RT-Thread 的串口设备类——如图所绘,多个硬件对象对接同一个父类对象接口。同理,从设备驱动框架层到IO设备管理接口层,又是多对一,又是再一次的屏蔽差异,再一次的抽象。——面向对象的思想贯穿其中。 + +tips: 新增 BSP 设备驱动到 I/O 设备模型框架上时,开发者只需开发驱动层即可,设备驱动框架层和 I/O 设备管理层 RT-Thread 已写好了,无需改动,除非发现BUG或增加新的类别。 + diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day5 \350\257\276\347\250\213\347\254\224\350\256\260.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day5 \350\257\276\347\250\213\347\254\224\350\256\260.md" new file mode 100644 index 0000000000000000000000000000000000000000..b0124c208832e1ad1549e93a260df78c2d11c36e --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/Day5 \350\257\276\347\250\213\347\254\224\350\256\260.md" @@ -0,0 +1,86 @@ +# Day5 软件包的使用、RT-Thread的构建与配置系统 + +## 软件包 +### 软件包的介绍 +软件包定义:运行于RT-Thread物联网操作系统平台上,面向不同应用领域的软件组件形成一个个软件包,由软件包描述信息,软件包源代码或库文件组成。 + +若要制作软件包,需要先对软件包的功能进行准确的定义,确保不要耦合与产品业务逻辑有关的代码,提高软件包的通用性。 + +![软件包](image_5/image.png) + +可以通过官网获取软件包:https://packages.rt-thread.org/ + +### 软件包的使用 +在拉取的rt-thread 的文件进 `rt-thread\bsp\qemu-vexpress-a9 ` 路径并打开env 输入 ` menuconfig.exe` +![使用1](image_5/image-1.png) +进入 ` menuconfig.exe`界面按/进入搜索hello,进入之后点击Esc在点击空格,使能,然后一直Esc退出直至保存。依次输入`pkgs --update` 更新软件包 `scons -j12`编译。.`\qemu-nographic.bat`开启qume,输入`hello_func`。 +![使用2](image_5/image-2.png) +![使用3](image_5/image-3.png) +![使用4](image_5/image-4.png) +![使用5](image_5/image-5.png) +![使用6](image_5/image-6.png) +![使用7](image_5/image-7.png) + +## RT-Thread的构建与配置系统 +本节只对其概念进行简单概述,关于相对应的语法,应用,环境的搭建可以查阅官方文档:https://www.rt-thread.org/document/site/#/development-tools/build-config-system/summary。 + +RT-Thread的构建与配置系统由以下几个部分组成: +![构建](image_5/image-8.png) +### Kconfig在RT-Thread中的工作机制 +C语言项目的裁剪配置本质上通过条件编译和宏的展开来实现的,RT-Thread借助Kconfig这套机制更方便的实现了这一功能。当前以Windows下Env工具中的使用为例,简述Kconfig在RT-Thread的工作机制。 + +Kconfig机制包括了Kconfig文件和配置UI界面(如menuconfig,pyconfig等)。Kconfig机制有如下特点: + +* Kconfig文件中的配置项会映射至rtconfig.h中 +* Kconfig文件可以随源码分散至各级子目录,便于灵活修改。 + +``` +#.config片段 +CONFIG_RT_USING_TIMER_SOFT=y +CONFIG_RT_TIMER_THREAD_PRIO=4 +CONFIG_RT_TIMER_THREAD_STACK_SIZE=512 +CONFIG_RT_DEBUG=y +``` + +``` +// 相对应的rtconfig.h片段 +#define RT_USING_TIMER_SOFT +#define RT_TIMER_THREAD_PRIO 4 +#define RT_TIMER_THREAD_STACK_SIZE 512 +#define RT_DEBUG +``` +![构建2](image_5/image-9.png) +Kconfig文件在源码中呈现树形结构,需要在工程的根目录下存在一份顶层Kconfig文件,顶层Kconfig文件在文件中通过source语句显示地调用各子目录下的Kconfig文件。Env在根目录下执行menuconfig命令后会递归解析各级Kconfig文件,然后提供如下配置界面,完成相应的配置后并保存,根目录下会存在一份.config文件保存当前选择的配置项,并将.config文件转为RT-Thread的系统配置文件rtconfig.h。 + +### RT-Thread中Scons的脚本结构 +SCons 使用 SConscript 和 SConstruct 文件来组织源码结构并进行构建,SConstruct是scons构建的主脚本,SConscript存放在源代码的子目录下,通常放在项目的子目录,以达到分层构建的目的。一个项目 (BSP) 只有一 SConstruct,但是会有多个 SConscript。一般情况下,每个存放有源代码的子目录下都会放置一个 SConscript。 +``` +/ + -- rtconfig.py ---- 控制SCons构建的配置文件,存放了如工具链,构建参数等配置。 + -- SConscript + -- SConstruct ---- SCons的入口脚本,初始化了SCons构建rt-thread所需的必要环境 + -- Kconfig ---- 顶层Kconfig文件,menuconfig的入口Kconfig文件 + -- rt-thread/ + --- src/ + ---- SConscript ---- 各级源码的scons子脚本,控制当前级别下的源码构建行为 + ---- Kconfig ---- 各级源码的Kconfig子脚本,存放当前级别下的配置项 + ---- **.c +``` +如上图所示,为了方便开发者使用SCons,RT-Thread搭建了如图所示的构建框架,其中包括了一份SCons的入口脚本(SConstruct),以及分散在各级源码的SCons子脚本(SConscript),还有一份便于配置构建行为的配置脚本(rtconfig.py)同时,RT-Thread也在SCons标准接口的基础上,提供了一组用于组织源码工程的扩展接口。开发者在使用时,可以借助RT-Thread提供的扩展接口,更方便的完成源码的组织与配置。 + +![结构1](image_5/image-10.png) +为了使 RT-Thread 更好的支持多种编译器,以及方便的调整构建参数,RT-Thread 为每个 BSP 单独创建了一个名为 rtconfig.py 的配置文件。因此每一个 RT-Thread BSP 目录下都会存在下面三个文件:rtconfig.py、SConstruct 和 SConscript,它们控制 BSP 的构建。一个 BSP 中只有一个 SConstruct 文件,但是却会有多个 SConscript 文件,可以说 SConscript 文件是组织源码的主力军。 + +RT-Thread当前的构建系统由以下几个部分组成: +``` +flowchart LR + A(RT-Thread构建系统)-->Kconfig + A(RT-Thread构建系统)-->rtconfig.py + A(RT-Thread构建系统)-->SCons + SCons --> SConscript + SCons --> SConstruct + SConscript --> Scons标准函数 + SConscript --> RT-Thread自定义函数 + SConscript --> Python函数 +``` + diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-1.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-1.png" new file mode 100644 index 0000000000000000000000000000000000000000..037aeddee4865465c3f7a43d483f1dde15258302 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-1.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-2.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-2.png" new file mode 100644 index 0000000000000000000000000000000000000000..b4cead41eecee4a4a47ccd62919e07ebc476b83c Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-2.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-3.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-3.png" new file mode 100644 index 0000000000000000000000000000000000000000..d54a43898a513234ef27250b90481d3741d849cb Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-3.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-4.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-4.png" new file mode 100644 index 0000000000000000000000000000000000000000..1a7fe91b86b3b5a536f59169170a2adfe30cc58d Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-4.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-5.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-5.png" new file mode 100644 index 0000000000000000000000000000000000000000..350f54c25391d15834ca4ad8843978daf0b602ca Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-5.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-6.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-6.png" new file mode 100644 index 0000000000000000000000000000000000000000..ab23b948a2375f0f76b30a505c731a20aa79515c Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-6.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-7.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-7.png" new file mode 100644 index 0000000000000000000000000000000000000000..26c55a25f3af2155ba2c5d9ff5ac2482fcb516f2 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-7.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-8.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-8.png" new file mode 100644 index 0000000000000000000000000000000000000000..6a1d3a254c25ab361efe0507322f1ec64327d1b3 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image-8.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image.png" new file mode 100644 index 0000000000000000000000000000000000000000..2dbe1c5f62baaef61ef007777bdc194fb16c6816 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_1/image.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/1753343800389.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/1753343800389.png" new file mode 100644 index 0000000000000000000000000000000000000000..b4189b6bf9a5588fe2d860d613ecbac2dcb551d3 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/1753343800389.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-1.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-1.png" new file mode 100644 index 0000000000000000000000000000000000000000..e2ef91735e1431fefbc99783572ec5b115823332 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-1.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-10.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-10.png" new file mode 100644 index 0000000000000000000000000000000000000000..c02b5c7e32e3acdba9c53174547ac0d77595e90f Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-10.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-11.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-11.png" new file mode 100644 index 0000000000000000000000000000000000000000..882e4f6131cb9742c6cb551a95998667e4ea2170 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-11.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-12.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-12.png" new file mode 100644 index 0000000000000000000000000000000000000000..e006641cebe6c5fb1c0bc1bacb99f5a1edf619ca Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-12.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-13.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-13.png" new file mode 100644 index 0000000000000000000000000000000000000000..42118286c4fdd099003f35ffa62eef6c12f0b5c7 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-13.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-2.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-2.png" new file mode 100644 index 0000000000000000000000000000000000000000..1b7230c802ff01af9a5d17627aa80bd56f554c4b Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-2.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-3.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-3.png" new file mode 100644 index 0000000000000000000000000000000000000000..9b8fb40320065e264202b82b925d28456640bcb8 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-3.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-4.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-4.png" new file mode 100644 index 0000000000000000000000000000000000000000..f81e0b8b3c4057d916d8370a614a7d3521e907e5 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-4.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-5.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-5.png" new file mode 100644 index 0000000000000000000000000000000000000000..1d5e48fd8b9ee6eb8a7ff441536005261d24d91d Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-5.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-6.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-6.png" new file mode 100644 index 0000000000000000000000000000000000000000..8ca2c2fae11720a2db3e23ead76f1eadae1df37f Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-6.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-7.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-7.png" new file mode 100644 index 0000000000000000000000000000000000000000..4a8382f2f62733bd03dd7f21189dcbb9aff62191 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-7.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-8.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-8.png" new file mode 100644 index 0000000000000000000000000000000000000000..1030c998b1dc0ac228049f79125a22bbacf76c69 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-8.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-9.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-9.png" new file mode 100644 index 0000000000000000000000000000000000000000..58deab4d5784c96d5c88966115e7a545ca3f0adb Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image-9.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image.png" new file mode 100644 index 0000000000000000000000000000000000000000..47d980d2c81436135c3a4d5fdeddeba68820fe16 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_2/image.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-1.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-1.png" new file mode 100644 index 0000000000000000000000000000000000000000..fe187e3d71451130f4dfcda65266ab9452b8cb36 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-1.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-10.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-10.png" new file mode 100644 index 0000000000000000000000000000000000000000..7c4dc63cbe0a8a9c915910cd6de9a19133dc3af8 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-10.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-11.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-11.png" new file mode 100644 index 0000000000000000000000000000000000000000..ab885702286d216ea48ca0873b8233e0cd0ecc50 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-11.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-12.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-12.png" new file mode 100644 index 0000000000000000000000000000000000000000..051b16154c6d24f3e3f11ba79e905f52cbb58de0 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-12.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-13.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-13.png" new file mode 100644 index 0000000000000000000000000000000000000000..1850fd7e4632aa038b59a046be4aad46d9cbe83f Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-13.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-14.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-14.png" new file mode 100644 index 0000000000000000000000000000000000000000..ee7b121ff61f140c0e38d736c32767da0ed602fe Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-14.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-2.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-2.png" new file mode 100644 index 0000000000000000000000000000000000000000..c98b2250358f8b3707e16aba52add1049c4f45f8 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-2.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-3.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-3.png" new file mode 100644 index 0000000000000000000000000000000000000000..4eef1da6436f01e1fa6c2abcb0e23795889e9f77 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-3.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-4.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-4.png" new file mode 100644 index 0000000000000000000000000000000000000000..3d04a194300e8d0866da0ad7d4da0940017d53f3 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-4.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-5.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-5.png" new file mode 100644 index 0000000000000000000000000000000000000000..1e0938f0d5cbb29c4f5284b9e6acbf5b344d5aaa Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-5.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-6.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-6.png" new file mode 100644 index 0000000000000000000000000000000000000000..11fd1dfe83a9b5ab0056ebeb1e5f50d758948ee0 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-6.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-7.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-7.png" new file mode 100644 index 0000000000000000000000000000000000000000..bbcef14d83f3cfb6f927f7b5905f934fe25e4eb7 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-7.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-8.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-8.png" new file mode 100644 index 0000000000000000000000000000000000000000..b79d0a7a5781c3424993fbf14687e6307c6d1901 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-8.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-9.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-9.png" new file mode 100644 index 0000000000000000000000000000000000000000..dd544a25c44e8fb8a2823e33fa505819d595683e Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_3/image-9.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-1.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-1.png" new file mode 100644 index 0000000000000000000000000000000000000000..d8fd2bd8bd081848864b8a8542dafaacc64d980c Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-1.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-2.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-2.png" new file mode 100644 index 0000000000000000000000000000000000000000..37ff3c85e56b1326adb0d2b5b38095c6fb2ebad2 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-2.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-3.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-3.png" new file mode 100644 index 0000000000000000000000000000000000000000..73b608f4e2e64cb0081e8084b1653f97e8a20a59 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-3.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-4.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-4.png" new file mode 100644 index 0000000000000000000000000000000000000000..9e6fbf25600ac6b504af19e47f5b17e1183bf5c8 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-4.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-5.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-5.png" new file mode 100644 index 0000000000000000000000000000000000000000..25f495b07719da87040a509e811e8b012632485d Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-5.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-6.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-6.png" new file mode 100644 index 0000000000000000000000000000000000000000..d6da9b90a5fb4588686f115b2aa386eae8699df0 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image-6.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image.png" new file mode 100644 index 0000000000000000000000000000000000000000..d459cfac39f4a67822265d71e45c7bbfe6c7e933 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_4/image.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-1.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-1.png" new file mode 100644 index 0000000000000000000000000000000000000000..00a4e525395ded9247c4692af51c4ecaf7806b72 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-1.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-10.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-10.png" new file mode 100644 index 0000000000000000000000000000000000000000..210027af3412e39a9fbf579ffaba63a5df1e8530 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-10.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-2.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-2.png" new file mode 100644 index 0000000000000000000000000000000000000000..f10f02b60aae639bc23898e63a90028669a9ff45 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-2.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-3.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-3.png" new file mode 100644 index 0000000000000000000000000000000000000000..3de5ccdbbcb88ac2484adec392082274db7da313 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-3.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-4.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-4.png" new file mode 100644 index 0000000000000000000000000000000000000000..8d0b5c880753dfef7a9a2fba3f22ff56d9e8060f Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-4.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-5.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-5.png" new file mode 100644 index 0000000000000000000000000000000000000000..9660c094503dc6e22b7c4ac6492368040d5cbd1b Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-5.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-6.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-6.png" new file mode 100644 index 0000000000000000000000000000000000000000..2500fbb4eae7ef757926181186669dd12f84d3eb Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-6.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-7.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-7.png" new file mode 100644 index 0000000000000000000000000000000000000000..9fb3e023977fdeddbe13b1d4d14eff7b1d414d23 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-7.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-8.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-8.png" new file mode 100644 index 0000000000000000000000000000000000000000..e535e58d8aa5c43e39ccf1c8331cb82aaabaa17b Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-8.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-9.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-9.png" new file mode 100644 index 0000000000000000000000000000000000000000..7e9e3f8e16d02de8b4f895075272b2a8d47b2335 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image-9.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image.png" new file mode 100644 index 0000000000000000000000000000000000000000..114fc26c359c351350a7c70812bb12c55292562c Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\346\236\227\345\272\206\345\256\211/\347\254\224\350\256\260/image_5/image.png" differ