Hello,
I’m using CMSIS_v2 FreeRTOS on STM32F303. I’ve retargeted I/O to use queue.
int stdout_putchar(int ch)
{
char item = (char)ch;
osMessageQueuePut(tx_queue, &item, 0U, 0U);
return ch;
}
int stdin_getchar(void)
{
uint16_t msg;
osStatus_t status;
status = osMessageQueueGet(rx_queue, &msg, NULL, osWaitForever);
if (status == osOK)
return((int)msg);
else
return ((int)NULL);
}
This with help of scanf() & printf() i/o data through RS485 and terminal on PC. However, when trying to use printf or scanf program goes into HardFault.
UART is configured to receive through ISR
void UART4_IRQHandler(void)
{
static uint16_t rx_byte = 0x00;
if (USART_GetITStatus(UART4, USART_IT_RXNE) == SET )
{
rx_byte = USART_ReceiveData(UART4);
if (USART_GetFlagStatus(UART4, USART_FLAG_ORE) == SET)
USART_ClearITPendingBit(UART4, USART_IT_ORE);
}
if (rx_byte != NULL)
osMessageQueuePut(rx_queue, &rx_byte, NULL, NULL);
}
And output though low priority thread
void vTransmitUART4(void *argument)
{
uint8_t UART4_data;
for(;;)
{
if (osMessageQueueGetCount(tx_queue) == 0)
GPIO_ResetBits(GPIOA, GPIO_Pin_12); // Recieve State
osStatus_t status = osMessageQueueGet(tx_queue, &UART4_data, 0, osWaitForever);
if (status == osOK)
{
GPIO_SetBits(GPIOA, GPIO_Pin_12); // Output state
while(USART_GetFlagStatus(UART4, USART_FLAG_TC) == RESET);
USART_SendData(UART4, (uint16_t)UART4_data);
}
}
}
How to properly deal with this issue? This is critical to my application.
It is hard to provide direct support for third party APIs on top of FreeRTOS, as I would have to go and look up how to use the functions myself. Grateful if you could try using our native API (xQueueSend(), xQueueReceive(), etc.), and if you still have an issue post the code here as you have done above with the CMSIS API.
Have you followed the normal set of troubleshooting tips, such as ensuring configASSERT() is defined, you have stack overflow checking on, you are using an up-to-date version of FreeRTOS to ensure you have the maximum number of assert points in the code to help you debug configuration problems, you have followed the instructions to ensure interrupts that use API calls have a setting below configMAX_SYSCALL_INTERRUPT_PRIORITY, on and STM32 you also need to ensure all interrupt priority bits are set to preemption priority, etc. (many of these errors would be caught by asserts if you use up to date FreeRTOS versions).
Yes, I’ve looked over printf(0 from glibc and it calls malloc. I’ve decided to shift away from using queues and rewritten stdin/stdout func to use LL USART commands.
Yes, it checks if app is currently in IRQ and calls SendFromISR API. I’ve checked and ifunctions are IRQ safe. I’ve looked over troubleshooting tips and everything as it should be although configAssert() is a must to add. Can you point me in the direction of CMSIS RTOS support forums if it’s not ot much to ask?
I would say that the big disadvantage of this approach is that your output is now blocking, and calls to printf will take as long as it takes to send the results.