前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >小实验 | 利用信号量实现跑马灯

小实验 | 利用信号量实现跑马灯

作者头像
飞哥
发布2020-07-10 10:25:01
5530
发布2020-07-10 10:25:01
举报

上一次我们说到了uCOS中的信号量,信号量具有同步的作用,今天做一个小实验来说明这个。

实验任务:使用操作系统,创建三个任务,实现跑马灯的效果(即三个灯依次实现亮200ms,灭200ms)。

先看一下效果吧。

乍一看,可能觉得这个实验特别简单,确实,在裸机编程当中,即使是初学者也可以写出这个程序。但是带上了操作系统,就不能再使用原来的思维了。

我们先回忆一下如果是裸机当中,我们会怎么编。最简单的,只需要像下面这样写(省略main函数):

while(1)

{

led1亮;

延时200ms;

led1灭;

延时200ms;

led2亮;

延时200ms;

led2灭;

延时200ms;

led3亮;

延时200ms;

led3灭;

延时200ms;

}

这样完全就可以实现要求,当然为了让主函数简洁,我们最好用三个函数封装一下:

void led1(void)

{

led1亮;

延时200ms;

led1灭;

延时200ms;

}

while(1)

{

led1();

led2();

led3();

}

当然有人可能会说,只要使用一个函数就行了,直接发送端码就行了,比如发送0x7f,延时,再发送0xbf ……。这样确实没毛病,但这不是我们今天讨论的内容。

好了,那我们能不能在操作系统中也这样,创建三个优先级不等的任务,实现跑马灯呢?答案是不行的。因为在裸机中,任务是按顺序执行的,执行完led1亮灭之后,再执行led2亮灭,最后执行led3亮灭,循环下来就是跑马灯效果,但是操作系统中是不会让CPU空闲的,点亮led1的时候,并不会在那里等,而是马上切换任务,这时led2就会点亮,再切换。所以虽然三个任务是有不同优先级,但是看到的效果是三个灯同时亮,同时灭,根本不会有跑马灯的效果,或者说,你感觉上是三个任务同时执行。

那为了避免这种情况,使用信号量是一种不错的方法。编程思路如下:

信号量1初值为1,三个任务同时去获取信号量1,但是只有优先级高的才能获取,然后执行,执行完之后释放信号量1,接着获取信号量2,由于信号量2初值为0,因此任务1被阻塞,任务2获取到了信号量1往下执行,执行完后释放信号量1,获取信号量2同样被阻塞,任务3执行完毕之后释放信号量1和信号量2,然后任务1被得到执行,并且再次阻塞在获取信号量2上(因为刚刚信号量2被任务2获取了),同理,其他任务也是重复上面的动作。这样就实现了一个闭环。

总结:信号量具有同步的作用,通过信号量可以实现任务之间的“交流”,即哪个任务该被阻塞,哪个任务可以得到执行。

另外,点灯是一门学问,不管是初学单片机,还是像现在使用操作系统,我们都是在点灯,因为点灯操作起来简单,现象也易于观察,只不过虽然都是点灯,但是使用的方法和涉及到的知识点是完全不一样的。当能够将各种理论综合起来花样点灯的时候,就说明有一定基础了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-03-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 电子技术研习社 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档