creation of uCOS task of 1 milli second which is equivalent of TimerC 1 milli second interrupt

I am new to this uCOS tasks based programming.
So I tried one sample program with one task of one milli second delay.
But when I tried to see the task timing by using digital output toggling method, I am only getting 75uS.
My doubt is whether the uCOS task of 1 milli second is equivalent to timerC interrupt of 1 milli second.
In timing wise whether both will strictly execute at 1 millis second if you use digital output for checking
Can you please help me how to verify and how to go about it.
Please find the attached files.


#define TIMERC_MS 1UL
#if CPU_ID_MASK(CPU_ID) >= R6000 && defined PLL_DEFAULT_PLL_SPEED_MHz
#define MAIN_PCLK_FREQUENCY (PLL_DEFAULT_PLL_SPEED_MHz * 1000000UL / 2UL)
#else

#if CLOCK_DOUBLED
	#define MAIN_PCLK_FREQUENCY (_CRYSTAL_SPEED_ * 2UL)
#else
	#define MAIN_PCLK_FREQUENCY (_CRYSTAL_SPEED_ * 1UL)
#endif

#endif

#define TIMERC_DIVIDER_IDEAL
(TIMERC_MS * MAIN_PCLK_FREQUENCY / 16. / 2000. - 1.)

#define TIMERC_DIVIDER ((unsigned long) (TIMERC_DIVIDER_IDEAL + 0.5))

#if TIMERC_DIVIDER > 65535UL
#undef TIMERC_DIVIDER
#define TIMERC_DIVIDER 65535UL
#warns “Out of range TIMERC_DIVIDER redefined to the maximum value (65535).”
#warns “Reduce the TIMERC_MS macro value to an achievable setting.”
#endif

#define TCDLR_SETTING (int)(0xff & TIMERC_DIVIDER)
#define TCDHR_SETTING (int)(0xff & (TIMERC_DIVIDER/0x100))
#undef THRESHOLD
#define THRESHOLD 18.00
#class auto
#use “BLxS2xx.lib”
#use “COSTATE.LIB”
#define FINBUFSIZE 255
#define FOUTBUFSIZE 1023
#ifndef _232BAUD
#define _232BAUD 19200
#endif

unsigned short usTemp = 0x00;
unsigned long timerc_count;
int ct=0x00,ch,channel=0,dpcnt=0,blinc=0,i=0;
float cosval[40],sinval[40],cosval_2n[40],sinval_2n[40],cosval_3n[40],sinval_3n[40],cosval_4n[40],sinval_4n[40],cosval_5n[40],sinval_5n[40];
float sdiff,fac=0.0,fas=0.0,fac_2n=0.0,fas_2n=0.0,fac_3n=0.0,fas_3n=0.0,fac_4n=0.0,fas_4n=0.0,fac_5n=0.0,fas_5n=0.0,olda[40],ias,ia=0.0,ia_2n=0.0,ia_3n=0.0,ia_4n=0.0,ia_5n=0.0;
float idc1=0.0,idc2=0.0;
char strig[22],temp1[30],setval[50];
unsigned long int temp, n=0,n1=0,n2=0;

xmem ocuc()
{
digOut(0,0);

  ias = anaInVolts(1,0);     /*input from channel 1 */

  digOut(0,1);

  sdiff = (olda[n1] - ias);

  idc1 = (idc1 + sdiff);

  idc2 = -idc1/40;

	
  olda[n1] = ias;

  n1 = (n1+1)% 40;
  dpcnt++;

}

#asm
timerC_isr::
push af ; save all used registers
push bcde
push jkhl
ioi ld a, (TCCSR) ; clear the interrupt request and get status
; handle all interrupts flagged in TCCSR here
ld bcde, (timerc_count)
ld jkhl, 1
add jkhl, bcde
ld (timerc_count), jkhl
pop jkhl ; restore all used registers
pop bcde
pop af
ipres
ret
#endasm

int main(void)
{
int waitFlag;

/******** ANALOG INPUT VARIABLES ********/
for (n=0;n<40;n++)
{
olda[n] = 0.0; /*setting initialially values to zero */
}

  brdInit();                                          /*initialises system I/O ports */
  
  serFopen(_232BAUD);
  serMode(0);
  for(channel = 0; channel &lt; 8; ++channel)
   {
   setDigOut(channel, 0);
  }
  anaInConfig(1, SE1_MODE);               /*configures an A/D converter input channel 1 for single ended bipolar mode of operation . */
  anaInConfig(2, SE1_MODE);              /* configures an A/D converter input channel 2 for single ended bipolar mode of operation.*/
  digOut(0, 0);                           /* digout from channel 0 */

// ensure timer C is disabled
   WrPortI(TCCSR, &amp;TCCSRShadow, 0x00);
   // set up timer C to use pclk/16
   WrPortI(TCCR, &amp;TCCRShadow, 0x09);
   WrPortI(TCDLR, NULL, TCDLR_SETTING);
   WrPortI(TCDHR, NULL, TCDHR_SETTING);
   // install timer C's ISR
   SetVectIntern(TIMERC_OFS / 0x10, timerC_isr);
   // enable timer C
   WrPortI(TCCSR, &amp;TCCSRShadow, 0x01);

   timerc_count = 0;
   while (1)
   {
      if( timerc_count )
      {
         timerc_count = 0;
         ocuc( );
      }

    }

}


#class auto

#define OS_TASK_CREATE_EXT_EN 1 // Enable extended task creation
#define OS_SEM_EN 1 // Enable semaphores
#define OS_SEM_POST_EN 1 // Enable old style post to semaphore

#define OS_MAX_TASKS 6 // Maximum number of tasks system can create (less stat and idle tasks)
#define OS_TIME_DLY_HMSM_EN 1
#define OS_MBOX_EN 1

#define OS_MAX_EVENTS 4

#define STACK_CNT_256 2
#define STACK_CNT_512 3
#define STACK_CNT_1K 1
#define STACK_CNT_2K 1
#define STACK_CNT_4K 2
#use “BLxS2xx.lib”
#use “ucos2.lib”

#define INVALID_COMMAND “$INVALID_COMMAND;\r”
#define USER_BLOCK_HEADER 0x55555555

void task1(void);
void task2(void);
void task3(void);
void task4(void);

int channel=0,blinc=0;

void main()
{

brdInit();

for(channel = 0; channel < 8; ++channel)
{
setDigOut(channel, 0);
}

OSInit();

OSTaskCreateExt(task1,            \
             (void *)0,                      \
             0,          \
             10,            \
             2048,                 \
             (void *)0,                      \
             OS_TASK_OPT_STK_CHK);

OSStart(); // start uC/OS
while(1)
{
}

}

void task1()
{
while(1)
{

  blinc = !blinc;

  digOut(0,blinc);

  OSTimeDlyHMSM(0,0,0,1);

}

}


1 Like

Per the documentation for OSTimeDlyHMSM() (use CTRL-H in the IDE to display function help):

Note that the resolution on
the milliseconds depends on the tick rate. For example, you
can’t do a 10 mS delay if the ticker interrupts every 100
mS. In this case, the delay would be set to 0. The actual
delay is rounded to the nearest tick.

The default value of OS_TICKS_PER_SEC is 64 (15.6ms), so you would need to increase that to at least 1000 to get the 1ms resolution you’re looking for.

But increasing the OS_TICKS_PER_SEC that high will have an impact on your program due to the increased task switching taking place, and there is likely code in the libraries that block longer than 1ms and could throw your timing off.

On a Rabbit 6000 I would be comfortable trying a value of 256, but knowing that there could be some variability from a task calling an OSTimeDly() function, depending on what other tasks are doing.

If you need a precise event to happen every 1ms, Timer C is a good choice for that. And you probably want to make timerc_count an 8-bit or 16-bit variable to simplify your ISR. For example, inc (hl) increments the byte at address HL.