diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-1/\345\261\217\345\271\225\346\210\252\345\233\276 2025-07-29 121824.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-1/\345\261\217\345\271\225\346\210\252\345\233\276 2025-07-29 121824.png" new file mode 100644 index 0000000000000000000000000000000000000000..6189d1b7b9ecf4a7bcf7f03cfa430ba93e98c9d3 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-1/\345\261\217\345\271\225\346\210\252\345\233\276 2025-07-29 121824.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-1/\345\261\217\345\271\225\346\210\252\345\233\276 2025-07-29 130309.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-1/\345\261\217\345\271\225\346\210\252\345\233\276 2025-07-29 130309.png" new file mode 100644 index 0000000000000000000000000000000000000000..60028f5fc8ee1f82bf3c8fd40929ece54772a564 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-1/\345\261\217\345\271\225\346\210\252\345\233\276 2025-07-29 130309.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-2/main.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-2/main.c" new file mode 100644 index 0000000000000000000000000000000000000000..0827fdf7ec809e6183bfe88fa702d860677fd39d --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-2/main.c" @@ -0,0 +1,83 @@ +//以下是一个在RT-Thread Studio中可直接运行的main.c文件代码,创建了3个线程来体现抢占式调度和时间片轮转功能: + +#include + +#define THREAD_PRIORITY_1 20 +#define THREAD_PRIORITY_2 20 +#define THREAD_PRIORITY_3 15 +#define THREAD_STACK_SIZE 512 +#define THREAD_TIMESLICE 10 + +static void thread1_entry(void *parameter) + { + int count = 0; + while (1) + { + rt_kprintf("Thread 1 is running, count: %d\n", count++); + rt_thread_mdelay(100); + } + } + +static void thread2_entry(void *parameter) + { + int count = 0; + while (1) + { + rt_kprintf("Thread 2 is running, count: %d\n", count++); + rt_thread_mdelay(100); + } + } + +static void thread3_entry(void *parameter) + { + int count = 0; + while (1) + { + rt_kprintf("===== Thread 3 is running, count: %d =====\n", count++); + rt_thread_mdelay(1000); + } + } + +int main(void) + { + rt_thread_t tid1, tid2, tid3; + + tid1 = rt_thread_create("thread1", + thread1_entry, + RT_NULL, + THREAD_STACK_SIZE, + THREAD_PRIORITY_1, + THREAD_TIMESLICE); + + tid2 = rt_thread_create("thread2", + thread2_entry, + RT_NULL, + THREAD_STACK_SIZE, + THREAD_PRIORITY_2, + THREAD_TIMESLICE); + + tid3 = rt_thread_create("thread3", + thread3_entry, + RT_NULL, + THREAD_STACK_SIZE, + THREAD_PRIORITY_3, + THREAD_TIMESLICE); + + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + else + return -1; + + if (tid2 != RT_NULL) + rt_thread_startup(tid2); + else + return -1; + + if (tid3 != RT_NULL) + rt_thread_startup(tid3); + else + return -1; + + return 0; + } + diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-2/\346\225\210\346\236\234\345\233\276.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-2/\346\225\210\346\236\234\345\233\276.png" new file mode 100644 index 0000000000000000000000000000000000000000..8b291b7a5ffa0844ba3082cc246f89093c82cb86 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-2/\346\225\210\346\236\234\345\233\276.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/1.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/1.c" new file mode 100644 index 0000000000000000000000000000000000000000..337bd8672ec4d0084ac67a8bfbf96dacb315629e --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/1.c" @@ -0,0 +1,69 @@ +//信号量 +#include + +// 定义信号量控制块 +static rt_sem_t test_sem; + +// 线程 1 入口函数,用于获取信号量 +static void thread1_entry(void *parameter) +{ + while (1) + { + // 获取信号量,等待时间为无限等待 + rt_sem_take(test_sem, RT_WAITING_FOREVER); + rt_kprintf("Thread 1 took the semaphore.\n"); + // 模拟使用信号量后执行的操作,这里简单延时 + rt_thread_mdelay(1000); + } +} + +// 线程 2 入口函数,用于释放信号量 +static void thread2_entry(void *parameter) +{ + while (1) + { + // 释放信号量 + rt_sem_release(test_sem); + rt_kprintf("Thread 2 released the semaphore.\n"); + // 模拟间隔一段时间再次释放,这里简单延时 + rt_thread_mdelay(2000); + } +} + +int sem_example_init(void) +{ + // 创建信号量,初始值为 0 + test_sem = rt_sem_create("test_sem", 0, RT_IPC_FLAG_FIFO); + if (test_sem == RT_NULL) + { + rt_kprintf("Failed to create semaphore.\n"); + return -1; + } + + // 创建线程 1 + rt_thread_t thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 1024, 25, 10); + if (thread1 != RT_NULL) + { + rt_thread_startup(thread1); + } + else + { + rt_kprintf("Failed to create thread1.\n"); + return -1; + } + + // 创建线程 2 + rt_thread_t thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, 1024, 20, 10); + if (thread2 != RT_NULL) + { + rt_thread_startup(thread2); + } + else + { + rt_kprintf("Failed to create thread2.\n"); + return -1; + } + + return 0; +} +INIT_APP_EXPORT(sem_example_init); \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/2.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/2.c" new file mode 100644 index 0000000000000000000000000000000000000000..b496634c33301b8512793d819b13535d2b23f5dd --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/2.c" @@ -0,0 +1,75 @@ +//互斥量 +#include + +// 定义互斥量控制块 +static rt_mutex_t test_mutex; +// 共享资源,这里简单用一个整型变量模拟 +static int shared_resource = 0; + +// 线程 1 入口函数,访问共享资源 +static void thread1_entry(void *parameter) +{ + while (1) + { + // 获取互斥量 + rt_mutex_take(test_mutex, RT_WAITING_FOREVER); + shared_resource++; + rt_kprintf("Thread 1 access shared resource, value: %d\n", shared_resource); + // 释放互斥量 + rt_mutex_release(test_mutex); + rt_thread_mdelay(1500); + } +} + +// 线程 2 入口函数,访问共享资源 +static void thread2_entry(void *parameter) +{ + while (1) + { + // 获取互斥量 + rt_mutex_take(test_mutex, RT_WAITING_FOREVER); + shared_resource--; + rt_kprintf("Thread 2 access shared resource, value: %d\n", shared_resource); + // 释放互斥量 + rt_mutex_release(test_mutex); + rt_thread_mdelay(1000); + } +} + +int mutex_example_init(void) +{ + // 创建互斥量 + test_mutex = rt_mutex_create("test_mutex", RT_IPC_FLAG_FIFO); + if (test_mutex == RT_NULL) + { + rt_kprintf("Failed to create mutex.\n"); + return -1; + } + + // 创建线程 1 + rt_thread_t thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 1024, 25, 10); + if (thread1 != RT_NULL) + { + rt_thread_startup(thread1); + } + else + { + rt_kprintf("Failed to create thread1.\n"); + return -1; + } + + // 创建线程 2 + rt_thread_t thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, 1024, 20, 10); + if (thread2 != RT_NULL) + { + rt_thread_startup(thread2); + } + else + { + rt_kprintf("Failed to create thread2.\n"); + return -1; + } + + return 0; +} +INIT_APP_EXPORT(mutex_example_init); \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/3.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/3.c" new file mode 100644 index 0000000000000000000000000000000000000000..0df9d7859e3298ded4594508f4e48f1af6a52944 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/3.c" @@ -0,0 +1,80 @@ +//事件集 +#include + +// 定义事件集控制块 +static rt_event_t test_event; + +// 线程 1 入口函数,等待事件 +static void thread1_entry(void *parameter) +{ + rt_uint32_t recv_events; + while (1) + { + // 等待事件,等待事件 0x01 和 0x02 中的任意一个或多个,无限等待 + recv_events = rt_event_recv(test_event, 0x01 | 0x02, RT_EVENT_OR | RT_EVENT_CLEAR, RT_WAITING_FOREVER, RT_NULL); + if (recv_events & 0x01) + { + rt_kprintf("Thread 1 received event 0x01.\n"); + } + if (recv_events & 0x02) + { + rt_kprintf("Thread 1 received event 0x02.\n"); + } + rt_thread_mdelay(500); + } +} + +// 线程 2 入口函数,发送事件 +static void thread2_entry(void *parameter) +{ + while (1) + { + // 发送事件 0x01 + rt_event_send(test_event, 0x01); + rt_kprintf("Thread 2 sent event 0x01.\n"); + rt_thread_mdelay(1000); + + // 发送事件 0x02 + rt_event_send(test_event, 0x02); + rt_kprintf("Thread 2 sent event 0x02.\n"); + rt_thread_mdelay(2000); + } +} + +int event_example_init(void) +{ + // 创建事件集 + test_event = rt_event_create("test_event", RT_IPC_FLAG_FIFO); + if (test_event == RT_NULL) + { + rt_kprintf("Failed to create event.\n"); + return -1; + } + + // 创建线程 1 + rt_thread_t thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 1024, 25, 10); + if (thread1 != RT_NULL) + { + rt_thread_startup(thread1); + } + else + { + rt_kprintf("Failed to create thread1.\n"); + return -1; + } + + // 创建线程 2 + rt_thread_t thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, 1024, 20, 10); + if (thread2 != RT_NULL) + { + rt_thread_startup(thread2); + } + else + { + rt_kprintf("Failed to create thread2.\n"); + return -1; + } + + return 0; +} +INIT_APP_EXPORT(event_example_init); \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/4.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/4.c" new file mode 100644 index 0000000000000000000000000000000000000000..b01d6424450cb3fcff7295ad927c2bcafc728088 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/4.c" @@ -0,0 +1,77 @@ +//邮箱 +#include + +// 定义邮箱控制块 +static rt_mailbox_t test_mailbox; +// 邮件内容,这里简单用整型指针模拟 +static int mail_content[5]; + +// 线程 1 入口函数,接收邮件 +static void thread1_entry(void *parameter) +{ + int *recv_mail; + while (1) + { + // 接收邮件,无限等待 + recv_mail = (int *)rt_mb_recv(test_mailbox, RT_WAITING_FOREVER); + if (recv_mail != RT_NULL) + { + rt_kprintf("Thread 1 received mail: %d\n", *recv_mail); + // 这里简单处理,实际可根据需求释放内存等,示例中用静态数组,不用动态释放 + } + rt_thread_mdelay(800); + } +} + +// 线程 2 入口函数,发送邮件 +static void thread2_entry(void *parameter) +{ + int i = 0; + while (1) + { + mail_content[i % 5] = i; + // 发送邮件 + rt_mb_send(test_mailbox, (rt_ubase_t)&mail_content[i % 5]); + rt_kprintf("Thread 2 sent mail: %d\n", mail_content[i % 5]); + i++; + rt_thread_mdelay(1200); + } +} + +int mailbox_example_init(void) +{ + // 创建邮箱,邮件大小为指针大小,最多 5 封邮件 + test_mailbox = rt_mb_create("test_mailbox", 5, RT_IPC_FLAG_FIFO); + if (test_mailbox == RT_NULL) + { + rt_kprintf("Failed to create mailbox.\n"); + return -1; + } + + // 创建线程 1 + rt_thread_t thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 1024, 25, 10); + if (thread1 != RT_NULL) + { + rt_thread_startup(thread1); + } + else + { + rt_kprintf("Failed to create thread1.\n"); + return -1; + } + + // 创建线程 2 + rt_thread_t thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, 1024, 20, 10); + if (thread2 != RT_NULL) + { + rt_thread_startup(thread2); + } + else + { + rt_kprintf("Failed to create thread2.\n"); + return -1; + } + + return 0; +} +INIT_APP_EXPORT(mailbox_example_init); \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/5.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/5.c" new file mode 100644 index 0000000000000000000000000000000000000000..a33ca0cc5a558fc7dfa04619ecb5d290b808b1fc --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/5.c" @@ -0,0 +1,75 @@ +//消息队列 +#include + +// 定义消息队列控制块 +static rt_mq_t test_msgqueue; +// 消息内容,这里简单用整型数组模拟 +static rt_int32_t msg_content[10]; + +// 线程 1 入口函数,接收消息 +static void thread1_entry(void *parameter) +{ + rt_int32_t recv_msg; + while (1) + { + // 接收消息,无限等待 + if (rt_mq_recv(test_msgqueue, &recv_msg, sizeof(rt_int32_t), RT_WAITING_FOREVER) == RT_EOK) + { + rt_kprintf("Thread 1 received message: %d\n", recv_msg); + } + rt_thread_mdelay(900); + } +} + +// 线程 2 入口函数,发送消息 +static void thread2_entry(void *parameter) +{ + int i = 0; + while (1) + { + msg_content[i % 10] = i; + // 发送消息 + rt_mq_send(test_msgqueue, &msg_content[i % 10], sizeof(rt_int32_t)); + rt_kprintf("Thread 2 sent message: %d\n", msg_content[i % 10]); + i++; + rt_thread_mdelay(1500); + } +} + +int msgqueue_example_init(void) +{ + // 创建消息队列,消息大小为 rt_int32_t 大小,最多 10 条消息 + test_msgqueue = rt_mq_create("test_msgqueue", sizeof(rt_int32_t), 10, RT_IPC_FLAG_FIFO); + if (test_msgqueue == RT_NULL) + { + rt_kprintf("Failed to create message queue.\n"); + return -1; + } + + // 创建线程 1 + rt_thread_t thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 1024, 25, 10); + if (thread1 != RT_NULL) + { + rt_thread_startup(thread1); + } + else + { + rt_kprintf("Failed to create thread1.\n"); + return -1; + } + + // 创建线程 2 + rt_thread_t thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, 1024, 20, 10); + if (thread2 != RT_NULL) + { + rt_thread_startup(thread2); + } + else + { + rt_kprintf("Failed to create thread2.\n"); + return -1; + } + + return 0; +} +INIT_APP_EXPORT(msgqueue_example_init); \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/6.c" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/6.c" new file mode 100644 index 0000000000000000000000000000000000000000..2fe8d02c3506db19789a97a8824d26e682910457 --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\344\275\234\344\270\232/DAY-3/6.c" @@ -0,0 +1,69 @@ +//信号的作用 +#include + +// 线程 1 入口函数,等待信号 +static void thread1_entry(void *parameter) +{ + rt_sigset_t mask; + int sig; + // 初始化信号集 + rt_sigemptyset(&mask); + // 添加要等待的信号,这里假设等待 SIGUSR1 信号(RT-Thread 中自定义信号等,可按需调整) + rt_sigaddset(&mask, SIGUSR1); + while (1) + { + // 等待信号 + sig = rt_sigtimedwait(&mask, NULL, RT_WAITING_FOREVER); + if (sig > 0) + { + rt_kprintf("Thread 1 received signal: %d\n", sig); + } + rt_thread_mdelay(1000); + } +} + +// 线程 2 入口函数,发送信号 +static void thread2_entry(void *parameter) +{ + while (1) + { + // 向线程 1 发送信号 SIGUSR1,假设线程 1 的 PID 可通过相关方式获取,这里简单用查找线程名方式(实际更严谨的方式按需处理) + rt_thread_t thread1 = rt_thread_find("thread1"); + if (thread1 != RT_NULL) + { + rt_kill(thread1, SIGUSR1); + rt_kprintf("Thread 2 sent signal SIGUSR1 to thread1.\n"); + } + rt_thread_mdelay(3000); + } +} + +int signal_example_init(void) +{ + // 创建线程 1 + rt_thread_t thread1 = rt_thread_create("thread1", thread1_entry, RT_NULL, 1024, 25, 10); + if (thread1 != RT_NULL) + { + rt_thread_startup(thread1); + } + else + { + rt_kprintf("Failed to create thread1.\n"); + return -1; + } + + // 创建线程 2 + rt_thread_t thread2 = rt_thread_create("thread2", thread2_entry, RT_NULL, 1024, 20, 10); + if (thread2 != RT_NULL) + { + rt_thread_startup(thread2); + } + else + { + rt_kprintf("Failed to create thread2.\n"); + return -1; + } + + return 0; +} +INIT_APP_EXPORT(signal_example_init); \ No newline at end of file diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/1.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/1.png" new file mode 100644 index 0000000000000000000000000000000000000000..a5ec6d52ed26b3f889ad80b9f06d6b12df6a3544 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/1.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/10.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/10.png" new file mode 100644 index 0000000000000000000000000000000000000000..ad84b7ebd58a6c09b05aceac90515048b50ea147 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/10.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/11.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/11.png" new file mode 100644 index 0000000000000000000000000000000000000000..c222ba039b86818302125ea370df57ae927f44ab Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/11.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/12.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/12.png" new file mode 100644 index 0000000000000000000000000000000000000000..eb29e379fca8689e92149955432fd9b160b572cb Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/12.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/2.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/2.png" new file mode 100644 index 0000000000000000000000000000000000000000..5e7bb11173a126929d9d3998bc40b79f2dd297cf Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/2.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/3.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/3.png" new file mode 100644 index 0000000000000000000000000000000000000000..bf23e7e605ccd7f4a037a210366590eba239ba09 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/3.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/4.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/4.png" new file mode 100644 index 0000000000000000000000000000000000000000..8e23699484c8c7d2ab8254dec449899c395569b0 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/4.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/5.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/5.png" new file mode 100644 index 0000000000000000000000000000000000000000..8f6930cbd2186674a70fdcf2c33e709bc34b519c Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/5.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/6.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/6.png" new file mode 100644 index 0000000000000000000000000000000000000000..04f1f2bd08f27ec9fc719096d833e2dbb85f2761 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/6.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/7.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/7.png" new file mode 100644 index 0000000000000000000000000000000000000000..71906322ad22a91dd80e585b0755f5930c1654cd Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/7.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/8.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/8.png" new file mode 100644 index 0000000000000000000000000000000000000000..a09d5ab1e4c13a08f44c09671db18f23b1825691 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/8.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/9.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/9.png" new file mode 100644 index 0000000000000000000000000000000000000000..2228cba7daec0e53003d8f3f65cd0857a40006cd Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-2/9.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\210\233\345\273\272\344\277\241\345\217\267\351\207\217.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\210\233\345\273\272\344\277\241\345\217\267\351\207\217.png" new file mode 100644 index 0000000000000000000000000000000000000000..03d5b2370d0341d0889f2005a6f06ce1fe7e0fa8 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\210\233\345\273\272\344\277\241\345\217\267\351\207\217.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-08 182040.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-08 182040.png" new file mode 100644 index 0000000000000000000000000000000000000000..7c1ac260560c72b0772f55fecfe8fce6b738e20e Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-08 182040.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 171954.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 171954.png" new file mode 100644 index 0000000000000000000000000000000000000000..9001c60817803da866f1488953b69ea31893fa60 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 171954.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172006.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172006.png" new file mode 100644 index 0000000000000000000000000000000000000000..80a7ca9b59ea5080b4747a845c8e1270bac5fb3e Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172006.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172021.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172021.png" new file mode 100644 index 0000000000000000000000000000000000000000..bfc02644dd7661fc1447af25e757b6cb90b622b2 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172021.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172029.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172029.png" new file mode 100644 index 0000000000000000000000000000000000000000..a07c6f7b72685f7cd8508b8507d16e582dd0c6e1 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172029.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172036.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172036.png" new file mode 100644 index 0000000000000000000000000000000000000000..38ec8f68f751f8639a35b88c05dd017953a25568 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172036.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172043.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172043.png" new file mode 100644 index 0000000000000000000000000000000000000000..eb6a1043a51f0e480a8583af74d46e5d4d4f195d Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172043.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172048.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172048.png" new file mode 100644 index 0000000000000000000000000000000000000000..a461ef03f4153393880fa8447269ba8b7bd240cb Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172048.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172056.png" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172056.png" new file mode 100644 index 0000000000000000000000000000000000000000..b5dd9705fecaa4216edba6984e853219a5e706a6 Binary files /dev/null and "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/day-3/\345\233\276\347\211\207/\345\261\217\345\271\225\346\210\252\345\233\276 2025-08-09 172056.png" differ diff --git "a/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/test-1.md" "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/test-1.md" new file mode 100644 index 0000000000000000000000000000000000000000..30486c1c998a43eedcf3711006fd66443140fe9b --- /dev/null +++ "b/2025/\347\254\2542\347\273\204(RA8D1-Vision-Board)/\351\231\210\345\215\253/\347\254\224\350\256\260/test-1.md" @@ -0,0 +1,103 @@ +## DAY1笔记 +/########课程所用命令记录########/ +day1-1 + +配置 +``` +many configure +``` +目录 +``` +ls +``` +重新完整编译(4:基于电脑的线程数 没理解) +``` +scons -j4 +``` +清理旧编译产物 +``` +scons -c +``` +确保构建依赖重置 +``` +scons --clean +``` + +查看所有命令 +``` +help +``` +可以看到它当前的设备当前已经开启的设备。 +``` +list device +``` +查看选项(thread timer ...) +``` +list +``` +day1-2 + +初始化仓库 +``` +git init +``` +(查看状态?) +``` +git status +``` +提交代码(vs中插件有图形化提交界面) +``` +git commit -m “提交说明” +``` +查看历史 +``` +git log +``` + 当前文件添加到暂存区 +``` +git add . +``` +查看当前所有分支 +``` +git branch -a +``` +切换分支(test) +``` +git checkout test +``` +创建分支(test) +``` +git checkout\switch -b test +``` +强制回到上一次提交(硬重置) +``` +git reset --hard HEAD~ +``` + 软重置 +``` +git reset --sodt HEAD~ +``` +在当前界面打开vs code(终端执行) +``` +code . +``` +修改上游仓库地址 +``` +git remote set-url origin 地址 +``` +远程仓库推送 +``` +git push +``` +本地的远程与远程同步 +``` +git fetch +``` +本地的本地分支与远程同步 +``` +git pull +``` +/#######################################################/ + +PR流程参考链接 +https://github.com/HPUJSJSH/codingForUs/blob/main/PR%E6%8F%90%E4%BA%A4%E6%95%99%E7%A8%8B%2Freadme.md \ No newline at end of file diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/drv_vir.c" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/drv_vir.c" new file mode 100644 index 0000000000000000000000000000000000000000..3e0c3ae1ee9243470df097dc805ed26d8272faac --- /dev/null +++ "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/drv_vir.c" @@ -0,0 +1,38 @@ +#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\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/drv_vir.h" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/drv_vir.h" new file mode 100644 index 0000000000000000000000000000000000000000..2eb1c42b5766fb4492997cb6a5df9e0aa29d18af --- /dev/null +++ "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/drv_vir.h" @@ -0,0 +1,14 @@ +#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\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/main.c" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/main.c" new file mode 100644 index 0000000000000000000000000000000000000000..2b6614e17dac9a5802490a85bf1c28436c5a87ab --- /dev/null +++ "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/main.c" @@ -0,0 +1,39 @@ +/* + * 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) +{ + //IO + 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 = 1128; + 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); + val = 4444; + rt_vir_write((rt_vir_device_t)vir, val); + rt_vir_read((rt_vir_device_t)vir, &ret); + rt_kprintf("ret :%d\n", ret); +} diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/vir.c" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/vir.c" new file mode 100644 index 0000000000000000000000000000000000000000..7417b94e99f21a2a87bc429218171032a9e41113 --- /dev/null +++ "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/vir.c" @@ -0,0 +1,95 @@ +#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_write(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_write; + 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_write(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 diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/vir.h" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/vir.h" new file mode 100644 index 0000000000000000000000000000000000000000..b6409f868515fb5842c9b1b0803c6867bae68549 --- /dev/null +++ "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\344\275\234\344\270\232/Day4/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 vir 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_write(rt_vir_device_t device, rt_uint32_t val); + +#endif diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/IO\350\256\276\345\244\207\345\222\214\351\251\261\345\212\250\346\241\206\346\236\266.md" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/IO\350\256\276\345\244\207\345\222\214\351\251\261\345\212\250\346\241\206\346\236\266.md" new file mode 100644 index 0000000000000000000000000000000000000000..21f9d642c3f6476d7de8ea239a9a1618971004db --- /dev/null +++ "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/IO\350\256\276\345\244\207\345\222\214\351\251\261\345\212\250\346\241\206\346\236\266.md" @@ -0,0 +1,256 @@ +# I/O设备和驱动框架 + +绝大部分的嵌入式系统都包括一些 I/O(Input/Output,输入 / 输出)设备,例如仪器上的数据显示屏、工业设备上的串口通信、数据采集设备上用于保存数据的 Flash 或 SD 卡,以及网络设备的以太网接口等,都是嵌入式系统中容易找到的 I/O 设备例子。 + +## 设备驱动框架 + +![I/O 设备模型框架补充图](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/figures/io-dev-ex.png) + +## I/O设备介绍 + +### I/O设备模型框架 + +RT-Thread 提供了一套简单的 I/O 设备模型框架,如下图所示,它位于硬件和应用程序之间,共分成三层,从上到下分别是 I/O 设备管理层、设备驱动框架层、设备驱动层。 + +![I/O 设备模型框架](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/figures/io-dev.png) + +应用程序通过 I/O 设备管理接口获得正确的设备驱动,然后通过这个设备驱动与底层 I/O 硬件设备进行数据(或控制)交互。 + +I/O 设备管理层实现了对设备驱动程序的封装。应用程序通过图中的"I/O设备管理层"提供的标准接口访问底层设备,设备驱动程序的升级、更替不会对上层应用产生影响。这种方式使得设备的硬件操作相关的代码能够独立于应用程序而存在,双方只需关注各自的功能实现,从而降低了代码的耦合性、复杂性,提高了系统的可靠性。 + +设备驱动框架层是对同类硬件设备驱动的抽象,将不同厂家的同类硬件设备驱动中相同的部分抽取出来,将不同部分留出接口,由驱动程序实现。 + +设备驱动层是一组驱使硬件设备工作的程序,实现访问硬件设备的功能。它负责创建和注册 I/O 设备,对于操作逻辑简单的设备,可以不经过设备驱动框架层,直接将设备注册到 I/O 设备管理器中。 + +### I/O设备模型 + +RT-Thread 的设备模型是建立在内核对象模型基础之上的,设备被认为是一类对象,被纳入对象管理器的范畴。每个设备对象都是由基对象派生而来,每个具体设备都可以继承其父类对象的属性,并派生出其私有属性,下图是设备对象的继承和派生关系示意图。 + +![设备继承关系图](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/figures/io-parent.png) + +设备对象具体定义如下所示: + +```C +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 设备类型,主要设备类型如下所示: + +```C +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 /* 杂类设备 */ +``` + +## 创建和注册I/O设备 + +### 动态创建设备 + +驱动层负责创建设备实例,并注册到 I/O 设备管理器中,可以通过静态申明的方式创建设备实例,也可以用下面的接口进行动态创建: + +```C +rt_device_t rt_device_create(int type, int attach_size); +``` + +当一个动态创建的设备不再需要使用时可以通过如下函数来销毁: + +```C +void rt_device_destroy(rt_device_t device); +``` + +### 注册设备 + +设备被创建后,需要注册到 I/O 设备管理器中,应用程序才能够访问,注册设备的函数如下所示: + +```C +rt_err_t rt_device_register(rt_device_t dev, const char* name, rt_uint8_t flags); +``` + +当设备注销后的,设备将从设备管理器中移除,也就不能再通过设备查找搜索到该设备。注销设备不会释放设备控制块占用的内存。注销设备的函数如下所示: + +```C +rt_err_t rt_device_unregister(rt_device_t dev); +``` + +## 访问I/O设备 + +应用程序通过 I/O 设备管理接口来访问硬件设备,当设备驱动实现后,应用程序就可以访问该硬件。I/O 设备管理接口与 I/O 设备的操作方法的映射关系下图所示: + +![I/O 设备管理接口与 I/O 设备的操作方法的映射关系](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/figures/io-fun-call.png) + +### 查找设备 + +应用程序根据设备名称获取设备句柄,进而可以操作设备。查找设备函数如下所示: + +```C +rt_device_t rt_device_find(const char* name); +``` + +### 初始化设备 + +```C +rt_err_t rt_device_init(rt_device_t dev); +``` + +### 打开设备 + +通过设备句柄,应用程序可以打开和关闭设备,打开设备时,会检测设备是否已经初始化,没有初始化则会默认调用初始化接口初始化设备。通过如下函数打开设备: + +```C +rt_err_t rt_device_open(rt_device_t dev, rt_uint16_t oflags); +``` + +### 关闭设备 + +应用程序打开设备完成读写等操作后,如果不需要再对设备进行操作则可以关闭设备,通过如下函数完成: + +```C +rt_err_t rt_device_close(rt_device_t dev); +``` + +### 控制设备 + +通过命令控制字,应用程序也可以对设备进行控制,通过如下函数完成: + +```C +rt_err_t rt_device_control(rt_device_t dev, rt_uint8_t cmd, void* arg); +``` + +### 读写设备 + +应用程序从设备中读取数据可以通过如下函数完成: + +```C +rt_size_t rt_device_read(rt_device_t dev, rt_off_t pos,void* buffer, rt_size_t size); +``` + +向设备中写入数据,可以通过如下函数完成: + +```C +rt_size_t rt_device_write(rt_device_t dev, rt_off_t pos,const void* buffer, rt_size_t size); +``` + +### 数据收发回调 + +当硬件设备收到数据时,可以通过如下函数回调另一个函数来设置数据接收指示,通知上层应用线程有数据到达: + +```C +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)); +``` + +## IO框架调用关系 + +![image-20250731155040831](./image/image-20250731155040831.png) + +## PIN设备 + +应用程序通过 RT-Thread 提供的 PIN 设备管理接口来访问 GPIO,相关接口如下所示: + +| **函数** | **描述** | +| ------------------- | -------------------- | +| rt_pin_get() | 获取引脚编号 | +| rt_pin_mode() | 设置引脚模式 | +| rt_pin_write() | 设置引脚电平 | +| rt_pin_read() | 读取引脚电平 | +| rt_pin_attach_irq() | 绑定引脚中断回调函数 | +| rt_pin_irq_enable() | 使能引脚中断 | +| rt_pin_detach_irq() | 脱离引脚中断回调函数 | + +芯片上的引脚一般分为 4 类:电源、时钟、控制与 I/O,I/O 口在使用模式上又分为 General Purpose Input Output(通用输入 / 输出),简称 GPIO,与功能复用 I/O(如 SPI/I2C/UART 等)。 + +大多数 MCU 的引脚都不止一个功能。不同引脚内部结构不一样,拥有的功能也不一样。可以通过不同的配置,切换引脚的实际功能。通用 I/O 口主要特性如下: + +- 可编程控制中断:中断触发模式可配置,一般有下图所示 5 种中断触发模式: + +![5 种中断触发模式](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/pin/figures/pin2.png) + +- 输入输出模式可控制。 + - 输出模式一般包括:推挽、开漏、上拉、下拉。引脚为输出模式时,可以通过配置引脚输出的电平状态为高电平或低电平来控制连接的外围设备。 + - 输入模式一般包括:浮空、上拉、下拉、模拟。引脚为输入模式时,可以读取引脚的电平状态,即高电平或低电平。 + +## I2C总线设备 + +I2C(Inter Integrated Circuit)总线是 PHILIPS 公司开发的一种半双工、双向二线制同步串行总线。I2C 总线传输数据时只需两根信号线,一根是双向数据线 SDA(serial data),另一根是双向时钟线 SCL(serial clock)。SPI 总线有两根线分别用于主从设备之间接收数据和发送数据,而 I2C 总线只使用一根线进行数据收发。 + +I2C 和 SPI 一样以主从的方式工作,不同于 SPI 一主多从的结构,它允许同时有多个主设备存在,每个连接到总线上的器件都有唯一的地址,主设备启动数据传输并产生时钟信号,从设备被主设备寻址,同一时刻只允许有一个主设备。如下图所示: + +![I2C 总线主从设备连接方式](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/i2c/figures/i2c1.png) + +如下图所示为 I2C 总线主要的数据传输格式: + +![I2C 总线数据传输格式](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/i2c/figures/i2c2.png) + + + +当总线空闲时,SDA 和 SCL 都处于高电平状态,当主机要和某个从机通讯时,会先发送一个开始条件,然后发送从机地址和读写控制位,接下来传输数据(主机发送或者接收数据),数据传输结束时主机会发送停止条件。传输的每个字节为8位,高位在前,低位在后。数据传输过程中的不同名词详解如下所示: + +- **开始条件:** SCL 为高电平时,主机将 SDA 拉低,表示数据传输即将开始。 +- **从机地址:** 主机发送的第一个字节为从机地址,高 7 位为地址,最低位为 R/W 读写控制位,1 表示读操作,0 表示写操作。一般从机地址有 7 位地址模式和 10 位地址模式两种,如果是 10 位地址模式,第一个字节的头 7 位 是 11110XX 的组合,其中最后两位(XX)是 10 位地址的两个最高位,第二个字节为 10 位从机地址的剩下8位,如下图所示: + +![7 位地址和 10 位地址格式](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/i2c/figures/i2c3.png) + +- **应答信号:** 每传输完成一个字节的数据,接收方就需要回复一个 ACK(acknowledge)。写数据时由从机发送 ACK,读数据时由主机发送 ACK。当主机读到最后一个字节数据时,可发送 NACK(Not acknowledge)然后跟停止条件。 +- **数据:** 从机地址发送完后可能会发送一些指令,依从机而定,然后开始传输数据,由主机或者从机发送,每个数据为 8 位,数据的字节数没有限制。 +- **重复开始条件:** 在一次通信过程中,主机可能需要和不同的从机传输数据或者需要切换读写操作时,主机可以再发送一个开始条件。 +- **停止条件:** 在 SDA 为低电平时,主机将 SCL 拉高并保持高电平,然后在将 SDA 拉高,表示传输结束。 + +## SPI设备 + +SPI(Serial Peripheral Interface,串行外设接口)是一种高速、全双工、同步通信总线,常用于短距离通讯,主要应用于 EEPROM、FLASH、实时时钟、AD 转换器、还有数字信号处理器和数字信号解码器之间。SPI 一般使用 4 根线通信,如下图所示: + +![SPI 主设备和从设备的连接方式](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/spi/figures/spi1.png) + +- MOSI –主机输出 / 从机输入数据线(SPI Bus Master Output/Slave Input)。 +- MISO –主机输入 / 从机输出数据线(SPI Bus Master Input/Slave Output)。 +- SCLK –串行时钟线(Serial Clock),主设备输出时钟信号至从设备。 +- CS –从设备选择线 (Chip select)。也叫 SS、CSB、CSN、EN 等,主设备输出片选信号至从设备。 + +SPI 以主从方式工作,通常有一个主设备和一个或多个从设备。通信由主设备发起,主设备通过 CS 选择要通信的从设备,然后通过 SCLK 给从设备提供时钟信号,数据通过 MOSI 输出给从设备,同时通过 MISO 接收从设备发送的数据。 + +如下图所示芯片有 2 个 SPI 控制器,SPI 控制器对应 SPI 主设备,每个 SPI 控制器可以连接多个 SPI 从设备。挂载在同一个 SPI 控制器上的从设备共享 3 个信号引脚:SCK、MISO、MOSI,但每个从设备的 CS 引脚是独立的。 + +![一个 SPI 主设备与多个从设备连接](https://www.rt-thread.org/document/site/rt-thread-version/rt-thread-standard/programming-manual/device/spi/figures/spi2.png) + +一般情况下 MCU 的 SPI 器件都是作为主机和从机通讯,在 RT-Thread 中将 SPI 主机虚拟为 SPI 总线设备,应用程序使用 SPI 设备管理接口来访问 SPI 从机器件,主要接口如下所示: + +| **函数** | **描述** | +| ------------------------- | ------------------------------------- | +| rt_device_find() | 根据 SPI 设备名称查找设备获取设备句柄 | +| rt_spi_transfer_message() | 自定义传输数据 | +| rt_spi_transfer() | 传输一次数据 | +| rt_spi_send() | 发送一次数据 | +| rt_spi_recv() | 接受一次数据 | +| rt_spi_send_then_send() | 连续两次发送 | +| rt_spi_send_then_recv() | 先发送后接收 | + diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250729204757987.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250729204757987.png" new file mode 100644 index 0000000000000000000000000000000000000000..fa7c852c975e979dd7a4bb50495eb34fe5deca64 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250729204757987.png" differ diff --git "a/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250731155040831.png" "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250731155040831.png" new file mode 100644 index 0000000000000000000000000000000000000000..4730709bc7461fecb5e99e2b88239c17cfc34d75 Binary files /dev/null and "b/2025/\347\254\2545\347\273\204(CanMV-K230)/\351\230\256\347\247\213\345\251\225/\347\254\224\350\256\260/image/image-20250731155040831.png" differ