cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F4 HAL_UART_Transmit() Unexpected Behavior Debugging Help

Liferafter
Associate III

So I have a abstracted function to read the INA226 component. The function reads the data completely fine over I2C. The problem occurs when I try to display the read data on my dev terminal (Terra Term) over the COM port for STM32.

 

The output on the TerraTerm Terminal shows, the INA260 data with a hallucinated sentence. Something that should not be printed or should not be possible to print with the existing logic in the code.

I am also calling the INA226Read() directly from main() without any other function calls before it.

Example Output:

 

 

0.00500
INA226 not present
INA226 b4.96600
INA226 not present
INA226 b0.03000
INA226 not present
INA226 b

 

 

The phrase "INA226 not present" should not print with the logic in my code.

The function that is executing:

 

 

void INA226Read()
{
    INA226_Init();
    COM_Init();

    uint8_t exit_counter = 0;
    uint16_t data;
    char tes[32];

    float current;
    float power;
    float bus_voltage;

    // Initialize the buffer with 0
    memset(tes, 0, sizeof(tes));

    if (INA226_present() != HAL_OK)
    {
        COM_printf("INA226 not present\n");
        return;
    }

    for (;;)
    {
        HAL_StatusTypeDef status = readCurrent(&data);
        current = (float)data / 1000;

        HAL_StatusTypeDef status2 = readBusVoltage(&data);
        bus_voltage = (float)data / 1000;

        HAL_StatusTypeDef status3 = readPower(&data);
        power = (float)data / 1000;

        if (status != HAL_OK || status2 != HAL_OK || status3 != HAL_OK)
        {

            if (status == HAL_BUSY)
            {
                COM_printf("INA226 busy");
                continue;
            }
            COM_printf("Error reading INA226 \n");

            exit_counter++;
            if (exit_counter == 5)
            {
                COM_printf("INA226 not responding, exiting\n");
                break;
            }

            vTaskDelay(1000);

            continue;
        }

        float_to_char(current, tes);
        COM_printf_chararray(tes, 32);
        COM_printf("\n");

        memset(tes, 0, sizeof(tes));

        float_to_char(bus_voltage, tes);
        COM_printf_chararray(tes, 32);
        COM_printf("\n");

        memset(tes, 0, sizeof(tes));

        float_to_char(power, tes);
        COM_printf_chararray(tes, 32);
        COM_printf("\n");

        break;
    }

 

 

The functions for float_to_char() work as intended, so I will leave that out to not bloat this question. However I will add the functions Com_printf() and Com_printf_chararray().

Com_printf_chararray:

 

 

void COM_printf_chararray(char *str, uint16_t size)
{
    if (HAL_UART_Transmit(&uart_handle, (uint8_t *)str, size, HAL_MAX_DELAY) != HAL_OK)
    {
        Error_Handler();
    }
}

 

 

Com_printf:

 

 

void COM_printf(char *str)
{
    if (HAL_UART_Transmit(&uart_handle, (uint8_t *)str, 32, HAL_MAX_DELAY) != HAL_OK)
    {
        Error_Handler();
    }
}

 

 

Also when debugging the code, I get a HardFault error after the break at the end of the INA226Read() function

Call Stack:

 

 

HardFault_Handler@0x08000c0e (c:\Zaid\Fun_Projects_Code\CASE\Core\Src\stm32f4xx_it.c:90)
<signal handler called>@0xffffffe9 (Unknown Source:0)
HAL_UART_Transmit@0x08002902 (c:\Zaid\Fun_Projects_Code\CASE\Drivers\STM32F4xx_HAL_Driver\Src\stm32f4xx_hal_uart.c:1207)
??@0x00000000 (Unknown Source:0)

 

 

For full context, you can checkout the github for this project: Github 
Question I have: Is there some type of config I am missing in my code, or is this a bug in the HAL?

9 REPLIES 9
Pavel A.
Evangelist III

hallucinated sentence. Something that should not be printed or should not be possible to print with the existing logic in the code.

Hmm? Print "INA226 not present" is in your code, line 19.

I am also calling the INA226Read() directly from main() without any other function calls before it.

How about initializing the clocks, GPIOs? There's a lot of code that you don't show. And you're using FreeRTOS? Other tasks run in parallel?

In your COM_printf function the size to send is weird. Why 32?

 

 

By the logic in my code it should not print when the execution is able to reach line 56, since the code exits soon after with the break. It should have printed on line 19, but it prints for some reason on line 58 and onward.

On the second point, I should have clarified, all the config calls are still being made. But its only two calls, one initializes the clock, the other initializes the HAL.

  HAL_Init();
  SystemClock_Config();

After that I call the INA266Read()

For my context FreeRTOS is completely being ignored, since no other tasks are created and scheduled. I am not utilizing it when reading the INA226. 

COM_printf has size 32 as arbitrary value, since I had some problems with the sizeof() function.

This is just a dev build so I am not going for code quality rn.
 
Edit: The problem might be in the size 32, if I transmit a str less than 32 that might cause the transmission to read into memory and send in any junk that would be present after the string. But I still dont understand how the next thing in memory is a string.
 
PCarn.1
Associate III

The hardfault might be causing a system reset. Perhaps during the first read the INA226 fails. So you're seeing the system fail to read the first try, then succeed on the second try, then hardfault and reset. 

When debugging using the SWD, that doesnt seem to be happening, since all return HAL_OK. Also Call Stack shows the hardfault happens in UART_Transmit

Liferafter
Associate III

The 32 constant size on the UART_Transmission call was definitely the problem for the hallucinogenic sentence outputs. By simply adding a self determining length solution similar to strlen I was able to fix that issue.

The problem with the HardFault still hasnt been identified. It only happens after complete execution of the INA226 function code.

PCarn.1
Associate III

So when you're debugging you don't see "INA226 not present" in the terminal? That makes me think you enabled the watch dog but you're not resetting it. For the hardfault, it might something to do with DMA. Is the mode setting in the USART DMA set to circular?

The INA226 was being read into terminal because of the 32 set size on the UART_Transmission. When I called the UART transmission with a string smaller than 32 characters, it would grab whatever was next in memory. Since I was calling the transmission with only two chars "\n" it would grab another 30 characters, which ended up being the INA226 not present phrase.

There isnt a watchdog enabled neither is the code using USART with DMA, its just the base version of the UART Transmission function.

PCarn.1
Associate III

That's interesting, were you not calling memset before the print? 

The base STM32 config doesn't help much with hard faults but if you follow some of the instructions here you can get more info

https://www.freertos.org/Debugging-Hard-Faults-On-Cortex-M-Microcontrollers.html#:~:text=Debugging%20a%20ARM%20Cortex%2DM%20Hard%20Fault&text=First%2C%20a%20very%20short%20assembly,C%20function%20called%20prvGetRegistersFromStack().

Dont think the CMSIS memset uses the STM32 DMA, but I might be wrong there. Also ty for the webpage, will look into it!!