Add FreeRTOS-Plus directory.

This commit is contained in:
Richard Barry 2012-08-11 21:34:11 +00:00
parent 7bd5f21ad5
commit f508a5f653
6798 changed files with 134949 additions and 19 deletions

View file

@ -0,0 +1,163 @@
/*
* Code provided by Xilinx.
*/
/* BSP includes. */
#include "xemaclite.h"
/* lwIP includes. */
#include "lwip/opt.h"
/* Advertisement control register. */
#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
#define ADVERTISE_100_AND_10 (ADVERTISE_10FULL | ADVERTISE_100FULL | ADVERTISE_10HALF | ADVERTISE_100HALF)
/* PHY registers/offsets. */
#define IEEE_CONTROL_REG_OFFSET 0
#define IEEE_STATUS_REG_OFFSET 1
#define IEEE_AUTONEGO_ADVERTISE_REG 4
#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET 10
#define IEEE_1000_ADVERTISE_REG_OFFSET 9
#define IEEE_CTRL_1GBPS_LINKSPEED_MASK 0x2040
#define IEEE_CTRL_LINKSPEED_MASK 0x0040
#define IEEE_CTRL_LINKSPEED_1000M 0x0040
#define IEEE_CTRL_LINKSPEED_100M 0x2000
#define IEEE_CTRL_LINKSPEED_10M 0x0000
#define IEEE_CTRL_AUTONEGOTIATE_ENABLE 0x1000
#define IEEE_STAT_AUTONEGOTIATE_CAPABLE 0x0008
#define IEEE_STAT_AUTONEGOTIATE_COMPLETE 0x0020
#define IEEE_STAT_AUTONEGOTIATE_RESTART 0x0200
#define IEEE_STAT_1GBPS_EXTENSIONS 0x0100
#define IEEE_AN3_ABILITY_MASK_1GBPS 0x0C00
#define IEEE_AN1_ABILITY_MASK_100MBPS 0x0380
#define IEEE_AN1_ABILITY_MASK_10MBPS 0x0060
#define PHY_DETECT_REG 1
#define PHY_DETECT_MASK 0x1808
static int detect_phy_emaclite(XEmacLite *pxEMACLiteInstance);
unsigned short vInitialisePHY( XEmacLite *pxEMACLiteInstance )
{
u16 control;
u16 status;
u16 partner_capabilities;
u16 partner_capabilities_1000;
u16 phylinkspeed;
u32 phy_addr = detect_phy_emaclite(pxEMACLiteInstance);
/* Dont advertise PHY speed of 1000 Mbps */
XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,
IEEE_1000_ADVERTISE_REG_OFFSET,
0);
/* Advertise PHY speed of 100 and 10 Mbps */
XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,
IEEE_AUTONEGO_ADVERTISE_REG,
ADVERTISE_100_AND_10);
XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
IEEE_CONTROL_REG_OFFSET,
&control);
control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |
IEEE_STAT_AUTONEGOTIATE_RESTART);
XEmacLite_PhyWrite(pxEMACLiteInstance, phy_addr,
IEEE_CONTROL_REG_OFFSET,
control);
/* Read PHY control and status registers is successful. */
XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
IEEE_CONTROL_REG_OFFSET,
&control);
XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
IEEE_STATUS_REG_OFFSET,
&status);
if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) &&
(status & IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {
while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
IEEE_STATUS_REG_OFFSET,
&status);
}
XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
IEEE_PARTNER_ABILITIES_1_REG_OFFSET,
&partner_capabilities);
if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr,
IEEE_PARTNER_ABILITIES_3_REG_OFFSET,
&partner_capabilities_1000);
if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS) return 1000;
}
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS) return 100;
if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS) return 10;
xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
__FUNCTION__);
return 10;
} else {
/* Update TEMAC speed accordingly */
if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
/* Get commanded link speed */
phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;
switch (phylinkspeed) {
case (IEEE_CTRL_LINKSPEED_1000M):
return 1000;
case (IEEE_CTRL_LINKSPEED_100M):
return 100;
case (IEEE_CTRL_LINKSPEED_10M):
return 10;
default:
xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
__FUNCTION__, phylinkspeed);
return 10;
}
} else {
return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;
}
}
}
static int detect_phy_emaclite(XEmacLite *pxEMACLiteInstance)
{
u16 phy_reg;
u32 phy_addr;
for (phy_addr = 31; phy_addr > 0; phy_addr--) {
XEmacLite_PhyRead(pxEMACLiteInstance, phy_addr, PHY_DETECT_REG, &phy_reg);
if ((phy_reg != 0xFFFF) &&
((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
/* Found a valid PHY address */
LWIP_DEBUGF(NETIF_DEBUG, ("XEMacLite detect_phy: PHY detected at address %d.\r\n", phy_addr));
LWIP_DEBUGF(NETIF_DEBUG, ("XEMacLite detect_phy: PHY detected.\r\n"));
return phy_addr;
}
}
LWIP_DEBUGF(NETIF_DEBUG, ("XEMacLite detect_phy: No PHY detected. Assuming a PHY at address 0\r\n"));
/* default to zero */
return 0;
}

View file

@ -0,0 +1,513 @@
/*
FreeRTOS V7.1.1 - Copyright (C) 2012 Real Time Engineers Ltd.
***************************************************************************
* *
* FreeRTOS tutorial books are available in pdf and paperback. *
* Complete, revised, and edited pdf reference manuals are also *
* available. *
* *
* Purchasing FreeRTOS documentation will not only help you, by *
* ensuring you get running as quickly as possible and with an *
* in-depth knowledge of how to use FreeRTOS, it will also help *
* the FreeRTOS project to continue with its mission of providing *
* professional grade, cross platform, de facto standard solutions *
* for microcontrollers - completely free of charge! *
* *
* >>> See http://www.FreeRTOS.org/Documentation for details. <<< *
* *
* Thank you for using FreeRTOS, and thank you for your support! *
* *
***************************************************************************
This file is part of the FreeRTOS distribution.
FreeRTOS is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License (version 2) as published by the
Free Software Foundation AND MODIFIED BY the FreeRTOS exception.
>>>NOTE<<< The modification to the GPL is included to allow you to
distribute a combined work that includes FreeRTOS without being obliged to
provide the source code for proprietary components outside of the FreeRTOS
kernel. FreeRTOS is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
more details. You should have received a copy of the GNU General Public
License and the FreeRTOS license exception along with FreeRTOS; if not it
can be viewed here: http://www.freertos.org/a00114.html and also obtained
by writing to Richard Barry, contact details for whom are available on the
FreeRTOS WEB site.
1 tab == 4 spaces!
***************************************************************************
* *
* Having a problem? Start by reading the FAQ "My application does *
* not run, what could be wrong? *
* *
* http://www.FreeRTOS.org/FAQHelp.html *
* *
***************************************************************************
http://www.FreeRTOS.org - Documentation, training, latest information,
license and contact details.
http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products,
including FreeRTOS+Trace - an indispensable productivity tool.
Real Time Engineers ltd license FreeRTOS to High Integrity Systems, who sell
the code with commercial support, indemnification, and middleware, under
the OpenRTOS brand: http://www.OpenRTOS.com. High Integrity Systems also
provide a safety engineered and independently SIL3 certified version under
the SafeRTOS brand: http://www.SafeRTOS.com.
*/
/* FreeRTOS includes. */
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
/* BSP includes. */
#include "xemaclite.h"
#include "xintc_l.h"
/* lwIP includes. */
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/sys.h"
#include <lwip/stats.h>
#include <lwip/snmp.h>
#include "netif/etharp.h"
/* Define those to better describe your network interface. */
#define IFNAME0 'e'
#define IFNAME1 'l'
/* When a packet is ready to be sent, if it cannot be sent immediately then
* the task performing the transmit will block for netifTX_BUFFER_FREE_WAIT
* milliseconds. It will do this a maximum of netifMAX_TX_ATTEMPTS before
* giving up.
*/
#define netifTX_BUFFER_FREE_WAIT ( ( portTickType ) 2UL / portTICK_RATE_MS )
#define netifMAX_TX_ATTEMPTS ( 5 )
#define netifMAX_MTU 1500
struct xEthernetIf
{
struct eth_addr *ethaddr;
/* Add whatever per-interface state that is needed here. */
};
/*
* Copy the received data into a pbuf.
*/
static struct pbuf *prvLowLevelInput( const unsigned char * const pucInputData, unsigned short usDataLength );
/*
* Send data from a pbuf to the hardware.
*/
static err_t prvLowLevelOutput( struct netif *pxNetIf, struct pbuf *p );
/*
* Perform any hardware and/or driver initialisation necessary.
*/
static void prvLowLevelInit( struct netif *pxNetIf );
/*
* Functions that get registered as the Rx and Tx interrupt handers
* respectively.
*/
static void prvRxHandler( void *pvNetIf );
static void prvTxHandler( void *pvUnused );
/*-----------------------------------------------------------*/
/* The instance of the xEmacLite IP being used in this driver. */
static XEmacLite xEMACInstance;
/*-----------------------------------------------------------*/
/**
* In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param pxNetIf the already initialized lwip network interface structure
* for this etherpxNetIf
*/
static void prvLowLevelInit( struct netif *pxNetIf )
{
portBASE_TYPE xStatus;
extern void vInitialisePHY( XEmacLite *xemaclitep );
unsigned portBASE_TYPE uxOriginalPriority;
/* Hardware initialisation can take some time, so temporarily lower the
task priority to ensure other functionality is not adversely effected.
The priority will get raised again before this function exits. */
uxOriginalPriority = uxTaskPriorityGet( NULL );
vTaskPrioritySet( NULL, tskIDLE_PRIORITY );
/* set MAC hardware address length */
pxNetIf->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */
pxNetIf->hwaddr[ 0 ] = configMAC_ADDR0;
pxNetIf->hwaddr[ 1 ] = configMAC_ADDR1;
pxNetIf->hwaddr[ 2 ] = configMAC_ADDR2;
pxNetIf->hwaddr[ 3 ] = configMAC_ADDR3;
pxNetIf->hwaddr[ 4 ] = configMAC_ADDR4;
pxNetIf->hwaddr[ 5 ] = configMAC_ADDR5;
/* device capabilities */
pxNetIf->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
/* maximum transfer unit */
pxNetIf->mtu = netifMAX_MTU;
/* Broadcast capability */
pxNetIf->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
/* Initialize the mac */
xStatus = XEmacLite_Initialize( &xEMACInstance, XPAR_EMACLITE_0_DEVICE_ID );
if( xStatus == XST_SUCCESS )
{
/* Set mac address */
XEmacLite_SetMacAddress( &xEMACInstance, ( Xuint8* )( pxNetIf->hwaddr ) );
/* Flush any frames already received */
XEmacLite_FlushReceive( &xEMACInstance );
/* Set Rx, Tx interrupt handlers */
XEmacLite_SetRecvHandler( &xEMACInstance, ( void * ) pxNetIf, prvRxHandler );
XEmacLite_SetSendHandler( &xEMACInstance, NULL, prvTxHandler );
/* Enable Rx, Tx interrupts */
XEmacLite_EnableInterrupts( &xEMACInstance );
/* Install the standard Xilinx library interrupt handler itself.
*NOTE* The xPortInstallInterruptHandler() API function must be used
for this purpose. */
xStatus = xPortInstallInterruptHandler( XPAR_INTC_0_EMACLITE_0_VEC_ID, ( XInterruptHandler ) XEmacLite_InterruptHandler, &xEMACInstance );
vInitialisePHY( &xEMACInstance );
/* Enable the interrupt in the interrupt controller.
*NOTE* The vPortEnableInterrupt() API function must be used for this
purpose. */
vPortEnableInterrupt( XPAR_INTC_0_EMACLITE_0_VEC_ID );
}
/* Reset the task priority back to its original value. */
vTaskPrioritySet( NULL, uxOriginalPriority );
configASSERT( xStatus == pdPASS );
}
/**
* This function should do the actual transmission of the packet. The packet is
* contained in the pbuf that is passed to the function. This pbuf
* might be chained.
*
* @param pxNetIf the lwip network interface structure for this etherpxNetIf
* @param p the MAC packet to send (e.g. IP packet including MAC addresses and type)
* @return ERR_OK if the packet could be sent
* an err_t value if the packet couldn't be sent
*
* @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to
* strange results. You might consider waiting for space in the DMA queue
* to become availale since the stack doesn't retry to send a packet
* dropped because of memory failure (except for the TCP timers).
*/
static err_t prvLowLevelOutput( struct netif *pxNetIf, struct pbuf *p )
{
/* This is taken from lwIP example code and therefore does not conform
to the FreeRTOS coding standard. */
struct pbuf *q;
static unsigned char ucBuffer[ 1520 ] __attribute__((aligned(32)));
unsigned char *pucBuffer = ucBuffer;
unsigned char *pucChar;
struct eth_hdr *pxHeader;
u16_t usTotalLength = p->tot_len - ETH_PAD_SIZE;
err_t xReturn = ERR_OK;
long x;
( void ) pxNetIf;
#if defined(LWIP_DEBUG) && LWIP_NETIF_TX_SINGLE_PBUF
LWIP_ASSERT("p->next == NULL && p->len == p->tot_len", p->next == NULL && p->len == p->tot_len);
#endif
/* Initiate transfer. */
if( p->len == p->tot_len )
{
/* No pbuf chain, don't have to copy -> faster. */
pucBuffer = &( ( unsigned char * ) p->payload )[ ETH_PAD_SIZE ];
}
else
{
/* pbuf chain, copy into contiguous ucBuffer. */
if( p->tot_len >= sizeof( ucBuffer ) )
{
LINK_STATS_INC( link.lenerr );
LINK_STATS_INC( link.drop );
snmp_inc_ifoutdiscards( pxNetIf );
xReturn = ERR_BUF;
}
else
{
pucChar = ucBuffer;
for( q = p; q != NULL; q = q->next )
{
/* Send the data from the pbuf to the interface, one pbuf at a
time. The size of the data in each pbuf is kept in the ->len
variable. */
/* send data from(q->payload, q->len); */
LWIP_DEBUGF( NETIF_DEBUG, ( "NETIF: send pucChar %p q->payload %p q->len %i q->next %p\n", pucChar, q->payload, ( int ) q->len, ( void* ) q->next ) );
if( q == p )
{
memcpy( pucChar, &( ( char * ) q->payload )[ ETH_PAD_SIZE ], q->len - ETH_PAD_SIZE );
pucChar += q->len - ETH_PAD_SIZE;
}
else
{
memcpy( pucChar, q->payload, q->len );
pucChar += q->len;
}
}
}
}
if( xReturn == ERR_OK )
{
for( x = 0; x < netifMAX_TX_ATTEMPTS; x++ )
{
xReturn = XEmacLite_Send( &xEMACInstance, pucBuffer, ( int ) usTotalLength );
if( xReturn == XST_SUCCESS )
{
break;
}
else
{
vTaskDelay( netifTX_BUFFER_FREE_WAIT );
}
}
if( xReturn != XST_SUCCESS )
{
LINK_STATS_INC( link.memerr );
LINK_STATS_INC( link.drop );
snmp_inc_ifoutdiscards( pxNetIf );
xReturn = ERR_BUF;
}
else
{
LINK_STATS_INC( link.xmit );
snmp_add_ifoutoctets( pxNetIf, usTotalLength );
pxHeader = ( struct eth_hdr * )p->payload;
if( ( pxHeader->dest.addr[ 0 ] & 1 ) != 0 )
{
/* broadcast or multicast packet*/
snmp_inc_ifoutnucastpkts( pxNetIf );
}
else
{
/* unicast packet */
snmp_inc_ifoutucastpkts( pxNetIf );
}
}
}
return xReturn;
}
/**
* Should allocate a pbuf and transfer the bytes of the incoming
* packet from the interface into the pbuf.
*
* @param pxNetIf the lwip network interface structure for this etherpxNetIf
* @return a pbuf filled with the received packet (including MAC header)
* NULL on memory error
*/
static struct pbuf *prvLowLevelInput( const unsigned char * const pucInputData, unsigned short usDataLength )
{
struct pbuf *p = NULL, *q;
if( usDataLength > 0U )
{
#if ETH_PAD_SIZE
len += ETH_PAD_SIZE; /* allow room for Ethernet padding */
#endif
/* We allocate a pbuf chain of pbufs from the pool. */
p = pbuf_alloc( PBUF_RAW, usDataLength, PBUF_POOL );
if( p != NULL )
{
#if ETH_PAD_SIZE
pbuf_header( p, -ETH_PAD_SIZE ); /* drop the padding word */
#endif
/* We iterate over the pbuf chain until we have read the entire
* packet into the pbuf. */
usDataLength = 0U;
for( q = p; q != NULL; q = q->next )
{
/* Read enough bytes to fill this pbuf in the chain. The
* available data in the pbuf is given by the q->len
* variable.
* This does not necessarily have to be a memcpy, you can also preallocate
* pbufs for a DMA-enabled MAC and after receiving truncate it to the
* actually received size. In this case, ensure the usTotalLength member of the
* pbuf is the sum of the chained pbuf len members.
*/
memcpy( q->payload, &( pucInputData[ usDataLength ] ), q->len );
usDataLength += q->len;
}
#if ETH_PAD_SIZE
pbuf_header( p, ETH_PAD_SIZE ); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.recv);
}
}
return p;
}
/**
* Should be called at the beginning of the program to set up the
* network interface. It calls the function prvLowLevelInit() to do the
* actual setup of the hardware.
*
* This function should be passed as a parameter to pxNetIf_add().
*
* @param pxNetIf the lwip network interface structure for this etherpxNetIf
* @return ERR_OK if the loopif is initialized
* ERR_MEM if private data couldn't be allocated
* any other err_t on error
*/
err_t ethernetif_init( struct netif *pxNetIf )
{
err_t xReturn = ERR_OK;
/* This is taken from lwIP example code and therefore does not conform
to the FreeRTOS coding standard. */
struct xEthernetIf *pxEthernetIf;
LWIP_ASSERT( "pxNetIf != NULL", ( pxNetIf != NULL ) );
pxEthernetIf = mem_malloc( sizeof( struct xEthernetIf ) );
if( pxEthernetIf == NULL )
{
LWIP_DEBUGF(NETIF_DEBUG, ( "ethernetif_init: out of memory\n" ) );
xReturn = ERR_MEM;
}
else
{
#if LWIP_NETIF_HOSTNAME
{
/* Initialize interface hostname */
pxNetIf->hostname = "lwip";
}
#endif /* LWIP_NETIF_HOSTNAME */
pxNetIf->state = pxEthernetIf;
pxNetIf->name[ 0 ] = IFNAME0;
pxNetIf->name[ 1 ] = IFNAME1;
/* We directly use etharp_output() here to save a function call.
* You can instead declare your own function an call etharp_output()
* from it if you have to do some checks before sending (e.g. if link
* is available...) */
pxNetIf->output = etharp_output;
pxNetIf->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_IGMP;
pxNetIf->hwaddr_len = ETHARP_HWADDR_LEN;
pxNetIf->mtu = netifMAX_MTU;
pxNetIf->linkoutput = prvLowLevelOutput;
pxEthernetIf->ethaddr = ( struct eth_addr * ) &( pxNetIf->hwaddr[ 0 ] );
/* initialize the hardware */
prvLowLevelInit( pxNetIf );
}
return xReturn;
}
/*-----------------------------------------------------------*/
static void prvRxHandler( void *pvNetIf )
{
/* This is taken from lwIP example code and therefore does not conform
to the FreeRTOS coding standard. */
struct eth_hdr *pxHeader;
struct pbuf *p;
unsigned short usInputLength;
static unsigned char ucBuffer[ 1520 ] __attribute__((aligned(32)));
extern portBASE_TYPE xInsideISR;
struct netif *pxNetIf = ( struct netif * ) pvNetIf;
XIntc_AckIntr( XPAR_ETHERNET_LITE_BASEADDR, XPAR_ETHERNET_LITE_IP2INTC_IRPT_MASK );
/* Ensure the pbuf handling functions don't attempt to use critical
sections. */
xInsideISR++;
usInputLength = ( long ) XEmacLite_Recv( &xEMACInstance, ucBuffer );
/* move received packet into a new pbuf */
p = prvLowLevelInput( ucBuffer, usInputLength );
/* no packet could be read, silently ignore this */
if( p != NULL )
{
/* points to packet payload, which starts with an Ethernet header */
pxHeader = p->payload;
switch( htons( pxHeader->type ) )
{
/* IP or ARP packet? */
case ETHTYPE_IP:
case ETHTYPE_ARP:
/* full packet send to tcpip_thread to process */
if( pxNetIf->input( p, pxNetIf ) != ERR_OK )
{
LWIP_DEBUGF(NETIF_DEBUG, ( "ethernetif_input: IP input error\n" ) );
pbuf_free(p);
p = NULL;
}
break;
default:
pbuf_free( p );
p = NULL;
break;
}
}
xInsideISR--;
}
/*-----------------------------------------------------------*/
static void prvTxHandler( void *pvUnused )
{
( void ) pvUnused;
XIntc_AckIntr( XPAR_ETHERNET_LITE_BASEADDR, XPAR_ETHERNET_LITE_IP2INTC_IRPT_MASK );
}

View file

@ -0,0 +1,93 @@
/*
* Copyright (c) 2001-2003 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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>
*
*/
#ifndef __ARCH_CC_H__
#define __ARCH_CC_H__
/* Include some files for defining library routines */
#include <stdio.h> /* printf, fflush, FILE */
#include <stdlib.h> /* abort */
/** @todo fix some warnings: don't use #pragma if compiling with cygwin gcc */
#ifndef __GNUC__
#include <limits.h>
#pragma warning (disable: 4244) /* disable conversion warning (implicit integer promotion!) */
#pragma warning (disable: 4127) /* conditional expression is constant */
#pragma warning (disable: 4996) /* 'strncpy' was declared deprecated */
#pragma warning (disable: 4103) /* structure packing changed by including file */
#endif
#define LWIP_PROVIDE_ERRNO
/* Define generic types used in lwIP */
typedef unsigned char u8_t;
typedef signed char s8_t;
typedef unsigned short u16_t;
typedef signed short s16_t;
typedef unsigned long u32_t;
typedef signed long s32_t;
typedef size_t mem_ptr_t;
typedef u32_t sys_prot_t;
/* Define (sn)printf formatters for these lwIP types */
#define X8_F "02x"
#define U16_F "hu"
#define S16_F "hd"
#define X16_F "hx"
#define U32_F "lu"
#define S32_F "ld"
#define X32_F "lx"
#define SZT_F U32_F
/* Compiler hints for packing structures */
#define PACK_STRUCT_STRUCT __attribute__( (packed) )
/* Plaform specific diagnostic output */
#define LWIP_PLATFORM_DIAG(x) do { printf x; } while(0)
#define LWIP_PLATFORM_ASSERT(x) do { printf("Assertion \"%s\" failed at line %d in %s\n", \
x, __LINE__, __FILE__); fflush(NULL); abort(); } while(0)
#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \
printf("Assertion \"%s\" failed at line %d in %s\n", message, __LINE__, __FILE__); \
fflush(NULL);handler;} } while(0)
/* C runtime functions redefined */
#define snprintf _snprintf
u32_t dns_lookup_external_hosts_file(const char *name);
#define LWIP_RAND() ((u32_t)rand())
#endif /* __ARCH_CC_H__ */

View file

@ -0,0 +1,40 @@
/*
* 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>
*
*/
#ifndef __PERF_H__
#define __PERF_H__
#define PERF_START /* null definition */
#define PERF_STOP(x) /* null definition */
#endif /* __PERF_H__ */

View file

@ -0,0 +1,56 @@
/*
* Copyright (c) 2001-2003 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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>
*
*/
#ifndef __ARCH_SYS_ARCH_H__
#define __ARCH_SYS_ARCH_H__
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"
#include "semphr.h"
#define SYS_MBOX_NULL ( ( xQueueHandle ) NULL )
#define SYS_SEM_NULL ( ( xSemaphoreHandle ) NULL )
#define SYS_DEFAULT_THREAD_STACK_DEPTH configMINIMAL_STACK_SIZE
typedef xSemaphoreHandle sys_sem_t;
typedef xSemaphoreHandle sys_mutex_t;
typedef xQueueHandle sys_mbox_t;
typedef xTaskHandle sys_thread_t;
#define sys_mbox_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
#define sys_mbox_set_invalid( x ) ( ( *x ) = NULL )
#define sys_sem_valid( x ) ( ( ( *x ) == NULL) ? pdFALSE : pdTRUE )
#define sys_sem_set_invalid( x ) ( ( *x ) = NULL )
#endif /* __ARCH_SYS_ARCH_H__ */

View file

@ -0,0 +1,584 @@
/*
* Copyright (c) 2001-2003 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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>
*
*/
//*****************************************************************************
//
// Include OS functionality.
//
//*****************************************************************************
/* ------------------------ System architecture includes ----------------------------- */
#include "arch/sys_arch.h"
/* ------------------------ lwIP includes --------------------------------- */
#include "lwip/opt.h"
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/stats.h"
/* Very crude mechanism used to determine if the critical section handling
functions are being called from an interrupt context or not. This relies on
the interrupt handler setting this variable manually. */
portBASE_TYPE xInsideISR = pdFALSE;
/*---------------------------------------------------------------------------*
* Routine: sys_mbox_new
*---------------------------------------------------------------------------*
* Description:
* Creates a new mailbox
* Inputs:
* int size -- Size of elements in the mailbox
* Outputs:
* sys_mbox_t -- Handle to new mailbox
*---------------------------------------------------------------------------*/
err_t sys_mbox_new( sys_mbox_t *pxMailBox, int iSize )
{
err_t xReturn = ERR_MEM;
*pxMailBox = xQueueCreate( iSize, sizeof( void * ) );
if( *pxMailBox != NULL )
{
xReturn = ERR_OK;
SYS_STATS_INC_USED( mbox );
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_mbox_free
*---------------------------------------------------------------------------*
* Description:
* Deallocates a mailbox. If there are messages still present in the
* mailbox when the mailbox is deallocated, it is an indication of a
* programming error in lwIP and the developer should be notified.
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* Outputs:
* sys_mbox_t -- Handle to new mailbox
*---------------------------------------------------------------------------*/
void sys_mbox_free( sys_mbox_t *pxMailBox )
{
unsigned long ulMessagesWaiting;
ulMessagesWaiting = uxQueueMessagesWaiting( *pxMailBox );
configASSERT( ( ulMessagesWaiting == 0 ) );
#if SYS_STATS
{
if( ulMessagesWaiting != 0UL )
{
SYS_STATS_INC( mbox.err );
}
SYS_STATS_DEC( mbox.used );
}
#endif /* SYS_STATS */
vQueueDelete( *pxMailBox );
}
/*---------------------------------------------------------------------------*
* Routine: sys_mbox_post
*---------------------------------------------------------------------------*
* Description:
* Post the "msg" to the mailbox.
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* void *data -- Pointer to data to post
*---------------------------------------------------------------------------*/
void sys_mbox_post( sys_mbox_t *pxMailBox, void *pxMessageToPost )
{
while( xQueueSendToBack( *pxMailBox, &pxMessageToPost, portMAX_DELAY ) != pdTRUE );
}
/*---------------------------------------------------------------------------*
* Routine: sys_mbox_trypost
*---------------------------------------------------------------------------*
* Description:
* Try to post the "msg" to the mailbox. Returns immediately with
* error if cannot.
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* void *msg -- Pointer to data to post
* Outputs:
* err_t -- ERR_OK if message posted, else ERR_MEM
* if not.
*---------------------------------------------------------------------------*/
err_t sys_mbox_trypost( sys_mbox_t *pxMailBox, void *pxMessageToPost )
{
err_t xReturn;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if( xInsideISR != pdFALSE )
{
xReturn = xQueueSendFromISR( *pxMailBox, &pxMessageToPost, &xHigherPriorityTaskWoken );
}
else
{
xReturn = xQueueSend( *pxMailBox, &pxMessageToPost, ( portTickType ) 0 );
}
if( xReturn == pdPASS )
{
xReturn = ERR_OK;
}
else
{
/* The queue was already full. */
xReturn = ERR_MEM;
SYS_STATS_INC( mbox.err );
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_mbox_fetch
*---------------------------------------------------------------------------*
* Description:
* Blocks the thread until a message arrives in the mailbox, but does
* not block the thread longer than "timeout" milliseconds (similar to
* the sys_arch_sem_wait() function). The "msg" argument is a result
* parameter that is set by the function (i.e., by doing "*msg =
* ptr"). The "msg" parameter maybe NULL to indicate that the message
* should be dropped.
*
* The return values are the same as for the sys_arch_sem_wait() function:
* Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a
* timeout.
*
* Note that a function with a similar name, sys_mbox_fetch(), is
* implemented by lwIP.
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* void **msg -- Pointer to pointer to msg received
* u32_t timeout -- Number of milliseconds until timeout
* Outputs:
* u32_t -- SYS_ARCH_TIMEOUT if timeout, else number
* of milliseconds until received.
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_fetch( sys_mbox_t *pxMailBox, void **ppvBuffer, u32_t ulTimeOut )
{
void *pvDummy;
portTickType xStartTime, xEndTime, xElapsed;
unsigned long ulReturn;
xStartTime = xTaskGetTickCount();
if( NULL == ppvBuffer )
{
ppvBuffer = &pvDummy;
}
if( ulTimeOut != 0UL )
{
configASSERT( xInsideISR == ( portBASE_TYPE ) 0 );
if( pdTRUE == xQueueReceive( *pxMailBox, &( *ppvBuffer ), ulTimeOut/ portTICK_RATE_MS ) )
{
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS;
ulReturn = xElapsed;
}
else
{
/* Timed out. */
*ppvBuffer = NULL;
ulReturn = SYS_ARCH_TIMEOUT;
}
}
else
{
while( pdTRUE != xQueueReceive( *pxMailBox, &( *ppvBuffer ), portMAX_DELAY ) );
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS;
if( xElapsed == 0UL )
{
xElapsed = 1UL;
}
ulReturn = xElapsed;
}
return ulReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_mbox_tryfetch
*---------------------------------------------------------------------------*
* Description:
* Similar to sys_arch_mbox_fetch, but if message is not ready
* immediately, we'll return with SYS_MBOX_EMPTY. On success, 0 is
* returned.
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* void **msg -- Pointer to pointer to msg received
* Outputs:
* u32_t -- SYS_MBOX_EMPTY if no messages. Otherwise,
* return ERR_OK.
*---------------------------------------------------------------------------*/
u32_t sys_arch_mbox_tryfetch( sys_mbox_t *pxMailBox, void **ppvBuffer )
{
void *pvDummy;
unsigned long ulReturn;
long lResult;
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if( ppvBuffer== NULL )
{
ppvBuffer = &pvDummy;
}
if( xInsideISR != pdFALSE )
{
lResult = xQueueReceiveFromISR( *pxMailBox, &( *ppvBuffer ), &xHigherPriorityTaskWoken );
}
else
{
lResult = xQueueReceive( *pxMailBox, &( *ppvBuffer ), 0UL );
}
if( lResult == pdPASS )
{
ulReturn = ERR_OK;
}
else
{
ulReturn = SYS_MBOX_EMPTY;
}
return ulReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_new
*---------------------------------------------------------------------------*
* Description:
* Creates and returns a new semaphore. The "ucCount" argument specifies
* the initial state of the semaphore.
* NOTE: Currently this routine only creates counts of 1 or 0
* Inputs:
* sys_mbox_t mbox -- Handle of mailbox
* u8_t ucCount -- Initial ucCount of semaphore (1 or 0)
* Outputs:
* sys_sem_t -- Created semaphore or 0 if could not create.
*---------------------------------------------------------------------------*/
err_t sys_sem_new( sys_sem_t *pxSemaphore, u8_t ucCount )
{
err_t xReturn = ERR_MEM;
vSemaphoreCreateBinary( ( *pxSemaphore ) );
if( *pxSemaphore != NULL )
{
if( ucCount == 0U )
{
xSemaphoreTake( *pxSemaphore, 1UL );
}
xReturn = ERR_OK;
SYS_STATS_INC_USED( sem );
}
else
{
SYS_STATS_INC( sem.err );
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_sem_wait
*---------------------------------------------------------------------------*
* Description:
* Blocks the thread while waiting for the semaphore to be
* signaled. If the "timeout" argument is non-zero, the thread should
* only be blocked for the specified time (measured in
* milliseconds).
*
* If the timeout argument is non-zero, the return value is the number of
* milliseconds spent waiting for the semaphore to be signaled. If the
* semaphore wasn't signaled within the specified time, the return value is
* SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore
* (i.e., it was already signaled), the function may return zero.
*
* Notice that lwIP implements a function with a similar name,
* sys_sem_wait(), that uses the sys_arch_sem_wait() function.
* Inputs:
* sys_sem_t sem -- Semaphore to wait on
* u32_t timeout -- Number of milliseconds until timeout
* Outputs:
* u32_t -- Time elapsed or SYS_ARCH_TIMEOUT.
*---------------------------------------------------------------------------*/
u32_t sys_arch_sem_wait( sys_sem_t *pxSemaphore, u32_t ulTimeout )
{
portTickType xStartTime, xEndTime, xElapsed;
unsigned long ulReturn;
xStartTime = xTaskGetTickCount();
if( ulTimeout != 0UL )
{
if( xSemaphoreTake( *pxSemaphore, ulTimeout / portTICK_RATE_MS ) == pdTRUE )
{
xEndTime = xTaskGetTickCount();
xElapsed = (xEndTime - xStartTime) * portTICK_RATE_MS;
ulReturn = xElapsed;
}
else
{
ulReturn = SYS_ARCH_TIMEOUT;
}
}
else
{
while( xSemaphoreTake( *pxSemaphore, portMAX_DELAY ) != pdTRUE );
xEndTime = xTaskGetTickCount();
xElapsed = ( xEndTime - xStartTime ) * portTICK_RATE_MS;
if( xElapsed == 0UL )
{
xElapsed = 1UL;
}
ulReturn = xElapsed;
}
return ulReturn;
}
/** Create a new mutex
* @param mutex pointer to the mutex to create
* @return a new mutex */
err_t sys_mutex_new( sys_mutex_t *pxMutex )
{
err_t xReturn = ERR_MEM;
*pxMutex = xSemaphoreCreateMutex();
if( *pxMutex != NULL )
{
xReturn = ERR_OK;
SYS_STATS_INC_USED( mutex );
}
else
{
SYS_STATS_INC( mutex.err );
}
return xReturn;
}
/** Lock a mutex
* @param mutex the mutex to lock */
void sys_mutex_lock( sys_mutex_t *pxMutex )
{
while( xSemaphoreTake( *pxMutex, portMAX_DELAY ) != pdPASS );
}
/** Unlock a mutex
* @param mutex the mutex to unlock */
void sys_mutex_unlock(sys_mutex_t *pxMutex )
{
xSemaphoreGive( *pxMutex );
}
/** Delete a semaphore
* @param mutex the mutex to delete */
void sys_mutex_free( sys_mutex_t *pxMutex )
{
SYS_STATS_DEC( mutex.used );
vQueueDelete( *pxMutex );
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_signal
*---------------------------------------------------------------------------*
* Description:
* Signals (releases) a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to signal
*---------------------------------------------------------------------------*/
void sys_sem_signal( sys_sem_t *pxSemaphore )
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
if( xInsideISR != pdFALSE )
{
xSemaphoreGiveFromISR( *pxSemaphore, &xHigherPriorityTaskWoken );
}
else
{
xSemaphoreGive( *pxSemaphore );
}
}
/*---------------------------------------------------------------------------*
* Routine: sys_sem_free
*---------------------------------------------------------------------------*
* Description:
* Deallocates a semaphore
* Inputs:
* sys_sem_t sem -- Semaphore to free
*---------------------------------------------------------------------------*/
void sys_sem_free( sys_sem_t *pxSemaphore )
{
SYS_STATS_DEC(sem.used);
vQueueDelete( *pxSemaphore );
}
/*---------------------------------------------------------------------------*
* Routine: sys_init
*---------------------------------------------------------------------------*
* Description:
* Initialize sys arch
*---------------------------------------------------------------------------*/
void sys_init(void)
{
}
u32_t sys_now(void)
{
return xTaskGetTickCount();
}
/*---------------------------------------------------------------------------*
* Routine: sys_thread_new
*---------------------------------------------------------------------------*
* Description:
* Starts a new thread with priority "prio" that will begin its
* execution in the function "thread()". The "arg" argument will be
* passed as an argument to the thread() function. The id of the new
* thread is returned. Both the id and the priority are system
* dependent.
* Inputs:
* char *name -- Name of thread
* void (* thread)(void *arg) -- Pointer to function to run.
* void *arg -- Argument passed into function
* int stacksize -- Required stack amount in bytes
* int prio -- Thread priority
* Outputs:
* sys_thread_t -- Pointer to per-thread timeouts.
*---------------------------------------------------------------------------*/
sys_thread_t sys_thread_new( const char *pcName, void( *pxThread )( void *pvParameters ), void *pvArg, int iStackSize, int iPriority )
{
xTaskHandle xCreatedTask;
portBASE_TYPE xResult;
sys_thread_t xReturn;
xResult = xTaskCreate( pxThread, ( signed char * ) pcName, iStackSize, pvArg, iPriority, &xCreatedTask );
if( xResult == pdPASS )
{
xReturn = xCreatedTask;
}
else
{
xReturn = NULL;
}
return xReturn;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_protect
*---------------------------------------------------------------------------*
* Description:
* This optional function does a "fast" critical region protection and
* returns the previous protection level. This function is only called
* during very short critical regions. An embedded system which supports
* ISR-based drivers might want to implement this function by disabling
* interrupts. Task-based systems might want to implement this by using
* a mutex or disabling tasking. This function should support recursive
* calls from the same task or interrupt. In other words,
* sys_arch_protect() could be called while already protected. In
* that case the return value indicates that it is already protected.
*
* sys_arch_protect() is only required if your port is supporting an
* operating system.
* Outputs:
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
sys_prot_t sys_arch_protect( void )
{
if( xInsideISR == pdFALSE )
{
taskENTER_CRITICAL();
}
return ( sys_prot_t ) 1;
}
/*---------------------------------------------------------------------------*
* Routine: sys_arch_unprotect
*---------------------------------------------------------------------------*
* Description:
* This optional function does a "fast" set of critical region
* protection to the value specified by pval. See the documentation for
* sys_arch_protect() for more information. This function is only
* required if your port is supporting an operating system.
* Inputs:
* sys_prot_t -- Previous protection level (not used here)
*---------------------------------------------------------------------------*/
void sys_arch_unprotect( sys_prot_t xValue )
{
(void) xValue;
if( xInsideISR == pdFALSE )
{
taskEXIT_CRITICAL();
}
}
/*
* Prints an assertion messages and aborts execution.
*/
void sys_assert( const char *pcMessage )
{
(void) pcMessage;
for (;;)
{
}
}
/*-------------------------------------------------------------------------*
* End of File: sys_arch.c
*-------------------------------------------------------------------------*/