【问题标题】:Context switching in uC/OS (embedded systems)uC/OS(嵌入式系统)中的上下文切换
【发布时间】:2012-01-05 16:48:01
【问题描述】:

我想知道是否有可能让中断强制调度程序将上下文切换到 RTOS 中的特定任务。我正在使用 microCOS 操作系统

这是执行按键扫描并将字符发送到邮箱的任务,我需要在此代码中添加更多功能,例如去抖动和自动重复,但我需要整理一个触发机制以使其正常工作。

我不确定如何使用轮询或中断来完成此操作

        static  void  AppTaskKeyscan (void *p_arg)
    {
        CPU_INT08U debouncing = 1;
        CPU_INT16U key;
        key_t button={0,0,0};

        (void)p_arg;

         while (DEF_TRUE) 
         {
            static CPU_INT08U pattern;
            key=P10;

            OSTimeDlyHMSM(0, 0, 0, 50);
            P10=0x0E;
            if ((pattern=P10)==0xee)
                {button.data='1', button.live=1;}       
            else if (pattern==0xde)
                {button.data='4', button.live=1;}
            else if (pattern==0xbe)
                {button.data='7', button.live=1;}
            else if (pattern==0x7e)
                {button.data='*', button.live=1;}
            else
            {
                P10=0x0d;
                if ((pattern=P10)==0xed)
                    {button.data='2', button.live=1;}
                else if (pattern==0xdd)
                    {button.data='5', button.live=1;}
                else if (pattern==0xbd)
                    {button.data='8', button.live=1;}
                else if (pattern==0x7d)
                    {button.data='0', button.live=1;}
                else
                {
                    P10=0x0b;
                    if ((pattern=P10)==0xeb)
                        {button.data='3', button.live=1;}
                    else if (pattern==0xdb)
                        {button.data='6', button.live=1;}
                    else if (pattern==0xbb)
                        {button.data='9', button.live=1;}
                    else if (pattern==0x7b)
                        {button.data='#', button.live=1;}
                    else
                    {
                        P10=0x07;
                        if ((pattern=P10)==0xe7)
                            {button.data='A', button.live=1;}
                        else if (pattern==0xd7)
                            {button.data='B', button.live=1;}
                        else if (pattern==0xb7)
                            {button.data='C', button.live=1;}
                        else if (pattern==0x77)
                            {button.data='D', button.live=1;}
                        else
                            button.live=0;
                    }
                }
            }

            P10=pattern; 

            if (button.live==0)
                OSTimeDlyHMSM(0, 0, 0, 50);
            else
            {
                if (P10==pattern)
                OSTimeDlyHMSM(0, 0, 0, 50);
                else
                button.live=0;
            }

            P10=0x00;              
            if (button.live)        //if button live, set unread flag to 1 and start count down
            {
                button.unread=1;
            }

            if(button.unread&&button.data!='X')
            {
                key=button.data;
                OSMboxPost(KeyMbox, (void *) &key);
                button.live=0;
                button.unread=0;
            }

             OSTimeDlyHMSM(0, 0, 0, 200); 
         } // End of While
    }

【问题讨论】:

  • 为什么在{button.data='A', button.live=1;} 形式的行中使用逗号运算符?

标签: embedded scheduled-tasks rtos context-switch ucos


【解决方案1】:

执行此操作的典型方法是让键盘处理任务有一个循环,它在信号量上挂起。键盘中断处理程序将发布信号量,这将导致处理任务准备好并执行。

【讨论】:

    【解决方案2】:

    调度程序通常会这样做。它的工作是根据进程/线程的优先级(给定线程/进程感知调度程序)知道何时进行上下文切换

    编辑:

    不这样做的原因

    想象一个入侵者产生一个低优先级任务,迫使 CPU 切换到上下文切换(从更高优先级任务)到执行一些恶意负载

    【讨论】:

    • 当我正在编写一个keyscan任务并且我想在按下任何键时产生中断,那么如何让调度程序识别这一点?
    • @Amanni 通常你有一个键盘中断,然后你用按下的键向键盘进程发送一条消息。调度程序将知道何时运行键盘进程,该进程将拾取您通过按下的键发送的消息,并将显示它或您想用它做什么。
    • 很抱歉让您感到痛苦,但是键盘进程是什么意思?
    • @Amanni 没关系;我假设您正在制作操作系统。一个操作系统有很多进程;您可以根据需要添加任意数量,但一些必要的有:空进程、键盘、屏幕、计时器。请参阅我写的这篇文章:stackoverflow.com/a/8458921/1007845。可能会发现此链接有用:en.wikipedia.org/wiki/Process_%28computing%29
    • 非常感谢,我不是在编写操作系统,我只是在为我的键扫描寻找触发器,我可以决定是使用中断还是轮询,或者具体来说我也无法获得去工作。我将编辑问题,以便添加我的代码
    【解决方案3】:

    您必须使用可用的中断兼容(即非阻塞)IPC 机制来发出任务信号。维修键盘的最简单方法是让 ISR 将键码放入队列中。任何需要用户输入的任务都将从该队列中读取。

    或者,您可以简单地让 ISR 增加一个计数信号量,并将键盘解码推迟到一个任务,然后该任务可以将字符放入队列中,任何读取用户输入的任务都可以读取该队列。如果解码时间较长或执行时间可变,这可能更可取。

    特别是在 uC/OS-II 中,需要调度程序运行的 ISR 必须使用 OSIntEnter() 和 OSIntExit() 调用。当最后一个嵌套中断完成时,OSIntExit() 会导致调度程序运行。然后将根据调度策略调度任务。无法绕过策略以强制特定任务违反调度策略运行,您也不应该这样做!如果必须运行特定任务,则将其设为最高优先级。

    通常,只有进行操作系统调用的 ISR 才需要 ISR 序言/尾声功能,因为不需要的 ISR 不会导致调度程序需要运行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-11-01
      • 1970-01-01
      • 2021-12-22
      • 2012-02-11
      • 2015-03-16
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      相关资源
      最近更新 更多