注1:除非特别说明,以下内容针对 lwIP 2.0.0 及以上版本。
注2:操作系统使用 FreeRTOS
contrib 2.1.0 给出了一个 lwIP 的操作系统模拟层,使用的操作系统位 FreeRTOS。模拟层位于:contrib-2_1_0portsfreertos 。
宏 LWIP_TCPIP_CORE_LOCKING 定义在 opt.h 中:
#if !defined LWIP_TCPIP_CORE_LOCKING || defined __DOXYGEN__ #define LWIP_TCPIP_CORE_LOCKING 1 #endif
这个宏用于启用协议栈锁定功能,是通过互斥量实现的,要求互斥量具备优先级继承机制。使能后,在 tcpip.c 中定义全局变量:
#if LWIP_TCPIP_CORE_LOCKING sys_mutex_t lock_tcpip_core; #endif
在函数 tcpip_init 中会申请互斥量:
void
tcpip_init(tcpip_init_done_fn initfunc, void *arg)
{
lwip_init();
tcpip_init_done = initfunc;
tcpip_init_done_arg = arg;
if (sys_mbox_new(&tcpip_mbox, TCPIP_MBOX_SIZE) != ERR_OK) {
LWIP_ASSERT("failed to create tcpip_thread mbox", 0);
}
#if LWIP_TCPIP_CORE_LOCKING
if (sys_mutex_new(&lock_tcpip_core) != ERR_OK) { // <--- 这里
LWIP_ASSERT("failed to create lock_tcpip_core", 0);
}
#endif
sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO);
}
使用宏做了一层包装
#if LWIP_TCPIP_CORE_LOCKING extern sys_mutex_t lock_tcpip_core; #if !defined LOCK_TCPIP_CORE || defined __DOXYGEN__ #define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core) // <-- 这里 #define UNLOCK_TCPIP_CORE() sys_mutex_unlock(&lock_tcpip_core) // <-- 这里 #endif #else #define LOCK_TCPIP_CORE() #define UNLOCK_TCPIP_CORE() #endif
函数或宏
互斥量
struct _sys_mut {
void *mut;
};
typedef struct _sys_mut sys_mutex_t;
| 名称 | 功能 |
|---|---|
| sys_mutex_valid(mutex) | 宏,判断互斥量是否有效 |
| sys_mutex_set_invalid(mutex) | 宏,将一个互斥量设置为无效 |
| err_t sys_mutex_new(sys_mutex_t *mutex) | 函数,创建互斥量 |
| void sys_mutex_lock(sys_mutex_t *mutex) | 函数,阻塞进程,直到互斥量可用 |
| void sys_mutex_unlock(sys_mutex_t *mutex) | 函数,释放先前使用 sys_mutex_lock 函数锁定的互斥量 |
| void sys_mutex_free(sys_mutex_t *mutex) | 函数,释放互斥量资源 |
信号量
struct _sys_sem {
void *sem;
};
typedef struct _sys_sem sys_sem_t;
| 名称 | 功能 |
|---|---|
| sys_sem_valid(sema) | 宏,判断信号量是否有效 |
| sys_sem_set_invalid(sema) | 宏,将一个信号量设置为无效 |
| err_t sys_sem_new(sys_sem_t *sem, u8_t initial_count) | 函数,创建信号量 由 sem 指向新的信号量 initial_count 为 0 或 1 ,指定信号量的初始状态。为 1 表示信号量有效 |
| void sys_sem_signal(sys_sem_t *sem) | 函数,释放信号量(发信号) |
| void sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout_ms) | 函数,阻塞线程直到一个信号量有效。 timeout_ms 用于指定超时时间, = 0:表示无限阻塞,=其它:阻塞指定毫秒 |
| void sys_sem_free(sys_sem_t *sem) | 函数,释放互斥量资源 |
邮箱
FreeRTOS 并没有邮箱机制,模拟层使用 队列 来模拟邮箱。
struct _sys_mbox {
void *mbx;
};
typedef struct _sys_mbox sys_mbox_t;
| 名称 | 功能 |
|---|---|
| sys_mbox_valid(mbox) | 宏,判断邮箱是否有效 |
| sys_mbox_set_invalid(mbox) | 宏,将一个邮箱设置为无效 |
| err_t sys_mbox_new(sys_mbox_t *mbox, int size) | 函数,创建一个空的邮箱,最大可存放 size 个元素 存储到邮箱的元素应为指针类型 你应该在 lwipopts.h 中定义 _MBOX_SIZE 来确定邮箱的个数 |
| void sys_mbox_post(sys_mbox_t *mbox, void *msg) | 函数,向邮箱投递消息,如果邮箱满则无限阻塞,只能用于任务中。决不能在中断中调用。 |
| err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) | 函数,尝试向邮箱投递信息,如果邮箱满则返回错误 ERR_MEM |
| err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg) | 函数,尝试向邮箱投递信息,如果邮箱满则返回错误 ERR_MEM,用于中断 |
| u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout_ms) | 函数,阻塞线程直到一个消息有效。 timeout_ms 用于指定超时时间, = 0:表示无限阻塞,=其它:阻塞指定毫秒 msg 可以为 NULL ,表示丢弃掉这个消息 返回 SYS_ARCH_TIMEOUT 表示发生超时 |
| u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) | 函数,接收一个消息,如果当前邮箱为空,则立即返回 SYS_MBOX_EMPTY 。成功返回 0 。 |
| void sys_mbox_free(sys_mbox_t *mbox) | 函数,释放邮箱资源。 如果释放邮箱资源时,检测到邮箱内仍有消息,啧表明有了编程错误,应该设法通知开发者。 |



