cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 UART Call back function

Kumar B
Associate II

Hi,

I am using STM32F4 based microcontroller and configured it using STM32Cube IDE and free rtos.

I have my uart driver interrupt for reception with call back function.

HAL_UART_Receive_IT(&huart2, (uint8_t *)&Uart.RxByte, 1);

and call back function HAL_UART_RxCpltCallback

Its working fine.

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

HAL_UART_Receive_IT();

}

I want to transmit the received data back using transmission interrupt using HAL_UART_TxCpltCallback function.

I have transmitted this string using a serial console . The string started with $ and ended with \r\n (0x0D,0X0A).

$GPGGA,181908.00,3404.7041778,N,07044.3966270,

W,4,13,1.00,495.144,M,29.200,M,0.10,0000*40\r\n

But, the problem I faced is, when I transmit this string it is executing in infinite loop.

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)

{

HAL_UART_Transmit_IT();

}

int main(void)

{

//Inialization of clocks, USART, and RTOS threads.

void Default task(void)

{

for(;;)

{

}

}

void SerialTask(void)

{

for(;;)

{

if(Frameisready)

{

//sending one byte of data for triggering uart call back.

HAL_UART_Transmit_IT ();

}

}

}

void Transmit_Task(void)

{

for(;;)

{

HAL_UART_TxCpltCallback(&huart2);

}

}

After I send that $GPGGA,181908.00,3404.7041778,N,07044.3966270,

W,4,13,1.00,495.144,M,29.200,M,0.10,0000*40\r\n

I am getting infinite sentences instead of single one. How to break the HAL_UART_TxCpltCallback(&huart2); function. Kindly help me,

4 REPLIES 4
Bob S
Principal

You don't call HAL_UART_TxCpltCallback() from YOUR code, it gets called only from the HAL UART driver (stm32f4xx_hal_uart.c), and only when the driver thinks it is done sending the last buffer that you gave it in a HAL_UART_Transmit_IT() call. Not enough detail to tell anything else.

Seem to have scrubbed a lot of useful information from your cut-n-paste

As Bob indicates the HAL system needs to call the callback, and does so as a response to you calling into the HAL via your IRQHandler. You should be careful in callbacks as they occur under interrupt context, and might be blocking other things.

You should have only one HAL_UART_Transmit_IT (); pending at a time

You might also want to consider better solutions, where you handle buffering in the IRQHandler rather than involving the HAL, this would be especially true if trying to handle concurrent full-duplex communications.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Can you provide me any better example that works with HAL based UART interrupt both transmission and reception without call back.

Regards,

Kumar

Hi Clive,

I am able to transmit and receive the uart data from the same peripheral (usart2) through serial console using interrupt logic HAL_UART_Transmit_IT ();

HAL_UART_Transmit_IT(&huart2, (uint8_t *)Uart.TxBuffer,strlen((const char*)Uart.TxBuffer));

         while (HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX ||

         HAL_UART_GetState(&huart2) == HAL_UART_STATE_BUSY_TX_RX);

The data sent through serial console is stored in Uart.TxBuffer. But now, this is limited to few bytes. As I said, I am using free rtos application for this execution with context switching of 1 sec for each task.

#define configUSE_PREEMPTION                    1

#define configSUPPORT_STATIC_ALLOCATION         1

#define configSUPPORT_DYNAMIC_ALLOCATION        1

#define configUSE_IDLE_HOOK                     0

#define configUSE_TICK_HOOK                     0

#define configCPU_CLOCK_HZ                      ( SystemCoreClock )

#define configTICK_RATE_HZ                      ((TickType_t)1000)

#define configMAX_PRIORITIES                    ( 56 )

#define configMINIMAL_STACK_SIZE                ((uint16_t)128)

#define configTOTAL_HEAP_SIZE                   ((size_t)15360)

#define configMAX_TASK_NAME_LEN                 ( 16 )

#define configUSE_TRACE_FACILITY                1

#define configUSE_16_BIT_TICKS                  0

#define configUSE_MUTEXES                       1

#define configQUEUE_REGISTRY_SIZE               8

#define configUSE_RECURSIVE_MUTEXES             1

#define configUSE_COUNTING_SEMAPHORES           1

#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0

If I want to send hundred bytes of data through usart, the data is missing. What might be the reason? Is it rtos switching or anything wrong with the usart HAL driver.

 Anything required for rtos stack allocation.

I am using preemptive scheduling.

Please let me know.