前言:砸在脑壳上的Protothreads

前言:砸在脑壳上的Protothreads

初见Protothreads

记得那是一个阳光明媚的下午,我百般无聊地阅读着小米的SDK,偶样一段这样的代码引起了我的注意。
在这里插入图片描述

我实在没有想明白PT这个单词的含义,本着刨根问底的精神。在查询百度之后,我学会了一个新名词 : protothreads。我似懂非懂的阅读着这个全部由宏写成的,磕磕碰碰地理解着另类的switch case的调度原理。就算是有百度在后见支持着,我还是难以得到其精髓。一怒之下,我突然灵光一闪,想起了程序预编译的过程,于是我在ubuntu上用gcc -E 把宏展开,这下不就一目了然了吗?

于是我决定把的代码进行展开

static PT_THREAD(demo_thread(struct pt *pt))
{
    static uint8_t s_cond = PT_FALSE;

    PT_BEGIN_EX(pt);

    LOG("线程的开始了 ,while 1 在下面 demo thread \r\n");
    while (1)
    {
        LOG("PT_YIELD 的前面 \r\n");
        PT_YIELD(pt);
        LOG("PT_YIELD 的后面 \r\n");

        LOG("PT_YIELD_UNTIL 的前面:等待条件变真 \r\n");
        PT_YIELD_UNTIL(pt, s_cond);

        LOG("PT_YIELD_UNTIL 的后面:条件变真后进入 \r\n");
    }

    LOG("线程的结束 ,由于while 1 在上面 \r\n");
    PT_END_EX(pt);
}

结果我得到了以下的代码


static char demo_thread(struct pt *pt)
{
    static uint8_t s_cond = 0;

    {
        char PT_YIELD_FLAG = 1;
        switch ((pt)->lc)
        {
            case 0:;

                printf("线程的开始了 ,while 1 在下面 demo thread \r\n");
                while (1)
                {
                    printf("PT_YIELD 的前面 \r\n");
                    do
                    {
                        PT_YIELD_FLAG = 0;
                        (pt)->lc = 40;
                        case 40:;
                            if (PT_YIELD_FLAG == 0)
                            {
                                return 1;
                            }
                    }
                    while (0);
                    printf("PT_YIELD 的后面 \r\n");

                    printf("PT_YIELD_UNTIL 的前面:等待条件变真 \r\n");
                    do
                    {
                        PT_YIELD_FLAG = 0;
                        (pt)->lc = 44;
                        case 44:;
                            if ((PT_YIELD_FLAG == 0) || !(s_cond))
                            {
                                return 1;
                            }
                    }
                    while (0);

                    printf("PT_YIELD_UNTIL 的后面:条件变真后进入 \r\n");
                }

                printf("线程的结束 ,由于while 1 在上面 \r\n");
        };
        PT_YIELD_FLAG = 0;
        (pt)->lc = 0;
        ;
        return 3;
    };
}

这回我终于看懂了,原理这个PT的任务调度是通过标记代码行数,跳转到对应的case 行数。再经过轮询的结构,从而实现一个任务调度。这个发现确实让我非常着迷,似乎看到一个与众不同的OS,而且这个OS是裸机的朋友来说这么的友好,对低资源的MCU是如此友好。但此时我能力并没有我萌发封装这个PT的,实现一个无堆栈的操作的想法。一番了解之后,再次把它放到一个角落里面。只留下了一个叫PT的协程,它的任务调度仅需要2个字节的记忆

再遇Protothreads

机遇巧合之下我再次在小米的SDK里面遇到了这个PT,这是多么熟悉的PT_BEGIN啊。这个时候的我已经不再是一个初出茅庐的程序员了,这几年来的陆陆续续使用过Free RTOS ,阅读过ucos等操作系统,再次看到这个PT的时候,我发现我可以具备让他成为一个OS的能力,我封装起来,让它运行Sleep!
这个想法一旦出现,我完全着迷了,是啊。我可以通过我的设计,让PT,具备OS的sleep功能,让他成为一个操作系统,解决资源少的MCU,更容易加入操作系统,让异步的业务可以使用同步的设计逻辑。

于是我在github上创建了一个仓库 https://github.com/liufuzhao/Protothreads.git
于是我在在CSDN上展开Protothreads的专栏。主要详解github上的Protothreads特性和设计方案已经使用建议。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值