3 Replies Latest reply on Jul 11, 2012 12:25 AM by oman_nadeem

    Nucleus Plus 1.2 question

    look

      Hi,

      I'm an engineer working on some legacy products where we have a PC104 that runs Nucleus Plus 1.2. We recently found a bug in code that freezes up the machine by creating a state in the while loop that runs for a really long time. Its basically a delay function. We have fixed the bug, but still want to find out the root cause. We would like to know from the nucleus team what the root cause is. Here is what we have seen so far. Most of the time we see that after we call new NU_Sleep(10) and check NU_Retrieve_Clock(), at the top of the while loop, it is 10 (or timeleft) ticks greater than before we slept, as expected. However, other times NU_Retrieve_Clock() returns a value greater than what the time slept was specified. And if we NU_Retrieve_Clock() is one tick greater than endtime, the while loop will run until the NU_Retrieve_Clock() value rolls back around to match endtime. We have implemented fixes in this code in the while condition but really want to know why NU_Sleep() does not always yield the expected results from NU_Retrieve_Clock(). Here is our code:

       

       

       

      void Delay (delayTimeInTicks)

      {

      endTime=NU_Retrieve_Clock() + delayTimeInTicks;

       

      while((timeLeft= (endTime - NU_Retrieve_Clock() )) > 0) //Loop ends when endTime = NU_Retrieve_Clock()

      {

            /* kick the watch dog timer */

            Fault_Kick_WDT();

       

            if (timeLeft<10)

            {

                 NU_Sleep(timeLeft);

            }

            else

            {

                 NU_Sleep(10);

            }

      }

      }

        • 1. Re: Nucleus Plus 1.2 question
          oman_nadeem

          Hello,

           

          NU_Sleep puts the current task (suppose task 1) into suspend state for specified ticks. After the completion of this period the task 1 gets ready again but it does not guarantee that task 1 will get executed right after the suspension period. Because there can be some high priority task or same priority task with longer time slice will be holding the cpu when the task 1 gets ready. So the task 1 will wait for the completion of the high priority task.

           

          So this might be the reason in your case that NU_Retrieve_Clock returns increased. The correct implementation of this loop is to declare timeLeft as signed variable.

           

          Regards

          Oman

          • 2. Re: Nucleus Plus 1.2 question
            look

            Thanks Oman. We agree that that is a fix, but the problem is that we are trying to figure out why this extra sleep tick occurs on only one of the three different platforms that we are running the identical software on. We do know that that processor runs about 50% slower than the other two, but we can't figure out how this can happen. Is there anyway that the NU system clock can increment, but the task sleeps an extra tick if it is the highest priority task running? We are monitoring the IRQs, and sometimes the system clock preempts another IRQ when this happens, can this prevent the task from running or decrementing its sleep counter?

            • 3. Re: Nucleus Plus 1.2 question
              oman_nadeem

              Task is resumed from Timer Hisr after expiration of timer. You can check the Timer tick value at this point and investigate where the extra tick is consumes, either before resuming the task of after it. Here is the path to resume the task.

               

              TMC_Timer_HISR -> TMC_Timer_Expiration -> TCC_Task_Timeout -> TCC_Resume_Task

               

              TMD_System_Clock can be compared in TCC_Task_Timeout when it calls TCC_Resume_Task. If it is exactly same when task should resume then you can see where control goes after resuming the task.