Hallo zusammen, vielleicht hatte ja einer von euch schon mal das selbe Problem: Ich versuche auf einem STM32H743 mithilfe des lwip Stacks (ohne RTOS) eine Kommunikation über UDP zu etablieren. Das Versenden von Paketen funktioniert einwandfrei, das Empfangen funktioniert allerdings nicht. Die Funktion "low_level_input" reagiert wenn ich eine Paket an den STM schicke, allerdings wird in der Funktion "ethernet_input" das Paket nicht an "ip4_input" übergeben dabei wird die Debug-Message:"Can't move over header in packet" ausgeben. Diese Fehlermeldung wird ausgelöst durch den Fehler "not enough space for new header size" durch "pbuf_header_impl" in "pbuf.c". Da ich ein absoluter Neuling im Bereich lwip bin, verstehe ich nicht wirklich wo das Problem liegen könnte. Bei der Konfiguration habe ich mich an diese Anleitung gehalten: https://community.st.com/docs/DOC-1811-faq-ethernet-not-working-on-stm32h7 Wenn einer von euch einen Rat hat würde ich mich sehr freuen! mfg
zum test den cache( beide ... ) der MCU mal deaktivieren aber grundsätzlich ... wo ist dein code hier? hänge den bitte ran ...
Hi, erstmal vielen dank für die schnelle Antwort! Code, siehe unten, habe ich erstmal nicht gepostet, weil ich dachte das Problem liegt im lwip Stack. Den DCache muss ich erst Enablen, sonst funktioniert lwip_init() nicht. Danach deaktiviere ich ihn wieder, weil ich sonst maximal drei Pakete hintereinander senden kann. Die MPU Konfiguration habe ich dem FAQ entnommen. main.c (abgespeckt)
1 | /* Includes ------------------------------------------------------------------*/
|
2 | #include "main.h" |
3 | #include "stm32h7xx_hal.h" |
4 | #include "lwip.h" |
5 | |
6 | /* USER CODE BEGIN Includes */
|
7 | #include "lwip/udp.h" |
8 | #include <string.h> |
9 | #include <stdio.h> |
10 | /* USER CODE END Includes */
|
11 | |
12 | /* Private variables ---------------------------------------------------------*/
|
13 | |
14 | /* USER CODE BEGIN PV */
|
15 | /* Private variables ---------------------------------------------------------*/
|
16 | static struct udp_pcb *udpPcb1_p; |
17 | extern struct netif gnetif; |
18 | __IO uint32_t message_count = 0; |
19 | /* Private function prototypes -----------------------------------------------*/
|
20 | void SystemClock_Config(void); |
21 | static void MPU_Config(void); |
22 | static void MX_GPIO_Init(void); |
23 | |
24 | /* USER CODE BEGIN PFP */
|
25 | /* Private function prototypes -----------------------------------------------*/
|
26 | void udpApp1_sendTESTPacket(void); |
27 | void udp_echo_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port); |
28 | void udpApp1_init(void); |
29 | /* USER CODE END PFP */
|
30 | |
31 | /* USER CODE BEGIN 0 */
|
32 | |
33 | /* USER CODE END 0 */
|
34 | |
35 | /**
|
36 | * @brief The application entry point.
|
37 | *
|
38 | * @retval None
|
39 | */
|
40 | int main(void) |
41 | {
|
42 | /* USER CODE BEGIN 1 */
|
43 | |
44 | /* USER CODE END 1 */
|
45 | |
46 | /* MPU Configuration----------------------------------------------------------*/
|
47 | MPU_Config(); |
48 | |
49 | /* Enable I-Cache-------------------------------------------------------------*/
|
50 | //SCB_EnableICache();
|
51 | |
52 | /* Enable D-Cache-------------------------------------------------------------*/
|
53 | SCB_EnableDCache(); |
54 | |
55 | /* MCU Configuration----------------------------------------------------------*/
|
56 | |
57 | /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
|
58 | HAL_Init(); |
59 | |
60 | /* USER CODE BEGIN Init */
|
61 | |
62 | /* USER CODE END Init */
|
63 | |
64 | /* Configure the system clock */
|
65 | SystemClock_Config(); |
66 | |
67 | /* USER CODE BEGIN SysInit */
|
68 | |
69 | /* USER CODE END SysInit */
|
70 | |
71 | /* Initialize all configured peripherals */
|
72 | MX_GPIO_Init(); |
73 | MX_LWIP_Init(); |
74 | //MX_DMA2D_Init();
|
75 | /* USER CODE BEGIN 2 */
|
76 | udpApp1_init(); |
77 | SCB_DisableDCache(); |
78 | /* USER CODE END 2 */
|
79 | |
80 | /* Infinite loop */
|
81 | /* USER CODE BEGIN WHILE */
|
82 | udpApp1_sendTESTPacket(); |
83 | HAL_Delay(1000); |
84 | while (1) |
85 | {
|
86 | |
87 | /* USER CODE END WHILE */
|
88 | |
89 | /* USER CODE BEGIN 3 */
|
90 | |
91 | |
92 | //MX_LWIP_Process();
|
93 | ethernetif_input(&gnetif); |
94 | |
95 | /* USER CODE BEGIN 4_2 */
|
96 | /* USER CODE END 4_2 */
|
97 | /* Handle timeouts */
|
98 | sys_check_timeouts(); |
99 | }
|
100 | /* USER CODE END 3 */
|
101 | |
102 | }
|
103 | |
104 | |
105 | |
106 | /* USER CODE BEGIN 4 */
|
107 | void udpApp1_sendTESTPacket(void){ |
108 | ip_addr_t client1IpAddr; |
109 | struct pbuf *ethTxBuffer_p; |
110 | u8_t data[100]; |
111 | |
112 | IP4_ADDR(&client1IpAddr, 192, 168, 1, 255); //-> Brodcast |
113 | |
114 | sprintf((char*)data, "sending udp client message %d", 10); |
115 | ethTxBuffer_p = pbuf_alloc(PBUF_TRANSPORT,strlen((char*)data), PBUF_RAM); |
116 | |
117 | |
118 | //ethTxBuffer_p = pbuf_alloc(PBUF_TRANSPORT, sizeof(clientMagicPacket_c), PBUF_RAM);
|
119 | if (ethTxBuffer_p == NULL){} |
120 | |
121 | memcpy(ethTxBuffer_p->payload, data, sizeof(data)); |
122 | //memcpy(ethTxBuffer_p->payload, clientMagicPacket_c, sizeof(clientMagicPacket_c));
|
123 | |
124 | udp_sendto(udpPcb1_p, ethTxBuffer_p, &client1IpAddr,65010); |
125 | |
126 | pbuf_free(ethTxBuffer_p); |
127 | }
|
128 | void udp_echo_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) |
129 | {
|
130 | /*increment message count */
|
131 | struct pbuf *p_tx; |
132 | |
133 | /* allocate pbuf from RAM*/
|
134 | p_tx = pbuf_alloc(PBUF_TRANSPORT,p->len, PBUF_RAM); |
135 | |
136 | message_count++; |
137 | |
138 | /* Free receive pbuf */
|
139 | pbuf_free(p); |
140 | }
|
141 | void udpApp1_init(void){ |
142 | err_t udpErr; |
143 | ip_addr_t ownIPaddr; |
144 | |
145 | udpPcb1_p = udp_new(); |
146 | |
147 | if(udpPcb1_p != NULL) |
148 | {
|
149 | IP4_ADDR(&ownIPaddr, 192, 168, 1, 20); //STM32-IP |
150 | |
151 | //udpErr = udp_bind(udpPcb1_p, &ownIPaddr, 61005);
|
152 | udpErr = udp_bind(udpPcb1_p, IP_ADDR_ANY, 61005); |
153 | |
154 | |
155 | udp_recv(udpPcb1_p, udp_echo_recv, NULL); |
156 | |
157 | if (udpErr ==ERR_OK){} |
158 | }
|
159 | }
|
160 | |
161 | /* USER CODE END 4 */
|
162 | |
163 | /* MPU Configuration */
|
164 | |
165 | void MPU_Config(void) |
166 | {
|
167 | MPU_Region_InitTypeDef MPU_InitStruct; |
168 | |
169 | /* Disables the MPU */
|
170 | HAL_MPU_Disable(); |
171 | /**Initializes and configures the Region and the memory to be protected
|
172 | */
|
173 | MPU_InitStruct.Enable = MPU_REGION_ENABLE; |
174 | MPU_InitStruct.Number = MPU_REGION_NUMBER2; |
175 | MPU_InitStruct.BaseAddress = 0x30040000; |
176 | MPU_InitStruct.Size = MPU_REGION_SIZE_256B; |
177 | MPU_InitStruct.SubRegionDisable = 0x0; |
178 | MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; |
179 | MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;; |
180 | MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; |
181 | MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;; |
182 | MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; |
183 | MPU_InitStruct.IsBufferable = MPU_ACCESS_BUFFERABLE; |
184 | |
185 | HAL_MPU_ConfigRegion(&MPU_InitStruct); |
186 | |
187 | /**Initializes and configures the Region and the memory to be protected
|
188 | */
|
189 | MPU_InitStruct.Enable = MPU_REGION_ENABLE; |
190 | MPU_InitStruct.Number = MPU_REGION_NUMBER1; |
191 | MPU_InitStruct.BaseAddress = 0x30044000; |
192 | MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; |
193 | MPU_InitStruct.SubRegionDisable = 0x0; |
194 | MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; |
195 | MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;; |
196 | MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; |
197 | MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; |
198 | MPU_InitStruct.IsCacheable = MPU_ACCESS_CACHEABLE; |
199 | MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; |
200 | |
201 | HAL_MPU_ConfigRegion(&MPU_InitStruct); |
202 | |
203 | /**Initializes and configures the Region and the memory to be protected
|
204 | */
|
205 | MPU_InitStruct.Enable = MPU_REGION_ENABLE; |
206 | MPU_InitStruct.Number = MPU_REGION_NUMBER0; |
207 | MPU_InitStruct.BaseAddress = 0x30040000; |
208 | MPU_InitStruct.Size = MPU_REGION_SIZE_16KB; |
209 | MPU_InitStruct.SubRegionDisable = 0x0; |
210 | MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL0; |
211 | MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;; |
212 | MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_ENABLE; |
213 | MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE; |
214 | MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE; |
215 | MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE; |
216 | |
217 | HAL_MPU_ConfigRegion(&MPU_InitStruct); |
218 | /* Enables the MPU */
|
219 | HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT); |
220 | |
221 | }
|
schau mal nach was dein linkerscript mit dem speicher macht. im STM gibt es DTCM, SRAM( mehrere regionen ) Je nach dem wo dein ethernetbuffer liegt und die descriptoren kann es da schon probleme geben . Die andere Frage: warum kein RTOS und interrupt betrieb? die CPU nur mit dem bisschen ethernet zu verheizen ist ... doof
In dem linkerscript habe ich bereits alle Zuweisungen von "DTCMRAM" nach "RAM D1" geändert, sonst Funktioniert auch das Senden nicht.... Das habe ich allerdings auch manuell gemacht. Das ganze soll, wenn es denn mal läuft, noch in ein größeres Projekt eingebettet werden, deswegen erst einmal so, ohne RTOS, um es überhaupt zum laufen zu bringen.
Tim B. schrieb: > habe ich bereits alle Zuweisungen von "DTCMRAM" nach > "RAM D1" geändert, sonst Funktioniert auch das Senden nicht.... > Das habe ich allerdings auch manuell gemacht. dann bitte das file anhängen ... eth buffer descriptoren init von diesen und ggf die größe der TX/RX buffer
Angehängt das linkerfile Die Initizialisrung der Descriptoren lautet wie folgt:
1 | __attribute__((at(0x30040000))) ETH_DMADescTypeDef DMARxDscrTab[ETH_RX_DESC_CNT]; /* Ethernet Rx DMA Descriptors */ |
2 | __attribute__((at(0x30040060))) ETH_DMADescTypeDef DMATxDscrTab[ETH_TX_DESC_CNT]; /* Ethernet Tx DMA Descriptors */ |
3 | __attribute__((at(0x30040200))) uint8_t Rx_Buff[ETH_RX_DESC_CNT][ETH_MAX_PACKET_SIZE]; /* Ethernet Receive Buffer */ |
Größe ist:
1 | #define ETH_TX_DESC_CNT ((uint32_t)4) /* Tx Descriptor Length */ |
2 | #define ETH_RX_DESC_CNT ((uint32_t)4) /* Rx Descriptor Length */ |
ansonsten habe ich auch alles auf Default gelassen ( Projekt mit MXCube erstellt)
Tim B. schrieb: > __attribute__((at(0x30040000))) Schau mal im Map File nach ob das funktioniert hat. Gnu LD kann normalerweise keine festen Addresszuweisungen außerhalb des LD Skripts - man muss mit __attribute__((section("foo"))) arbeiten AFAIK.
ich habe sections im LD angelegt.
1 | /* Ethernet memory*/
|
2 | .eth (NOLOAD): |
3 | {
|
4 | . = ALIGN(8); |
5 | *(.eth) |
6 | *(.eth*) |
7 | . = ALIGN(8); |
8 | } >RAM2 |
__attribute__((__section__(".eth"),used))
ich nutze überall 8 byte alignment ...
hat mir schon öfters kopfschmerzen bereitet warum der M7 dann meinte
hier und da langsamer zu sein
Vielen Dank schon mal an alle! Habe es jetzt hinbekommen, in dem ich in pbuf.c die Abfrage rausgenommen habe die den Fehler geliefert hat... meiner Meinung nach war die if Bedingung fehlerhaft.
Und die Entwickler haben einen solchen Fehler, der alle RX Frames wegwirft "übersehen"?
Ja wahrscheinlich!....ne keine Ahnung warum das so ist Hier der problematische C Code
1 | if ((u8_t *)p->payload > (u8_t *)p + SIZEOF_STRUCT_PBUF) { |
2 | LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, |
3 | ("pbuf_header: failed as %p < %p (not enough space for new header size)\n", |
4 | (void *)p->payload, (void *)((u8_t *)p + SIZEOF_STRUCT_PBUF))); |
5 | /* restore old payload pointer */
|
6 | p->payload = payload; |
7 | /* bail out unsuccessfully */
|
8 | return 1; |
9 | }
|
Das Problem ist, wenn ein Paket versendet werden soll ist ">" die richtig Beziehung. Wenn man aber empfängt, müsste die Abfrage andersherum, sprich "<", sein. Da ich beides will, habe ich das jetzt einfach rausgeschmissen, funktioniert offensichtlich auch so. Die Pakete sind ja sowieso über Checksums abgesichert, wenn da was schief geht sollte man es spätestens da noch merken. Falls jemand noch eine bessere Idee, oder Erklärung hat gerne her damit!
der lwip code funktioniert eigentlich ganz gut. habe selbst einen F7 mit RTOS + lwIP laufen. Ob das eine gute idee war das so umzufriemeln .. wird sich zeigen wenn du eine applikation laufen hast. Wenn es hier zu kuriositäten kommt .. schreib dir JETZT schonmal auf das du hier was geändert hattest ...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.