LWIP之API_MSG结构及其实现
来源:互联网 发布:禅道linux部署 编辑:程序博客网 时间:2024/05/14 19:12
从上面一篇的socket实现来看,如果要评起到最关键作用的一个结构体,那么struct api_msg当之无愧。先看下它的定义:
/** This struct contains a function to execute in another thread context and
a struct api_msg_msg that serves as an argument for this function.
This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */
struct api_msg
{
/** function to execute in tcpip_thread context */
void (* function)(struct api_msg_msg *msg);
/** arguments for this function */
struct api_msg_msg msg;
};
功能说的很清楚。但是具体怎么个操作法还是不知道,没关系,接着看它的调用。
举一个例子,刚好是上一篇中调用,但是没有看具体实现的
err_t netconn_getaddr(struct netconn *conn, struct ip_addr *addr, u16_t *port, u8_t local)
{
struct api_msg msg;
msg.function = do_getaddr;
msg.msg.conn = conn;
msg.msg.msg.ad.ipaddr = addr;
msg.msg.msg.ad.port = port;
msg.msg.msg.ad.local = local;
TCPIP_APIMSG(&msg);
return conn->err;
}
说明一下,api_msg结构几乎都是在netconn_xxx函数中被调用,方式千篇一律,除了msg.funcion的赋值不一样外。上面的调用很简单,对该结构体变量赋值,接着就是调用TCPIP_APIMSG,这个函数上面讲过,可过去看下。既然如此,就不得不说mbox及其相关函数了。
static sys_mbox_t mbox = SYS_MBOX_NULL;【tcp.c】
再看sys_mbox_t的定义,在【src\include\lwip\sys.h】中
/* For a totally minimal and standalone system, we provide null
definitions of the sys_ functions. */
typedef u8_t sys_sem_t;
typedef u8_t sys_mbox_t;
typedef u8_t sys_prot_t;
可以看到这里只是简单的定义成了u8类型,注意上面的红色字体的说明,很明显这个是可移植的一部分,需要根据不同的平台,不同的操作系统具体定义。可以借鉴焦海波大侠的关于ucos上对lwip的移植笔记来看。
我们可以看到在api_msg结构的处理过程中,所有的信息都是包含在api_msg_msg结构体中的,api_msg只是将其和function简单的组合了。下面看下这个牛结构的定义:
/** This struct includes everything that is necessary to execute a function
for a netconn in another thread context (mainly used to process netconns
in the tcpip_thread context to be thread safe). */
struct api_msg_msg
{
/** The netconn which to process - always needed: it includes the semaphore
which is used to block the application thread until the function finished. */
struct netconn *conn;
/** Depending on the executed function, one of these union members is used */
union
{
/** used for do_send */
struct netbuf *b;
/** used for do_newconn */
struct {
u8_t proto;
} n;
/** used for do_bind and do_connect */
struct {
struct ip_addr *ipaddr;
u16_t port;
} bc;
/** used for do_getaddr */
struct {
struct ip_addr *ipaddr;
u16_t *port;
u8_t local;
} ad;
/** used for do_write */
struct {
const void *dataptr;
int len;
u8_t apiflags;
} w;
/** used ofr do_recv */
struct {
u16_t len;
} r;
#if LWIP_IGMP
/** used for do_join_leave_group */
struct {
struct ip_addr *multiaddr;
struct ip_addr *interface;
enum netconn_igmp join_or_leave;
} jl;
#endif /* LWIP_IGMP */
#if TCP_LISTEN_BACKLOG
struct {
u8_t backlog;
} lb;
#endif /* TCP_LISTEN_BACKLOG */
} msg;
};
一个很合理的设计,至少笔者是这么认为的。关键在于msg union的设计。
/** This struct contains a function to execute in another thread context and
a struct api_msg_msg that serves as an argument for this function.
This is passed to tcpip_apimsg to execute functions in tcpip_thread context. */
struct api_msg
{
/** function to execute in tcpip_thread context */
void (* function)(struct api_msg_msg *msg);
/** arguments for this function */
struct api_msg_msg msg;
};
功能说的很清楚。但是具体怎么个操作法还是不知道,没关系,接着看它的调用。
举一个例子,刚好是上一篇中调用,但是没有看具体实现的
err_t netconn_getaddr(struct netconn *conn, struct ip_addr *addr, u16_t *port, u8_t local)
{
struct api_msg msg;
msg.function = do_getaddr;
msg.msg.conn = conn;
msg.msg.msg.ad.ipaddr = addr;
msg.msg.msg.ad.port = port;
msg.msg.msg.ad.local = local;
TCPIP_APIMSG(&msg);
return conn->err;
}
说明一下,api_msg结构几乎都是在netconn_xxx函数中被调用,方式千篇一律,除了msg.funcion的赋值不一样外。上面的调用很简单,对该结构体变量赋值,接着就是调用TCPIP_APIMSG,这个函数上面讲过,可过去看下。既然如此,就不得不说mbox及其相关函数了。
static sys_mbox_t mbox = SYS_MBOX_NULL;【tcp.c】
再看sys_mbox_t的定义,在【src\include\lwip\sys.h】中
/* For a totally minimal and standalone system, we provide null
definitions of the sys_ functions. */
typedef u8_t sys_sem_t;
typedef u8_t sys_mbox_t;
typedef u8_t sys_prot_t;
可以看到这里只是简单的定义成了u8类型,注意上面的红色字体的说明,很明显这个是可移植的一部分,需要根据不同的平台,不同的操作系统具体定义。可以借鉴焦海波大侠的关于ucos上对lwip的移植笔记来看。
我们可以看到在api_msg结构的处理过程中,所有的信息都是包含在api_msg_msg结构体中的,api_msg只是将其和function简单的组合了。下面看下这个牛结构的定义:
/** This struct includes everything that is necessary to execute a function
for a netconn in another thread context (mainly used to process netconns
in the tcpip_thread context to be thread safe). */
struct api_msg_msg
{
/** The netconn which to process - always needed: it includes the semaphore
which is used to block the application thread until the function finished. */
struct netconn *conn;
/** Depending on the executed function, one of these union members is used */
union
{
/** used for do_send */
struct netbuf *b;
/** used for do_newconn */
struct {
u8_t proto;
} n;
/** used for do_bind and do_connect */
struct {
struct ip_addr *ipaddr;
u16_t port;
} bc;
/** used for do_getaddr */
struct {
struct ip_addr *ipaddr;
u16_t *port;
u8_t local;
} ad;
/** used for do_write */
struct {
const void *dataptr;
int len;
u8_t apiflags;
} w;
/** used ofr do_recv */
struct {
u16_t len;
} r;
#if LWIP_IGMP
/** used for do_join_leave_group */
struct {
struct ip_addr *multiaddr;
struct ip_addr *interface;
enum netconn_igmp join_or_leave;
} jl;
#endif /* LWIP_IGMP */
#if TCP_LISTEN_BACKLOG
struct {
u8_t backlog;
} lb;
#endif /* TCP_LISTEN_BACKLOG */
} msg;
};
一个很合理的设计,至少笔者是这么认为的。关键在于msg union的设计。
- LWIP之API_MSG结构及其实现
- LWIP之SOCKET的实现
- LWIP之IP层实现
- LWIP之SOCKET的实现
- LwIP之UDP协议实现
- [LWIP学习]--netconn结构体及其接口分析
- LWIP源码结构分析
- LWIP源码结构分析
- LwIP代码目录结构
- 基础结构及其应用实现
- 轻量级TCP/IP实现包Lwip之ARP
- LWIP[转]LwIP BUG之ARP缓存
- LWIP 实现DNS域名解析
- LWIP之SOCKET编程
- lwip之http服务器
- LwIP之pbuf
- LWIP之HTTP
- LWIP之TCP通信
- 程序员--工作四年后该如何进行职业规划
- 详解C中volatile关键字
- LWIP之TCP层接收相关
- mallco和new的区别
- LWIP之TCP层发送相关
- LWIP之API_MSG结构及其实现
- SQL中的replace函数
- ZigBee基础
- Android高手进阶教程(七)----Android 中Preferences的使用!
- 初学ssh,觉得好难哪!
- LWIP之SOCKET的实现
- 关于SNS编程的一点收获
- 李嘉诚的忠告
- DMI和dmidecode