📄 sys_arch.c
字号:
/*
* Copyright (c) 2001, Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Institute nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
* $Id: sys_arch.c,v 1.1.1.1 2003/02/19 02:42:23 skyeye Exp $
*/
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "os_api.h"
//yangye 2003-1-22
#include "sys_arch.h"
//yangye 2003-1-27
//notice: we use OSTaskQuery in sys_arch_timeouts() !
//#include "ucos_ii.h"
//#include "os_cfg.h"
//added by dy
//#include "arch/cc.h"
PST_LWIP_MBOX pstCurFreeMBox;
static ST_LWIP_MBOX __staLwIPBoxs[MBOX_NB];
const void * const pvNullPointer=0xffffffff;
//* sys_timeouts数组,用于保存timeouts链表的首地址
static struct sys_timeouts __staSysTimeouts[T_LWIP_THREAD_MAX_NB+1];
static OS_MEM *pQueueMem;
//static char pcQueueMemoryPool[MAX_QUEUES * sizeof(TQ_DESCR) ];
//yangye 2003-1-27
struct sys_timeouts lwip_timeouts[LWIP_TASK_MAX];
struct sys_timeouts null_timeouts;
OS_STK T_LWIP_TASK_STK[LWIP_TASK_MAX][T_LWIP_STKSIZE];
u8_t curr_prio_offset;
/*-----------------------------------------------------------------------------------*/
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;
*/
//return OSAPISemNew(count);
PST_LWIP_MBOX __pstMBox = SYS_MBOX_NULL;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
OS_ENTER_CRITICAL()
{
if (pstCurFreeMBox != NULL) {
__pstMBox = pstCurFreeMBox;
pstCurFreeMBox = __pstMBox->pstNext;
}
}
OS_EXIT_CRITICAL()
return __pstMBox;
}
/*-----------------------------------------------------------------------------------*/
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 );
*/
PST_LWIP_MBOX __pstMBox = SYS_MBOX_NULL;
#if OS_CRITICAL_METHOD == 3
OS_CPU_SR cpu_sr;
#endif
// 主动清空一次邮箱
OSQFlush(mbox->hMBox);
OS_ENTER_CRITICAL()
{
mbox->pstNext = pstCurFreeMBox;
pstCurFreeMBox = mbox;
}
OS_EXIT_CRITICAL()
}
/*-----------------------------------------------------------------------------------*/
void
sys_mbox_post(sys_mbox_t mbox, void *data)
{
/*
if( !data )
data = (void*)&pvNullPointer;
(void)OSQPost( mbox->pQ, data);
*/
OSAPIQPost(mbox->hMBox, data);
}
//*----------------------------------------------------------
//* 自定义的消息投递函数
//*----------------------------------------------------------
UBYTE OSAPIQPost(HANDLER hQueue, void *pvMsg)
{
UBYTE __ubErr;
while((__ubErr = OSQPost(hQueue, pvMsg)) == OS_Q_FULL) {
OSTimeDlyHMSM(0, 0, 0, 100);
}
return __ubErr;
}
/*-----------------------------------------------------------------------------------*/
u16_t sys_arch_mbox_fetch(sys_mbox_t mbox, void **data, u16_t timeout)
{
if (OSAPIQReceive(mbox->hMBox, data, (u16_t)timeout)==OS_NO_ERR) {
return 0;
} else {
return SYS_ARCH_TIMEOUT;
}
/* u8_t ucErr;
u16_t ucos_timeout;
//yangye 2003-1-27
//in lwip ,timeout is millisecond
//in ucosII ,timeout is timer tick!
//chang timeout from millisecond to ucos 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_timeout = 65535;
}
//yangye 2003-1-29
//it is very importent!!!!
//sometimes lwip calls sys_mbox_fetch(mbox,NULL)
//it is dangrous to return (void *) to NULL ! (from OSQPend())
if(data != NULL){
*data = OSQPend( mbox->hMBox, (u16_t)ucos_timeout, &ucErr );
}else{
//just discard return value if data==NULL
OSQPend(mbox->hMBox,(u16_t)ucos_timeout,&ucErr);
}
if( ucErr == OS_TIMEOUT ) {
timeout = 0;
} else {
if(*data == (void*)&pvNullPointer )
*data = NULL;
timeout = 1;
}
return timeout; */
}
/*-----------------------------------------------------------------------------------*/
sys_sem_t sys_sem_new(u8_t count)
{
//sys_sem_t pSem;
//pSem = OSSemCreate((u16_t)count );
// return pSem;
return OSAPISemNew(count);
}
/*-----------------------------------------------------------------------------------*/
void sys_sem_signal(sys_sem_t sem)
{
//u8_t ucErr;
//ucErr = OSSemPost((OS_EVENT *)sem );
OSAPISemSend(sem);
}
/*-----------------------------------------------------------------------------------*/
//yangye 2003-1-25
u16_t sys_arch_sem_wait(sys_sem_t sem, u32_t timeout)
{/*
u8_t err;
u32_t ucos_timeout;
//yangye 2003-1-27
//in lwip ,timeout is millisecond
//in ucosII ,timeout is timer tick!
//chang timeout from millisecond to ucos 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_timeout = 65535;
}
OSSemPend ((OS_EVENT *)sem,(u16_t)ucos_timeout, (u8_t *)&err);
//should not return 0 when wait time is 0, only when timeout!
//see sys_arch.txt in lwip/doc
if(err == OS_TIMEOUT)
return 0;
else
return 1;
*/
if (OSAPISemWait(sem, timeout)==OS_NO_ERR)
return 0;
else
return SYS_ARCH_TIMEOUT;
}
/*-----------------------------------------------------------------------------------*/
void sys_sem_free(sys_sem_t sem)
{
// u8_t ucErr;
//(void)OSSemDel((OS_EVENT *)sem, OS_DEL_NO_PEND, &ucErr );
OSAPISemFreeExt(sem);
}
/*-----------------------------------------------------------------------------------*/
void sys_init(void)
{
u8_t i;
/* //this func is called first in lwip task!
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
for(i=0;i<LWIP_TASK_MAX;i++){
lwip_timeouts[i].next = NULL;
}*/
// 数组清0
memset(__staLwIPBoxs, 0, sizeof(__staLwIPBoxs));
// 建立链表和邮箱
for (i=0; i<(MBOX_NB-1); i++) {
// 将链表连接在一起
__staLwIPBoxs[i].pstNext = &__staLwIPBoxs[i+1];
// 建立邮箱
__staLwIPBoxs[i].hMBox = OSQCreate(__staLwIPBoxs[i].pvaMsgs, MBOX_SIZE); //2012.03.06修改
}
//别忘了数组中最后一个元素,它还没建立邮箱
__staLwIPBoxs[MBOX_NB-1].hMBox = OSQCreate(__staLwIPBoxs[MBOX_NB-1].pvaMsgs, MBOX_SIZE);
__staLwIPBoxs[MBOX_NB-1].pstNext = NULL;
//保持链表首地址
pstCurFreeMBox = __staLwIPBoxs;
//* 初始化sys_timeouts数组,将数组成员保存的链表地址设置为NULL
//for (i=0; i<sizeof(__staSysTimeouts); i++)T_LWIP_THREAD_MAX_NB+1
for (i=0; i<sizeof(__staSysTimeouts)/sizeof(__staSysTimeouts[0]); i++) {
__staSysTimeouts[i].next = NULL;
}
}
/*-----------------------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
struct sys_timeouts * sys_arch_timeouts(void)
{
/*u8_t curr_prio;
s16_t err,offset;
OS_TCB curr_task_pcb;
null_timeouts.next = NULL;
//get current task prio
err = OSTaskQuery(OS_PRIO_SELF,&curr_task_pcb);
curr_prio = curr_task_pcb.OSTCBPrio;
offset = curr_prio - T_LWIP_START_PRIO;
//not called by a lwip task ,return timeouts->NULL
if(offset < 0 || offset >= LWIP_TASK_MAX)
{
return &null_timeouts;
}
return &lwip_timeouts[offset];*/
u8_t __ubIdx;
//* 减去起始量获得偏移量,也就是LwIP内部的优先级定义
__ubIdx = OSTCBCur->OSTCBPrio - T_LWIP_START_PRIO;
//* 当前线程在指定的LwIP线程优先级号范围之内
if(__ubIdx >= 0 && __ubIdx < T_LWIP_THREAD_MAX_NB)
return &__staSysTimeouts[__ubIdx];
//* 如果出现意外情况,当前线程并不在指定的LwIP线程优先级资源之内,则返回__staSysTimeouts数组的最后一个成员
return &__staSysTimeouts[T_LWIP_THREAD_MAX_NB];
}
/*------------------------------------------------------------------------*/
sys_thread_t sys_thread_new(void (* thread)(void *arg), void *arg, int prio)
{
u8_t __ubPrio = 0;
INT8U lwip_val = 0;
if(prio > 0 && prio <= T_LWIP_THREAD_MAX_NB)
{
__ubPrio = T_LWIP_START_PRIO + (prio - 1);
//if( OS_NO_ERR == OSTaskCreate(thread, (void *)arg, &T_LWIP_TASK_STK[prio-1][T_LWIP_STKSIZE-1],__ubPrio ))
lwip_val = OSTaskCreate(thread, arg, &T_LWIP_TASK_STK[prio-1][T_LWIP_STKSIZE-1],__ubPrio );
// Uart_Printf("lwip tsk_vla is %d!\n",lwip_val);
return __ubPrio ;
} else {
// PRINT(" lwip task prio out of range ! error! ");
Uart_Printf("lwip task error!\n");
}
return __ubPrio;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -