u16_t psock_datalen(struct psock *psock) char psock_newdata(psock * s)
追加:
1. #define PSOCK_BEGIN(psock) 启用一个原始套接字的原始线程。
此宏启用一个原始套接字关联的原始线程,必须在使用此原始套接字的函数调用其他原始套接字函数之前出现。 参数:
psock (struct psock *)指向要启用的原始套接字的结构体指针。 应用例程: , and . 定义于的158行.
2.??#define PSOCK_CLOSE(psock)
此宏用于关闭一个原始套接字,只能用于此原始套接字生存的原始线程中. 参数:
psock (struct psock *)指向要关闭的原始套接字的结构体指针。 应用例程: , and .
定义于的235行.
3. #define PSOCK_CLOSE_EXIT(psock)
此宏用于关闭一个原始套接字,并退出原始套接字生存的线程. 参数:
psock (struct psock *)指向要关闭的原始套接字的结构体指针。 定义于的308行.
4. #define PSOCK_DATALEN(psock)
返回之前通过 PSOCK_READTO() 或 PSOCK_READ()读到的数据长度. 参数:
psock (struct psock *)指向盛放数据的原始套接字的结构体指针。 定义于的281行.
5. #define PSOCK_END(psock)
此宏用于声明原始套接字的原始线程结束.常于PSOCK_BEGIN(psock)配合使用. 参数:
psock (struct psock *)指向原始套接字的结构体指针 应用例程: , and . 定义于的325行.
6. #define PSOCK_EXIT(psock)
此宏用于终止原始套接字的原始线程,必须与PSOCK_CLOSE一起使用. 也可以直接使用PSOCK_CLOSE_EXIT(); 参数:
psock (struct psock *)指向原始套接字的结构体指针. 应用例程: .
定义于的297行.
7. #define PSOCK_GENERATOR_SEND(psock,generator,arg) 通过函数产生数据并发送. 参数:
psock 指向原始套接字的指针. generator 指向产生数据的函数的指针. arg 要传给函数的参数.
使宏用于通过函数产生数据,并通过原始套接字发送.它可以用于动态产生数据并传输,而不必先将产生的数据存入缓冲区.此函数减小了缓冲区内存的开销.产生器函数由应用程序实现,使用时要将函数的指针作为一个参数传给宏. 产生器函数应该将产生的数据直接存放在uip_appdata缓冲区中,并返回产生数据的长度.数据每一次发送时,原始套接字层会调用产生器函数,并且如果出现重发的情况,则也会调用一次产生器函数,也就是说重发的值并非第一次产生器函数调用时的值. 定义于的219行.
8. #define PSOCK_INIT(psock ,buffer,buffersize)
这个宏初始化一个原始套接字,它必须在使用套接字之间得到调用. 此宏还规定了套接字的输入缓冲区. 参数:
psock (struct psock *) 指向要初始化的原始套接字的指针. buffer (char * ) 指向原始套接字的输入缓冲区的指针. buffersize (unsigned int) 输入缓冲区的大小. 应用例程: , and . 定义于的144行.
9. #define PSOCK_NEWDATA(psock) 此宏用于查明是否有数据到达套接字。
它常和PSOCK_WAIT_UNTIL() 连用,查看套接字上是否有新的数据到达。
参数:
psock (struct psock *) 指向套接字的指针。 定义于的339行。
10. #define PSOCK_READBUF(psock) 读数据直到缓冲区满。
此宏会阻塞数据等待,把数据读入由PSOCK_INIT()指定的输入缓冲区。读数据操作会进行到缓冲区满为止。 参数:
psock (struct psock *) 指向数据读取来源套接字的指针。 定义于的250行。
11. #define PSOCK_READTO(psock,c) 读数据直到某字符出现。
此宏会阻塞数据等待并开始读取数据到由PSOCK_INIT()指定的输入缓冲区,数据读取会一直持续到由参数c指定的字符出现为止。 参数:
psock (struct psock *)指向数据读取来源套接字的指针。 c (char )用于指示停止读取数据的字符。 应用例程: , and .
定义于的268行。
12. #define PSOCK_SEND(psock,data,datalen) 发送数据。
此宏通过原始套接字发送数据。原始套接字阻塞原始线程,直到所有的数据发送完毕,并且已经被完程TCP终端接收。 参数:
psock (struct psock *) 指向用于发送数据的原始套接字的指针。 data (char *) 指向要发送的数据的指针。 datalen (unsigned int)要发送的数据长度。 应用例程: .
定义于的178行。
13. #define PSOCK_SEND_STR(psock,str) 发送一个以零结尾的字符串。 参数:
psock (struct psock *) 指向要用来发送数据的套接字指针。 str 要发送的字符串。 应用例程: , and .
定义于的191行。
14. #define PSOCK_WAIT_UNTIL(psock,condition) 等待直接条件为真。
下宏阻塞原始线程,直到条件为真。宏PSOCK_NEWDATA()可以用来检查此宏等待时有没有新数据到来。 此宏的典型用法如下:
1. PT_THREAD(thread(struct psock *s, struct timer *t)) 2. {
3. ? ?PSOCK_BEGIN(s); 4.
5. ? ?PSOCK_WAIT_UNTIL(s, PSOCK_NEWADATA(s) || timer_expired(t)); 6. ? ?
7. ? ?if(PSOCK_NEWDATA(s)) { 8. ? ???PSOCK_READTO(s, '\\n'); 9. ? ?} else {
10. ? ???handle_timed_out(s); 11. ? ?} 12. ? ?
13. ? ?PSOCK_END(s); 14. }
复制代码 参数:
psock (struct psock *)套接字指针。 condition 等待条件。 定义于的372行。
UIP中文文档第六 uIP原始线程(protothreads)
详细说明:“原始线程”是一种轻量级的、无需堆栈的线程。它主要用于内存极为受限的系统,如深入嵌入式系统、传感器网络等。
“原始线程”是以C代码实现的,为事件驱动的系统提供了线性的代码执行空间。“原始线程”即可以用在有实时操作
系统的系统中,也可以用在没有实时操作系统的系统中。
它在事件驱动的系统上层提供了阻塞上下文,省去了每个线程的单独堆栈空间开销。原始线程的目标是在没有复杂的状态机或多线程的情况下实现控制顺序流。原始线程在C语言内部实现了条件阻塞。
原始线程相对于纯事件驱动方法的优势是原始线程提供了可以阻塞函数的顺序代码结构。在纯事件驱动的方法中,阻塞的实现必须将一个函数手动分成两个部分。一部分放在阻塞调用前,一部分放在阻塞调用后。这让使用if()和while()语句变得困难。
原始线程相对于普通线程的优势是,它不需要为每个线程分配堆栈。在内存受限的系统中,为每个线程分配堆栈空间会占用大量的内存。相比而言,原始线程的每个线程只需2到12个字节的状态字,具体多大与构架有关。 注意:
由于原始线程有阻塞调用中中不需保存堆栈上下文,原始线程阻塞时,局部变量也不再保留。这意味着局部变量的使用必须十分小心。如果不确定的话,尽量不要有原始线程中使用局部变量。 主要特性:
无机器相关代码-代码完成是C写的。
不使用错误-倾向于像longjump()这样的函数。 很小的RAM开销-每条线程仅两个字节。 即可使用OS,也可以不使用。
提供阻塞等待而无需多线程或堆栈切换。
主要应用:
内存受限系统 事件驱动的协议栈 深入嵌入式系统 传感器网络
原始线程包括四个基本的操作:初妈化(PT_INIT()),执行(PT_BEGIN()),条件阻塞(PT_WAIT_UNTIL()),和退出(PT_EXIT()).在此之上还有两个方便使用的函数:反向条件阻塞(PT_WAIT_WHILE())和原始线程阻塞(PT_WAIT_THREAD()).
见:uIP中文文档第五 原始套接字
原始线程线的分布是基于一个类似于BSD的协议的。也就是说允许商业的和非商业的使用。唯的需要是\is given\作者: Adam Dunkels <> 作者的工作得到了Oliver Schmidt <>的支持。
这里算一段,追加见楼下。
原始线程:原始线程是极端轻量级的、无需堆栈的线程。它在事件驱动的系统上层提供阻塞上下文,无需为每个线程提供堆栈的开销。原始线程的目标是在没有复杂的状态机或多线程的情况下实现控制顺序流。原始线程在C函数内部实现了条件阻塞。
在内存受限的系统中,如深入嵌入式系统,传统的多线程的内存开销可能会显得过大。在传统线程中每条线程都需要自己堆栈,这种要求并非必要的。堆栈空间可能花去大部分的内存空间。
原始线程相对于多线程的优势在于原始线程是相当轻量极的,原始线程不需要自己的堆栈。相反,所有的线程都运行在同一个堆栈中,上下文的切换是通过堆栈的回转实现的。这在内存受限的系统中是具有优势的,因为那里一个线程的堆栈可能就占用了很大的一部分内存。原始线程的每条线程只需两字节,而且原始线程是纯用C实现的,不需要任何机器有关的汇编语言代码。