Hi,
(Source code at the end.)
The Arduino’s serial print utility (Serial.print()
) seems to be causing a stack overflow, so I’ve eliminated it from the project… but the problem still exists.
Facts:
If I use vTaskDelay()
, instead of vTaskDelayUntil()
, along xTaskAbortDelay()
, the program runs smoothly.
If I use vTaskDelayUntil()
without xTaskAbortDelay()
, the program runs smoothly.
If I use vTaskDelayUntil()
along xTaskAbortDelay()
, the program fails.
In such case apparently there’s not any stack overflow. After I execute a Ctrl-c in GDB I got this:
(gdb) p *task1_handler
$6 = {pxTopOfStack = 0x8002b7 "\034", xStateListItem = {xItemValue = 32568, pxNext = 0x800160 <pxReadyTasksLists+12>,
pxPrevious = 0x800160 <pxReadyTasksLists+12>, pvOwner = 0x8002f3, pvContainer = 0x80015d <pxReadyTasksLists+9>}, xEventListItem = {xItemValue = 2,
pxNext = 0x0 <__vectors>, pxPrevious = 0x0 <__vectors>, pvOwner = 0x8002f3, pvContainer = 0x0 <__vectors>}, uxPriority = 1 '\001',
pxStack = 0x8001f1 "", pcTaskName = "T1\000\000", ulNotifiedValue = {0}, ucNotifyState = "", ucStaticallyAllocated = 0 '\000',
ucDelayAborted = 0 '\000'}
(gdb) p/x (*task1_handler->pxStack)@32
$17 = {0xa5 <repeats 32 times>} // I might presume there aren't any overflows
But more important, the variable uxSchedulerSuspended
gets corrupted somewhere. The program runs as expected for some time, and then it fails:
...
Breakpoint 2, xTaskAbortDelay (xTask=<optimized out>) at /home/fjrg76/arduino-1.8.13/libraries/FreeRTOS/src/tasks.c:2720
2720 }
1: uxSchedulerSuspended = 0 '\000'
(gdb) c
Continuando.
Breakpoint 2, xTaskAbortDelay (xTask=<optimized out>) at /home/fjrg76/arduino-1.8.13/libraries/FreeRTOS/src/tasks.c:2720
2720 }
1: uxSchedulerSuspended = 0 '\000'
(gdb) c
Continuando.
Breakpoint 2, xTaskAbortDelay (xTask=<optimized out>) at /home/fjrg76/arduino-1.8.13/libraries/FreeRTOS/src/tasks.c:2720
2720 }
1: uxSchedulerSuspended = 0 '\000'
(gdb) c
Continuando.
^C // HERE THE PROGRAM HAS FAILED
Program received signal SIGINT, Interrupt.
0x00000eda in xTaskDelayUntil (pxPreviousWakeTime=0x8002e4, xTimeIncrement=500) at /home/fjrg76/arduino-1.8.13/libraries/FreeRTOS/src/tasks.c:1257
1257 configASSERT( uxSchedulerSuspended == 0 );
1: uxSchedulerSuspended = 169 '\251'
(gdb)
Unfortunately the GDB for the atmega328 is limited and watchpoints don’t work.
Any hint why or where uxSchedulerSuspended
gets corrupted or how I can catch the moment in which it gets corrupted without using the “watching” GDB’s utility?
I cannot write any application for this chip as long as this problem isn’t solved.
Thank you!
Source code:
#include <Arduino.h>
void initVariant() __attribute__((weak));
void setupUSB() __attribute__((weak));
int atexit(void (* /*func*/ )()) { return 0; }
void initVariant() { }
void setupUSB() { }
#include <FreeRTOS.h>
#include <task.h>
TaskHandle_t task0_handler;
TaskHandle_t task1_handler;
void task1( void* pvParameters )
{
pinMode( 13, OUTPUT );
uint16_t cont = 0;
TickType_t last_wakeup = xTaskGetTickCount();
bool state = false;
while( 1 )
{
vTaskDelayUntil( &last_wakeup, pdMS_TO_TICKS( 500 ) );
digitalWrite( 13, (state=!state) );
xTaskNotifyGive( task0_handler );
}
}
void task0( void* pvParameters )
{
uint16_t cont = 5;
bool state = false;
while( 1 )
{
ulTaskNotifyTake( pdTRUE, portMAX_DELAY );
digitalWrite( 2, (state=!state) );
--cont;
if( cont == 0 )
{
cont = 6;
vTaskDelay( pdMS_TO_TICKS( 100 ) );
xTaskAbortDelay( task1_handler ); // HERE IS THE CALLING
}
}
}
int main(void)
{
cli();
init();
initVariant();
#if defined(USBCON)
USBDevice.attach();
#endif
if( xTaskCreate( task1, "T1", 128 * 2, 0, tskIDLE_PRIORITY+1, &task1_handler ) != pdPASS )
configASSERT( 0 );
if( xTaskCreate( task0, "T0", 128 * 4, 0, tskIDLE_PRIORITY, &task0_handler ) != pdPASS )
configASSERT( 0 );
pinMode( 2, OUTPUT );
digitalWrite( 2, LOW );
vTaskStartScheduler();
while( 1 )
{
}
return 0;
}
#ifdef __cplusplus
extern "C"
{
#endif
void vApplicationStackOverflowHook( TaskHandle_t task, char* pcTaskName )
{
digitalWrite( 2, HIGH );
}
void vApplicationIdleHook()
{
}
void vApplicationMallocFailedHook()
{
cli();
pinMode( 13, OUTPUT );
while( 1 )
{
digitalWrite( 13, HIGH );
for( size_t i = 65000; i > 0; --i);
digitalWrite( 13, LOW );
for( size_t i = 65000; i > 0; --i);
}
}
#ifdef __cplusplus
}
#endif