从零开始学硬件<9>demo源码OceanOS-CM0-B7解读

从零开始学硬件<9>demo源码OceanOS-CM0-B7解读 B7课程互斥锁上一课B6讲的是临界区。临界区的做法比较硬把调度器锁住这段时间别的任务插不进来。能解决问题但代价也明显——锁得时间一长实时性就差了。B7换了个思路任务该阻塞就阻塞别把整个系统冻住。这就是互斥锁mutex。多任务共用一个资源本例是串口时如何保证同一时刻只有一个任务在用。图一工程跑在APM32Cortex-M0上应用层主要看al_main_task.c。main里关掉中断初始化OS创建一个优先级为1的main_task然后os_start()。真正干活的逻辑都在al_main_task里配SysTick1ms、USART1、LEDos_mutex_init(g_mutex)再创建两个优先级都是2的任务task1、task2void al_task1(void *arg){while (1){os_mutex_lock(g_mutex, OS_PEND_FOREVER);printf(11111\n);al_busy_delay(5000*1000);os_mutex_unlock(g_mutex);}}void al_task2(void *arg){os_tick_delay(100);while (1){os_mutex_lock(g_mutex, OS_PEND_FOREVER);printf(22222\n);al_busy_delay(5000*1000);os_mutex_unlock(g_mutex);}}共享资源就是串口。printf底层走fputc一个字符一个字符往USART塞。如果两个任务同时打字串口输出很容易搅在一起。锁把「打印 busy delay」包起来谁拿到锁谁独占这段输出。task2开头故意os_tick_delay(100)让task1先跑一会儿现象更直观。两个任务优先级相同中间那段al_busy_delay是空转不会主动让出CPU时间片到了还是可能切走但因为锁还在手里另一个任务进不了临界代码最多在外面干等。串口里正常应该看到完整的一行行11111 / 22222不会出现11212...这种穿插。修改完后按预期的打印。后期有兴趣可以研究下os_tick.c底层的机制就会更清晰地了解到为什么会是这个结果了。图二建议自己改一版对比把两个任务里的os_mutex_lock/unlock注释掉重新烧录看串口。大概率输出会糊成一团。再加回锁现象立刻干净。这一步比只看代码印象深。也可以试着把al_busy_delay挪到unlock后面观察两个任务输出切换会不会更密——这能帮你体会「锁住的时间」到底意味着什么。图三