- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的目标是将UDP数据包从微控制器(核板)发送到PC-就这么简单。更新:我成功达到了目标。我将在这里解释我是如何做到的,以及我最初偶然发现的问题。非常感谢StackOverflow社区以及LinkedIn ARM小组的人员为我提供帮助!
1.系统概述
我的系统如下:
1.1单片机端
具有STM32F767ZI微控制器的Nucleo_F767ZI板。该板有一个以太网连接器。
Mbed-OS 5操作系统。
lwip库(它是Mbed-OS 5操作系统的一部分)。
1.2电脑侧🖳
Windows 10(64位)。
可用的以太网端口(互联网通过WiFi,因此未使用此以太网端口)。
Wireshark查看微控制器是否实际发送了UDP数据包。它们的解释将在稍后的Python中完成。首先,我想在Wireshark中查看数据包。
1.3连接
最初,我将核子板直接连接到我的计算机,而没有涉及路由器或交换机。这种设置需要“静态IP配置”。我将配置PC的IP地址为“ 192.168.1.10”,将微控制器配置为“ 192.168.1.20”。我知道这是可行的,因为我之前使用PIC微控制器已经做到了。
但是这种情况有些不同。我在微控制器上运行了一个小的操作系统:mbed-os v5。该操作系统使用Lwip(轻量级IP堆栈)。尽管应该可以配置“静态IP地址”,但是该软件当前不支持该地址。可以在这里找到更多信息:https://developer.mbed.org/questions/74145/EthernetInterfaceinit-mbed-os-5x-not-wor/。由于无法在微控制器上配置静态IP地址,因此需要DHCP服务器。微控制器连接到没有IP地址的网络,并广播带有以下问题的数据包:“我应在该网络上使用哪个IP地址?”。如果微控制器没有得到答案,它将多次广播该问题,并最终放弃。
如果网络上连接了DHCP服务器,它将收到问题并交出可用的IP地址。这就是您所需要的。提供这种DHCP服务器的方法有几种:
在Windows PC上安装DHCP服务器。这是使交换机和路由器不被看到的唯一方法。核子板直接连接到PC。当微控制器广播问题时,Windows PC会移交IP地址。之后,可以开始通信。
将Raspberry PI投掷到游戏中。 Raspberry PI应该运行DHCP服务器。将三个设备(Windows PC,Raspberry PI和Nucleo板)连接到交换机。
买一个简单的路由器。家用路由器具有内置的DHCP服务器。将Windows PC和Nucleo板连接到此路由器的LAN端口。
我决定去第三个选择。下图显示了到我的Netgear R7000路由器的连接:
2.路由器设置
路由器内部的DHCP服务器会将IP地址分发给与其连接的所有设备。我的路由器会将IP地址“ 192.168.1.2”分配给第一个设备,将“ 192.168.1.3”分配给第二个设备,依此类推,一直到“ 192.168.1.254”。但这有点问题。 PC和微控制器如何相互知道IP地址?也许有更聪明的解决方案,但是我已经想出了以下方法。
每个DHCP服务器都有一个带有“保留的IP地址”的表。在此表中,您可以添加设备并为其分配静态IP地址。因此,无论何时该设备要求IP地址,DHCP服务器都会在表中查找并移交给您配置的地址。但是DHCP服务器如何识别设备?它可以通过其MAC地址识别设备。每个设备都有一个全球唯一的6字节MAC地址。
这是我将Windows PC和微控制器添加到表中的方式:
步骤1:将计算机连接到路由器的LAN端口之一。打开路由器。
步骤2:确保计算机上的所有WiFi都已断开连接。我遇到了很多问题。 (*)
步骤3:打开浏览器,然后浏览到“ 192.168.1.1”。这是我的路由器主页。您的路由器可能会有所不同。
第4步:登录(我的路由器的默认登录名是“ admin”,用户名是“ password”)
步骤5:将Windows PC和微控制器板添加到表中。您必须先查找其MAC地址(**):
2.1断开所有WiFi(*)
这应该是一个简单的步骤,但是Windows使它变得困难。 Windows可能非常顽固,即使您未选中自动连接框,它也会自动重新连接到周围的WiFi网络!要强制Windows收听您的声音,可以使用cmd终端。使用管理员权限打开一个cmd终端。接下来,键入以下命令以查看所有WiFi配置文件:
> netsh wlan show profiles
> netsh wlan set profileparameter name="someWifiName" connectionmode=manual
ipconfig /all
。我得到以下输出:
# Note: this is the correct item!
# --------------------------------
Ethernet adapter Local Area Connection:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Intel(R) Ethernet Connection (2) I219-LM
Physical Address. . . . . . . . . : C8-xx-xx-xx-xx-01 # Replaced some numbers by x for security :-)
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Ethernet adapter Local Area Connection
是我的计算机上正确的计算机,因为网卡说明符合预期:
Intel(R) Ethernet Connection (2) I219-LM
。在此之前,我正在查看列表中的另一项,标记为
Ethernet adapter Ethernet
:
# Note: this is the wrong item!
# ------------------------------
Ethernet adapter Ethernet:
Media State . . . . . . . . . . . : Media disconnected
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : TAP-Windows Adapter V9
Physical Address. . . . . . . . . : 00-xx-xx-xx-xx-F7
DHCP Enabled. . . . . . . . . . . : No
Autoconfiguration Enabled . . . . : Yes
TAP-Windows Adapter V9
。显然,这是一个虚拟网卡。那使我浪费很多时间。谢谢Joel C先生帮助我!
#include "lwip-interface/EthernetInterface.h"
//1. Make an ethernet object
EthernetInterface eth;
//2. Try to connect
eth.connect(); // <- This line will not work now,
// but at least it will help you to find out your
// own MAC-address.
//3. Print the MAC-address
logger.printf("Controller MAC Address is: %s\r\n", eth.get_mac_address());
Controller MAC Address is: 00:xx:xx:xx:xx:40
main.cpp
文件是从Mbed-os论坛上的
https://forums.mbed.com/t/udp-receive-with-nucleo-f767zi/1806上找到的代码启发的。
#include <string>
using std::string;
#include "mbed.h"
#include "lwip-interface/EthernetInterface.h"
static Serial logger(USBTX, USBRX);
static DigitalOut led1(LED1);
// IP addresses
#define IP_COMPUTER "192.168.1.10" // Make sure these IP addresses correspond to the
#define IP_NUCLEO "192.168.1.20" // table of 'reserved IP addresses' you have setup in
// your routers DHCP server!
// Ethernet settings
const int PORT_T = 50000;
const int PORT_R = 50001;
EthernetInterface eth;
static void udp_tx_thread_func();
static void udp_rx_thread_func();
static Thread udp_tx_thread;
static Thread udp_rx_thread;
int main()
{
// 1. Initialize the serial logger
logger.baud(115200);
logger.printf("\r\n\r\nApplication started\r\n");
// 2. Initialize and start the UDP connection
eth.connect();
logger.printf("Controller MAC Address is: %s\r\n", eth.get_mac_address());
logger.printf("Controller IP Address is: %s\r\n", eth.get_ip_address());
Thread::wait(200);
udp_tx_thread.start(udp_tx_thread_func);
udp_rx_thread.start(udp_rx_thread_func);
while (true)
{
led1 = !led1;
Thread::wait(500);
}
}
//------------------ Ethernet --------------------------------------------------
static void udp_tx_thread_func()
{
UDPSocket socket(ð);
SocketAddress sock_addr(IP_COMPUTER, PORT_T);
static uint32_t out_buffer[3];
while(true)
{
Thread::wait(100);
// Send 3 values of 32-bit each
out_buffer[0] = 150500;
out_buffer[1] = 255300;
out_buffer[2] = 54;
int ret = socket.sendto(sock_addr, &out_buffer[0], 12); // 3 values of 32-bit equals 12 bytes
//logger.printf("sendto return: %d\r\n", ret);
}
}
static void udp_rx_thread_func()
{
UDPSocket socket(ð);
SocketAddress sock_addr;
int bind = socket.bind(PORT_R);
logger.printf("bind return: %d\n", bind);
char buffer[256];
while(true)
{
//logger.printf("\nWait for packet...\n");
int n = socket.recvfrom(&sock_addr, buffer, sizeof(buffer));
buffer[n] = '\0';
//logger.printf("Packet from \"%s\": %s\n", sock_addr.get_ip_address(), buffer);
Thread::wait(500);
}
}
Local Area Connection
上流入的UDP数据包!哈雷!
import sys
import os
import socket
import dataprocessing.datastruct as datastruct
def main():
# 1. Configure the IP address
# -----------------------------
myAddr = ('192.168.1.10', 50000)
# 2. Create a UDP socket
# -----------------------
sock = None
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.settimeout(1.5)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(myAddr)
print('UDPsock @: ' + str(sock.getsockname()))
sys.stdout.flush()
except Exception as e:
print('Could not bind to the UDP socket.')
print(e)
sys.stdout.flush()
while (true):
try:
data, address = sock.recvfrom(256) # buffer size is 256 bytes
bytedata = bytearray(data)
# Each 32-bit number is cut in 8-bit pieces. Bring them back together.
value_01 = bytedata[0] + 256*bytedata[1] + 65536*bytedata[2] + 16777216*bytedata[3]
value_02 = bytedata[4] + 256*bytedata[5] + 65536*bytedata[6] + 16777216*bytedata[7]
value_03 = bytedata[8] + 256*bytedata[9] + 65536*bytedata[10] + 16777216*bytedata[11]
print("Value 01: %d", value_01)
print("Value 02: %d", value_02)
print("Value 03: %d", value_03)
except socket.error as err:
print(err)
if __name__== '__main__':
print("")
print("Start UDP catcher")
print("-----------------")
main()
最佳答案
您标记为Ethernet
的连接实际上是TAP连接(例如,虚拟以太网卡)。您实际的以太网连接标记为Local Area Connection
;这是您需要使用Wireshark等进行配置和监视的连接。
至于与Mbed-OS相关的其他一切,我个人还没有处理过。
关于c++ - mbed-os 5上的Lwip无法建立正确的以太网连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41202528/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!