Priority Level Question

ChibiOS public support forum for all topics not covered by a specific support forum.

Moderators: RoccoMarco, lbednarz, utzig, tfAteba, barthess

logan54
Posts: 22
Joined: Tue Apr 01, 2014 5:59 am
Location: Austria

Priority Level Question

Postby logan54 » Sat Sep 20, 2014 9:45 pm

Hello,

I ‘am using Chibi 2.6.3 and have question about the CPU usage. I’ve set up a small project on a Spansion 16FX to test the kernel. The Project has 3 Thread, where the first Thread just counts a 7 Segment Display up. The second thread drives an online Protocol for interfacing a PC Program by the serial port, the third Thread reads out the Idle loop count (u32IdleCnt ) that can be displayed at the PC. The main function will become the Idle Thread, ChibiOS Idle Thread is turned off in the configuration. This setup works properly and the setup reports about 47,7 million idle cycles on a 48 MHz MCU, which is an expected value. It must be noticed that the fSekSchleife Thread has the Priority Level LOWPRIO+14. When I set this value to LOWPRIO+13 or below, so the reported idle cycles will drop to about just 39 million cycles, without changing anything else.
What is the difference between LOWPRIO+13 and LOWPRIO+14 in my setup? Anyhow watching the idle loop with a scope does not report really more CPU load between the two setups.
BTW: Is there a common way to measure remain CPU time?

regards,

logan54

Code: Select all

void main(void)
{
… I/O Inits …
  __set_il(0);                /* disallow all levels           */
 
  chSysInit();                  /* __EI(); globally enable interrupts will be called inside chSysInit */

  chThdCreateStatic( strVarPassDemoWA , sizeof(strVarPassDemoWA) ,LOWPRIO+1, (tfunc_t)&VarPassDemo ,NULL);
  thread_ptr_netlink = chThdCreateStatic( strNetLinkWA , sizeof(strNetLinkWA) ,LOWPRIO+2, (tfunc_t)&NET_Link , NULL );
  chThdCreateStatic( strSekSchleife , sizeof(strSekSchleife) , LOWPRIO+14, (tfunc_t)&fSekSchleife , NULL );

  chThdSetPriority(IDLEPRIO);       /* Diese Schleife ist der IDLE Thread */
 
   __set_il(7);                /* allow all levels           */
   
  for(;;)
  {
        u32IdleCnt++;
  }
}

static msg_t VarPassDemo ( void* arg )
{
    systime_t time;
   
    time = chTimeNow();     // T0
    for(;;)
    {
        time += MS2ST(1000u);           //  1000 ms Intervall
       
        //  --- Sicher und Rücksetzen des Idle Loop Zählers
       
        //PDR00_P7 = 0;
        chThdSleepUntil(time);
        //PDR00_P7 = 1;
    }
    return (msg_t)0;     //  should be never reached!
}

uint32_t u32cyclesRemain;

static msg_t fSekSchleife ( void* arg )
{
    systime_t time;
   
    time = chTimeNow();     // T0
    for(;;)
    {
        time += MS2ST(1000u);           //  1000 ms Intervall
       
        //  --- Sicher und Rücksetzen des Idle Loop Zählers
        u32cyclesRemain = u32IdleCnt;
        u32IdleCnt = 0UL;
               
        PDR00_P7 = ~PDR00_P7;

        chThdSleepUntil(time);
    }
    return (msg_t)0;     //  should be never reached!
}

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Priority Level Question

Postby Giovanni » Sun Sep 21, 2014 7:26 am

Hi,

There is no difference for the two priority levels, only the numeric order matters not the absolute values.

I noticed that you manually change the priority to IDLEPRIO manually, there is no need to do that, the option CH_NO_IDLE_THREAD does that for you, the priority is already set to IDLEPRIO on exit of chSysInit().

ChibiOS 3.0 has a new statistic module that is able to measure consumed time for threads in cycles, you may try that.

Giovanni

logan54
Posts: 22
Joined: Tue Apr 01, 2014 5:59 am
Location: Austria

Re: Priority Level Question

Postby logan54 » Sun Sep 21, 2014 8:53 am

Hello,

I've set

Code: Select all

#define CH_NO_IDLE_THREAD               TRUE

and I've stepped through Initialisation by Debugger, but I've found no where a section where the main function thread priority is set in a way, so if I don't set the main function priority to IDLEPRIO, so my LOWPRIO Thread will never run. Anyhow you have described this behaviour in chconf.h.

Code: Select all

* @brief   Idle thread automatic spawn suppression.
 * @details When this option is activated the function @p chSysInit()
 *          does not spawn the idle thread automatically. The application has
 *          then the responsibility to do one of the following:
 *          - Spawn a custom idle thread at priority @p IDLEPRIO.
 *          - Change the main() thread priority to @p IDLEPRIO then enter
 *            an endless loop. In this scenario the @p main() thread acts as
 *            the idle thread.
 *          .
 * @note    Unless an idle thread is spawned the @p main() thread must not
 *          enter a sleep state.
 



.
.

I've found my Problem:

+ MCU: CISC Architecture with 5 State Pipeline and 8 Byte Prefetch queue,
depending on the code before the Idle loop count in the main function, the INCL statement was issued on an uneven adress in ROM, and so a Wait State was inserted into the CPU-Pipeline in the counting loop, this dropped my counting result. A solution is to use a fixed time base (e.g. microsecond timer) or put the counting loop in an extra function which need to be aligned at an even adress by a linker statement.

regards

logan54

User avatar
Giovanni
Site Admin
Posts: 14455
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1076 times
Been thanked: 922 times
Contact:

Re: Priority Level Question

Postby Giovanni » Sun Sep 21, 2014 9:39 am

It is a bug then. I will align the behavior to the documentation.

Giovanni


Return to “General Support”

Who is online

Users browsing this forum: No registered users and 11 guests