Hello,
We use FreeRTOS in our board.
I’ve the Task1 and Task2. Task1’s priority is 2, while Task2’s is 3. There is an external IRQ. When there is data ready on the SPI line, the 3rd party chip will set the PIN to high - the 3rd party chip uses this way to notify the host that the data is ready on SPI.
I have an IRQ_ISR() which will give the semaphore once the interrupt is triggered. Then Task2 will get chance to run. In Task1, after sending the data, normally the PIN will be turned to high by the 3rd party chip immediately. Then the host MCU will need to read the data from SPI. Once the data is read from the 3rd party chip, the PIN will be turned to low by the 3rd party chip.
bool GetPINValue(void)
{
bool result = FALSE;
io_level pin_value = IO_LEVEL_LOW;
if (SUCCESS == PinRead(&gpio, MY_IRQ_PIN, &pin_value))
{
result = (pin_value == IO_LEVEL_HIGH) ? TRUE : FALSE;
}
return result;
}
void IRQ_ISR(callback_args_t *p_args)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
xSemaphoreGiveFromISR(mySemaphore, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void Task1(void)
{
char ch = 0x00;
for (;;)
{
SendDataOverSPI();
printf("Task1 PIN Value: %d\n", GetPINValue());
DelayMS(500);
printf("Task1 PIN Value again: %d\n", GetPINValue());
ReadDataFromSPI(&ch);
printf("Data: 0x%02X\n", ch);
. . .
}
}
void Task2(void)
{
unsigned portBASE_TYPE uxHighWaterMark;
for (;;)
{
xSemaphoreTake(mySemaphore, MAX_DELAY);
printf("Task2 PIN Value: %d\n", GetPINValue());
. . .
}
}
// Printed output:
Task1 PIN Value: 1
Task1 PIN Value again: 1
Task2 PIN Value: 0
Data: 0x30
From the printed output, as you can see:
- Apprantely after the host MCU sending the data, the PIN is set to high. Then Task2 get a chance to run the printf statement.
- Of course, the Task1 PIN value is high because the 3rd party chip will turn it to high once the 3rd party chip receives the data. That’s why we see “Task1 PIN Value: 1”.
- Even if I delay 500ms, the PIN value is still high because the data isn’t read yet. So we see “Task1 PIN Value again: 1”.
- However, the “Task2 PIN value: 0” doesn’t make sense. It should be 1 because the data isn’t read yet.
- As we can see later, the host read the data back. Meaning, the PIN value is still high when reading the data.
The weird thing is, why the Task2 PIN value is 0? Calling PinRead() from different tasks can have different PIN value? Is there a way to fix it?
Thanks!