FreeRTOS+TCP and +FAT drivers STM32F4 and STM32F7

Hi All, New FreeRTOS+TCP and +FAT drivers for the STM32F4 and STM32F7. You will find them in the next post because when opening this new topic, I see no attach button 🙁 I used copies of the HAL library and put them as separate copies in the driver directories: ~~~ FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/NetworkInterface.c FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/stm32f7xxhaleth.c FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/stm32f7xxhaleth.h
FreeRTOS-Plus-FAT/portable/STM32F7xx/ff_sddisk.c
FreeRTOS-Plus-FAT/portable/STM32F7xx/stm32f7xx_hal_sd.c
FreeRTOS-Plus-FAT/portable/STM32F7xx/stm32f7xx_hal_sd.h
~~~ The STM32F4 versions: ~~~ FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F4xx/NetworkInterface.c FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F4xx/stm32f4xxhaleth.c FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F4xx/stm32f4xxhaleth.h
FreeRTOS-Plus-FAT/portable/STM32F4xx/ff_sddisk.c
FreeRTOS-Plus-FAT/portable/STM32F4xx/stm32f4xx_hal_sd.c
FreeRTOS-Plus-FAT/portable/STM32F4xx/stm32f4xx_hal_sd.h
~~~ So please include these two “portable” directories into the include search path using -I, earlier that the HAL include directory. The EMAC and the SDMMC peripherals of the F4 and F7 are very similar. I changed identifiers and comments so that the drivers also look very similar. The drivers have been tested by several people, but please test them for your self as well. I tested them my self by using the FTP-server: I copied 500MB on an SD-card, copied these files back to the host, and then compared the files. In my STM32F7 project, caching is enabled. An F7 cache-line has a fixed length of 32 bytes, so try to align all buffers at 32 bytes. For STM32F7 it is profitable to use BufferAllocation_1.c and use vNetworkInterfaceAllocateRAMToBuffers() as defined in :
FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/NetworkInterface.c
The +TCP drivers are optimised for and tested as zero-copy drivers in both directions: ~~~~ #define ipconfigZEROCOPYRXDRIVER 1 #define ipconfigZEROCOPYTXDRIVER 1 ~~~~ Also, all drivers are completely interrupt-driven. Please give us feed-back about your experiences with the drivers, either on this forum or privately. Regards, Hein ( find the attachment here. )

FreeRTOS+TCP and +FAT drivers STM32F4 and STM32F7

Now I do have an Add attachments button so here are the new +TCP and +FAT drivers for both the STM32F4 and STM32F7. Do not hesitate to ask any questions about them. Hein

FreeRTOS+TCP and +FAT drivers STM32F4 and STM32F7

After more testing with ipconfigZERO_COPY_TX_DRIVER = 1, a possible bug became apparent. Please make the following change in FreeRTOS_TCP_IP.c, around line 738 : ~~~ /* For sending, a pseudo network buffer will be used, as explained above. */
 if( pxNetworkBuffer == NULL )
 {
     memset( &xTempBuffer, '', sizeof( xTempBuffer ) );
     pxNetworkBuffer = &xTempBuffer;

     xTempBuffer.pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
     xTempBuffer.xDataLength = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
+ /* A pseudo network buffer can not be released. */ + xReleaseAfterSend = pdFALSE; } ~~~

FreeRTOS+TCP and +FAT drivers STM32F4 and STM32F7

Hi Hein, Thank you for sharing your driver for the STM32F7. I am trying to get FreeRTOS +TCP running on the STM32F769I-DISCO board, however a hard fault is raised after the code runs for a few seconds. I’m not really sure what the root of the problem is… That said, I would like to understand the sections attribute that you add within the NetworkInterface.c file (sorry if this is a basic question). You have a comment saying: /* Put the DMA descriptors in ‘.first_data’. This is important for STM32F7, which has an L1 data cache. The first 64KB of the SRAM is not cached. */ According to my .map file, the DMA descriptors are in >64kB (71,840 bytes): ~~~ .igot.plt 0x0000000000000000 0x0 /usr/bin/../lib/gcc/arm-none-eabi/4.9.3/cortex-m7/fpu/fpv5-sp-d16/crtbegin.o .firstdata 0x00000000200118a0 0xbb00 load address 0x0000000008019fd8 .firstdata 0x00000000200118a0 0xbb00 build/NetworkInterface.o 0x00000000200118a0 DMARxDscrTab 0x0000000020011920 DMATxDscrTab 0x000000002001d3a0 . = ALIGN (0x4) .bss 0x000000002001d3a0 0x54e8 load address 0x0000000008025ad8 ~~~ according to arm-none-eabi-nm -n STM32F769I_DISCOVERY.elf ~~~ 20011890 D _edata 200118a0 D DMARxDscrTab 20011920 D DMATxDscrTab 200119a0 d ucNetworkPackets 2001d3a0 b bss_start ~~~ Does this look legit? Presumably there are no changes required to the linker file? By the way, I have the following defines enabled in the FreeRTOSIPconfig.h file: ~~~

define ipconfigZEROCOPYRX_DRIVER ( 1 )

define ipconfigZEROCOPYTX_DRIVER ( 1 )

~~~ Best regards, Nick

FreeRTOS+TCP and +FAT drivers STM32F4 and STM32F7

-> I am trying to get FreeRTOS +TCP running on the STM32F769I-DISCO board Great, then we’re using the same board and this should be solvable.
You have a comment saying:
~~~ /* Put the DMA descriptors in ‘.first_data’. This is important for STM32F7, which has an L1 data cache. The first 64KB of the SRAM is not cached. */ ~~~ Sorry, my bad. I did not explain everything that I had done. I created a new data section that comes before the normal .data and .bss section’s. You can do that in your STM32F746xxx.ld linker script : ~~~ /* Initialized data sections goes into RAM, load LMA copy after code / .data : { . = ALIGN(4); _sdata = .; / create a global symbol at data start / *(.first_data) / .first_data sections */ *(.data) /* .data sections */ *(.data*) /* .data* sections */
. = ALIGN(4);
_edata = .;        /* define a global symbol at data end */
} >RAM AT> FLASH ~~~ When you recompile the project, you will see that the DMA-related buffers placed within the first 64KB data block: ~~~ 20000000 D _sdata 20000000 d pucDMABuffer 20000200 D DMATxDscrTab 20000280 D DMARxDscrTab 20000380 d ucNetworkPackets ~~~ The driver is indeed supposed to be comfigured as a true zero-copy driver: ~~~

define ipconfigZEROCOPYRX_DRIVER ( 1 )

define ipconfigZEROCOPYTX_DRIVER ( 1 )

~~~ Please have a try and let us here.

FreeRTOS+TCP and +FAT drivers STM32F4 and STM32F7

Hi Hein, Thanks for the very quick and informative reply! I have made the changes to the Linker script, however, I unfortunetly still have the same problem. I will need to spend some more time investigating why the code is crashing. I’ve uploaded the project to Github, in case you’re interested. https://github.com/0x4e/STM32F7/tree/master/Projects/FreeRTOS90BlinkySystemViewPlusTCP To build the code using the makefile, you’ll also need to place a number of other directories containing FreeRTOS90, FreeRTOS-Plus (which contains your driver) and SystemView (to debug using JLink). The source for this can be found under: https://github.com/0x4e/FreeRTOS Thanks again for your help. I’m really hoping its a silly mistake :). Best regards, Nick

FreeRTOS+TCP and +FAT drivers STM32F4 and STM32F7

Nick, I compiled your Makefile project successfully, but I must admit that I have never worked with SEGGER yet. I tried to debug the project using openocd.exe but it doesn’t get far, it doesn’t even reach the reset handler: ~~~ ResetHandler:
ldr sp, =
estack /* set stack pointer */ ~~~ What I miss in your Makefile is creating a total listing ( LSS ), which you can make as follows: ~~~ OBJDUMP = arm-none-eabi-objdump $(BUILDDIR)/%.lss: $(BUILDDIR)/%.elf | $(BUILD_DIR) $(OBJDUMP) -S $< > $@ ~~~ The LSS file is useful to understand a HardFault: you can lookup any address. But it won’t help avoiding the crash. … It turns out that the linker flags weren’t correct for me: a non-thumb ( =ARM ) version of __libc_init_array was linked used, causing a crash. See e.g. here Also I needed a different .LD file for my board: ~~~ #LDSCRIPT = STM32F769NIHxFLASH.ld # yours LDSCRIPT = STM32F746NGHxFLASH.ld # mine ~~~ Also I have to use a different version of port.c : ~~~ #portable/GCC/ARMCM4F/port.c # yours portable/GCC/ARMCM7/r0p1/port.c # mine ~~~ I always advice to start testing a TCP application without DHCP: ~~~ #define ipconfigUSE_DHCP 0 ~~~ So at least you know which device to ping. Would you mind to remove ( or rename ) two files from the HAL driver directories? ~~~ Drivers/STM32F7xxHALDriver/src/stm32f7xxhaleth.c Drivers/STM32F7xxHALDriver/inc/stm32f7xxhaleth.h ~~~ Otherwise there will be confusion. I always use the following utility files: ~~~ ../../FreeRTOS-Plus/Demo/Common/Utilities/printf-stdarg.c Src/memcpy.c ~~~ You will find them in the /labs release I never really liked these ( HAL ) functions: ~~~ void SysTickHandler(void) { HALIncTick(); if(xTaskGetSchedulerState() != taskSCHEDULERNOTSTARTED) { xPortSysTickHandler(); } } __weak void HAL_IncTick(void) { uwTick++; } /* And also */ void vApplicationTickHook( void ) { /* Call the ST HAL tick function. */ HAL_IncTick(); } /* And also */ void HALTIMPeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim->Instance == TIM13) { HAL_IncTick(); } } ~~~ In my opinion, SysTick_Handler() is part of the OS and should not be overridden. The function HAL_IncTick() will only increment a counter. Why not use the FreeRTOS tick-count? Or some other timer, like e.eg this: ~~~ #include “hrgettime.h” uint32t HALGetTick(void) { uint64t ullResult = ullGetHighResolutionTime(); /* convert uS to ms. */ return ( uint32_t ) ( ullResult / 1000ull ); } ~~~ What I can see is that my STM32F7 does not crash any more, and I can ping the device. But I still haven’t tested everything. Hope this helps for now, Hein

FreeRTOS+TCP and +FAT drivers STM32F4 and STM32F7

Hi Hein, Thanks once again for your help. The program now runs and I can ping the board! In the end I had to disable the LCD driver in my “BSPConfigTask”… I still do not know the exact cause, however, I have a feeling it is down to the way the HAL interferes with the SYSTICK. Therefore I’ll have a look at cleaning this up based on your recomendations. Thanks also for the tip on creating the total listing. I have added the commands you have to my Makefile (very useful).
What I miss in your Makefile is creating a total listing ( LSS ), which you can make as follows: OBJDUMP = arm-none-eabi-objdump $(BUILDDIR)/%.lss: $(BUILDDIR)/%.elf | $(BUILD_DIR) $(OBJDUMP) -S $< > $@ The LSS file is useful to understand a HardFault: you can lookup any address. But it won’t help avoiding the crash.
Hopefully I will have time tomorrow evening to clean everything up and post the complete code via GitHub + some SystemView captures for anyone interested. 🙂 Best regards, Nick

FreeRTOS+TCP and +FAT drivers STM32F4 and STM32F7

In the end I had to disable the LCD driver in my “BSPConfigTask”…
I forgot to tell it, but I also disabled the LCD task. PS. Some other tip for a Makefile : ~~~ GCCBIN ?= C:/Ac6.v1.8/SystemWorkbench/plugins/fr.ac6.mcu.externaltools.arm-none.win321.7.0.201602121829/tools/compiler/bin GCC_PREFIX ?= arm-none-eabi
CC = $(GCC_BIN)/$(GCC_PREFIX)-gcc
AS = $(GCC_BIN)/$(GCC_PREFIX)-as
CP = $(GCC_BIN)/$(GCC_PREFIX)-objcopy
AR = $(GCC_BIN)/$(GCC_PREFIX)-ar
SZ = $(GCC_BIN)/$(GCC_PREFIX)-size
OBJDUMP = $(GCC_BIN)/$(GCC_PREFIX)-objdump
~~~ The above helps me to remember which compiler I used for which project. Sometimes changing compilers will cause regression: a project that used to work wonderfully all of a sudden has a lack of RAM, or it just crashes. Now at least I can see that Ac6.v1.8 still worked well. Beside your gcc options, I often include -fno-builtin. Sometimes a memcpy() or memset() are being replaced by inline code, which may cause a crash because of a bad alignment. When the compiler sees memcpy( &b, &a, 4), it may be tempted to replace this with a single 4-byte move, assuming that both a and b are well aligned. If you’re interested in testing performance, here is an iperf3 server , along with some explanation. Thanks for testing, and please let me hear how things are going. Regards.

FreeRTOS+TCP and +FAT drivers STM32F4 and STM32F7

Hi Hein, I’ve updated the projects on git-hub with your suggestions. Unfortunately I’ve not had a chance to delve into the issue with the LCD and also to test the performance using the iperf3 server. Hopefully, I’ll gain some time over the next week. Thanks again for the help and insight! Nick