RYMCU

一个不一样的流水灯

ychost 2 年前
# C51 # 调度器

有啥不一样

仅两行核心代码就实现了来回循环的流水灯,代码如下:

// P_10 --> P_17 依次点亮
#define UP 0
// P_17 --> P_10 依次点亮
#define DOWN !UP

void led_flow(void)
{
	static direct = UP;
	// 上下流水,注意初始化 0xFF 和 0x8F 的位移操作
	P1 = (direct == UP) ? (P1 << 1 | (P1 == 0xFF ? 0x00 : 0x01)) : (P1 >> 1 | (P1 == 0x8F ? 0x00 : 0x80));
	// 流水灯掉头
	direct = ((P1 == 0x7F && direct == UP) || (P1 == 0xFE && direct == DOWN)) ? !direct : direct;
}

就这?

当然了,上面的流水灯代码并没有什么出奇的地方,真正有意思的地方来咯

void main(void)
{
	// 初始化调度器
	hsch_init_timmer2();
	// 追加任务,流水灯
	hsch_add_task(led_flow, 0, 1000, SCH_COO_TYPE);
	// 启动调度器
	hsch_start();
	while (true)
	{
		// 派遣任务
		hsch_dispatch_tasks();
	}
}

上述几行代码才是整个精华,可以看到 led_flow 方法并没被直接调用,而是通过 hsch_add_task 加到了一个任务池子里面,然后被系统所调用

原理

c51 一般不带系统的,所以没有相关的线程调度机制,这里手工实现了一个简单的调度器,hsch 是 hybird scheduler(混合调度器)的缩写,含抢占式调度器和协作式调度器,相关的介绍可以《调度器》相关的书籍和博客,其原理大概长下面这个样子

image.png

可以看到,通过调度器将一个中断等事件转换成任务句柄提交到任务池,然后定时器不断去轮询任务池提取可执行的任务交由 mcu 去执行,同时在整个调度流程中可以输出相关日志方便做一个链路监控

扩展

上述调度器仅用到了一个 MCU,可以更大胆一点实现一个调度器集群(几百块 MCU),实现也不复杂接入通讯芯片,外加一个共享的存储单元即可

  • 源码

https://github.com/ychost/HybSCH

后发布评论