diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/3fa6a968257ebd024fe0c76354a5acd.png" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/3fa6a968257ebd024fe0c76354a5acd.png" new file mode 100644 index 0000000000000000000000000000000000000000..0c14cec05c19dc9c321f394c3eab5fdf0e0cae81 Binary files /dev/null and "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/3fa6a968257ebd024fe0c76354a5acd.png" differ diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/befe15417e42e5cc0554c54b51c2485.jpg" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/befe15417e42e5cc0554c54b51c2485.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..7c64f71c0b5a424ca42406bc043167599e091beb Binary files /dev/null and "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/befe15417e42e5cc0554c54b51c2485.jpg" differ diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\200\346\254\241\344\275\234\344\270\232.md" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\200\346\254\241\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..6e4fb3310e6223e2f85c7333abd3a1acfc5ea6d8 --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\200\346\254\241\344\275\234\344\270\232.md" @@ -0,0 +1,2 @@ +![alt text](3fa6a968257ebd024fe0c76354a5acd.png) +![alt text](befe15417e42e5cc0554c54b51c2485.jpg) \ No newline at end of file diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\272\213\344\273\266\351\233\206.c" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\272\213\344\273\266\351\233\206.c" new file mode 100644 index 0000000000000000000000000000000000000000..440b582b2cf84f5d0e2daa1faf551471bfeea97f --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\272\213\344\273\266\351\233\206.c" @@ -0,0 +1,116 @@ + * 程序会初始化2个线程及初始化一个静态事件对象 + * 一个线程等待于事件对象上,以接收事件; + * 一个线程发送事件 (事件3/事件5) +*/ +#include + +#define THREAD_PRIORITY 9 +#define THREAD_TIMESLICE 5 + +#define EVENT_FLAG3 (1 << 3) +#define EVENT_FLAG5 (1 << 5) + +/* 事件控制块 */ +static struct rt_event event; + +#ifdef rt_align +rt_align(RT_ALIGN_SIZE) +#else +ALIGN(RT_ALIGN_SIZE) +#endif +static char thread1_stack[1024]; +static struct rt_thread thread1; + +/* 线程1入口函数 */ +static void thread1_recv_event(void *param) +{ + rt_uint32_t e; + + /* 第一次接收事件,事件3或事件5任意一个可以触发线程1,接收完后清除事件标志 */ + if (rt_event_recv(&event, (EVENT_FLAG3 | EVENT_FLAG5), + 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); + + /* 第二次接收事件,事件3和事件5均发生时才可以触发线程1,接收完后清除事件标志 */ + if (rt_event_recv(&event, (EVENT_FLAG3 | EVENT_FLAG5), + 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 leave.\n"); +} + +#ifdef rt_align +rt_align(RT_ALIGN_SIZE) +#else +ALIGN(RT_ALIGN_SIZE) +#endif +static char thread2_stack[1024]; +static struct rt_thread thread2; + +/* 线程2入口 */ +static void thread2_send_event(void *param) +{ + rt_kprintf("thread2: send event3\n"); + rt_event_send(&event, EVENT_FLAG3); + rt_thread_mdelay(200); + + rt_kprintf("thread2: send event5\n"); + rt_event_send(&event, EVENT_FLAG5); + rt_thread_mdelay(200); + + rt_kprintf("thread2: send event3\n"); + rt_event_send(&event, EVENT_FLAG3); + rt_kprintf("thread2 leave.\n"); +} + +int event_sample(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); +#ifdef RT_USING_SMP + /* 绑定线程到同一个核上,避免启用多核时的输出混乱 */ + rt_thread_control(&thread1, RT_THREAD_CTRL_BIND_CPU, (void*)0); +#endif + rt_thread_startup(&thread1); + + rt_thread_init(&thread2, + "thread2", + thread2_send_event, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); +#ifdef RT_USING_SMP + /* 绑定线程到同一个核上,避免启用多核时的输出混乱 */ + rt_thread_control(&thread2, RT_THREAD_CTRL_BIND_CPU, (void*)0); +#endif + rt_thread_startup(&thread2); + + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(event_sample, event sample); \ No newline at end of file diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\272\222\346\226\245\351\207\217.c" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\272\222\346\226\245\351\207\217.c" new file mode 100644 index 0000000000000000000000000000000000000000..61d4315fa63a40dae1cc2adfb931a7f5f9acf0a7 --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\272\222\346\226\245\351\207\217.c" @@ -0,0 +1,105 @@ + * 互斥锁是一种保护共享资源的方法。当一个线程拥有互斥锁的时候, + * 可以保护共享资源不被其他线程破坏。线程1对2个number分别进行加1操作 + * 线程2也会对2个number分别进行加1操作。使用互斥量保证2个number值保持一致 + */ +#include + +#define THREAD_PRIORITY 8 +#define THREAD_TIMESLICE 5 + +/* 指向互斥量的指针 */ +static rt_mutex_t dynamic_mutex = RT_NULL; +static rt_uint8_t number1, number2 = 0; + +#ifdef rt_align +rt_align(RT_ALIGN_SIZE) +#else +ALIGN(RT_ALIGN_SIZE) +#endif +static char thread1_stack[1024]; +static struct rt_thread thread1; +static void rt_thread_entry1(void *parameter) +{ + while (1) + { + /* 线程1获取到互斥量后,先后对number1、number2进行加1操作,然后释放互斥量 */ + rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); + number1++; + rt_thread_mdelay(10); + number2++; + rt_mutex_release(dynamic_mutex); + } +} + +#ifdef rt_align +rt_align(RT_ALIGN_SIZE) +#else +ALIGN(RT_ALIGN_SIZE) +#endif +static char thread2_stack[1024]; +static struct rt_thread thread2; +static void rt_thread_entry2(void *parameter) +{ + while (1) + { + /* 线程2获取到互斥量后,检查number1、number2的值是否相同,相同则表示mutex起到了锁的作用 */ + rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); + if (number1 != number2) + { + rt_kprintf("not protect.number1 = %d, mumber2 = %d \n", number1, number2); + } + else + { + rt_kprintf("mutex protect ,number1 = mumber2 is %d\n", number1); + } + + number1++; + number2++; + rt_mutex_release(dynamic_mutex); + + if (number1 >= 50) + return; + } +} + +/* 互斥量示例的初始化 */ +int mutex_sample(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(&thread1, + "thread1", + rt_thread_entry1, + RT_NULL, + &thread1_stack[0], + sizeof(thread1_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); +#ifdef RT_USING_SMP + /* 绑定线程到同一个核上,避免启用多核时的输出混乱 */ + rt_thread_control(&thread1, RT_THREAD_CTRL_BIND_CPU, (void*)0); +#endif + rt_thread_startup(&thread1); + + rt_thread_init(&thread2, + "thread2", + rt_thread_entry2, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY - 1, THREAD_TIMESLICE); +#ifdef RT_USING_SMP + /* 绑定线程到同一个核上,避免启用多核时的输出混乱 */ + rt_thread_control(&thread2, RT_THREAD_CTRL_BIND_CPU, (void*)0); +#endif + rt_thread_startup(&thread2); + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(mutex_sample, mutex sample); \ No newline at end of file diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\277\241\345\217\267.c" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\277\241\345\217\267.c" new file mode 100644 index 0000000000000000000000000000000000000000..fe8c82895a52d50a64e99937868cf75935b54cf4 --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\277\241\345\217\267.c" @@ -0,0 +1,57 @@ + * 这个例子会创建一个线程,线程安装信号,然后给这个线程发送信号。 +#include + +#define THREAD_PRIORITY 25 +#define THREAD_STACK_SIZE 512 +#define THREAD_TIMESLICE 5 + +static rt_thread_t tid1 = RT_NULL; + + +void thread1_signal_handler(int sig) +{ + rt_kprintf("thread1 received signal %d\n", sig); +} + +/* 线程1的入口函数 */ +static void thread1_entry(void *parameter) +{ + int cnt = 0; + + /* 安装信号 */ + rt_signal_install(SIGUSR1, thread1_signal_handler); + rt_signal_unmask(SIGUSR1); + + /* 运行10次 */ + while (cnt < 10) + { + /* 线程1采用低优先级运行,一直打印计数值 */ + rt_kprintf("thread1 count : %d\n", cnt); + + cnt++; + rt_thread_mdelay(100); + } +} + +/* 信号示例的初始化 */ +int signal_sample(void) +{ + /* 创建线程1 */ + tid1 = rt_thread_create("thread1", + thread1_entry, RT_NULL, + THREAD_STACK_SIZE, + THREAD_PRIORITY, THREAD_TIMESLICE); + + if (tid1 != RT_NULL) + rt_thread_startup(tid1); + + rt_thread_mdelay(300); + + /* 发送信号 SIGUSR1 给线程1 */ + rt_thread_kill(tid1, SIGUSR1); + + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(signal_sample, signal sample); \ No newline at end of file diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\277\241\345\217\267\351\207\217.c" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\277\241\345\217\267\351\207\217.c" new file mode 100644 index 0000000000000000000000000000000000000000..4a882b5355e967e1d5d17cb375d0705d8597a96f --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\344\277\241\345\217\267\351\207\217.c" @@ -0,0 +1,149 @@ +#include + +#define THREAD_PRIORITY 25 +#define THREAD_TIMESLICE 5 + +/* 指向信号量的指针 */ +static rt_sem_t dynamic_sem = RT_NULL; +static rt_sem_t rtt_sem = RT_NULL; + +#ifdef rt_align +rt_align(RT_ALIGN_SIZE) +#else +ALIGN(RT_ALIGN_SIZE) +#endif +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 <= 100) + { + count++; + } + else + return; + + /* count每计数10次,就释放一次信号量 */ + if (0 == (count % 10)) + { + rt_kprintf("thread1 release a dynamic semaphore.\n"); + rt_sem_release(dynamic_sem); + rt_sem_release(rtt_sem); + } + } +} + +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 (result != RT_EOK) + { + rt_kprintf("thread2 take a dynamic semaphore, failed.\n"); + rt_sem_delete(dynamic_sem); + return; + } + else + { + number++; + rt_kprintf("thread2 take a dynamic semaphore. number = %d\n", number); + } + } +} + +static char thread3_stack[1024]; +static struct rt_thread thread3; +static void rt_thread3_entry(void *parameter) +{ + static rt_err_t result; + static rt_uint8_t number = 0; + while (1) + { + /* 永久方式等待信号量,获取到信号量,则执行number自加的操作 */ + result = rt_sem_take(rtt_sem, RT_WAITING_FOREVER); + if (result != RT_EOK) + { + rt_kprintf("thread3 take a dynamic semaphore, failed.\n"); + rt_sem_delete(rtt_sem); + return; + } + else + { + number++; + rt_kprintf("thread3 take a dynamic semaphore. number = %d\n", number); + } + } +} + +/* 信号量示例的初始化 */ +int semaphore_sample() +{ + /* 创建一个动态信号量,初始值是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"); + } + + rtt_sem = rt_sem_create("rtt", 0, RT_IPC_FLAG_PRIO); + if (rtt_sem == RT_NULL) + { + rt_kprintf("create rtt semaphore failed.\n"); + return -1; + } + else + { + rt_kprintf("create done. rtt semaphore value = 0.\n"); + } + + rt_thread_init(&thread1, + "thread1", + rt_thread1_entry, + RT_NULL, + &thread1_stack[0], + sizeof(thread1_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); + #ifdef RT_USING_SMP + + 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); + + rt_thread_init(&thread3, + "thread3", + rt_thread3_entry, + RT_NULL, + &thread3_stack[0], + sizeof(thread3_stack), + THREAD_PRIORITY - 1, THREAD_TIMESLICE); + + rt_thread_startup(&thread3); + + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(semaphore_sample, semaphore sample); \ No newline at end of file diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\351\202\256\347\256\261.c" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\351\202\256\347\256\261.c" new file mode 100644 index 0000000000000000000000000000000000000000..05e7ac47fbed0578dd0d195326c27872db9ba60a --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\351\202\256\347\256\261.c" @@ -0,0 +1,131 @@ + * 这个程序会创建2个动态线程,一个静态的邮箱对象,其中一个线程往邮箱中发送邮件, + * 一个线程往邮箱中收取邮件。 + */ +#include + +#define THREAD_PRIORITY 10 +#define THREAD_TIMESLICE 5 + +/* 邮箱控制块 */ +static struct rt_mailbox mb; +/* 用于放邮件的内存池 */ +static char mb_pool[128]; + +static char mb_str1[] = "I'm a mail!"; +static char mb_str2[] = "this is another mail!"; +static char mb_str3[] = "over"; + +#ifdef rt_align +rt_align(RT_ALIGN_SIZE) +#else +ALIGN(RT_ALIGN_SIZE) +#endif +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_ubase_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); +} + +#ifdef rt_align +rt_align(RT_ALIGN_SIZE) +#else +ALIGN(RT_ALIGN_SIZE) +#endif +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 mailbox_sample(void) +{ + rt_err_t result; + + /* 初始化一个mailbox */ + result = rt_mb_init(&mb, + "mbt", /* 名称是mbt */ + &mb_pool[0], /* 邮箱用到的内存池是mb_pool */ + sizeof(mb_pool) / sizeof(rt_ubase_t), /* 邮箱中的邮件数目,sizeof(rt_ubase_t)表示指针大小 */ + RT_IPC_FLAG_PRIO); /* 采用PRIO方式进行线程等待 */ + 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); +#ifdef RT_USING_SMP + /* 绑定线程到同一个核上,避免启用多核时的输出混乱 */ + rt_thread_control(&thread1, RT_THREAD_CTRL_BIND_CPU, (void*)0); +#endif + rt_thread_startup(&thread1); + + rt_thread_init(&thread2, + "thread2", + thread2_entry, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); +#ifdef RT_USING_SMP + /* 绑定线程到同一个核上,避免启用多核时的输出混乱 */ + rt_thread_control(&thread2, RT_THREAD_CTRL_BIND_CPU, (void*)0); +#endif + rt_thread_startup(&thread2); + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(mailbox_sample, mailbox sample); diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\351\230\237\345\210\227.c" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\351\230\237\345\210\227.c" new file mode 100644 index 0000000000000000000000000000000000000000..afce5b74f6980b2f150faea2390f48463efb828b --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\270\211\346\254\241\344\275\234\344\270\232/\351\230\237\345\210\227.c" @@ -0,0 +1,155 @@ + * + * 这个程序会创建2个动态线程,一个线程会从消息队列中收取消息;一个线程会定时给消 + * 息队列发送 普通消息和紧急消息。 + */ + +#include + +#define THREAD_PRIORITY 25 +#define THREAD_TIMESLICE 5 +#define RT_VERSION_CHECK(major, minor, revise) ((major * 10000) + (minor * 100) + revise) +/* 消息队列控制块 */ +static struct rt_messagequeue mq; +/* 消息队列中用到的放置消息的内存池 */ +static rt_uint8_t msg_pool[2048]; + +#ifdef rt_align +rt_align(RT_ALIGN_SIZE) +#else +ALIGN(RT_ALIGN_SIZE) +#endif +static char thread1_stack[1024]; +static struct rt_thread thread1; + +/* 线程1入口函数 */ +static void thread1_entry(void *parameter) +{ + char buf = 0; + rt_uint8_t cnt = 0; + + while (1) + { + /* 从消息队列中接收消息 */ +#if (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); +} + +#ifdef rt_align +rt_align(RT_ALIGN_SIZE) +#else +ALIGN(RT_ALIGN_SIZE) +#endif +static char thread2_stack[1024]; +static struct rt_thread thread2; + +/* 线程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; + } + + rt_thread_init(&thread1, + "thread1", + thread1_entry, + RT_NULL, + &thread1_stack[0], + sizeof(thread1_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); +#ifdef RT_USING_SMP + /* 绑定线程到同一个核上,避免启用多核时的输出混乱 */ + rt_thread_control(&thread1, RT_THREAD_CTRL_BIND_CPU, (void*)0); +#endif + rt_thread_startup(&thread1); + + rt_thread_init(&thread2, + "thread2", + thread2_entry, + RT_NULL, + &thread2_stack[0], + sizeof(thread2_stack), + THREAD_PRIORITY, THREAD_TIMESLICE); +#ifdef RT_USING_SMP + /* 绑定线程到同一个核上,避免启用多核时的输出混乱 */ + rt_thread_control(&thread2, RT_THREAD_CTRL_BIND_CPU, (void*)0); +#endif + rt_thread_startup(&thread2); + + return 0; +} + +/* 导出到 msh 命令列表中 */ +MSH_CMD_EXPORT(msgq_sample, msgq sample); \ No newline at end of file diff --git "a/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\272\214\346\254\241\344\275\234\344\270\232.md" "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\272\214\346\254\241\344\275\234\344\270\232.md" new file mode 100644 index 0000000000000000000000000000000000000000..94f2a6c4d89dc39b27715f322ca00e7ce1a44987 --- /dev/null +++ "b/2025/\347\254\2546\347\273\204(GD32F527I-EVAL)/\345\200\252\345\260\224\345\272\267/\347\254\254\344\272\214\346\254\241\344\275\234\344\270\232.md" @@ -0,0 +1,93 @@ +时间片轮转 +#include +#include +#include + +/* defined the LED0 pin: PF9 */ + +void usr_thread1(void) +{ + while(1) + { + rt_kprintf("run in usr1 thread\n"); + } +} + +void usr_thread2(void) +{ + while(1) + { + rt_kprintf("run in usr2 thread\n"); + } +} + + +static rt_thread_t tid1 = RT_NULL; +static rt_thread_t tid2 = RT_NULL; +int main(void) +{ + tid1 = rt_thread_create("usr1", usr_thread1, RT_NULL, 1024, 11, 5); + tid2 = rt_thread_create("usr2", usr_thread2, RT_NULL, 1024, 11, 5); + + if(tid1 != RT_NULL) + { + rt_thread_startup(tid1); + } + + if(tid2 != RT_NULL) + { + rt_thread_startup(tid2); + } + + rt_kprintf("run in main\n"); + + return RT_EOK; +} + +抢占 +#include +#include +#include + +/* defined the LED0 pin: PF9 */ + +void usr_thread1(void) +{ + while(1) + { + rt_kprintf("run in usr1 thread\n"); + rt_thread_delay(5); + } +} + +void usr_thread2(void) +{ + while(1) + { + rt_kprintf("run in usr2 thread\n"); + rt_thread_delay(5); + } +} + + +static rt_thread_t tid1 = RT_NULL; +static rt_thread_t tid2 = RT_NULL; +int main(void) +{ + tid1 = rt_thread_create("usr1", usr_thread1, RT_NULL, 1024, 9, 5); + tid2 = rt_thread_create("usr2", usr_thread2, RT_NULL, 1024, 9, 5); + + if(tid1 != RT_NULL) + { + rt_thread_startup(tid1); + } + + if(tid2 != RT_NULL) + { + rt_thread_startup(tid2); + } + + rt_kprintf("run in main\n"); + + return RT_EOK; +} \ No newline at end of file