How can I test whether a port is working properly?


I’ve been having strange behaviours with the ATmega128 port (actually it’s for the ATmega328, but the core is the same). The misbehaviour shows up whenever the preemptive mode is active:

#define configUSE_PREEMPTION 1

When it is inactive, the system performs as expected:

#define configUSE_PREEMPTION 0

So my guess is that there’s something that isn’t working well when saving and restoring the task’s state.

BTW: TickType_t is set as 16bit.

This is the testing code if you’re interested.

#include <Arduino.h>

#include <FreeRTOS.h>
#include <task.h>

void software_delay( TickType_t ticks )
   volatile TickType_t now = xTaskGetTickCount();

   Serial.print( "\nBefore: " ); 
   Serial.println( now );

   Serial.print( "   Ticks: " ); 
   Serial.println( ticks );

   volatile TickType_t last = now;
   volatile TickType_t res;

   while( 1 )
      res = now-last;

      if( (TickType_t)res >= (TickType_t)ticks )
         Serial.print( "  *res: " );
         Serial.print( res );

         Serial.print( "  now: " );
         Serial.print( now ); 

         Serial.print( "  last: " );
         Serial.print( last );

         Serial.print( "  res: " );
         Serial.println( now-last );

      now = xTaskGetTickCount();

   Serial.print( "After: " ); 
   Serial.println( now );

 * High priority; retains the CPU
void task1( void* pvParameters )
   (void) pvParameters;

   pinMode( 13, OUTPUT );

   while( 1 )
      digitalWrite( 13, HIGH );
      software_delay( pdMS_TO_TICKS( 2000 ) );
      digitalWrite( 13, LOW );
      software_delay( pdMS_TO_TICKS( 2000 ) );
int main(void)

         (const portCHAR *)"T1",
         ( void* ) 0,
         tskIDLE_PRIORITY + 1,
         NULL );

   Serial.begin( 115200 );
   Serial.println( "OUT OF RESET" );


   while( 1 );

And what is the problem? The comparison

if( res >= ticks ){...}

inside the software_delay() function is wrong because of the values of the different variables. This is an excerpt from the output:


Before: 0
   Ticks: 2000
  *res: 84  now: 84  last: 0  res: 84
After: 84

Before: 536879103D5
   Ticks: 2000
  *res: 7  now: 92  last: 85  res: 7
After: 92

Before: 93
   Ticks: 2000
  *res: 15  now: 108  last: 93  res: 15
After: 108

Before: 110
   Ticks: 2000
  *res: 99  now: 209  last: 110  res: 99
After: 209

How is that possible that 84 is greater than 2000?:

Before: 0
   Ticks: 2000
  *res: 84  now: 84  last: 0  res: 84
After: 84

The correct output, when the preemptive mode is inactive, is something like this:

Before: 12490
   Ticks: 2000
  *res: 2000  now: 14490  last: 12490  res: 2000
After: 14490

Before: 14491
   Ticks: 2000
  *res: 2000  now: 16491  last: 14491  res: 2000
After: 16491

Before: 16492
   Ticks: 2000
  *res: 2000  now: 18492  last: 16492  res: 2000
After: 18492

(I’ve used volatile variables in order to trace the error and I added some variables to print out the results.)

EDIT: If I remove the critical section I get worst results!

Is there a standard way to test a port?


Where is “res” declared. Why are you not just calling vTaskDelay() rather than busy waiting?

Why did I declare an extra variable? I did so because I wanted to know whether the result was calculated correctly.

I was coding a program to test the function xTaskDelayUntil(), so I needed a task that keeps the CPU by itself so xTaskDelayUntil() fails. vTaskDelay() will call for a context switch, so it wouldn’t work for the aforementioned purpose.

However, such an easy exercise has resulted in a nightmare. I’ve been puting so much time and effort on the ATmega328 chip (along FreeRTOS) and I think I cannot even recomend FreeRTOS in the Arduino platform with those issues.

I know it’s not a FreeRTOS problem, but the atmega128 port; there are some FreeRTOS features that just doesn’t work for the atmega328 chip, for example, the notifications array just doesn’t work in such port. When using the original one notification field, it works as expected; but as soon as you set the array size equal o larger than two fields, the program fails. Period. And that’s sad.

Before I take those critical decisions, I would like to be sure that I’m the problem and not the port. In the later I should abandon all efforts and concentrate my time in modern chips like those from NXP and ST.

(BTW: one cannot enable INCLUDE_vTaskDelayUntil and INCLUDE_xTaskDelayUntil at the same time; an error is thrown. My guess is that INCLUDE_xTaskDelayUntil includes vTaskDelayUntil().)

Greetings :smiley:!