CCS+C6678LE开发记录08:以太网接口测试示例之代码研究

本文是针对CCS+C6678LE开发记录06:以太网接口测试的后续研究。

在已经通过测试之后我想研究一下测试用例的实现原理,至少应该明白大致原理。

为了方便贴代码,我将原始实例的代码做了精简;

为了探索其原理,我修改/添加了少量代码。

主要代码如下


  
  
  1. #include <stdio.h>
  2. #include <ti/ndk/inc/netmain.h>
  3. #include <ti/sysbios/BIOS.h>
  4. #include <ti/sysbios/knl/Task.h>
  5. #include <xdc/runtime/Error.h>
  6. #include <xdc/runtime/System.h>
  7. #include "ti/platform/platform.h"
  8. #include "ti/platform/resource_mgr.h"
  9. static int counter= 0;
  10. static HANDLE hHello= 0;
  11. char *HostName = "TMS320C6678";
  12. char *LocalIPAddr = "169.254.11.119"; // My PC Local IP
  13. char *LocalIPMask = "255.255.255.0"; // Not used when using DHCP
  14. char *GatewayIP = "192.168.2.101"; // Not used when using DHCP
  15. char *DomainName = "demo.net"; // Not used when using DHCP
  16. char *DNSServer = "0.0.0.0"; // Used when set to anything but zero
  17. Uint8 clientMACAddress[ 6] = { 0x01, 0x02, 0x03, 0x04, 0x0C, 0xEF}; /* MAC Addr */
  18. static void NetworkOpen();
  19. static void NetworkClose();
  20. static void NetworkIPAddr(IPN IPAddr, uint IfIdx, uint fAdd);
  21. extern int dtask_udp_hello();
  22. void EVM_init()
  23. {
  24. printf( "\nEVM_Init()\n");
  25. platform_init_flags sFlags;
  26. platform_init_config sConfig;
  27. memset( ( void *) &sFlags, 0, sizeof(platform_init_flags));
  28. memset( ( void *) &sConfig, 0, sizeof(platform_init_config));
  29. sFlags.pll = 0; /* PLLs for clocking */
  30. sFlags.ddr = 0; /* External memory */
  31. sFlags.tcsl = 1; /* Time stamp counter */
  32. sFlags.phy = 1; /* Ethernet */
  33. sFlags.ecc = 0; /* Memory ECC */
  34. sConfig.pllm = 0; /* Use libraries default clock divisor */
  35. platform_init(&sFlags, &sConfig);
  36. }
  37. Void Hello(UArg arg0, UArg arg1)
  38. {
  39. while( 1)
  40. {
  41. printf( "Hello\n");
  42. Task_sleep( 2000);
  43. if(counter>= 3) break;
  44. }
  45. }
  46. Void Test(UArg arg0,UArg arg1);
  47. int main()
  48. {
  49. Task_Handle task1 = Task_create(Test, NULL, NULL);
  50. Task_Handle task2 = Task_create(Hello, NULL, NULL);
  51. if (task1== NULL || task2== NULL)
  52. {
  53. printf( "Task_create() failed!\n");
  54. BIOS_exit( 0);
  55. }
  56. BIOS_start();
  57. }
  58. Void Test(UArg arg0,UArg arg1)
  59. {
  60. QMSS_CFG_T qmss_cfg;
  61. CPPI_CFG_T cppi_cfg;
  62. uint32_t coreID = platform_get_coreid();
  63. uint32_t master=(coreID== 0)? 1: 0;
  64. qmss_cfg.master_core = master;
  65. qmss_cfg.max_num_desc = MAX_NUM_DESC;
  66. qmss_cfg.desc_size = MAX_DESC_SIZE;
  67. qmss_cfg.mem_region = Qmss_MemRegion_MEMORY_REGION0;
  68. cppi_cfg.master_core = master;
  69. cppi_cfg.dma_num = Cppi_CpDma_PASS_CPDMA;
  70. cppi_cfg.num_tx_queues = NUM_PA_TX_QUEUES;
  71. cppi_cfg.num_rx_channels = NUM_PA_RX_CHANNELS;
  72. res_mgr_init_qmss(&qmss_cfg);
  73. res_mgr_init_cppi(&cppi_cfg);
  74. res_mgr_init_pass();
  75. int rc = NC_SystemOpen( NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT );
  76. if( rc!= 0 )
  77. {
  78. NC_SystemClose();
  79. return;
  80. }
  81. HANDLE hCfg = CfgNew();
  82. if( !hCfg )
  83. {
  84. NC_SystemClose();
  85. return;
  86. }
  87. CfgAddEntry( hCfg,CFGTAG_SYSINFO,CFGITEM_DHCP_HOSTNAME, 0, strlen(HostName),(UINT8*)HostName, 0);
  88. CI_IPNET NA;
  89. bzero( &NA, sizeof(NA) );
  90. NA.IPAddr = inet_addr(LocalIPAddr);
  91. NA.IPMask = inet_addr(LocalIPMask);
  92. strcpy( NA.Domain, DomainName );
  93. NA.NetType = 0;
  94. CfgAddEntry( hCfg, CFGTAG_IPNET, 1, 0, sizeof(CI_IPNET), (UINT8 *)&NA, 0 );
  95. CI_ROUTE RT;
  96. bzero( &RT, sizeof(RT) );
  97. RT.IPDestAddr = 0;
  98. RT.IPDestMask = 0;
  99. RT.IPGateAddr = inet_addr(GatewayIP);
  100. CfgAddEntry( hCfg, CFGTAG_ROUTE, 0, 0, sizeof(CI_ROUTE), (UINT8 *)&RT, 0 );
  101. IPN IPTmp = inet_addr(DNSServer);
  102. if( IPTmp )
  103. {
  104. CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER, 0, sizeof(IPTmp), (UINT8 *)&IPTmp, 0 );
  105. }
  106. rc = DBG_WARN;
  107. CfgAddEntry(hCfg,CFGTAG_OS,CFGITEM_OS_DBGPRINTLEVEL,CFG_ADDMODE_UNIQUE, sizeof(uint),(UINT8 *)&rc, 0);
  108. rc = 8192;
  109. CfgAddEntry(hCfg,CFGTAG_IP,CFGITEM_IP_SOCKUDPRXLIMIT,CFG_ADDMODE_UNIQUE, sizeof(uint),(UINT8 *)&rc, 0);
  110. do
  111. {
  112. rc = NC_NetStart( hCfg, NetworkOpen, NetworkClose, NetworkIPAddr );
  113. } while( rc > 0 );
  114. CfgFree( hCfg );
  115. NC_SystemClose();
  116. }
  117. static void NetworkOpen()
  118. {
  119. hHello = DaemonNew( SOCK_DGRAM, 0, 7,dtask_udp_hello,OS_TASKPRINORM,OS_TASKSTKNORM, 0, 1);
  120. }
  121. static void NetworkClose()
  122. {
  123. DaemonFree( hHello );
  124. }
  125. static void NetworkIPAddr( IPN IPAddr, uint IfIdx, uint fAdd )
  126. {
  127. IPN IPTmp;
  128. if( fAdd ) printf( "Network Added: ");
  129. else printf( "Network Removed: ");
  130. IPTmp = ntohl( IPAddr );
  131. printf( "If-%d:%d.%d.%d.%d\n", IfIdx,
  132. (UINT8)(IPTmp>> 24)& 0xFF,(UINT8)(IPTmp>> 16)& 0xFF,
  133. (UINT8)(IPTmp>> 8)& 0xFF, (UINT8)IPTmp& 0xFF );
  134. }
  135. int dtask_udp_hello( SOCKET s, UINT32 unused )
  136. {
  137. printf( "TASK execution %d\n",++counter);
  138. ( void)unused;
  139. struct timeval tv;
  140. tv.tv_sec = 3;
  141. tv.tv_usec = 0;
  142. setsockopt(s,SOL_SOCKET,SO_SNDTIMEO,&tv, sizeof(tv));
  143. setsockopt(s,SOL_SOCKET,SO_RCVTIMEO,&tv, sizeof(tv));
  144. struct sockaddr_in sin1;
  145. int sz= sizeof(sin1);
  146. int recvSize;
  147. HANDLE hBuffer;
  148. unsigned char* pBuf;
  149. while( 1)
  150. {
  151. recvSize=recvncfrom( s, ( void**)&pBuf, 0, (PSA)&sin1, &sz, &hBuffer );
  152. if(recvSize<= 0) break;
  153. sendto( s, pBuf, recvSize, 0, (PSA)&sin1, sz );
  154. recvncfree( hBuffer );
  155. }
  156. // Since the socket is still open, return "1"
  157. // (we need to leave UDP sockets open)
  158. return 1;
  159. }


其中EVM_init()函数被设置为在main()函数之前执行,具体设置在一个*.cfg文件中,

部分内容如下


  
  
  1. var Memory = xdc.useModule( 'xdc.runtime.Memory');
  2. var BIOS = xdc.useModule( 'ti.sysbios.BIOS');
  3. var Task = xdc.useModule( 'ti.sysbios.knl.Task');
  4. var HeapBuf = xdc.useModule( 'ti.sysbios.heaps.HeapBuf');
  5. var Log = xdc.useModule( 'xdc.runtime.Log');
  6. //...省略...
  7. Program.sectMap[ "sharedL2"] = "DDR3";
  8. Program.sectMap[ "systemHeap"] = "DDR3";
  9. Program.sectMap[ ".sysmem"] = "DDR3";
  10. Program.sectMap[ ".args"] = "DDR3";
  11. Program.sectMap[ ".cio"] = "DDR3";
  12. Program.sectMap[ ".far"] = "DDR3";
  13. Program.sectMap[ ".rodata"] = "DDR3";
  14. Program.sectMap[ ".neardata"] = "DDR3";
  15. //...省略...
  16. Startup.lastFxns.$add( '&EVM_init');
  17. BIOS.taskEnabled = true;
  18. Ecm.eventGroupHwiNum[ 0] = 7;
  19. Ecm.eventGroupHwiNum[ 1] = 8;
  20. Ecm.eventGroupHwiNum[ 2] = 9;
  21. Ecm.eventGroupHwiNum[ 3] = 10;
  22. Global.IPv6 = true;

注意其中的

Startup.lastFxns.$add('&EVM_init');


在主函数中执行BIOS_start()会完成一些主动操作

(似乎是因为main函数在DSP中的地位和在PC上不一样)

总之,在执行完EVM_init()完成基本的初始化后,创建我们的主要任务:

Task_Handle task1 = Task_create(Test, NULL, NULL);
Task_Handle task2 = Task_create(Hello, NULL, NULL);


其中Hello任务只是为了演示一下,每隔2秒(sleep(2000))打印一个“Hello”字样

而Test任务则执行了QMSS、CPPI、PA等等的初始化,完成了基本网络配置

启动Network服务后,关联了dtask_udp_hello任务,等待以太网接口的连接

另一边使用PC执行测试,发送字符串进行交互。


因为我们的程序中设置了一个计数器counter

每次发送一个字符串,dtask_udp_hello()就执行一次,counter++

在Hello任务中,一旦发现条件counter>=3满足了就会退出while()循环,它的使命也就终结了

(注意并不是真的终结,因为没有执行KillTask这样的命令,只是Hello任务不再执行任何操作罢了)

这样只剩下Test任务独自运行了


某次测试如下



发布了0 篇原创文章 · 获赞 123 · 访问量 88万+

猜你喜欢

转载自blog.csdn.net/kunkliu/article/details/104413258
今日推荐