1 / 58

TI C64x 的网络开发应用技术

作者 :risc700@gmail.com. TI C64x 的网络开发应用技术. OSI 和 TCP/IP 网络层次模型 SOCKET 函数 TI DSP 平台下网络开发工具 ——NDK NDK 的结构,基本使用方法 NDK 的 web server 开发 NDK 的流媒体组播开发 NDK 使用经验总结. 讨论的主要内容. 应用层. 传输层. 应用层. 网络层. 表示层. 物理层. 会话层. 传输层. 网络层. 数据链路层. 物理层. OSI 和 TCP/IP 网络层次模型. 抽象的数据. 多样的 物理的数据. TCP/IP 模型.

rasia
Télécharger la présentation

TI C64x 的网络开发应用技术

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 作者:risc700@gmail.com. TI C64x的网络开发应用技术

  2. OSI和TCP/IP网络层次模型 SOCKET函数 TI DSP平台下网络开发工具——NDK NDK的结构,基本使用方法 NDK的web server开发 NDK的流媒体组播开发 NDK使用经验总结 讨论的主要内容

  3. 应用层 传输层 应用层 网络层 表示层 物理层 会话层 传输层 网络层 数据链路层 物理层 OSI和TCP/IP网络层次模型 抽象的数据 多样的 物理的数据 TCP/IP模型 OSI模型 • 开放式系统互联模型(ISO) 结构完整严谨,设计先于实现,体系复杂, 而过于理想 • 各层有不同的协议 • 协议的开销

  4. 数据包的封装,解封装 • 封装 指在发送数据过程中,数据自上而下经过每一层时,每层为数据添加上特定的头部/尾部信息的操作。 应用层 →协议数据头(HTTP头,RTP头…)  传输层 →UDP头 TCP头 网络层 →IP头 物理层 →MAC地址头 解封装    所谓解封装是指在接收方发生的自下而上的过程逐层的去掉头部以及尾部信息

  5. TCP/IP物理层 • 1,OSI模型中的物理层, 此层规范了通讯设备的电气特性和物理特性,功能上为数据链路层提供物理连接。在其上串行传送比特流。 RS232,以太网,FDDI,令牌环网,WIFI, IrDA • 2,OSI模型中的数据链路层.包括LLC(Logic Link Control ) 和MAC(媒体访问控制器)子层 LLC负责与上层(网络层)通讯, MAC负责对物理层的控制。 本层的典型设备是SWITCH(交换机) ADLS拨号所使用的PPPoe协议,也是建立在此层次上的

  6. TCP/IP(网络层与传输层) • 3、网络层:本层的作用是负责对数据包的路由工作。 路由表的建立,维护,数据包的转发等等.(IP协议工作的层) 典型设备:路由器 • 4、传输层:本层将应用数据分包,建立端到端的虚连接,提供可靠或者不可靠传输。 • TCP传输 • 特点:流式传输(stream):需要分包 • 面向连接(通过“滑动窗口”等方法确保数据准确) • 提供可靠的传输服务——可靠性高 • UDP传输 • 特点: 包式传输(packet):通常不需要分包 • 无连接:不需要虚连接,可能会丢包,乱序 • 提供尽力而为(Best-Effort)的服务——效率 • ARP,ICMP(Internet Control Message Protocol)……

  7. TCP/IP(应用层) • 5、OSI会话层:本层负责两个应用之间会话的管理和维护。 • 6、OSI表示层:本层解决数据的表示、转换问题,是人机之间通讯的协调者,如进行二进制与ASCII码的转换。 • 7、OSI应用层:本层是人机通讯的接口。 HTTP,FTP,POP3,SMTP,RTP…….

  8. 举例:UDP数据包结构

  9. UDP数据包结构举例

  10. UDP数据包结构举例 没有描述包顺序的信息,因此收方无法判断包颠倒/包重复/包丢失

  11. TCP数据包结构举例

  12. TCP数据包结构举例

  13. TCP数据包结构举例

  14. 数据包结构中重要字段 数据包结构中重要字段 ●TTL(Time To Live,生存时间):每经过路由器一次,此值减一。如果该值为0路由器就不会再转发此数据包。(IP层) ●Protocol(协议):网络层和传输层之间的通讯接口,用于识别传输层的传输协议。 ●Identification(序号):对每发送的一个数据包进行编号。注意:收方不能依靠这个标记判断包连续 

  15. 基本Socket函数的介绍 Socket接口是TCP/IP网络的API,Socket接口定义了许多函数或例程,开发者用它们来开发TCP/IP网络上的应用程序。要学Internet上的TCP/IP网络编程,必须理解Socket接口。 • linux/window下网络开发,以及dsp下网络开发的相似性

  16. Socket函数的介绍 1.UDP Send Client SOCKET socket( int af, int type, int protocol ); int bind(int sockfd,struct sockaddr *my_addr, int addrlen); int sendto(SOCKET s, void *pbuf, int size, int flags, struct sockaddr* pName, int len ); 2.UDP Recive Client SOCKET socket( int domain, int type, int protocol ); int bind(int sockfd,struct sockaddr *my_addr, int addrlen); Int recvfrom(SOCKET s, void *pbuf, int size, int flags, struct sockaddr* pName, int *plen );

  17. Socket函数的介绍 • 3. TCP Client • SOCKET socket( int domain, int type, int protocol ); • int bind(int sockfd,struct sockaddr *my_addr, int addrlen); • int connect( SOCKET s, struct sockaddr* pName, int len ); • int recv( SOCKET s, void *pbuf, int size, int flags ); • int send( SOCKET s, void *pbuf, int size, int flags ); • 4. TCP Server • SOCKET accept( SOCKET s, struct sockaddr* pName, int *plen ); • int bind(int sockfd,struct sockaddr *my_addr, int addrlen); • int listen( SOCKET s, int maxcon ); • SOCKET accept( SOCKET s, struct sockaddr* pName, int *plen ); • int recv( SOCKET s, void *pbuf, int size, int flags ); • int send( SOCKET s, void *pbuf, int size, int flags );

  18. Socket函数的介绍 • 5.设置读取网络参数 • int setsockopt( SOCKET s, int level, int op, • void *pbuf, int bufsize ); • int getsockopt( SOCKET s, int level, int op, • void *pbuf, int *pbufsize ); • 设置buffer大小、超时时间,TTL生存时间,TCP分包大小…….. • 6.读取一个有连接socket的远端点信息 • int getpeername( SOCKET s, PSA pName, int *plen ); • 7.读取一个socket的近端点信息(bind参数) • int getsockname( SOCKET s, PSA pName, int *plen ); • 8. 通过域名获得ip地址 struct hostent * gethostbyname(const char* name);

  19. TI DSP平台下网络开发工具——NDK • Code Composer Studio™ (CCStudio) Development Tools TI 推出的for TI DSP的集成开发环境,包括IDE,编译器,优化器,调试器,DSP模拟器等,还支持很多JTAG口上的高级功能(RTDX)。编译优化器支持汇编,C , C++语言,对于TI DSP程序的开发,基本都在CCS上进行。 版本: V2.2 V3.0 V3.3 • DSP/BIOS 由TI开发的,运行在TI DSP平台上的,具有简单操作系统功能的函数包。它具有简单的内存管理,多任务调度,任务(Task)间通讯(Semaphore, Mailbox, Queue, Resource Lock…..)等。 版本:V4.9 V5.2 V5.31

  20. TI DSP平台下网络开发工具——NDK Network Developer's Kit NDK是TI提供的一个相对完整的TCP/IP Stack及一些网络工具包,还集成了一些常用的网络服务器组件。 NDK的版本 • 有1.61, 1.71, 1.92。 • 每个版本又分两个不同的模式,其中一个是有driver的source code。 • 哪里得到? • 一般购买开发板,会附带一个安装包。

  21. NDK目录结构 • 安装文件 100_O_NDK_TMS320_1_92_00_22.exe Ndk的安装没有路径限制

  22. ndk相关文档 • SPRU523 —TMS320C6000 Network Developer's Kit (NDK) Software User's Guide • SPRU524 —TMS320C6000 Network Developer's Kit (NDK) Programmer’s Reference Guide. • SPRU189 —TMS320C6000 DSP CPU and Instruction Set Reference Guide. • SPRU198 —TMS320C6000 Programmer's Guide. • SPRU509 —TMS320C6000 Code Composer Studio ™Development Tools v3.3 Getting Started Guide.

  23. NDK介绍 NDK把操作系统(DSP/BIOS)抽象为OS Adaptation Layer(操作系统适应层),以适应不同的操作系统,它对应OS.LIB. NDK把底层硬件抽象成Hardware Abstraction Layer(硬件抽象层),以适应不同的底层硬件接口,它对应HAL.LIB.

  24. NDK工作结构图

  25. NDK功能 • IP Stack • DHCP client • DNS client • IGMP (Internet Group Management Protocol) • DHCP Server • DNS Server • HTTP Server • NAT Service (Network Address Translation) • ………

  26. 把NDK添加到项目中 • 配置DSP/BISO ,(tcf文件,cdb文件) • 包含h文件,链接lib文件 • 配置DNK所使用的内存块(cmd文件) • 配置启动NetControl模块

  27. 把NDK添加到项目中 1.DSP/BIOS修改(项目中的cdb文件) 增加PRD object (Periodic Function Manager) 定期调用位于NDK的驱动层的函数llTimerTick(). 这个调用时间间隔需要配置为100ms

  28. 把NDK添加到项目中 增加HOOK Object NDK运行时,需要使用一些各个运行task的环境信息. 为此需要在DSP/BIOS的hook module 模块建立一个hook,这个hook调用了NDK_hookInit(),NDK_hookCreate()这两个函数.

  29. 把NDK添加到项目中 • 包含头文件 把NDK下inc目录,增加到.h的搜索路径中 通常在project的项目属性中修改(.pjt) • 在项目中链接NDK的LIB库文件 NETCTRL.LIB HAL_xxx.LIB NETTOOL.LIB STACK.LIB OS.LIB MiniPrintf.LIB 需要注意CCStudio Project Link Order 通常在 .cmd( Linker-command file )文件中设置

  30. 把NDK添加到项目中 配置NDK 的所用到的Memory block(不是必须的) .far:NDK_PACKETMEM —packet buffer memory The size required is normally 32k bytes to 48k bytes. .far:NDK_MMBUFFER — a scratchpad memory default is less than 48k bytes.(adjustable) . far:NDK_OBJMEM — other large data buffe the example in project CMD file: SECTIONS { .far:PACKETMEM: {} > MYSDRAM .far:MMBUFFER: {} > MYSDRAM .far:OBJMEM: {} > MYSDRAM }

  31. 启动NDKtask • 创建NDK使用的task struct TSK_Attrs attr; attr=TSK_ATTRS; attr.priority=8; attr.name="network"; attr.stack = 0; attr.stacksize = 15*1024; // <= 32*1024 >=4*1024 attr.stackseg = extHeap; htsk_network=TSK_create((Fxn)network_main, &attr); if(htsk_network == NULL) { printf("TSK_create((Fxn)network_main error!\n"); exit(0); }

  32. NDK Task中的主要工作 • 初始化NetControl • 配置NetControl • 运行NetControl

  33. 初始化NetControl • 1.初始化协议栈,及协议栈组件 int NC_SystemOpen (int Priority, int OpMode); 注意此函数会自动调整NDK task的Priority 的优先级(6,7,8) 另外所有使用NDK的其他task的Priority不能超过NDK rc = NC_SystemOpen( NC_PRIORITY_HIGH, NC_OPMODE_INTERRUPT );

  34. 配置NetControl 创建一个NDK 的配置结构. HANDLE hCfg = CfgNew(); Configuration Functions: CfgNew() Create a new configuration CfgFree() Destroy a configuration CfgSetDefault() Set default configuration CfgGetDefault() Get default configuration CfgLoad() Load configuration from a linear memory buffer CfgSave() Save configuration to a linear memory buffer CfgAddEntry() Add a configuration entry to a configuration CfgRemoveEntry() Remove entry from configuration CfgGetEntryCnt() Get the number of item instances for a tag/item pair CfgGetEntry() Get a referenced handle to a configuration entry CfgEntryGetData() Get configuration entry data from entry handle CfgEntrySetData() Replace data block of entry data using entry handle

  35. 配置NetControl 3.配置NetControl int CfgAddEntry(HANDLE hCfg, uint Tag, uint Item, uint Mode, uint Size, UINT8 *pData, HANDLE *phCfgEntry); Tag :Tag value of new entry Item :Item value of new entry Mode :Mode flags for how to add entry 需要要设置的信息有: 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.)

  36. Tag种类 CFGTAG_SERVICE Network Service CFGTAG_IPNET IP Network (Address, subnet mask, etc.) CFGTAG_ROUTE IP Gateway Route CFGTAG_CLIENT IP Client (Client IP, Hostname, etc) CFGTAG_ACCT Client user account (name, password, etc.) CFGTAG_SYSINFO Global System Information CFGTAG_OS Operating System Configuration entry CFGTAG_IP IP Stack Configuration entry

  37. 配置NetControl的例子 // Add our global hostname CfgAddEntry( hCfg, CFGTAG_SYSINFO,CFGITEM_DHCP_HOSTNAME, 0,strlen(HostName), (UINT8 *)HostName, 0 ); //配置IP CI_IPNET NA; CfgAddEntry( hCfg, CFGTAG_IPNET, 1, 0, sizeof(CI_IPNET), (UINT8 *)&NA, 0 ); //配置网关 CfgAddEntry( hCfg, CFGTAG_ROUTE, 0, 0, sizeof(CI_ROUTE), (UINT8 *)&RT, 0 ); //配置DNS CfgAddEntry( hCfg, CFGTAG_SYSINFO, CFGITEM_DHCP_DOMAINNAMESERVER, 0, sizeof(IPTmp), (UINT8 *)&IPTmp, 0 );

  38. 配置NetControl的例子 //Highest priority for stack task rc = 1; CfgAddEntry( hCfg, CFGTAG_OS, CFGITEM_OS_TASKPRIHIGH,CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 ); // This code sets up the TCP and UDP buffer sizes rc = 1664*10; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPTXBUF, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 ); // TCP Receive buffer size (copy mode) rc = 1664*10; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXBUF, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 ); // TCP Receive limit (non-copy mode) rc = 1664*10; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTCPRXLIMIT, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 ); // UDP Receive limit rc = 1664*400; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKUDPRXLIMIT, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

  39. 配置NetControl的例子 // Timeout of validated route in seconds rc = 1; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_RTKEEPALIVETIME, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 ); // Max time for connect socket rc = 100000; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTIMECONNECT, / CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 ); // Max time in seconds to wait on socket read/write rc = 1000; CfgAddEntry( hCfg, CFGTAG_IP, CFGITEM_IP_SOCKTIMEIO, CFG_ADDMODE_UNIQUE, sizeof(uint), (UINT8 *)&rc, 0 );

  40. 启动NetControl int NC_NetStart(HANDLE hCfg, void (*NetStartCb)(), void (*NetStopCb)(), void (*NetIPCb)(IPN,uint,uint)); do { rc = NC_NetStart( hCfg, NetworkOpen, NetworkClose, NetworkIPAddr ); } while( rc > 0 );

  41. NDK task的例子 DM642 EVM板配套的安装程序安装之后,会有一个$(Install_dir)\boards\evmdm642\examples\video_networking\jpeg_network\jpeg_network.pjt 项目。 这个项目里有一个network_main.c 的文件。这个文件展示了ndk的初始化的过程。 在使用ndk之前,要了解这个文件。

  42. NDK 2个重要的回调函数 获得MAC地址 void DM642EMAC_getConfig( UINT8 *pMacAddr, uint *pIntVector ); pMacAddr 返回一个6byte的MAC地址 报告网络联接状态 void DM642EMAC_linkStatus( uint phy, uint linkStatus ) phy 物理口标识 linkStatus 连接状态

  43. 一个UDP Send Client的例子 Char buf[1024]; fdOpenSession( TaskSelf() ); MBX_pend(mbx_audio_decoder,&recv_msg,SYS_FOREVER); struct sockaddr_in sendinfo; HANDLE soch = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); memset(&sendinfo, 0, sizeof(struct sockaddr_in)); sendinfo.sin_family = AF_INET; sendinfo.sin_len = sizeof(struct sockaddr_in); sendinfo.sin_addr.s_addr = inet_addr(“192.168.1.100”); sendinfo.sin_port = htons(8888); sendto(buf,1024, 0,&(sendinfo), sizeof(struct sockaddr_in)); 注意点: 1.如果在一个task中要使用socket函数,必须首先调用fdOpenSession, 之后才能使用任何其它的socket 函数。 2.任务结束的时候需要使用fdCloseSession(). 要不然会有内存泄露。

  44. NDK上Web Server 开发 • 配置Web Server • 增加网页 • 编写CGI程序 • 增加网页的身份认证

  45. 配置Web Server 通过hCfg,配置Web Server // Specify HTTP service CI_SERVICE_HTTP http; bzero( &http, sizeof(http) ); http.cisargs.IPAddr = INADDR_ANY; http.cisargs.pCbSrv = &ServiceReport;//一个用于汇报状态的函数 CfgAddEntry( hCfg, CFGTAG_SERVICE, CFGITEM_SERVICE_HTTP, 0, sizeof(http), (UINT8 *)&http, 0 );

  46. 增加网页 Create (declare) a RAM Based File void efs_createfile (char *name, INT32 length, UINT8 *pData); efs_createfile() Create (declare) RAM based file efs_destroyfile() Destroy RAM based file efs_fopen() Open file efs_fclose() Close file efs_feof() Check for end of file efs_fread() Read from file efs_fseek() Set file position efs_ftell() Get file position efs_fwrite() Write to file efs_rewind() Reset file position to start of file

  47. 增加网页 //增加静态页面 efs_createfile(“index.html”, index_SIZE, index);//数据指针 efs_createfile("leftindex.htm", leftindex_SIZE,leftindex); efs_createfile("jump.htm", jump_SIZE, jump); efs_createfile("back.jpg", back_SIZE,back); //增加动态页面 efs_createfile(“post.cgi”, 0, (UINT8 *)function_post); //函数指针 efs_createfile(“config.cgi", 0, (UINT8 *)function_config);

  48. 编写CGI程序 1.CGI函数定义 static int cgiSample (int htmlSock, int ContentLength, char *pArgs ); 2.分析提交的参数 void save_manual_nat(char *buffer,int *parseIndex) { char *key, *value; do { key = cgiParseVars( buffer, parseIndex ); value = cgiParseVars( buffer, parseIndex ); if(!strcmp("keyname",key)) { //use value to do something } }while(*parseIndex != -1); }

  49. 编写CGI程序 CGI如何返回数据给client //http header httpSendStatusLine(htmlSock, HTTP_OK, CONTENT_TYPE_HTML); httpSendClientStr(htmlSock, CRLF); HTTP_AUTH_REQUIRED,HTTP_NOT_FOUND, HTTP_NOT_ALLOWED ,HTTP_NOT_IMPLEMENTED //写文件信息 char tempstr[ ] = "ncif.innerHTML = 'SIF';\n"; send(htmlSock,tempstr,strlen(tempstr),0); //操作完毕 return 1;

  50. Web Server的身份认证 1.NDK内分4个用户组,每个用户组都可以增加多个用户,用户组与用户组之间处于平级关系。 通过CfgAddEntry( hCfg, CFGTAG_ACCT, CFGITEM_ACCT_REALM,……..) 来添加用户 2.Web文件中,同一目录下的所有文件具有相同的保护权限(不包含子目录)。 设置方法如下: static int OurRelm1 = 1; static int OurRelm2 = 2; efs_createfile("%R%",4,(UINT8 *)&OurRelm1); efs_createfile("advlink/%R%", 4, (UINT8 *)&OurRelm2);

More Related