W tym poście chciałbym opisać konfigurację Ethernetu oraz stosu LWIP wraz z systemem operacyjnym FreeRtos.
Konfiguracja bloków pamięci oraz miejsc na deskryptory ethernetu udostępniona w poprzednim poście, zdaje się działać poprawnie dla wersji bez FreeRtos oraz bibliotek mbedTLS. Natomiast w przypadku ich zastosowania rozmieszczenie tych bloków musi być dużo bardziej przemyślane. Tak aby stos LWIP oraz potrzebne deskryptory miały wystarczającą ilość miejsca w pamięci.
Bardzo dobry opis konfiguracji dla różnych układów STM32H7 stosowanych w płytkach Nucleo i Discovery można znaleźć na githubie pod tym linkiem.
STM32H725 Konfiguracja pamięci:
Pamięć dla buforów RX oraz TX jest umieszcza najczęściej w całości w pamięci D2 RAM. Z takimi rozwiązaniami można się najczęściej spotkać przy przykładowych aplikacjach.
Wygenerowana mapa pamięci przez program CubeMx:
- MEMORY
- {
- ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K
- DTCMRAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K
- FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K
- RAM_D1 (xrw) : ORIGIN = 0x24000000, LENGTH = 320K
- RAM_D2 (xrw) : ORIGIN = 0x30000000, LENGTH = 32K
- RAM_D3 (xrw) : ORIGIN = 0x38000000, LENGTH = 16K
- }
W przypadku tego układu pamięć RAM_D2 jest za mała i należy jeden z buforów przenieść do RAM D1.
Konfiguracja CubeMx:
Konfiguracja CortexM7:
- /* Define to prevent recursive inclusion --------------------------------------*/
- #ifndef __LWIPOPTS__H__
- #define __LWIPOPTS__H__
- #include "main.h"
- /*-----------------------------------------------------------------------------*/
- /* Current version of LwIP supported by CubeMx: 2.1.2 -*/
- /*-----------------------------------------------------------------------------*/
- /* Within 'USER CODE' section, code will be kept by default at each generation */
- /* USER CODE BEGIN 0 */
- /* USER CODE END 0 */
- #ifdef __cplusplus
- extern "C" {
- #endif
- /* STM32CubeMX Specific Parameters (not defined in opt.h) ---------------------*/
- /* Parameters set in STM32CubeMX LwIP Configuration GUI -*/
- /*----- WITH_RTOS enabled (Since FREERTOS is set) -----*/
- #define WITH_RTOS 1
- /* Temporary workaround to avoid conflict on errno defined in STM32CubeIDE and lwip sys_arch.c errno */
- #undef LWIP_PROVIDE_ERRNO
- /*----- CHECKSUM_BY_HARDWARE enabled -----*/
- #define CHECKSUM_BY_HARDWARE 1
- /*-----------------------------------------------------------------------------*/
- /* LwIP Stack Parameters (modified compared to initialization value in opt.h) -*/
- /* Parameters set in STM32CubeMX LwIP Configuration GUI -*/
- /*----- Default value in ETH configuration GUI in CubeMx: 1524 -----*/
- #define ETH_RX_BUFFER_SIZE 1536
- /*----- Value in opt.h for MEM_ALIGNMENT: 1 -----*/
- #define MEM_ALIGNMENT 4
- /*----- Default Value for MEM_SIZE: 1600 ---*/
- #define MEM_SIZE 32232
- /*----- Default Value for H7 devices: 0x30044000 -----*/
- #define LWIP_RAM_HEAP_POINTER 0x30000200
- /*----- Default Value for MEMP_NUM_TCP_SEG: 16 ---*/
- #define MEMP_NUM_TCP_SEG 17
- /*----- Value supported for H7 devices: 1 -----*/
- #define LWIP_SUPPORT_CUSTOM_PBUF 1
- /*----- Value in opt.h for LWIP_ETHERNET: LWIP_ARP || PPPOE_SUPPORT -*/
- #define LWIP_ETHERNET 1
- /*----- Value in opt.h for LWIP_DNS_SECURE: (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) -*/
- #define LWIP_DNS_SECURE 7
- /*----- Default Value for TCP_MSS: 536 ---*/
- #define TCP_MSS 1460
- /*----- Default Value for TCP_SND_BUF: 2920 ---*/
- #define TCP_SND_BUF 5840
- /*----- Default Value for TCP_SNDQUEUELOWAT: 9 ---*/
- #define TCP_SNDQUEUELOWAT 8
- /*----- Value in opt.h for LWIP_NETIF_LINK_CALLBACK: 0 -----*/
- #define LWIP_NETIF_LINK_CALLBACK 1
- /*----- Value in opt.h for TCPIP_THREAD_STACKSIZE: 0 -----*/
- #define TCPIP_THREAD_STACKSIZE 1024
- /*----- Value in opt.h for TCPIP_THREAD_PRIO: 1 -----*/
- #define TCPIP_THREAD_PRIO osPriorityNormal
- /*----- Value in opt.h for TCPIP_MBOX_SIZE: 0 -----*/
- #define TCPIP_MBOX_SIZE 6
- /*----- Value in opt.h for SLIPIF_THREAD_STACKSIZE: 0 -----*/
- #define SLIPIF_THREAD_STACKSIZE 1024
- /*----- Value in opt.h for SLIPIF_THREAD_PRIO: 1 -----*/
- #define SLIPIF_THREAD_PRIO 3
- /*----- Value in opt.h for DEFAULT_THREAD_STACKSIZE: 0 -----*/
- #define DEFAULT_THREAD_STACKSIZE 1024
- /*----- Value in opt.h for DEFAULT_THREAD_PRIO: 1 -----*/
- #define DEFAULT_THREAD_PRIO 3
- /*----- Value in opt.h for DEFAULT_UDP_RECVMBOX_SIZE: 0 -----*/
- #define DEFAULT_UDP_RECVMBOX_SIZE 6
- /*----- Value in opt.h for DEFAULT_TCP_RECVMBOX_SIZE: 0 -----*/
- #define DEFAULT_TCP_RECVMBOX_SIZE 6
- /*----- Value in opt.h for DEFAULT_ACCEPTMBOX_SIZE: 0 -----*/
- #define DEFAULT_ACCEPTMBOX_SIZE 6
- /*----- Value in opt.h for RECV_BUFSIZE_DEFAULT: INT_MAX -----*/
- #define RECV_BUFSIZE_DEFAULT 2000000000
- /*----- Default Value for LWIP_HTTPD: 0 ---*/
- #define LWIP_HTTPD 1
- /*----- Value in opt.h for HTTPD_USE_CUSTOM_FSDATA: 0 -----*/
- #define HTTPD_USE_CUSTOM_FSDATA 1
- /*----- Default Value for LWIP_SNMP: 0 ---*/
- #define LWIP_SNMP 1
- /*----- Value in opt.h for MIB2_STATS: 0 or SNMP_LWIP_MIB2 -----*/
- #define MIB2_STATS 1
- /*----- Value in opt.h for CHECKSUM_GEN_IP: 1 -----*/
- #define CHECKSUM_GEN_IP 0
- /*----- Value in opt.h for CHECKSUM_GEN_UDP: 1 -----*/
- #define CHECKSUM_GEN_UDP 0
- /*----- Value in opt.h for CHECKSUM_GEN_TCP: 1 -----*/
- #define CHECKSUM_GEN_TCP 0
- /*----- Value in opt.h for CHECKSUM_GEN_ICMP6: 1 -----*/
- #define CHECKSUM_GEN_ICMP6 0
- /*----- Value in opt.h for CHECKSUM_CHECK_IP: 1 -----*/
- #define CHECKSUM_CHECK_IP 0
- /*----- Value in opt.h for CHECKSUM_CHECK_UDP: 1 -----*/
- #define CHECKSUM_CHECK_UDP 0
- /*----- Value in opt.h for CHECKSUM_CHECK_TCP: 1 -----*/
- #define CHECKSUM_CHECK_TCP 0
- /*----- Value in opt.h for CHECKSUM_CHECK_ICMP6: 1 -----*/
- #define CHECKSUM_CHECK_ICMP6 0
- /*-----------------------------------------------------------------------------*/
- /* USER CODE BEGIN 1 */
- /* USER CODE END 1 */
- #ifdef __cplusplus
- }
- #endif
- #endif /*__LWIPOPTS__H__ */
Po wygenerowaniu projektu należy się upewnić, że plik *.FLASH zawiera poprawne dane:
- . = ALIGN(4);
- .bss (NOLOAD) :
- {
- /* This is used by the startup in order to initialize the .bss section */
- _sbss = .; /* define a global symbol at bss start */
- __bss_start__ = _sbss;
- *(.bss)
- *(.bss*)
- *(COMMON)
- . = ALIGN(32);
- *(.Rx_PoolSection)
- . = ALIGN(4);
- _ebss = .; /* define a global symbol at bss end */
- __bss_end__ = _ebss;
- } >RAM_D1
- .lwip_sec (NOLOAD) :
- {
- . = ABSOLUTE(0x30000000);
- *(.RxDecripSection)
- . = ABSOLUTE(0x30000100);
- *(.TxDecripSection)
- } >RAM_D2
Do pliku ethernetif, należy dołożyć deklarację bufora RX:
- __attribute__((section(".Rx_PoolSection"))) extern u8_t memp_memory_RX_POOL_base[];
Sprawdzam komunikację przez wysłanie komendy ping.
Standardowy przykład czyli serwer TCP. Był on już wielokrotnie umieszczany na tym blogu. Więc poniżej będzie screen z przebiegu komunikacji:
Przykładowy projekt można pobrać z dysku Google lub z serwisu Github.