This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] CCS/TM4C129XNCZAD:TM4C129XNCZAD Tiva UDP 示例

Guru**** 2425680 points


请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/723207/ccs-tm4c129xnczad-tm4c129xnczad-tiva-udp-example

器件型号:TM4C129XNCZAD

工具/软件:Code Composer Studio

我在使用静态 IP 时遇到类似的问题。  我的计算机 IP 为192.168.101.11、DK 电路板为192.168.101.10。  我可以从计算机 ping 192.168.101.10、但无法输出 UDP。

//

//

//此示例演示了以太网控制器的使用。

//

//

main (空)

uint32_t ui32User0、ui32User1;

uint8_t pui8MACArray[8];

struct ip_addr ipaddr;

struct ip_addr ipAddr2;

struct ip_addr subnet;

struct ip_addr gateway;

char errorFlag;

struct udp_PCB * UDPSock;

ipaddr.addr =(192u << 24)|(168u << 16)|(101u << 8)| 10U;

ipAddr2.addr =(192u << 24)|(168u << 16)|(101u << 8)| 11u;

subnet.addr =(255u << 24)|(255u << 16)|(255u << 8)| 0;

//网关=(192u << 24)|(168u << 16)|(0U << 8)| 1;

// IP4_ADDR (&ipaddr、192、168、101、10);

// IP4_ADDR (&subnet,255,255,255,0);

IP4_ADDR (&gateway、0、0、0、0);

//

//从 PLL 以120MHz 运行。

//

G_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz |

SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |

SYSCTL_CFG_VCO_480)、120000000);

//

//配置器件引脚。

//

PinoutSet();

//

//初始化显示驱动程序。

//

Kentec320x240x16_SSD2119Init (g_ui32SysClock);

//

//初始化图形上下文。

//

GrContextInit (&g_sContext、&g_sKentec320x240x16_SSD2119);

//

//绘制应用程序帧。

//

FrameDraw (&g_sContext、"enet-static");

//

//为周期性中断配置 SysTick。

//

ROM_SysTickPeriodSet (g_ui32SysClock/SYSTICKHZ);

ROM_SysTickEnable();

ROM_SysTickIntEnable();

//

//初始化文件系统。

//

fs_init();

//

//为的以太网控制器过滤配置硬件 MAC 地址

//传入数据包。 MAC 地址将存储在非易失性存储器中

// USER0和 User1寄存器。

//

ROM_FlashUserGet (&ui32User0、&ui32User1);

if ((ui32User0 == 0xffffffff)||(ui32User1 == 0xffffffff)

//

//我们永远不应该来这里。 如果 MAC 地址有、则这是一个错误

//未编程到器件中。 退出程序。

//

GrContextForegroundSet (&g_sContext、ClrRed);

GrStringDrawCenter(&G_sContext,"MAC 地址",-1,

GrContextDpyWidthGet (&g_sContext)/ 2、

(GrContextDpyHeightGet (&g_sContext)/ 2)- 4、

false);

GrStringDrawCenter(&g_sContext,“未编程!”,-1,

GrContextDpyWidthGet (&g_sContext)/ 2、

(GrContextDpyHeightGet (&g_sContext)/ 2)+ 16、

false);

while (1)

//

//将24/24拆分 MAC 地址从 NV RAM 转换为32/16拆分 MAC

//对硬件寄存器进行编程所需的地址,然后对 MAC 进行编程

//将地址输入以太网控制器寄存器。

//

pui8MACArray[0]=((ui32User0 >> 0)& 0xff);

pui8MACArray[1]=((ui32User0 >> 8)& 0xff);

pui8MACArray[2]=((ui32User0 >> 16)& 0xff);

pui8MACArray[3]=((ui32User1 >> 0)& 0xff);

pui8MACArray[4]=((ui32User1 >> 8)& 0xff);

pui8MACArray[5]=((ui32User1 >> 16)& 0xff);

//

//使用 DHCP 初始化 lwIP 库。

//

lwIPInit (g_ui32SysClock、pui8MACArray、ipaddr.addr、subnet.addr、gateway.addr、 ipaddr_use_static);

UDPSock = UDP_NEW ();

UDP_recv (UDPSock、NULL、NULL);

errorFlag = UDP_BIND (UDPSock、&ipaddr、7070);

IF (错误标志)

错误标志= 0;

// errorFlag = UDP_CONNECT (UDPSock、IP_ADDR_ANY、7070);

// if (错误标志)

// errorFlag = 0;

char buf[500]="hello Kitty"

struct pbuf *p = 0;

//struct ip_addr server;

// IP4_ADDR (&server,192,168,253,236);

//

//

//设置设备定位服务。

//

//LocatorInit();

//LocatorMACAddrSet (pui8MACArray);

//LocatorAppTitleSet ("DK-TM4C129X enet_lwip");

//

//初始化示例 httpd 服务器。

//

//httpd_init();

//

//设置中断优先级。 我们将 SysTick 中断设置为更高的值

//优先级比以太网中断高,以确保文件系统

如果 SysTick 在以太网处理程序运行时发生、则处理// tick

//已处理。 这很可能是因为所有 TCP/IP 和 HTTP 工作都是

//在以太网中断上下文中完成。

//

ROM_IntPrioritySet (INT_EMAC0、ETHERNET_INT_PRIORITY);

ROM_IntPrioritySet (FAULT_SysTick、SysTK_INT_PRIORITY);

uint32_t ui32Loop;

//

//永久循环。 所有工作都在中断处理程序中完成。

//

while (1)

p=pbuf_alloc (PBUF_transport、500、PBUF_RAM);

memcpy(p->payload、buf、500);

errorFlag = udp_sendto (UDPSock、p、&ipAddr2、7070);

IF (错误标志)

错误标志= 0;

pbuf_free (p);

for (ui32Loop = 0;ui32Loop < 2000000;ui32Loop +)

{}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Robert、

     您可以尝试此 UDP_echo 示例吗?

    #include 
    #include 
    #include "inc/hw_ints.h"
    #include "inc/hw_memmap.h"
    #include "driverlib/flash.h"
    #include "driverlib/interrupt.h"
    #include "driverlib/rom_map.h"
    
    #include "driverlib/sysctl.udpinh"
    #include "drivers/udpintrinu.h
    
    
    
    
    
    
    
    
    
    
    //
    //! \addtogroup example_list
    //! 

    具有 lwIP 的以太网(enet_lwip)

    //! //! 此示例应用演示了 Tiva //! 使用 lwIP TCP/IP 堆栈的以太网控制器。 DHCP 用于获取 //! 以太网地址。 如果 DHCP 在未获取地址的情况下超时、 //! AutoIP 将用于获取链路本地地址。 是//!的地址 所选的值将显示在 UART 上。 //! //! UART0、连接到 ICDI 虚拟 COM 端口并以115、200运行、 //! 8-N-1用于显示来自此应用程序的消息。 使用 //! 按照命令重新构建所更改的任何文件系统文件。 //! //! ./../../../tools/bin/makefsfile -I FS -o enet_fsdata.h -r -h -q //! //! 有关 lwIP 的更多详细信息、请参阅 lwIP 网页、网址为: //! savannah.nongnu.org/.../ ///********* // // //定义设置系统时钟。 //// ***************** #define SYSTICKHZ 100 #define SYSTICKMS (1000 / SYSTICKHZ) //********* // //中断优先级定义。 这些值的前3位是 //有效的、较低的值表示较高优先级的中断。 //// ***************** #define SysTK_INT_PRIORITY 0x80 #define ETHERNET_INT_PRIORITY 0xC0 //********* // //当前 IP 地址。 //// ***************** uint32_t g_ui32IPAddress; //********* // //系统时钟频率。 //// ***************** uint32_t g_ui32SysClock; //********* // //用于管理 LED 闪烁的易失性全局标志,因为它用于中断 //和主应用程序。 LED 以 SYSTICKHZ 的速率闪烁。 //// ***************** 易失性 bool g_bled; //********* // //如果驱动程序库遇到错误,则调用的错误例程。 //// ***************** #ifdef debug void __error__(char *pcFilename、uint32_t ui32Line) { #endif void udp_echo_init (void); //********* // //显示 lwIP 类型的 IP 地址。 //// ***************** void DisplayIPAddress (uint32_t ui32Addr) { char pcBuf[16]; // //将 IP 地址转换为字符串。 // usprintf (pcBuf、"%d.%d.%d.%d"、ui32Addr & 0xff、(ui32Addr >> 8)& 0xff、 (ui32Addr >> 16)& 0xff、(ui32Addr >> 24)& 0xff); // //显示字符串。 // UARTprintf (pcBuf); } //************* // // lwIP 库支持任何与主机相关的计时器函数所需的//。 //// ***************** void lwIPHostTimerHandler (void) { uint32_t ui32NewIPAddress; // //获取当前 IP 地址。 // ui32NewIPAddress = lwIPLocalIPAddrGet (); // //查看 IP 地址是否已更改。 // if (ui32NewIPAddress!= g_ui32IPAddress) { // //查看是否分配了 IP 地址。 // if (ui32NewIPAddress == 0xffffffff) { // //表示没有链接。 // UARTprintf ("正在等待链接。\n"); } 否则、如果(ui32NewIPAddress =0) { // //没有 IP 地址,因此请指明 DHCP 进程是什么 //正在运行。 // UARTprintf ("正在等待 IP 地址。\n"); } 其他 { // //显示新的 IP 地址。 // UARTprintf ("IP 地址:"); DisplayIPAddress (ui32NewIPAddress); UARTprintf ("\n 回显服务器已就绪。\n"); } // //保存新的 IP 地址。 // G_ui32IPAddress = ui32NewIPAddress; } // //如果没有 IP 地址。 // if ((ui32NewIPAddress =0)||(ui32NewIPAddress =0xffffffff)) { // //不执行任何操作并继续等待。 // } } //********* // // SysTick 中断的中断处理程序。 //// ***************** void SysTickIntHandler (void) { // //调用 lwIP 计时器处理程序。 // lwIPTimer (SYSTICKMS); // //告诉应用程序更改 LED 的状态(换句话说 //闪烁)。 // G_bled = true; } //********* // //此示例演示了以太网控制器的使用。 //// ***************** int main (void) { uint32_t ui32User0、ui32User1; uint8_t pui8MACArray[8]; // //确保主振荡器已启用,因为这是所要求的 // PHY。 系统必须将一个25MHz 晶体连接到 OSC //引脚。 晶体时使用 SYSCTL_MOSC_HIGHFREQ 参数 //频率为10MHz 或更高。 // SysCtlMOSCConfigSet (SYSCTL_MOSC_HIGHFREQ); // //从 PLL 以120MHz 运行。 // G_ui32SysClock = MAP_SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000); // //配置器件引脚。 // // // //! 针对 EK-TM4C1294XL 上的标准用法配置器件引脚。 //! //! \param bethernet 是一个布尔值、用于确定以太网引脚的功能。 //! 如果真以太网引脚配置为以太网 LED。 GPIO 是否为假 //! 可供应用使用。 //! \param bUSB 是用于确定 USB 引脚功能的布尔值。 如果是真正的 USB //! 引脚配置为供 USB 使用。 如果为 false、则 USB 引脚可用于 //! 应用程序用作 GPIO。 // // // void // PinoutSet (bool bEthernet、bool bUSB) PinoutSet (true、false); // //配置 UART。 // UARTStdioConfig (0、115200、g_ui32SysClock); // //清除终端并打印横幅。 // UARTprintf ("\033[2J\033[H"); UARTprintf ("以太网 lwIP UDP 回显示例\n"); // //将的端口 N1配置为动画 LED 的输出。 // MAP_GPIOPinTypeGPIOOutput (GPIO_PORTN_BASE、GPIO_PIN_1); // //将 LED 初始化为关闭(0) // MAP_GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_1、~GPIO_PIN_1); // //为周期性中断配置 SysTick。 // MAP_SysTickPeriodSet (g_ui32SysClock / SYSTICKHZ); map_SysTickEnable(); map_SysTickIntEnable(); // //为的以太网控制器过滤配置硬件 MAC 地址 //传入数据包。 MAC 地址将存储在非易失性存储器中 // USER0和 User1寄存器。 // map_FlashUserGet (&ui32User0、&ui32User1); if ((ui32User0 == 0xffffffff)||(ui32User1 == 0xffffffff) { // //我们永远不应该来这里。 如果 MAC 地址有、则这是一个错误 //未编程到器件中。 退出程序。 //告知用户没有 MAC 地址 // UARTprintf ("未对 MAC 进行编程!\n"); while (1) { } } // //告诉用户我们现在正在做什么。 // UARTprintf ("正在等待 IP.\n"); // //将24/24拆分 MAC 地址从 NV RAM 转换为32/16拆分 MAC //对硬件寄存器进行编程所需的地址,然后对 MAC 进行编程 //将地址输入以太网控制器寄存器。 // pui8MACArray[0]=((ui32User0 >> 0)& 0xff); pui8MACArray[1]=((ui32User0 >> 8)& 0xff); pui8MACArray[2]=((ui32User0 >> 16)& 0xff); pui8MACArray[3]=((ui32User1 >> 0)& 0xff); pui8MACArray[4]=((ui32User1 >> 8)& 0xff); pui8MACArray[5]=((ui32User1 >> 16)& 0xff); // //使用 DHCP 初始化 lwIP 库。 // lwIPInit (g_ui32SysClock、pui8MACArray、0、0、0、 ipaddr_use_dhcp); // //初始化回显服务器。 //运行与 TI-RTOS 一起提供的 udpSendReceive Linux 或 Windows 可执行文件。 //可执行文件位于: // \packages/examples\tools\udpSendReceive. //用法:./udpSendReceive. l[length]-s[休眠模式] // 是 IP 地址 // 是否侦听 UDP 端口(23) // 是可执行文件的唯一 ID。 1000个数据包时打印出来 // 传输。 它允许用户运行多个实例 // 接收器的说明。 //可选: //-l[长度] 以字节为单位的数据包大小。 默认为1024字节。 //-s[我们中的睡眠时间]发送之间的睡眠时间。 默认为1000 uSecs。 //示例: // udpSendReceive 192.168.1.5 23 1 -s100 //下列消息将在以下时间开始出现在终端窗口中 //a UDP 封包已回送: // 开始测试时、传输之间的延迟为1000微秒 // [ID 1]计数= 1000、时间= 12 // [ID 1]计数= 2000、时间= 24 // [ID 1]计数= 3000、时间= 36 // udp_echo_init(); // //设置中断优先级。 我们将 SysTick 中断设置为更高的值 //优先级比以太网中断高,以确保文件系统 如果 SysTick 在以太网处理程序运行时发生、则处理// tick //已处理。 这很可能是因为所有 TCP/IP 和 HTTP 工作都是 //在以太网中断上下文中完成。 // MAP_IntPrioritySet (INT_EMAC0、ETHERNET_INT_PRIORITY); MAP_IntPrioritySet (FAULT_SysTick、SysTK_INT_PRIORITY); // //循环永久、处理 LED 闪烁。 所有工作都在中完成 //中断处理程序。 // while (1) { // //等待 SysTick 中断指示更改的状态 // LED。 // while (g_bled == false) { } // //清除标志。 // G_bled = false; // //切换 LED。 // MAP_GPIOPinWrite (GPIO_PORTN_BASE、GPIO_PIN_1、 (MAP_GPIOPinRead (GPIO_PORTN_BASE、GPIO_PIN_1)^ GPIO_PIN_1); } } void udp_echo_recv (void *arg、struct udp_pcb * pcb、struct pbuf * p、struct ip_addr * addr、u16_t port) { if (p!= NULL){ /*将收到的数据包发送回发件人*/ udp_sendto (pcb、p、addr、port); /*释放 pbuf */ pbuf_free (p); } } void udp_echo_init (void) { struct udp_PCB * pcb; /*获取新的 PCB */ PCB = UDP_NEW (); if (PCB == NULL){ LWIP_DEBUGF (UDP_DEBUG、("UDP_NEW FAILED!\n"); 返回; } /*绑定到端口23上的任何 IP 地址*/ if (udp_bind (PCB、IP_ADDR_ANY、23)!= ERR_OK){ LWIP_DEBUGF (UDP_DEBUG、("UDP_BIND FAILED!\n"); 返回; } /*将 udp_echo_recv()设置为回调函数 对于接收到的数据包*/ UDP_recv (PCB、UDP_ECHO_recv、NULL); }

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    将 enet_lwip.c 内容替换为您发送的内容。

    对于 enet_lwip 示例、PinoutSet 的 pinout.c 中没有定义参数。

    UARTStdioConfig 和 UARTprintf 未定义符号。  从何处获取这些函数?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Robert、

     这是项目。

    e2e.ti.com/.../udp_5F00_echo.zip

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我缺少项目中的链接文件。 pinout.c 和 pinout.h
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我使用了 C:\ti\TivaWare_C_Series-2.1.4.178\examples\boards\dk-tm4c129x\drivers 文件夹中的 pinout.c 和 pinout.h、现在可以对其进行编译。 它被分配了一个 IP、我可以对其执行 ping 操作。 如何连接到 ICDI 虚拟 COM 端口?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Robert、

     您需要转到 Windows 设备管理、然后在端口(COM 和 LPT)下查找 ICDI 被枚举的 COM 端口号。 该示例将 UART 配置为115200波特率、1个停止位且无奇偶校验。

     您可以使用 PC 实用程序 \packages\examples\tools\udpSendReceive 专为 TI-RTOS UDP 示例开发、用于测试连接。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您有 Wireshark 吗? 请参阅:wireshark.org

    该程序非常有用。 此外、当我遇到嵌入式系统的网络问题时、我希望在办公桌上创建一个不连接到建筑物其他部分或互联网的隔离式网络。 这有助于诊断问题、因为它消除了其他不相关的系统。

    请注意需要注意的一些与网络相关的注意事项:

    这听起来很基本、但请检查网线! 如果不确定、请尝试使用不同的电缆。

    如果您的 DK 电路板和 PC 通过以太网交换机进行连接、尤其是如果这是不同计算机的更大网络的一部分、则来自电路板的数据报不会出现在您的 PC 上的 Wireshark 中、除非它们实际发送给您的 PC。 这是因为以太网交换机只将通信定向到必要的地方、从而减少/避免冲突。 如果由于配置错误、交换机认为没有必要将某种通信路由到您的 PC、您将看不到它。

    老式集线器(与交换机相反)没有"切换"通信、因此您可以使用 Wireshark 监视连接到集线器的所有计算机。 如果您怀疑交换机存在问题(不太可能但可能)、并且周围有旧式集线器、则可以尝试一下、 但是、由于交叉网络电缆/上行链路端口等原因、您可能会遇到其他问题、因为据我所知、10 MBit 集线器不支持 Auto-MDIX。

    一种更好的方法是直接将 DK 连接到您的 PC、而无需交换机或集线器。 如果您使用具有内置 PHY 的 TM4C 器件、则它支持 Auto-MDIX;如果使用外部 PHY、则必须检查它是否支持该 PHY。 Auto-MDIX 消除了对直通或交叉网络电缆的担忧。 如果通信链路的至少一侧支持 Auto-MDIX、则它适用于任一类型的电缆。

    请注意、如果您的固件依赖于 DHCP、您将需要一个可用的 DHCP 服务器、或者您将需要配置 lwIP 以使用 Auto-IP。 Auto-IP 是在 DHCP 超时并分配自分配 IP 地址后生效的内容。 我认为默认超时时间大约为您的主板自行分配 IP 地址的40秒。 在开始测试之前,您需要检查 PC 上的控制面板或"ipconfig",以验证您的 PC 是否还为自己提供了自分配的 IP (或者,如果使用*nix 样式的操作系统,则需要检查"ifconfig"/"IP addr"或操作系统上的等效项)。

    如果您不想使用 Auto-IP 而乱转、或者您认为它不起作用、但您喜欢将开发板直接连接到您的 PC、并且您需要 DHCP、则可以在您的 PC 上运行 DHCP 服务器。

    Dual Server 是一个很好的程序: dhcp-dns-server.sourceforge.net

    双服务器的优点是可以通过两种不同的方式来运行它:作为一种服务,它可以自动启动计算机并在后台运行,或者--最适合调试的模式-- 作为独立程序、您可以随时启动(例如、从 Windows 开始菜单)和手动停止。 确保计算机未连接到任何其它网络,或者确保配置为专用 DHCP 服务器不会干扰其它网络的 DHCP 服务器--网络上只应有一个 DHCP 服务器。

    通过将开发板直接连接到您的 PC 并在 PC 上运行类似这样的 DHCP 服务器、您可以创建一个仅包含您的 PC 和 DK 的专用网络。

    另一种可能是使用静态 IP 地址,但如果将 PC 设置为静态 IP 地址,则可能需要记住稍后将 PC 设置回 DHCP。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢12月12日下午的信息。  从 enet_lwip 示例中替换 pinout.c 和 pinout.h 后、我现在 看到 的是使用 Wireshark 的 UDP 消息。 我注意到、导入具有链接文件的 CCS 工程不包含链接文件。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    [引用用户="Robert Applebee's ]

    我注意到、导入具有链接文件的 CCS 工程不包含链接文件。

    [/报价]
    您是指作为 TivaWare 的一部分安装的文件吗? 是的、CCS Project Explorer 使其看起来好像所有文件都"在项目中"、但正如您发现的、这并不意味着代码的副本最终会出现在您的工作目录中。 导入项目的操作不会导致所有文件都被复制到磁盘上。 我处理这一问题的方法是自己设置一个空的 TM4C 项目、遵循以下网站中有关"可移植项目"的建议: http://processors.wiki.ti.com/index.php/Portable_Projects
    此外、我使用版本控制(Subversion)、因此我遵循了单独 Wiki 页面上有关要版本的 CCS 文件的建议: http://software-dl.ti.com/ccs/esd/documents/sdto_ccs_source-control.html
    之后、我要确保项目所需的所有文件都实际位于项目目录中!