打印

TI的TCP/IP协议栈--NDK(1)

[复制链接]
593|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Orchids|  楼主 | 2017-11-9 10:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
TI的TCP/IP协议栈--NDK


这是之前用TI的DM642做视频编码器用到的网络协议栈,源码TI官网上有的下载。维基网上也有关于NDK的一些技术文档,都是英文的,看了费劲。
看这个之前我对TCP/IP协议几乎不了解,拿到这个就开始看英文文档,天昏地暗的,边看边整理些东西,没基础真的痛苦,硬着头皮看吧。下面都是我边看边整理的,怕丢了,放到这,以后还有用。

       一、NDK中创建任务的方法:
       1、用标准的DSP/BIOS API
  • struct TSK_Attrs ta;
  • ta = TSK_ATTRS;
  • ta.priority = OS_TASKPRINORM;
  • ta.stack = 0;
  • ta.stacksize = stacksize;
  • ta.stackseg = 0;
  • ta.environ = 0;
  • ta.name = "TaskName";
  • ta.exitflag = 0;
  • hMyTask = TSK_create( (Fxn)entrypoint, &ta, arg1, arg2, arg3 );

复制代码
      2、用NDK的任务抽象API
  • hMyTask = TaskCreate( entrypoint, "TaskName", OS_TASKPRINORM, stacksize, arg1, arg2, arg3 );
  • In both cases, hMyTask is a handle to a DSP/BIOS TSK task thread.

复制代码
      二、内存分配
       应用程序在分配内存时最好使用标准的malloc()/free()函数,或者使用DSP/BIOS来分配。

       三、NDK初始化和配置
       1、必须包含NETCTRL.LIB,NETCTRL模块是协议栈初始化、配置和事件调度的核心。
       2、由DSP/BIOS创建的线程是程序的入口点,并且最终成为NETCTRL调度线程。这个控制线程直到协议栈关闭才返回给调用者。
       3、在调用其他任何协议栈API之前必须先调用NC_SystemOpen()函数。它初始化协议栈及其所需内存环境。它的两个参数Priority和OpMode分别决定调度任务的优先级和调度器何时开始执行。
       Priority包括NC_PRIORITY_LOW 和 NC_PRIORITY_HIGH两种,
       OpMode包括NC_OPMODE_POLLING 和 NC_OPMODE_INTERRUPT两种,大部分情况使用interrupt模式,而polling模式会持续运行,当使用polling模式时,优先级必须设为低(NC_PRIORITY_LOW)。
       4、使用实例:
  • //
  • // THIS IS THE FIRST THING DONE IN AN APPLICATION!!
  • //
  • rc = NC_SystemOpen( NC_PRIORITY_LOW, NC_OPMODE_INTERRUPT );
  • if( rc )
  • {
  • printf("NC_SystemOpen Failed (%d)/n",rc);
  • for(;;);
  • }

复制代码

       5、系统配置,包括以下参数:
  • · Network Hostname
  • · IP Address and Subnet Mask
  • · IP Address of Default Routes
  • · Services to be Executed (DHCP, DNS, HTTP, etc.)
  • · IP Address of name servers
  • · Stack Properties (IP routing, socket buffer size, ARP timeouts, etc.)

复制代码

       系统配置开始时调用CfgNew()来创建配置句柄。
       配置好之后调用NC_NetStart()函数,该函数有4个参数,配置句柄,指向开始回调函数的指针,指向结束函数的指针,指向IP地址事件的函数。开始和结束函数都只被调用一次。开始函数在初始化结束准备执行网络应用程序时调用,结束函数在系统完全关闭时调用,意味着协议栈将不能执行网路应用。IP地址事件函数能够多次被调用。
       NC_NetStart()到系统关闭才返回一个关闭代码。
  • //
  • // Boot the system using our configuration
  • //
  • // We keep booting until the function returns 0. This allows
  • // us to have a "reboot" command.
  • //
  • do
  • {
  • rc = NC_NetStart( hCfg, NetworkStart, NetworkStop, NetworkIPAddr );
  • } while( rc > 0 );
  • As an example of a network start callback, the NetworkStart() function below opens a user SMTP server
  • application by calling an open function to create the main application thread.
  • //
  • // NetworkStart
  • //
  • // This function is called after the configuration has booted
  • //
  • static SMTP_Handle hSMTP;
  • static void NetworkStart( )
  • {
  • // Create an SMTP server
  • task hSMTP = SMTP_open( );
  • }
  • //
  • // NetworkStop
  • //
  • // This function is called when the network is shutting down
  • //
  • static void NetworkStop()
  • {
  • // Close our SMTP server task
  • SMTP_close( hSMTP );
  • }

复制代码

       NetworkIPAddr()函数通常用来同步网络任务,该网络任务需要在执行前设置一个本地IP地址。
  • void NetIPCb( IPN IPAddr, uint IfIndex, uint fAdd );
  •     IPAddr            增加或者移除的IP地址
  •     IfIndex           外设接口获取或者移除IP地址的标识
  •     fAdd              增加一个IP地址时设为1,移除IP地址时设为0
  • //
  • // NetworkIPAddr
  • //
  • // This function is called whenever an IP address binding is
  • // added or removed from the system.
  • //
  • static void NetworkIPAddr( IPN IPAddr, uint IfIdx, uint fAdd )
  • {
  • IPN IPTmp;
  • if( fAdd )
  •   printf("Network Added: ");
  • else
  •   printf("Network Removed: ");
  • // Print a message
  • IPTmp = ntohl( IPAddr );
  • printf("If-%d:%d.%d.%d.%d/n", IfIdx,
  •           (UINT8)(IPTmp>>24) & 0xFF,
  •           (UINT8)(IPTmp>>16) & 0xFF,
  •           (UINT8)(IPTmp>>8) & 0xFF,
  •           (UINT8) IPTmp & 0xFF );
  • }

复制代码
      6、关闭协议栈的方法:
       ①手动关闭,NC_NetStop(1)重启网络栈,NC_NetStop(0)关闭网络栈。
       ②当检测到致命错误时关闭,NC_NetStop(-1)。
  • // We do not want the stack to abort on any error禁止错误引起的关闭
  •   uint rc = DBG_NONE;
  •   CfgAddEntry( hCfg, CFGTAG_OS, CFGITEM_OS_DBGABORTLEVEL,
  •                CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

复制代码

       7、追踪服务状态
       当使用NETTOOLS库时,NETTOOLS状态回调函数被引入,这个回调函数追踪被配置使能的服务的状态。状态回调函数有两级,第一个回调由NETTOOLS服务生成,当服务状态改变时它调用配置服务提供者。然后配置服务提供者增加它自己的状态到报告中,并且调用应用程序回调函数。当应用程序增加服务到系统配置中时,一个指向应用程序回调的指针被提供。
  • void StatusCallback( uint Item, uint Status, uint Code, HANDLE hCfgEntry )
  • Item         Item value of entry changed被更改的入口的项目值
  • Status       New status新状态
  • Code         Report code (if any)报告代码
  • hCfgEntry    Non-Referenced HANDLE to entry with status change不引用

复制代码

       实例:
  • //
  • // Service Status Reports
  • //
  • static char *TaskName[] = { "Telnet","HTTP","NAT","DHCPS","DHCPC","DNS" };  //不能改变,在netcfg.h中定义
  • static char *ReportStr[] = { "","Running","Updated","Complete","Fault" };  //不能改变,在nettools.h中定义
  • static char *StatusStr[] = { "Disabled", "Waiting", "IPTerm", "Failed", "Enabled" }
  • static void ServiceReport( uint Item, uint Status, uint Report, HANDLE h )
  • {
  • printf( "Service Status: %-9s: %-9s: %-9s: %03d/n",
  •   TaskName[Item-1], StatusStr[Status],
  •   ReportStr[Report/256], Report&0xFF );
  • }

复制代码

       以上函数打印的最后一个值是答应通过Report传递的低8位的值,这个值是固定的,大部分情况下这个值不需要。通常,如果服务成功,它报告Complete,失败,他报告Fault。对于那些不会结束的服务(例如,当IP分配启动时,DHCP客户端会持续运行),Report的高位字节意味着Running,而服务特定的低字节必须被用来指定当前状态。
       For example, the status codes returned in the 8 least significant bits of Report when using the DHCP client service are:
  • DHCPCODE_IPADD           Client has added an IP address
  • DHCPCODE_IPREMOVE        IP address removed and CFG erased
  • DHCPCODE_IPRENEW         IP renewed, DHCP config space reset

复制代码

       大部分情况下不必去核对这些状态报告代码,除非以下情况:
       当使用DHCP客户端来配置协议栈,DHCP客户端控制CFGTAG_SYSINFO标签空间的前256个入口。这些入口与这256个DHCP操作标签通信。应用程序可以检查DHCPCODE_IPADD或者DHCPCODE_IPRENEW返回代码以便它能够读或者改变通过DHCP客户端获得的信息。
       8、不使用DHCP client时,手动配置DNS的IP地址方法如下:
  • IPN IPTmp;
  • // Manually add the DNS server "128.114.12.2"
  • IPTmp = inet_addr("128.114.12.2");
  • CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER,
  •   0, sizeof(IPTmp), (UINT8 *)&IPTmp, 0 );

复制代码
      如果以上代码被加到使用DHCP的应用程序中,当DHCP执行状态更新时这个入口将会被清除。
      



[color=rgb(51, 102, 153) !important]

相关帖子

发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

697

主题

993

帖子

4

粉丝