Undefined library functions

Downloaded FreeRTOS-Plus-TCP software and added it to my FreeRTOS + TCP based project.
After compiling project getting “undefined reference” errors pointing to the following undefined
NetworkInterface.c functions:
HAL_ETH_Init()
HAL_ETH_ConfigMAC()
HAL_ETH_Start()
HAL_ETH_Stop()
Couldn’t find those functions definitions among loaded library functions?

Seems you have a STM32 MCU. Then you probably need the HAL (Hardware Abstraction Layer) provided by ST as well. Unless you have/want your own drivers. In this case you have to add an ethernet/MAC driver needed by the (upper) FreeRTOS+TCP networking stack.

Thanks, it is right, I’m using STM32F407 and will try to use STM32 HAL

The STM32Fx network driver comes with these files:

STM32Fxx\NetworkInterface.c
STM32Fxx\readme.txt
STM32Fxx\stm32f2xx_hal_eth.h
STM32Fxx\stm32f4xx_hal_eth.h
STM32Fxx\stm32f7xx_hal_eth.h
STM32Fxx\stm32fxx_hal_eth.c
STM32Fxx\stm32fxx_hal_eth.h

The source file stm32fxx_hal_eth.c has the definitions of the HAL_ETH_xxx functions that you are looking for.

Please read readme.txt, which explains how to use the driver.

The HAL distribution that you install also has the xx_hal_eth sources files. Please move them away, the versions in the network driver are slightly different.

If it helps, here you find a sample Makefile project for an STM32F4x.

Thanks, Hein,
I was able to use those functions in stm32fxx_hal_eth.c. Now I have another challenge: to find definition for HAL_GetTick() function. I read some comments about this function written by you and other people, but not sure which way to go better? Create my own or there is one, which is good for use?

This subject often causes confusion.

Solution 1:

Make sure that xPortSysTickHandler is defined in FreeRTOSConfig.h:

#define xPortSysTickHandler SysTick_Handler

xPortSysTickHandler () is a function in port.c With this macro, it will get a new name SysTick_Handler(), so it becomes an ISR for the system-tick.

Now provide your own HAL_GetTick(), base on the FreeRTOS clock-tick:

uint32_t HAL_GetTick( void )
{
    return xTaskGetTickCount();
}

Remember that xTaskGetTickCount() only works once the scheduler has started.

Solution 2

Make sure that xPortSysTickHandler is not defined, and provide your own version of SysTick_Handler() which calls xPortSysTickHandler() defined in port.c :

void SysTick_Handler( void )
{
    if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED )
    {
        /* Call the FreeRTOS system-tick handler. */
        xPortSysTickHandler();
    }
    /* Increment the value of 'uwTick'. */
    HAL_IncTick();
}

Make sure that HAL_InitTick() is never called.
Now you can use this implementation of HAL_GetTick():

uint32_t HAL_GetTick( void )
{
    return uwTick;
}

I normally user solution 2.

If you need a high-resolution and very precise time source, the use of a timer interrupt is recommended.

Now it works, thanks.
Another questions about xApplicationGetRandomNumber() and ulApplicationGetNextSequenceNumber() functions.
I’ve read your explanation of :
“Replace the ipconfigRAND32 macro with a function #1494” on git hub and looked at its
implementation in iot_secure_sockets.c
I understand why we are doing this but in the new xApplicationGetRandomNumber() function there are some unknown variables (for example like SemaphoreHandle_t xSessionLock ) and functions (like C_GenerateRandom ) which also are not present in the project?

Since you have a STM32F407 you could use the HW RNG (as I do on the same MCU).
It’s very easy to use and it’s probably also covered by HAL library.
The network stack just requires a good random number generator. No matter how the random number is generated.

Thanks Hartmut, but for now I need only software based solution of random number generator.

You don’t need a lot of code to use the RNG :slight_smile:

    RNG_HandleTypeDef hrng;

    /* Enable the RNG clock. */
    __HAL_RCC_RNG_CLK_ENABLE();
    /* Enabled the RNG. */
    RCC->AHB2ENR |= RCC_AHB2ENR_RNGEN;
    RNG->CR |= RNG_CR_RNGEN;

    /* Set the Instance pointer. */
    hrng.Instance = RNG;
    /* Initialise it. */
    HAL_RNG_Init( &hrng );

If you use the FreeRTOS+TCP library, it is very important to use the hardware generator or a comparable source of randomness.
TCP often uses randomness: to determine the initial sequence numbers, and to select a random port number.
Now if you use rand(), you may end up using the same port number series, and the same predictable sequence numbers.

BaseType_t xApplicationGetRandomNumber( uint32_t *pulValue )
{
    HAL_StatusTypeDef xResult;
    BaseType_t xReturn;
    uint32_t ulValue;

    xResult = HAL_RNG_GenerateRandomNumber( &hrng, &ulValue );
    if( xResult == HAL_OK )
    {
        xReturn = pdPASS;
        *pulValue = ulValue;
    }
    else
    {
        xReturn = pdFAIL;
    }
    return xReturn;
}
1 Like