📄 sys_arch.c
字号:
/*
*********************************************************************************************************
* lwIP TCP/IP Stack
* port for uC/OS-II RTOS on TIC6711 DSK
*
* File : sys_arch.c
* By : ZengMing @ DEP,Tsinghua University,Beijing,China
* Reference: YangYe's source code for SkyEye project
*********************************************************************************************************
*/
//#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "arch/sys_arch.h"
static OS_MEM *pQueueMem;
const void * const pvNullPointer;
static char pcQueueMemoryPool[MAX_QUEUES * sizeof(TQ_DESCR) ];
struct sys_timeouts lwip_timeouts[LWIP_TASK_MAX+1];
struct sys_timeouts null_timeouts;
OS_STK LWIP_TASK_STK[LWIP_TASK_MAX+1][LWIP_STK_SIZE];
/*-----------------------------------------------------------------------------------*/
/* This func should be called first in lwip task!
* sys_int必须在tcpip协议栈任务tcpip_thread创建前被调用
* ------------------------------------------------- */
void sys_init(void)
{
u8_t i;
u8_t ucErr;
//init mem used by sys_mbox_t //use ucosII functions
//为消息队列创建内存分区
pQueueMem = OSMemCreate( (void*)pcQueueMemoryPool, MAX_QUEUES, sizeof(TQ_DESCR), &ucErr );
//init lwip task prio offset
//curr_prio_offset = 0;
//init lwip_timeouts for every lwip task
//初始化lwip定时事件表,具体实现参考下面章节
for(i=0;i<LWIP_TASK_MAX+1;i++){
lwip_timeouts[i].next = NULL;
}
}
/*-----------------------------------------------------------------------------------*/
//建立信号量
sys_sem_t sys_sem_new(u8_t count)
{
sys_sem_t pSem;
pSem = OSSemCreate((u16_t)count );
return pSem;
}
/*-----------------------------------------------------------------------------------*/
//删除信号量
void sys_sem_free(sys_sem_t sem)
{
u8_t ucErr;
(void)OSSemDel((OS_EVENT *)sem, OS_DEL_NO_PEND, &ucErr );
}
/*-----------------------------------------------------------------------------------*/
//释放信号量
void sys_sem_signal(sys_sem_t sem)
{
OSSemPost((OS_EVENT *)sem );
}
/*-----------------------------------------------------------------------------------*/
//请求信号量,并进行超时时间转换
u32_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
{
u8_t err;
u32_t ucos_timeout;
ucos_timeout = 0;
if(timeout != 0){
ucos_timeout = (timeout * OS_TICKS_PER_SEC) / 1000;
if(ucos_timeout < 1)
ucos_timeout = 1;
else if(ucos_timeout > 65535) //ucOS only support u16_t pend
ucos_timeout = 65535;
}
OSSemPend ((OS_EVENT *)sem,(u16_t)ucos_timeout, (u8_t *)&err);
if(err == OS_TIMEOUT)
return 0; // only when timeout!
else
return 1;
}
/*-----------------------------------------------------------------------------------*/
sys_mbox_t sys_mbox_new(void)
{
u8_t ucErr;
PQ_DESCR pQDesc;
//从消息队列内存分区中得到一个内存块
pQDesc = OSMemGet( pQueueMem, &ucErr );
if( ucErr == OS_NO_ERR ) {
//创建一个消息队列
pQDesc->pQ = OSQCreate( &(pQDesc->pvQEntries[0]), MAX_QUEUE_ENTRIES );
if( pQDesc->pQ != NULL ) {
return pQDesc;
}
}
return SYS_MBOX_NULL;
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_free(sys_mbox_t mbox)
{
u8_t ucErr;
//clear OSQ EVENT
OSQFlush( mbox->pQ );
//del OSQ EVENT
(void)OSQDel( mbox->pQ, OS_DEL_NO_PEND, &ucErr);
//put mem back to mem queue
ucErr = OSMemPut( pQueueMem, mbox );
}
/*-----------------------------------------------------------------------------------*/
/*const void * const pvNullPointer = 0xffffffff;
void sys_mbox_post(sys_mbox_t mbox, void *data)
{
INT8U err;
if( !data )
data = (void*)&pvNullPointer;
err= OSQPost( mbox->pQ, data);
}*/
//在ucos 中,如果OSQPost (OS_EVENT *pevent, void *msg)中的msg==NULL 会返回一条OS_ERR_POST_NULL_PTR
//错误.而在lwip中会调用sys_mbox_post(mbox,NULL)发送一条空消息,我们在本函数中把NULL变成一个常量指针0xffffffff.
void
sys_mbox_post(sys_mbox_t mbox, void *msg)
{
if( !msg )
msg = (void*)&pvNullPointer;
(void)OSQPost( mbox->pQ, msg);
}
/*-----------------------------------------------------------------------------------*/
u32_t
sys_arch_mbox_fetch(sys_mbox_t mbox, void **msg, u32_t timeout)
{
u8_t ucErr;
u32_t ucos_timeout;
//在 lwip中 ,timeout的单位是ms
// 在ucosII ,timeout 的单位是timer tick
ucos_timeout = 0;
if(timeout != 0){
ucos_timeout = (timeout * OS_TICKS_PER_SEC)/1000;
if(ucos_timeout < 1)
ucos_timeout = 1;
else if(ucos_timeout > 65535) //ucOS only support u16_t timeout
ucos_timeout = 65535;
}
//如果data!=NULL就返回消息指针,
if(msg != NULL){
*msg = OSQPend( mbox->pQ, (u16_t)ucos_timeout, &ucErr );
}else{
//just discard return value if msg==NULL
OSQPend(mbox->pQ,(u16_t)ucos_timeout,&ucErr);
}
//这里修改了ucos中的OSQPend系统调用,
//原来的void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
// err的返回值只有两种:收到消息就返回OS_NO_ERR,超时则返回OS_TIMEOUT
//这里先将err从8位数据改变成了16位数据 OSQPend(*pevent,timeout, INT16U *err)
//重新定义了OS_TIMEOUT
//在ucos中原有#define OS_TIMEOUT 20
//改为 #define OS_TIMEOUT -1
//err返回值的意义也改变了,如果超时返回OS_TIMEOUT
// 如果收到消息,则返回OSTCBCur->OSTCBDly修改部分代码如下
//if (msg != (void *)0) { /* Did we get a message? */
// OSTCBCur->OSTCBMsg = (void *)0;
// OSTCBCur->OSTCBStat = OS_STAT_RDY;
// OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
// *err = OSTCBCur->OSTCBDly;// zhangzs @2003.12.12
// OS_EXIT_CRITICAL();
// return (msg); /* Return message received */
// }
//关于ucos的OSTBCur->OSTCBDly的含义请查阅ucos的书籍
if( ucErr == OS_TIMEOUT ) {
timeout = 0;
} else {
if(*msg == (void*)&pvNullPointer )
*msg = NULL;
timeout = 1;
}
return timeout;
}
/*----------------------------------------------------------------------*/
//函数sys_arch_timeouts返回对应于当前任务的指向定时事件链表的起始指针.该指针存在lwip_timeouts[MAX_LWIP_TASKS]中.
struct
sys_timeouts * sys_arch_timeouts(void)
{
u8_t curr_prio;
s16_t offset;
OS_TCB curr_task_pcb;
null_timeouts.next = NULL;
OSTaskQuery(OS_PRIO_SELF,&curr_task_pcb);
curr_prio = curr_task_pcb.OSTCBPrio;
//获取当前任务的优先级
offset = curr_prio - LWIP_START_PRIO;
if(curr_prio == TCPIP_THREAD_PRIO)
return &lwip_timeouts[LWIP_TASK_MAX];
else if(offset >= 0 && offset < LWIP_TASK_MAX)
return &lwip_timeouts[offset];
else return &null_timeouts;
//if not called by a lwip task ,return timeouts->NULL
}
/*------------------------------------------------------------------------*/
sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio)
{
if(prio == TCPIP_THREAD_PRIO){
OSTaskCreate(thread, (void *)0x1111, &LWIP_TASK_STK[LWIP_TASK_MAX][LWIP_STK_SIZE-1], prio);
return prio;
}
else if(prio - LWIP_START_PRIO < LWIP_TASK_MAX){
OSTaskCreate(thread, (void *)0x1111, &LWIP_TASK_STK[prio - LWIP_START_PRIO][LWIP_STK_SIZE-1], prio);
return prio;
}
else {
printf(" lwip task prio out of range ! error! ");
return 0;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -