/*
* 主要实现的内容:内核邮箱、内核互斥量、内核信号量、内核线程创建、内核保护
* 可参照STM32CubeMX生成的sys_arch.c
*
*/#include<lwip/stats.h>#include<lwip/debug.h>#include<string.h>#include"lwip/def.h"#include"lwip/sys.h"#include<lwip/opt.h>#include<lwip/arch.h>#include"tcpip.h"#include"rtthread.h"/*------------------------IPC邮箱实现-------------------------------------------*/uint32_t mbox_count=0;//用于对象容器名称计数
err_t sys_mbox_new(sys_mbox_t *mbox,int size){char s1[]="RT_MBX";char s2=mbox_count+'0';char*s3=s1+s2;
mbox_count++;*mbox =rt_mb_create(s3,(rt_ubase_t)size,RT_IPC_FLAG_PRIO);if(*mbox ==NULL){return ERR_MEM;}return ERR_OK;}voidsys_mbox_free(sys_mbox_t *mbox){rt_mb_delete(*mbox);}voidsys_mbox_post(sys_mbox_t *mbox,void*msg){
rt_base_t ret;//由于RTThread邮箱大小为4个字节,所以这里传递的是指针指向的地址while(ERR_OK !=rt_mb_send_wait(*mbox,(rt_uint32_t)msg, RT_WAITING_FOREVER));}
err_t sys_mbox_trypost(sys_mbox_t *mbox,void*msg){
rt_base_t ret;//由于RTThread邮箱大小为4个字节,所以这里传递的是指针指向的地址
ret =rt_mb_send(*mbox,(rt_uint32_t)msg);if(ret == RT_EOK){return ERR_OK;}else{return ERR_MEM;}}
err_t sys_mbox_trypost_fromisr(sys_mbox_t *mbox,void*msg){returnsys_mbox_trypost(mbox, msg);}
u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox,void**msg, u32_t timeout_ms){
rt_base_t ret;void*msg_dummy;if(!msg){
msg =&msg_dummy;}if(!timeout_ms){/* wait infinite */
ret =rt_mb_recv(*mbox,(rt_uint32_t*)msg, RT_WAITING_FOREVER);}else{
rt_tick_t timeout_ticks = timeout_ms;
ret =rt_mb_recv(*mbox,(rt_uint32_t*)msg, timeout_ticks);if(ret != RT_EOK){/* timed out */*msg =NULL;return SYS_ARCH_TIMEOUT;}}/* Old versions of lwIP required us to return the time waited.
This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
here is enough. */return1;}
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox,void**msg){
rt_base_t ret;void*msg_dummy;if(!msg){
msg =&msg_dummy;}
ret =rt_mb_recv(*mbox,(rt_uint32_t*)&(*msg),0);if(ret != RT_EOK){*msg =NULL;return SYS_MBOX_EMPTY;}/* Old versions of lwIP required us to return the time waited.
This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
here is enough. */return1;}intsys_mbox_valid(sys_mbox_t *mbox){if(*mbox ==NULL)return0;elsereturn1;}voidsys_mbox_set_invalid(sys_mbox_t *mbox){*mbox =NULL;}/*----------------------------IPC信号量实现---------------------------------*/uint32_t sem_count=0;//用于对象容器名称计数
err_t sys_sem_new(sys_sem_t *sem, u8_t initial_count){char s1[]="RT_SEM";char s2=sem_count+'0';char*s3=s1+s2;
sem_count++;*sem =rt_sem_create(s3,1,RT_IPC_FLAG_PRIO);if(*sem ==NULL){return ERR_MEM;}if(initial_count ==0){rt_sem_trytake(*sem);}elseif(initial_count ==1){
rt_base_t ret =rt_sem_release(*sem);}return ERR_OK;}
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout_ms){
rt_base_t ret;if(!timeout_ms){/* wait infinite */
ret =rt_sem_take(*sem, RT_WAITING_FOREVER);}else{
rt_tick_t timeout_ticks = timeout_ms;
ret =rt_sem_take(*sem, timeout_ticks);if(ret != RT_EOK){/* timed out */return SYS_ARCH_TIMEOUT;}}/* Old versions of lwIP required us to return the time waited.
This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
here is enough. */return1;}voidsys_sem_signal(sys_sem_t *sem){
rt_base_t ret;
ret =rt_sem_release(*sem);}voidsys_sem_free(sys_sem_t *sem){rt_sem_delete(*sem);}intsys_sem_valid(sys_sem_t *sem){if(*sem ==NULL)return0;elsereturn1;}voidsys_sem_set_invalid(sys_sem_t *sem){*sem =NULL;}/*----------------------------IPC互斥量---------------------------------*/#if LWIP_COMPAT_MUTEX == 0uint32_t mutex_count=0;//用于对象容器名称计数
err_t sys_mutex_new(sys_mutex_t *mutex){char s1[]="RT_MUTEX";char s2=mutex_count+'0';char*s3=s1+s2;
mutex_count++;*mutex =rt_mutex_create(s3,RT_IPC_FLAG_PRIO);if(*mutex ==NULL){return ERR_MEM;}return ERR_OK;}voidsys_mutex_free(sys_mutex_t *mutex){rt_mutex_delete(*mutex);}voidsys_mutex_lock(sys_mutex_t *mutex){
rt_base_t ret;
ret =rt_mutex_take(*mutex, RT_WAITING_FOREVER);}voidsys_mutex_unlock(sys_mutex_t *mutex){
rt_base_t ret;
ret =rt_mutex_release(*mutex);}#endif/*----------------------------IPC线程---------------------------------*/
sys_thread_t sys_thread_new(constchar*name, lwip_thread_fn thread,void*arg,int stacksize,int prio){
rt_base_t ret;
sys_thread_t lwip_thread;
size_t rtos_stacksize;
rtos_stacksize =(size_t)stacksize;
lwip_thread =rt_thread_create(name,thread,arg,rtos_stacksize,prio,50);rt_thread_startup(lwip_thread);return lwip_thread;}/*----------------------------保护内存申请等---------------------------------*///强烈建议在lwipopts.h将该宏打开,//SYS_LIGHTWEIGHT_PROT宏实现可以用于保护内核申请内存时通过互斥量保护,//可以有效避免由于内存申请出现的错误。#if SYS_LIGHTWEIGHT_PROT == 1
sys_mutex_t lwip_sys_mutex;//内存保护voidsys_init(void){
lwip_sys_mutex =rt_mutex_create("RT_MUTEX_PRO",RT_IPC_FLAG_PRIO);}
sys_prot_t sys_arch_protect(void){
rt_base_t ret;
ret =rt_mutex_take(lwip_sys_mutex, RT_WAITING_FOREVER);return1;}voidsys_arch_unprotect(sys_prot_t pval){LWIP_UNUSED_ARG(pval);
rt_base_t ret;
ret =rt_mutex_release(lwip_sys_mutex);}//void sys_arch_msleep(u32_t delay_ms)//{// rt_thread_delay(delay_ms);//}#endif/*-----------------------------LWIP时间计数-------------------------------------*/
u32_t sys_now(void){returnrt_tick_get();}
u32_t sys_jiffies(void){returnrt_tick_get();}