Skip to main content
GreenGuy
Senior III
April 4, 2024
Solved

AZRTOS and FTP support

  • April 4, 2024
  • 6 replies
  • 7021 views

STM32CubeIDE

Version: 1.14.1

STM32CubeMX - STM32 Device Configuration Tool

Version: 6.10.0-RC9

Build: 20231120-2037 (UTC)

OS: Linux (Mint 21)

I am trying to add support for FTP support using CubeIDE.  In the Software Packs Component Selector, under Network NetXDuo> NetXDuo> there are several Addons that can be applied.  One that I am currently using is Addons Web Server and that is working.  However, I do not see a selection for FTP.  I do find in the software packs repo for STM32H7 (version 3.2.0), in the Middlewares/ST/netxduo/addons folder another folder called ftp.  This folder contains the nxd_ftp_server.c and nxd_ftp_server.h files I need to support ftp service.  If I add those files to my project, in the same place the web addons are kept, when I regen the project the files I added are taken away.  It seems like there should be several more options available in the Software Packs selection so CubeMx knows to add them or at least not take them away. 

 

I guess for now, if have to put them in a safer location.  A little annoying.  

    Best answer by GreenGuy

    Copy the files in Middlewares...addons/ftp to a location that cubemx does not update.  Two solutions.  1) add folder to project root and put the files there, or 2) in my case I added them to the common Src and Inc folders.  That way i dont have update the project includes and source paths.  Then create the ftp instance.

    6 replies

    Intector
    Senior
    April 11, 2024

    Hey GreenGuy,

    I've the same issue. The files can be found in the X-CUBE-AZRTOS-F7 v1.1.0, at file location "x-cube-azrtos-f7\Middlewares\ST\netxduo\addons\ftp". I did the same as you and imported the "ftp" directory into my project, but as soon as I regenerate in X-Cube it'll remove everything. I don't know how many hours I spend unsuccessfully searching the internet for a solution. It's almost like nobody ever tried to run an FTP server on an STM32.

    However, I kind of gave up on this issue and started thinking on switching to a different solution by using a different MCU. My actual candidates are ESP32, nRF52840, and maybe something from NXP.

     

    Let me know if you ever find a solution for this issue.

    GreenGuy
    GreenGuyAuthorBest answer
    Senior III
    April 11, 2024

    Copy the files in Middlewares...addons/ftp to a location that cubemx does not update.  Two solutions.  1) add folder to project root and put the files there, or 2) in my case I added them to the common Src and Inc folders.  That way i dont have update the project includes and source paths.  Then create the ftp instance.

    Intector
    Senior
    April 12, 2024

    Good idea, I'm going to try this.

    Pavel A.
    Super User
    April 11, 2024

     It's almost like nobody ever tried to run an FTP server on an STM32.

    Indeed why could anyone want a ftp server on STM32? As there were no decent Linux boxes and Raspberry Pi's?

     

    GreenGuy
    GreenGuyAuthor
    Senior III
    April 11, 2024

    Simple method to update files on the SD card and grab log files off of the sd.

    Pavel A.
    Super User
    April 29, 2024

    STM32 freezing up - where? have you tried to debug and find where it is?  does it spin on some while (1) ?

     

    Intector
    Senior
    April 30, 2024

    Hey Pavel,

    I've tried to debug it, but I always lose my breakpoint somewhere and it's very random. It almost seems to be a memory issue, but I checked the memory too and it looks very good.

    It's hard to believe that nobody ever made an application using the FTP-Server on a STM32H7.

    I'm going to setup a "demo" version and post it here just to see if anybody can pinpoint it down.

    GreenGuy
    GreenGuyAuthor
    Senior III
    April 30, 2024

    One of the symptoms of not having sufficient memory available for NetX is that it simply stops working without somehow getting the message out that it ran our of resources.  This can be very difficult to determine in some cases which I have seen.  Sorry I don't have a magic bullet for you.  I can say that in CubeMX, after selecting system view and selecting the X-Cube-AZRTOS button under Additional Software and ten selecting the AzureRTOS Application tab in the Configuration window, the top items is Memory configuration and in there you can statically allocate how much memory each component will use.  I have 1024 * 150 for the NetXDuo memory pool size.  The suggested size was 120K when using the WebServer module.  The FTP thread, in my code, is using the NetX byte pool., so I increased the pool to 150K.  Yes it is a lot.  But my design has SDRAM and I am using some of it for the NetX byte pool so for me it is a small portion of the SDRAM.

     

    Intector
    Senior
    May 4, 2024

    I finally found the problem and got everything working. The problem is that I connected the SD-Card to SDMMC1 which is in the D1 Domain. I had the AZRTOS system as static allocation and placed it in the address range of the D2 Domain. The SD driver cannot access anything in the D1 Domain under these conditions.  

    Intector_0-1714796274323.png

    To solve the problem, I simply moved everything belonging to the AZRTOS to the D1 Domain.

    This is my new memory assignment in the linker script:

    MEMORY
    {
     ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
     FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 2048K
     DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
    
     ETH_DMA (xrw) : ORIGIN = 0x24000000, LENGTH = 1K
     AZRTOS (xrw) : ORIGIN = 0x24000400, LENGTH = 236K
     RAM_D1 (xrw) : ORIGIN = 0x2403B400, LENGTH = 275K
    
     /* RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 512K */
     RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 288K
     RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 64K
    }
    ...
    ...
    ...
     /* ########################################################### */
     /* definitions for tcp Rx and Tx -DescripSection */
     /* ########################################################### */
     .tcp_sec 0x24000000 (NOLOAD) : {
    
     /* ETH DMA Descriptor Rx - 512 Bytes */
     . = ABSOLUTE(0x24000000);
     *(.RxDescripSection)
    
     /* ETH DMA Descriptor Tx - 512 Bytes */
     . = ABSOLUTE(0x24000200);
     *(.TxDescripSection)
     } >ETH_DMA
    
     /* ########################################################### */
     /* definitions for AZURE RTOS - ThreadX, FileX, NetXDuo */
     /* ########################################################### */
    
     .azrtos_sec 0x24000400 (NOLOAD):
     {
     /* .TxPoolSection section - 10240 Bytes */
     . = ABSOLUTE(0x24000400);
     *(.TxPoolSection)
    
     /* .FxPoolSection section - 10240 Bytes */
     . = ABSOLUTE(0x24002C00);
     *(.FxPoolSection)
    
     /* .NxPoolSection section - 204800 Bytes */
     . = ABSOLUTE(0x24005400);
     *(.NxPoolSection)
    
     /* HTTP-Server pool section - 8192 Bytes */
     . = ABSOLUTE(0x24037400);
     *(.Nx_HTTP_ServerPoolSection)
    
     /* FTP-Server pool section - 8192 Bytes */
     . = ABSOLUTE(0x24039400);
     *(.Nx_FTP_ServerPoolSection)
    
     } >AZRTOS

     

    Here are the adjustments for the MPU settings in the "main.c":

    #pragma region ***** MPU configuration *****
    void MPU_Config(void)
    {
    	MPU_Region_InitTypeDef MPU_InitStruct = { 0 };
    
    	/* Disables the MPU */
    	HAL_MPU_Disable();
    
    	/* Initializes and configures the Region and the memory to be protected */
    	/* default settings for the complete memory address range */
    	MPU_InitStruct.Enable = MPU_REGION_ENABLE;
    	MPU_InitStruct.Number = MPU_REGION_NUMBER0;
    	MPU_InitStruct.BaseAddress = 0x0;
    	MPU_InitStruct.Size = MPU_REGION_SIZE_4GB;
    	MPU_InitStruct.SubRegionDisable = 0x87;
    	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    	MPU_InitStruct.AccessPermission = MPU_REGION_NO_ACCESS;
    	MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
    	MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
    	MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
    	MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
    
    	HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    	/** Initializes and configures the Region and the memory to be protected
    	*/
    	MPU_InitStruct.Number = MPU_REGION_NUMBER1;
    	MPU_InitStruct.BaseAddress = 0x24000000;
    	MPU_InitStruct.Size = MPU_REGION_SIZE_512KB;
    	MPU_InitStruct.SubRegionDisable = 0x0;
    	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
    	MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
    
    	HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    	/** Initializes and configures the Region and the memory to be protected
    	*/
    	MPU_InitStruct.Number = MPU_REGION_NUMBER2;
    	MPU_InitStruct.Size = MPU_REGION_SIZE_1KB;
    	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0;
    	MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
    
    	HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    	/** Initializes and configures the Region and the memory to be protected
    	*/
    	MPU_InitStruct.Number = MPU_REGION_NUMBER3;
    	MPU_InitStruct.BaseAddress = 0x30000000;
    	MPU_InitStruct.Size = MPU_REGION_SIZE_128KB;
    	MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
    	MPU_InitStruct.IsShareable = MPU_ACCESS_SHAREABLE;
    
    	HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    	/** Initializes and configures the Region and the memory to be protected
    	*/
    	MPU_InitStruct.Number = MPU_REGION_NUMBER4;
    	MPU_InitStruct.BaseAddress = 0x30002000;
    
    	HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    	/** Initializes and configures the Region and the memory to be protected
    	*/
    	MPU_InitStruct.Number = MPU_REGION_NUMBER5;
    	MPU_InitStruct.BaseAddress = 0x30004000;
    	MPU_InitStruct.Size = MPU_REGION_SIZE_32KB;
    
    	HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    	/** Initializes and configures the Region and the memory to be protected
    	*/
    	MPU_InitStruct.Number = MPU_REGION_NUMBER6;
    	MPU_InitStruct.BaseAddress = 0x38000000;
    	MPU_InitStruct.Size = MPU_REGION_SIZE_64KB;
    
    	HAL_MPU_ConfigRegion(&MPU_InitStruct);
    
    	/* Enables the MPU */
    	HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
    
    }
    #pragma endregion

     

    Also, I placed a public repo on GitHub which a complete functional example for the STM32H7 with AZRTOS, HTTP-Server with content from SD-Card, and FTP-Server to update the SD-Card content. I tested FileZilla in passive mode with binary file transfer which works great.

    GitHub repo for STM32H7-AZRTOS example 

    The memory has to be optimized because I used it very generous.

    mbarg.1
    Senior III
    March 12, 2025

    upgrade to ver 3.3  - NetXDuo ver 6.4 and you have FTP - no demo or detailled instructions on how to use it - server and client but not both

    Intector
    Senior
    March 14, 2025

    Thanks for the info. I've had it running for quite some time now. I made a GitHub repo for whoever is interested:

    intector/Test-XSPI: Working example for the use of XSPI on STM32H7R3L8H6H

    It's like a starter project; I thought it'd save others time and frustration. 

     


    Great fleas have little fleas upon their backs to bite 'em,
    And little fleas have lesser fleas, and so ad infinitum.
    And the great fleas themselves, in turn, have greater fleas to go on;
    While these again have greater still, and greater still, and so on.

                                                                         Augustus De Morgan