Hello,
I learned from http://www.keil.com/support/docs/3008.htm: a) It is not possible to mix the wait method os_itv_wait() and os_dly_wait(). b) It is possible to mix os_evt_wait_or(0x0001, 0xffff) (without timeout!) and os_dly_wait(). But is it possible in RTX to use os_evt_wait_or(0x0001, 100) (with timeout!) and os_dly_wait() in the same task? e.g.:
void task1 (void) _task_ 1 { while (1) { os_evt_wait_or (0x0001, 100); // wait for event flag set or timeout (100 ticks) ... // some code os_dly_wait (10); // wait here for 10 ticks ... } } void task2 (void) _task_ 2 { ... if (...) { os_evt_set (0x0001, id1); // send event to task 1 } }
Or is it impossible because of the same timer is used for both delays in task 1?
Thanks in advance for your answers, Norbert
You simply need to make a better os_itv_wait function that has it's own counters. There are many places where a brief delay it a task is useful or required but the loop rate should remain constant.
Why this is such a difficult task for tho OS writer to do is beyond me. The RAM cost for this support would be 16 bits if it was in Keil's code.
An on idle type function is also easy to add that runs low priority stuff for the task with a little more code ... that is left to the user.
Chad
#include "rtl.h" /* for os_dly_wait FN. */ #if 0 /*allows to compile stand alone or as part of RTX */ /* library. */ #include "RTX_Config.h" /*OS includes, insert others as needed. */ #include "rt_task.h" /* path to these must be added if being used. */ #else /*if not compiling with the OS library, declare */ /* the types here. */ //typedef unsigned long U32; typedef unsigned char U8; typedef unsigned short U16; typedef U32 OS_RESULT; #endif #ifdef LIBS_OS_ARM7 /* USE ARM7 rtos commands. */ OS_RESULT os_block( U16 timeout, U8 block_state ); #define mOS_BLOCK( x ) os_block ( x, WAIT_DLY ) #define mTASK_LOCK( ) tsk_lock ( ) #define mTASK_UNLOCK( ) tsk_unlock ( ) extern void tsk_lock (void) __swi (5); extern void tsk_unlock( void ); #elif defined ( LIBS_OS_CM ) /* use CM3 libs. */ #define mOS_BLOCK( x ) os_dly_wait ( x ) /*< calls assembly routine. > */ #define mTASK_LOCK( ) /*< not used. > */ #define mTASK_UNLOCK( ) /*< not used. > */ #else #error : NO_LIB_DEFINED . Define LIBS_OS_ARM7 or LIBS_OS_CM #endif typedef struct OS_ITV_DLY_STRUCT { U16 delay_clock; /* < MDK 4.60 / 4.7 changed os_timer to 32 bit */ /* from 16. 16 bit is still used in RTX */ /* source for items so continue to do so. > */ U16 interval; } OS_ITV_DLY_COUNTS; void os_itv_dly_set( U16 Interval, OS_ITV_DLY_COUNTS *Delay ) /*< set the delay counts per interval > */ { Delay->delay_clock = ( ( OS_TIMEType )os_time ); /* get current clock */ Delay->interval = Interval; /* save the desired run interval */ } void os_itv_delay_wait( OS_ITV_DLY_COUNTS *Delay ) /*< pauses task to allow the desired interval to */ /* elapse before allowing task to continue. > */ { U16 NewDelay; mTASK_LOCK( ); /* lock the task if necessary. */ Delay->delay_clock += Delay->interval; /* add the interval to the present target */ /* execution time to get the next desired */ /* execution time. */ NewDelay = Delay->delay_clock - ( ( OS_TIMEType )os_time ); /* subtract desired execution time from the */ /* present time. This = wait time. */ if( NewDelay <= Delay->interval ) /* only delay if desired delay is < = interval. */ /* If >, there was an underflow. */ { mOS_BLOCK( NewDelay ); /* for ARM7 */ } mTASK_UNLOCK( ); /* unlock. */ }