Using LwIP on the STM32H7

Robin Müller robin.mueller.m at gmail.com
Fri Jan 29 16:47:02 UTC 2021


Alright, I figured out the issue, that was an application level problem,
the UDP frames are received and sent without issues as far as I can see.
I think I might submit a patch soon with some of initial improvements. But
I will summarize the changes I had to do here for now in case other people
want to
use lwIP, based on the example application provided by STM.

*BSP Changes:*

*Inside bsps/arm/stm32h7/start/bspstart.c:*

I changed the HAL_GetTick() function, which returned 0 previously to return
the tick count by default:

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

I'm not sure whether there was a specific reason to have it return 0 by
default, but that led to some issues because this function is generally
called by the
HAL or by example applications and it's a lot of hassle to replace every
call with  rtems_clock_get_ticks_since_boot()

*bsps/arm/shared/start/linkcmds.base:*

I added following section to the linker file.
This is a really ugly solution because this file is used by all ARM bsps. I
might look into how to make it stm32h7 specific, but it worked for me now
because
I only have the STM32H7

    /* Ugly solution for now */
    .lwip_sec (NOLOAD) : ALIGN_WITH_INPUT {
        . = ABSOLUTE(0x30040000);
        *(.RxDecripSection)
        . = ABSOLUTE(0x30040060);
        *(.TxDecripSection)
        . = ABSOLUTE(0x30040200);
       *(.RxArraySection)
    } >SRAM_3 AT> REGION_TEXT_LOAD



*bsps/arm/stm32h7/hal/stm32h7xx_hal_eth.c:*
On line 364 in *HAL_ETH_Init*, comment out the preprocessor guards to set
the DSL to 64bit. I don't know what this line exactly does yet, but it was
necessary
to get lwIP to work properly.

#ifndef __rtems__
   /* SET DSL to 64 bit */
   MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT);
#endif /* __rtems__ */

On line 2648 in *ETH_DMATxDescListInit *comment the preprocessor guard so
that the function is executed. This is necessary
so the DMA descriptors are set up properly.

Do the same for *ETH_DMARxDescListInit* starting at line 2687.

I think that was all. Hope it helps some people

Kind Regards
Robin Müller



On Fri, 29 Jan 2021 at 15:45, Robin Müller <robin.mueller.m at gmail.com>
wrote:

> I think I might have found one issue. In the
> HAL_ETH_Init(ETH_HandleTypeDef *heth) function
>
> The following piece of code was excluded:
>
> #ifndef __rtems__
>   /* SET DSL to 64 bit */
>   MODIFY_REG(heth->Instance->DMACCR, ETH_DMACCR_DSL, ETH_DMACCR_DSL_64BIT);
> #endif /* __rtems__ */
>
> I reintroduced the line and now I have been able to receive UDP frames and
> send some back. I am still missing some frames, but at least it's working
> now.
> I might look into how to put the lwIP section in a separate linkcmd file
> once I have figured out why some frames are missing, but the way I see it,
> it is driver specific (STM used SDRAM3 for the required lwIP memory. One
> way would be to add an option in the config.ini like STM32H7_USE_LWIP and
> then
> load those additional sections for lwIP.
>
> Kind Regards
> Robin
>
> On Fri, 29 Jan 2021 at 14:18, Joel Sherrill <joel at rtems.org> wrote:
>
>>
>>
>> On Fri, Jan 29, 2021, 5:52 AM Robin Müller <robin.mueller.m at gmail.com>
>> wrote:
>>
>>> Hi,
>>>
>>> I am actually configuring the MPU with the following function, which was
>>> taken over from the STM32 example project:
>>>
>>> /*Configure the MPU attributes */
>>> void MPU_Config(void)
>>> {
>>>     MPU_Region_InitTypeDef MPU_InitStruct;
>>>
>>>     /* Disable the MPU */
>>>     HAL_MPU_Disable();
>>>
>>>     /* Configure the MPU attributes as Device not cacheable
>>>      for ETH DMA descriptors */
>>>     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
>>>     MPU_InitStruct.BaseAddress = 0x30040000;
>>>     MPU_InitStruct.Size = MPU_REGION_SIZE_256B;
>>>     MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
>>>     MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE;
>>>     MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
>>>     MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
>>>     MPU_InitStruct.Number = MPU_REGION_NUMBER0;
>>>     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
>>>     MPU_InitStruct.SubRegionDisable = 0x00;
>>>     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
>>>
>>>     HAL_MPU_ConfigRegion(&MPU_InitStruct);
>>>
>>>     /* Configure the MPU attributes as Cacheable write through
>>>      for LwIP RAM heap which contains the Tx buffers */
>>>     MPU_InitStruct.Enable = MPU_REGION_ENABLE;
>>>     MPU_InitStruct.BaseAddress = 0x30044000;
>>>     MPU_InitStruct.Size = MPU_REGION_SIZE_16KB;
>>>     MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
>>>     MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
>>>     MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE;
>>>     MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
>>>     MPU_InitStruct.Number = MPU_REGION_NUMBER1;
>>>     MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
>>>     MPU_InitStruct.SubRegionDisable = 0x00;
>>>     MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE;
>>>
>>>     HAL_MPU_ConfigRegion(&MPU_InitStruct);
>>>
>>>     /* Enable the MPU */
>>>     HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
>>> }
>>>
>>> If I read the function correctly, it configures the descriptor areas as
>>> non-cacheable and the LwIP heap region
>>> as non bufferable. I call this in hardware_init, which is the first
>>> function called in my Init funnction
>>>
>>> void hardware_init() {
>>>     BSP_LED_Init(LED1);
>>>     BSP_LED_Init(LED2);
>>>     BSP_LED_Init(LED3);
>>>
>>>     MPU_Config();
>>>
>>>     /* Initialize the LwIP stack */
>>>     lwip_init();
>>>
>>>     /* Configure the Network interface */
>>>     Netif_Config();
>>>
>>> }
>>>
>>> I checked everything again and basically the setup appears to be
>>> identical to the example now.. I'm confused that it's not working.
>>> I also supplied the following interrupt function in my C code:
>>>
>>> /**
>>>   * @brief  This function handles Ethernet interrupt request.
>>>   * @param  None
>>>   * @retval None
>>>   */
>>> void ETH_IRQHandler(void)
>>> {
>>>   HAL_ETH_IRQHandler(&EthHandle);
>>> }
>>>
>>> But it appears not to be called..
>>>
>>
>> Is the irq being registered via the RTEMS interrupt APIs? If not and you
>> are getting an interrupt, I'd wonder why you aren't seeing a spurious
>> interrupt flagged.
>>
>> It shouldn't be installed directly at the hardware level.
>>
>> --joel
>>
>>
>>> Kind Regards
>>> Robin
>>>
>>> On Fri, 29 Jan 2021 at 12:03, Sebastian Huber <
>>> sebastian.huber at embedded-brains.de> wrote:
>>>
>>>> On 29/01/2021 12:01, Robin Müller wrote:
>>>>
>>>> > The HAL_ETH_Transmit call just times out. If I set the timeout to 20
>>>> > to HAL_MAX_DELAY, the function will just block indefinitely.
>>>> > Does anyone have an idea why this might happen?
>>>> I would check the memory settings in the MPU for this area. You
>>>> probably
>>>> need some sort of device memory (uncached).
>>>>
>>>> --
>>>> embedded brains GmbH
>>>> Herr Sebastian HUBER
>>>> Dornierstr. 4
>>>> 82178 Puchheim
>>>> Germany
>>>> email: sebastian.huber at embedded-brains.de
>>>> phone: +49-89-18 94 741 - 16
>>>> fax:   +49-89-18 94 741 - 08
>>>>
>>>> Registergericht: Amtsgericht München
>>>> Registernummer: HRB 157899
>>>> Vertretungsberechtigte Geschäftsführer: Peter Rasmussen, Thomas Dörfler
>>>> Unsere Datenschutzerklärung finden Sie hier:
>>>> https://embedded-brains.de/datenschutzerklaerung/
>>>>
>>>> _______________________________________________
>>> users mailing list
>>> users at rtems.org
>>> http://lists.rtems.org/mailman/listinfo/users
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20210129/0d7915fc/attachment.html>


More information about the users mailing list