Hi,
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 )
{
portENTER_CRITICAL();
res = now-last;
portEXIT_CRITICAL();
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 );
break;
}
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)
{
cli();
init();
xTaskCreate(
task1,
(const portCHAR *)"T1",
512,
( void* ) 0,
tskIDLE_PRIORITY + 1,
NULL );
Serial.begin( 115200 );
Serial.println( "OUT OF RESET" );
vTaskStartScheduler();
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:
OUT OF RESET
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?
Greetings!