zoukankan      html  css  js  c++  java
  • CMSIS-RTOS 时间管理之时间延迟Time Delay

    时间管理 Time Management

    此RTOS除了可以把你的应用代码作为线程运行,它还可以提供一些时间服务功能,使用这些功能你就可以访问RTOS的一些系统调用。

    时间延迟Time Delay

    在所有的时间服务功能中,最基本的一个就是延时函数。它可以在你的应用中提供非常简单易用的延时功能。也许你会觉得CMSIS-RTOS已经占用了5k字节的代码量,但是在非RTOS的应用中,我们也常会用到一些延时循环、简单的调度循环等,这些循环功能同样会占用一些字节,而我们的RTOS在这方面可能会占用更少的代码量。

    void osDelay(uint32_t millisec)

    上面这个调用会导致当前线程进入等待延时状态(WAIT_DELAY),延时时间由用户指定。与此同时调度器将会执行下一个处于准备状态(READY)的线程。

    这里写图片描述

    注:在线程的生命周期中,它会进入多种状态。这里一个处于运行状态(RUN)的线程被osDelay阻塞,然后它就会进入等待状态(WAIT)。当延时时间结束时,它就会进入准备状态(READY),调度器就会把它置于运行状态(RUN)。如果它的时间片结束了,它就会返回准备状态(READY)。

    当定时时间结束时,线程会离开等待延时状态,进入READY状态。当调度器把线程移入RUNNING状态时,它就会继续运行。如果线程在以后的执行过程中没有任何阻塞调用,在它的时间片结束时就会被置于READY状态,同时另外一个同优先级的线程就会进入运行状态。

    等待事件

    除了单纯的时间延迟,同样可以使用事件等待让线程暂停并进入等待状态,当有另外一个RTOS事件出现时,就会触发线程继续运行。RTOS事件可以是一个信号,消息或者邮件。如果没有事件出现,就可以osWait()这个API,它有一个毫秒级别的超时机制,可以允许线程的唤醒和继续执行。

    osStatus osWait(uint32_t millisec)//RTX不支持此函数

    当设定的时间结束,线程就会由WAIT状态进入到READY状态,随后被调度器置于RUN状态。osWait在CMSIS RTOS里面是一个可选API。如果你打算使用这个函数,必须先确定你使用的RTOS是支持的。需要注意的是,CMSIS RTOS目前封装的keil RTX 是不支持这个API的。

     

    通过STM32的simulaiton,我发现他的执行顺序是这样的:首先进入main函数,一系列初始化后,完成osKernelStart (); 后,马上进入led_Thread2,执行到osSemaphoreRelease(sem1);,转到led_Thread1,LED_On(1); osDelay(500);还没开始delay就又转到led_Thread2。恰好线程2又是delay,程序中没什么可执行,索性线程1和线程2就delay了500ms,然后又回到线程1执行led关,等待semaphore。

     

    /*----------------------------------------------------------------------------
        
        Designers Guide to the Cortex-M Family
        Semaphore Example
    *----------------------------------------------------------------------------*/
    #include "stm32f10x.h"
    #include "cmsis_os.h"
     
    #include "Board_LED.h"
     
    void led_Thread1 (void const *argument);
    void led_Thread2 (void const *argument);
    osThreadDef(led_Thread1, osPriorityAboveNormal, 1, 0);            //note the raised priority for led_thread 1
    osThreadDef(led_Thread2, osPriorityNormal, 1, 0);
     
    osThreadId T_ledOn;
    osThreadId T_ledOff;
    /*----------------------------------------------------------------------------
      Define the semaphore
     *---------------------------------------------------------------------------*/    
    osSemaphoreId sem1;                                    
    osSemaphoreDef(sem1);
    /*----------------------------------------------------------------------------
      Wait to acquire a semaphore token from sem1 then flash LED 1
     *---------------------------------------------------------------------------*/
    void led_Thread1 (void const *argument) 
    {
        for (;;) 
        {
            osSemaphoreWait(sem1, osWaitForever);
            LED_On(1);                          
            osDelay(500);
            LED_Off(1);
        }
    }
    /*----------------------------------------------------------------------------
      Flash LED 2 and 'release' a semaphore token to sem1
     *---------------------------------------------------------------------------*/
    void led_Thread2 (void const *argument) 
    {
        for (;;) 
        {
            LED_On(2);        
            osSemaphoreRelease(sem1);
            osDelay(500);
            LED_Off(2);
            osDelay(500);
        }
    }
     
    /*----------------------------------------------------------------------------
      Initilise the LED's, Create the semaphore and start the threads
     *---------------------------------------------------------------------------*/
    int main (void) 
    {
        osKernelInitialize ();                    // initialize CMSIS-RTOS
     
        LED_Initialize ();
        sem1 = osSemaphoreCreate(osSemaphore(sem1), 0);    
        T_ledOff = osThreadCreate(osThread(led_Thread2), NULL);
        T_ledOn = osThreadCreate(osThread(led_Thread1), NULL);
        
        osKernelStart ();                         // start thread execution 
    }

     

     

  • 相关阅读:
    POJ2762 Going from u to v or from v to u?
    POJ3422或洛谷2045 Kaka's Matrix Travels
    LaTeX数学公式大全
    POJ1966 Cable TV Network
    转:Android中的Handler的机制与用法详解
    Httpservlet cannot be resolved to a type的原因与解决方法
    Textchangedlistener的用法
    contextMenu的使用
    转:android studio 一直卡在Gradle:Build Running的解决办法
    Sqlite操作的一些关键类的官方说明与Intent的startactivityforresult方法
  • 原文地址:https://www.cnblogs.com/zzdbullet/p/9547333.html
Copyright © 2011-2022 走看看