[AT32F407] 【AT-START-F407测评】+udp通讯测试

[复制链接]
 楼主| yinwuqing110 发表于 2023-1-8 20:46 | 显示全部楼层 |阅读模式
        AT-START-F407板载以太网PHY带RJ45连接器,以太网PHY联杰DM9162NP支持10/100Mbps双速以太网通讯,使用以太网MAC时,JP8连体跳线须选择右测IO端。本次工程是在参考官方提供的FreeRTOS例程上,移植进lwip源码,实现PC端与AT-START-F407建立UDP网络通讯。本来想通过0.96寸OLED屏显示PC端发送过来的数据,但不知道是OLED屏硬件的问题还是AT-START-F407板子设置的问题,硬是没能成功驱动。论坛上有坛友使用AT-START-F407成功驱动OLED屏的,奇怪的是采用仿STM32的代码驱动,初始化GPIO函数中还带有“GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_10MHz;”,雅特力官方的外设库中并没有所谓的“GPIO_MaxSpeed ”成员参数,也不知道坛友们是如何封装并顺利驱动的。
        移植lwip,首先得进入lwip官网,下载最新的“lwIP 2.1.3 released”版本,网址:https://savannah.nongnu.org/projects/lwip/
        然后参考“at32f403a_407_freertos_demo”工程,将lwip源码加入到工程中,并添加头文件路径。官方提供的“at32f407_emac_iap_demo”可借鉴一下,主要用到开发板上的emac模块驱动,DM9162NP相关PHY底层库函数。
        在主函数中创建四个进程任务,任务优先级都设置成2,多任务并发执行,任务四中的udp接收线程优先级设置成1。部分参考代码如下:
  1. #include "at32f403a_407_board.h"
  2. #include "at32f403a_407_clock.h"
  3. #include "at32_emac.h"
  4. #include "stdio.h"
  5. #include "FreeRTOS.h"
  6. #include "task.h"

  7. extern void tcpip_stack_init(void);
  8. extern void udpecho_init(void);

  9. TaskHandle_t led2_handler;
  10. TaskHandle_t led3_handler;
  11. TaskHandle_t led4_handler;
  12. TaskHandle_t network_handler;

  13. /* led2 task */
  14. void led2_task_function(void *pvParameters);
  15. /* led3 task */
  16. void led3_task_function(void *pvParameters);
  17. /* led4 task */
  18. void led4_task_function(void *pvParameters);
  19. /* AppTaskCreate task */
  20. void AppTaskCreate(void *pvParameters);

  21. int main(void)
  22. {
  23.   nvic_priority_group_config(NVIC_PRIORITY_GROUP_4);
  24.   system_clock_config();
  25.   
  26.   /* init led2*/
  27.   at32_led_init(LED2);
  28.   /* init led3*/
  29.   at32_led_init(LED3);
  30.   /* init led4*/
  31.   at32_led_init(LED4);
  32.   
  33.   /* init usart1 */
  34.   uart_print_init(115200);
  35.   
  36.   /* enter critical */
  37.   taskENTER_CRITICAL();

  38.   /* create led2 task */
  39.   if(xTaskCreate((TaskFunction_t )led2_task_function,     
  40.                  (const char*    )"LED2_task",   
  41.                  (uint16_t       )512,
  42.                  (void*          )NULL,
  43.                  (UBaseType_t    )2,
  44.                  (TaskHandle_t*  )&led2_handler) != pdPASS)
  45.   {
  46.     printf("LED2 task could not be created as there was insufficient heap memory remaining.\r\n");
  47.   }        
  48.   else
  49.   {
  50.     printf("LED2 task was created successfully.\r\n");
  51.   }
  52.           /* create led3 task */
  53.   if(xTaskCreate((TaskFunction_t )led3_task_function,     
  54.                  (const char*    )"LED3_task",   
  55.                  (uint16_t       )512,
  56.                  (void*          )NULL,
  57.                  (UBaseType_t    )2,
  58.                  (TaskHandle_t*  )&led2_handler) != pdPASS)
  59.   {
  60.     printf("LED3 task could not be created as there was insufficient heap memory remaining.\r\n");
  61.   }        
  62.   else
  63.   {
  64.     printf("LED3 task was created successfully.\r\n");
  65.   }
  66.           /* create led4 task */
  67.   if(xTaskCreate((TaskFunction_t )led4_task_function,     
  68.                  (const char*    )"LED4_task",   
  69.                  (uint16_t       )512,
  70.                  (void*          )NULL,
  71.                  (UBaseType_t    )2,
  72.                  (TaskHandle_t*  )&led4_handler) != pdPASS)
  73.   {
  74.     printf("LED4 task could not be created as there was insufficient heap memory remaining.\r\n");
  75.   }        
  76.   else
  77.   {
  78.     printf("LED4 task was created successfully.\r\n");
  79.   }
  80.   if(xTaskCreate((TaskFunction_t )AppTaskCreate,     
  81.                  (const char*    )"AppTaskCreate_task",   
  82.                  (uint16_t       )512,
  83.                  (void*          )NULL,
  84.                  (UBaseType_t    )2,
  85.                  (TaskHandle_t*  )&network_handler) != pdPASS)
  86.   {
  87.     printf("AppTaskCreate task could not be created.\r\n");
  88.   }        
  89.   else
  90.   {
  91.     printf("AppTaskCreate task was created successfully.\r\n");
  92.   }
  93.   
  94.   /* exit critical */            
  95.   taskEXIT_CRITICAL();      
  96.               
  97.   /* start scheduler */            
  98.   vTaskStartScheduler();
  99.   
  100. }

  101. /* led2 task function */
  102. void led2_task_function(void *pvParameters)
  103. {
  104.   while(1)
  105.   {
  106.     at32_led_toggle(LED2);
  107.     vTaskDelay(500);
  108.   }
  109. }

  110. /* led3 task function */
  111. void led3_task_function(void *pvParameters)
  112. {
  113.   while(1)
  114.   {
  115.     at32_led_toggle(LED3);
  116.     vTaskDelay(500);
  117.   }
  118. }
  119. /* led4 task function */
  120. void led4_task_function(void *pvParameters)
  121. {
  122.   while(1)
  123.   {
  124.     at32_led_toggle(LED4);
  125.     vTaskDelay(500);
  126.   }
  127. }
  128. /* AppTaskCreate_task */
  129. void AppTaskCreate(void *pvParameters)
  130. {
  131.   while(emac_system_init() == ERROR);
  132.   tcpip_stack_init();
  133.   udpecho_init();
  134.   while(1)
  135.   {
  136.     vTaskDelay(500);
  137.   }
  138. }
   netconf.c中设置本地ip,这里使用静态分配ip地址,没有使能DHCP功能。
  1. #include "lwip/memp.h"
  2. #include "lwip/tcp.h"
  3. #include "lwip/priv/tcp_priv.h"
  4. #include "lwip/udp.h"
  5. #include "netif/etharp.h"
  6. #include "lwip/dhcp.h"
  7. #include "ethernetif.h"
  8. #include "netconf.h"
  9. #include "stdio.h"
  10. #include "at32_emac.h"

  11. #define MAC_ADDR_LENGTH                  (6)
  12. #define ADDR_LENGTH                      (4)

  13. struct netif netif;
  14. TaskHandle_t link_status_handler;
  15. volatile uint32_t tcp_timer = 0;
  16. volatile uint32_t arp_timer = 0;

  17. static uint8_t mac_address[MAC_ADDR_LENGTH] = {0, 0, 0x44, 0x45, 0x56, 1};
  18. #if LWIP_DHCP
  19. volatile uint32_t dhcp_fine_timer = 0;
  20. volatile uint32_t dhcp_coarse_timer = 0;
  21. #else
  22. static uint8_t local_ip[ADDR_LENGTH]   = {192, 168, 0, 105};
  23. static uint8_t local_gw[ADDR_LENGTH]   = {192, 168, 0, 1};
  24. static uint8_t local_mask[ADDR_LENGTH] = {255, 255, 255, 0};
  25. #endif

  26. void tcpip_stack_init(void)
  27. {
  28.   ip_addr_t ipaddr;
  29.   ip_addr_t netmask;
  30.   ip_addr_t gw;
  31.   
  32.   /* Initializes the dynamic memory heap defined by MEM_SIZE.*/
  33.   mem_init();

  34.   /* Initializes the memory pools defined by MEMP_NUM_x.*/
  35.   memp_init();


  36. #if LWIP_DHCP  //need DHCP server
  37.   ipaddr.addr = 0;
  38.   netmask.addr = 0;
  39.   gw.addr = 0;

  40. #else
  41.   IP4_ADDR(&ipaddr, local_ip[0], local_ip[1], local_ip[2], local_ip[3]);
  42.   IP4_ADDR(&netmask, local_mask[0], local_mask[1], local_mask[2], local_mask[3]);
  43.   IP4_ADDR(&gw, local_gw[0], local_gw[1], local_gw[2], local_gw[3]);
  44.         printf("\r\n");
  45.         printf("local_ip:%d.%d.%d.%d\r\n",local_ip[0], local_ip[1], local_ip[2], local_ip[3]);
  46.         printf("local_mask:%d.%d.%d.%d\r\n",local_mask[0], local_mask[1], local_mask[2], local_mask[3]);
  47.         printf("local_gw:%d.%d.%d.%d\r\n",local_gw[0], local_gw[1], local_gw[2], local_gw[3]);
  48. #endif

  49.   lwip_set_mac_address(mac_address);
  50. if(netif_add(&netif, &ipaddr, &netmask, &gw, NULL, ðernetif_init, &netif_input) == NULL)
  51.   {
  52.     while(1);
  53.   }
  54.   
  55.   /*  Registers the default network interface.*/
  56.   netif_set_default(&netif);

  57. #if LWIP_DHCP
  58. dhcp_start(&netif);
  59. #endif
  60. /*  When the netif is fully configured this function must be called.*/
  61.   netif_set_up(&netif);  
  62.   
  63.   /* Set the link callback function, this function is called on change of link status*/
  64.   netif_set_link_callback(&netif, ethernetif_update_config);
  65.   
  66.   /* Create the Ethernet link handler thread */
  67.   xTaskCreate((TaskFunction_t)ethernetif_set_link, "ethernetif_set_link", 512, &netif, tskIDLE_PRIORITY + 3, &link_status_handler);
  68. }

  69. void lwip_pkt_handle(void)
  70. {
  71.   /* Read a received packet from the Ethernet buffers and send it to the lwIP for handling */
  72.   if(ethernetif_input(&netif) != ERR_OK)
  73.   {
  74.     while(1);
  75.   }
  76. }

  77. void lwip_periodic_handle(volatile uint32_t localtime)
  78. {
  79.   /* TCP periodic process every 250 ms */
  80.   if (localtime - tcp_timer >= TCP_TMR_INTERVAL)
  81.   {
  82.     tcp_timer =  localtime;
  83.     tcp_tmr();
  84.   }
  85.   /* ARP periodic process every 5s */
  86.   if (localtime - arp_timer >= ARP_TMR_INTERVAL)
  87.   {
  88.     arp_timer =  localtime;
  89.     etharp_tmr();
  90.   }

  91. #if LWIP_DHCP
  92.   /* Fine DHCP periodic process every 500ms */
  93.   if (localtime - dhcp_fine_timer >= DHCP_FINE_TIMER_MSECS)
  94.   {
  95.     dhcp_fine_timer =  localtime;
  96.     dhcp_fine_tmr();
  97.   }
  98.   /* DHCP Coarse periodic process every 60s */
  99.   if (localtime - dhcp_coarse_timer >= DHCP_COARSE_TIMER_MSECS)
  100.   {
  101.     dhcp_coarse_timer =  localtime;
  102.     dhcp_coarse_tmr();
  103.   }
  104. #endif
  105. }
  1. #include "lwip/opt.h"

  2. #if LWIP_NETCONN
  3. #include "lwip/api.h"
  4. #include "lwip/sys.h"

  5. #define UDPECHO_THREAD_PRIO          1
  6. #define UDPECHO_STK_SIZE                         256  
  7. TaskHandle_t Udpecho_Handler;

  8. static struct netconn *conn;
  9. static struct netbuf *buf;
  10. static ip_addr_t *addr;
  11. static unsigned short port;
  12. static void udpecho_thread(void *arg)
  13. {
  14.   err_t err, recv_err;

  15.   LWIP_UNUSED_ARG(arg);

  16.   conn = netconn_new(NETCONN_UDP);
  17.         printf("connection create successfully\n");
  18.   if (conn!= NULL)
  19.   {
  20.     err = netconn_bind(conn, IP_ADDR_ANY, 8080);
  21.                 printf("bind successfully\n");
  22.     if (err == ERR_OK)
  23.     {
  24.       while (1)
  25.       {
  26.                                 printf("Receiving...\n");
  27.         recv_err = netconn_recv(conn, &buf);
  28.                                 printf("Received done\n");

  29.         if (recv_err == ERR_OK)
  30.         {
  31.           addr = netbuf_fromaddr(buf);
  32.           port = netbuf_fromport(buf);
  33.           netconn_connect(conn, addr, port);
  34.           buf->addr.addr = 0;
  35.           netconn_send(conn,buf);
  36.           netbuf_delete(buf);
  37.         }
  38.       }
  39.     }
  40.     else
  41.     {
  42.       netconn_delete(conn);
  43.     }
  44.   }
  45. }
  46. void udpecho_init(void)
  47. {
  48.   sys_thread_new("udpecho_thread", udpecho_thread, NULL, UDPECHO_STK_SIZE,UDPECHO_THREAD_PRIO );       
  49. }
  50. #endif /* LWIP_NETCONN */
     编译、下载到开发板中,PC端打开串口调试助手,根据串口输出信息,先在“cmd窗口”中ping一下,看是否能够正常ping通。
打印信息.png
ping信息.png
      然后在PC端中打开“netassist”网路调试助手,并设置好udp通讯方式,本地主机地址(PC)的ip地址,端口号设置成代码中设定的8080;根据串口打印信息,设置远程主机(AT-START-F407)的ip地址,端口号同样设置成8080。
netassist.zip (548.52 KB, 下载次数: 4)
网络通讯.gif
        开发板上的各个指示灯显示如下:
现象.gif
         一路走来,感觉移植lwip还是需要点耐心的,结合FreeRTOS,需要打开的宏必须得打开,否则会报莫名其妙的error,这里尤其注意在“FreeRTOS.h”的文件中,打开“configUSE_COUNTING_SEMAPHORES”宏。以下附件为工程文件,此次分享就告一段落,咱们后会有期。
FreeRTOS_lwip_project.zip (4.81 MB, 下载次数: 12)
updownq 发表于 2023-1-9 10:42 | 显示全部楼层
这个udp的速度怎么样              
 楼主| yinwuqing110 发表于 2023-1-9 13:42 | 显示全部楼层
updownq 发表于 2023-1-9 10:42
这个udp的速度怎么样

挺快的呀,具体数值就没测了
claretttt 发表于 2023-1-9 14:43 | 显示全部楼层
使用的是哪个网络模块?              
 楼主| yinwuqing110 发表于 2023-1-10 09:29 | 显示全部楼层
claretttt 发表于 2023-1-9 14:43
使用的是哪个网络模块?

开发板上就有集成的DM9162NP芯片呀
您需要登录后才可以回帖 登录 | 注册

本版积分规则

106

主题

1096

帖子

7

粉丝
快速回复 返回顶部 返回列表