Etablish an Ethernet connection with STM32F107 - ethernet

Hello I wan't to use the ethernet of my MCU (STM32F103VCT6) with using Lwip module. I'm using a dev board (EasyMx Pro V7). For the moment I've connect a etehernet cable between my computer and my ethernet board I've used some example of ethernet example for test the ethernet communication. But I don't arrive to ping my board after settings the differents parameters (GW address, Mask Address, IP Address). All my code has been generated with CubeMx.
I've also debug my program for try to understand why I can't ping my card and all seems to work fine netif is set up. I use wireshark to see the ethernets frame from my ethernet port I don't see PING frame (icmp), only some ARP frame.
Here is my main loop and it is the part that I modified :
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
/* Read a received packet from the Ethernet buffers and send it
to the lwIP for handling */
ethernetif_input(&gnetif);
/* Handle timeouts */
sys_check_timeouts();
HAL_GPIO_TogglePin(LED_PA_10_GPIO_Port, LED_PA_10_Pin);
HAL_Delay(500);
}
/* USER CODE END 3 */
}
I try to ping my deb board from a PC by a ethernet cable.

Related

Tc bpf packet forward to other device by updating the Checksum

I want to forward the UDP/TCP packet to other devices connected to the same router. I just write the code which forwards the packet to other interfaces by checking the packet type and its payload. This is working fine, but when I try to forward the same packet to other devices I don't receive the packet on other devices.
I updated the checksum by using helper functions and redirect to other devices is not working for me. Is TC_ACT_REDIRECT similar to XDP_TX?
Here is the piece of code
(If the value of c is 1 it updates the destination address and forwards the packet to destination):
if (c == 1) {
int ipaddr = htonl(3232260738); // Dest: 192.168.98.130
sum = bpf_csum_diff((void *)&old1_daddr, 4, (void *)&ipaddr, 4, 0);
bpf_skb_store_bytes(skb, ETH_HLEN + offsetof(struct iphdr, daddr),
(void *)&ipaddr, 4, 0);
bpf_l3_csum_replace(skb, IP_CSUM_OFFSET, 0, sum, 0);
bpf_l4_csum_replace(skb, IP_CSUM_OFFSET1, 0, sum, BPF_F_PSEUDO_HDR);
bpf_clone_redirect(skb, skb->ifindex, 0 );
return TC_ACT_REDIRECT;
}
Here is the ingress tc command
sudo tc filter add dev ens33 ingress bpf da obj tcbpf1_kern.o sec classifier
with an above chunk of code, I can redirect the packet to virtual interface but not to the updated destination.
if I am not wrong, you're missing the MAC address of your destination device. You need to update the MAC address as well. You are receiving the packet on a virtual machine because it has no mac address. Please check the mac address and your problem will be solved.

using USART in STM32L4R5

I am using asynchronous USART on STM32L4R5 for communication with PC. I am able to receive data on PC side but I am not able to receive any data on nucleo board send by PC. Following is the code I am using for transmission
while (1)
{
HAL_GPIO_TogglePin(LD2_GPIO_Port,LD2_Pin); //Toggle LED
HAL_Delay(1000);
for(i = 0; i < 5; i++)
{
USART1->TDR = p[i];
while((USART1->ISR & 0x40) == 0);
}
while ((USART1->ISR & 0x20) == 0);
uint32_t receivedByte = (uint32_t)(USART1->RDR);
}
In the above sending part is working fine but receiving is not working. I have checked and wiring is proper.
Why don't you just using USART Receiving interrupt it will help you in capturing received data. Rather than polling for USART Reception.
There are two reasons for no response
You might not sending EOD and Carriage return while sending data on USART. Many USART based operation based on these character. Module will listen to USART untill these characters are received.
Your hardware connections are not right. Make sure you are connecting TX to Host to Rx of Slave and vice versa.
I suggest USART interrupt because polling is not a good method while writing a code.

Monitoring UDP data on wireshark shows ARP packet

I am trying to send UDP packet to my server 10.20.1.2 with port number 20000. I have implemented UDP client on PC and when i send data using sendto API , at the same time i monitor data on wireshark wireshark shows it as an ARP packet.
18967 5440.858646 PcsCompu_ef:b4:89 Broadcast ARP 42 Who has 10.20.1.2? Tell 192.168.1.70
192.168.1.70 is my machine ip where UDP client is running.
I am not sure how UDP packet is getting converted into ARP packet ?
I understand ARP is for finding MAC address of target node but here i already know MAC address of target device , How can i add it in my udp client so it directly starts UDP communication . My target device is one embedded camera , i am not expecting it to reply on ARP request so i want to prevent sending ARP request.
Below is my UDP client code :
Any inputs are highly appreciated. Thanks in advance.
/*
Simple udp client
*/
#include<stdio.h> //printf
#include<string.h> //memset
#include<stdlib.h> //exit(0);
#include<arpa/inet.h>
#include<sys/socket.h>
#define SERVER "10.20.1.2"
#define PORT 20000 //The port on which to send data
char message[3]={0x00, 0x00 , 0x24};
int main(void)
{
struct sockaddr_in si_other;
int s, i, slen=sizeof(si_other);
int ret;
if ( (s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
{
printf("socket failed");
}
memset((char *) &si_other, 0, sizeof(si_other));
si_other.sin_family = AF_INET;
si_other.sin_port = htons(PORT);
if (inet_aton(SERVER , &si_other.sin_addr) == 0)
{
fprintf(stderr, "inet_aton() failed\n");
exit(1);
}
ret = sendto(s, message, sizeof(message) , 0 , (struct sockaddr *) &si_other, slen);
close(s);
return 0;
}
Some clarifications regarding networking.
1. ARP must be sent and replied
Your camera has IP interface, which means it must handle ARP requests fine without any doubts. ARP is essential part of communicating via IP, camera without ARP support makes no sense. And ARP isn't a result of converting UDP, it's a preliminary step before sending actual UDP datagram. Once ARP reply is discovered with destination MAC-address, UDP packet is sent to that destination. The issue you see isn't about hardcoding MAC to avoid ARP.
2. Your code looks fine
Compiled it locally with minor corrections (missing #include <unistd.h> header with close() declaration), tested on several targets, client works as expected.
3. Something is wrong with your network topology
You are sending message from 192.168.1.70 to 10.20.1.2, which is weird. 192.168.0.0/24 and 10.0.0.0/8 are private IP addresses from different ranges, so they normally can't reach each other without black magic (like NAT traversal). And, what is much weirder, during your attempt ARP request is sent to strange destination. Let me illustrate different cases:
if both devices are in same subnet (e.g. 192.168.1.70 sends to 192.168.1.71), then message is sent directly, so client asks "who has 192.168.1.71" in ARP request.
if devices are in different subnets (e.g. 192.168.1.70 sends to 8.8.8.8), then message is sent through gateway, thus ARP request reads "who has 192.168.1.1" or whatever your gateway address is. Gateway MAC may be already in cache, in which case ARP isn't sent at all.
in your case subnets are obviously different, but ARP is asking about direct destination address rather than gateway MAC address.
It's a shot in the dark, but probably you have two network interfaces on your PC, one connected to 192.168.0.0 subnet, the other to 10.0.0.0 and ARP request is sent from both. If you sniff the wrong interface, you see weird ARP request and don't see UDP, which is actually sent after it. By the way, seeing single arp request is also confusing, because it should be repeated several times if noone answers.
Anyway, you need to check network topology and/or simplify it. Remove unnecessary network interfaces, configure PC and camera to be on the same subnet connected to the same switch/router and investigate further.

Sending data from STM32F401 MCU to ESP8266 and getting response from ESP8266 to MCU

I am working on an STM32f401 Nucleo board and ESP8266 wifi module. I am using Eclipse gcc-arm tool chain and cubeMx to generate code. I can transfer and receive data perfectly with USART/UART DMA.
Now I am stuck with ESP8266. I cannot send data from MCU to ESP and I'm not getting response from ESP to MCU. I already tested the ESP module communication, I can connect TO THE wifi with AT commands through USB and can also receive data in web via socket connection.
I configured USART1_TX/USART1_RX with PA9/PA10
Thanks in advance.
I'm not an expert, but I try to help you.
Which baud rate are you using? Is it coherent with the ESP8266 documentation?
Check the power supply and the connections.
Therefore, remember that the AT commands are case sensitive (they must be written with capital letters only) and they must terminate with carriage return and line feed, so "/r/n".
That's right at first check baud rate are matching
Then do you use dma for both tx/rx direction ?
For dma rx note that the "completion" callback will be called only when the full buffer will be filled.
If you neeed to "break" reception on ending "\n" "\n" then you might use the interrupt rx method oen hatr at a time and inspect it as it arrives in the callback that keep on asking one more byte until not done.
Alternatively with dma keep on polling the dma count and analyzed current rx buffer for some \r \n. abort/Stop dma when done.

Get Base address of UART registers

I'm using PCI card which opens two serial ports(UART).Developing driver for same.
For doing operation on UART,i need to know base address from where i can shift and access uart configuration register(exa.LCR,IER,LSR,...etc.)
Using which function i can get UART base address? or In datasheer where it is mentioned?
Thank you.
The standard port addresses are:
Standard port addresses are:
COM1 0x3F8 (1016)
COM2 0x2F8 (760)
COM3 0x3E8 (1000)
COM4 0x2E8 (744)
Additional port addresses are:
COM5 0x3E0 (992)
COM6 0x2E0 (736)
COM7 0x338 (824)
COM8 0x238 (568)
This is from the IntelĀ® 82547EI Gigabit Ethernet Controller Data sheet :
10.1.1.1 Memory-Mapped Access to Internal Registers and Memories The internal registers and memories can be accessed as direct
memory-mapped offsets from the Base Address Register 0 (BAR0). The
appropriate offset for each specific internal register is described in
this section.
So I think that your card needs to be enumerated first by U-Boot or Linux.
Then you can access your card internal registers as offsets to the BAR0 address (from U-Boot or Linux).