damien_d wrote on Friday, October 12, 2018:
Dear All,
I am currently attempting to debug a problem I have running stock FreeRTOS v10.1.0 on an NXP S32K144 EVK (ARM Cortex-M4F) using GCC 7.3.1:
/opt/gcc-arm-none-eabi-7-2018-q2-update/bin/arm-none-eabi-gcc --version
arm-none-eabi-gcc (GNU Tools for Arm Embedded Processors 7-2018-q2-update) 7.3.1 20180622 (release) [ARM/embedded-7-branch revision 261907]
In this application, I have a sensor sampling task triggered by a HW timer servicing 3 sensors at 3200Hz, two comms tasks (a UART and CAN), and a general debugging task triggered from the tick hook.
The problem I have is in the sensor task. The three sensors are each on their own SPI bus, which operate almost simultaneously. At the end of the SPI transaction, an interrupt is generated, where it wakes the main sensor task with a semaphore, i.e.
void SensorN_SPI_Interrupt(void)
{
// <snip>
// Check if the transaction is complete
if (m_spi_txIndex >= m_spi_numTransactions)
{
#if (SPI_BUSY_WAIT)
m_spi_ready = 1;
#else
// Flag the main loop
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(m_spi_semaphore, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
#endif
}
else
{
// Stuff more data in the SPI port
}
}
(The ISR is implemented three times, each pointing to unique data structures, and have their own interrupt vector and priority).
The sensor loop waits on the sensor as follows:
void SensorN_SPI_TransactionSequence_Wait(void)
{
#if (SPI_BUSY_WAIT)
while (!m_spi_ready)
{
}
#else
const TickType_t xMaxExpectedBlockTime = portMAX_DELAY;
xSemaphoreTake(m_spi_semaphore, xMaxExpectedBlockTime);
#endif
}
So far, I have observed the following behavior:
a) If I have exactly one sensor operating, then the system operates indefinately
b) if I have all three sensors running, then it will crash anywhere between 10sec and 3 minutes, with no apparent activity in any thread or interrupt. configASSERT() is defined, but appears not to execute.
c) If I define SPI_BUSY_WAIT which uses a busy wait rather than the semaphore mechanism, then the system operates indefinately.
I suspect therefore it has something to do with yielding when multiple interrupts are pending execution.
I have checked the usual advice with respect to Cortex-M interrupt. The NXP S32K144 implements 4 priority bits. The SPI interrupts each operate at (unshifted) priority 9, although changing the priorites to be 7, 8 and 9 on each sensor makes no difference.
Stack overflow detection is enabled, and there is no evidence of any task getting close to their stack limit.
/* The lowest interrupt priority that can be used in a call to a "set priority"
function. */
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY (0x0F)
/* The highest interrupt priority that can be used by any interrupt service
routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL
INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER
PRIORITY THAN THIS! (higher priorities are lower numeric values. */
#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY (0x05)
/* Interrupt priorities used by the kernel port layer itself. These are generic
to all Cortex-M ports, and do not rely on any particular library functions. */
#ifndef configKERNEL_INTERRUPT_PRIORITY
#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8-configPRIO_BITS))
#endif
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#ifndef configMAX_SYSCALL_INTERRUPT_PRIORITY
#define configMAX_SYSCALL_INTERRUPT_PRIORITY (configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8-configPRIO_BITS))
#endif
I have been following this thread with interest as it appears to also have some problems with task switching behavior:
https://sourceforge.net/p/freertos/discussion/382005/thread/0fd89fda36/
Is there anything you might suggest that I try to help debug what may be happening?
Kind regards,
Damien.