⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sys_arch.c

📁 uCOS-II下实现的lwip协议栈实现Ping功能
💻 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 + -