From fb4739b12b905317a2a9d680f5e0b79b2c780374 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 5 Jul 2014 16:09:29 +0000 Subject: lwIP code by Eddie, not fully "RT-free" in the HAL LLD. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7009 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/ext/lwip-1.4.1_patched.zip | Bin 0 -> 632802 bytes os/hal/hal.mk | 1 + os/hal/include/hal.h | 3 +- os/hal/include/mac.h | 214 ++++++++++++++++++++++ os/hal/include/mii.h | 162 +++++++++++++++++ os/hal/ports/STM32/LLD/mac_lld.c | 65 ++++--- os/hal/ports/STM32/LLD/mac_lld.h | 6 +- os/hal/src/mac.c | 268 +++++++++++++++++++++++++++ os/various/lwip_bindings/arch/cc.h | 74 ++++++++ os/various/lwip_bindings/arch/perf.h | 57 ++++++ os/various/lwip_bindings/arch/sys_arch.c | 240 ++++++++++++++++++++++++ os/various/lwip_bindings/arch/sys_arch.h | 68 +++++++ os/various/lwip_bindings/lwip.mk | 54 ++++++ os/various/lwip_bindings/lwipthread.c | 302 +++++++++++++++++++++++++++++++ os/various/lwip_bindings/lwipthread.h | 131 ++++++++++++++ os/various/lwip_bindings/readme.txt | 6 + 16 files changed, 1613 insertions(+), 38 deletions(-) create mode 100644 os/ext/lwip-1.4.1_patched.zip create mode 100644 os/hal/include/mac.h create mode 100644 os/hal/include/mii.h create mode 100644 os/hal/src/mac.c create mode 100644 os/various/lwip_bindings/arch/cc.h create mode 100644 os/various/lwip_bindings/arch/perf.h create mode 100644 os/various/lwip_bindings/arch/sys_arch.c create mode 100644 os/various/lwip_bindings/arch/sys_arch.h create mode 100644 os/various/lwip_bindings/lwip.mk create mode 100644 os/various/lwip_bindings/lwipthread.c create mode 100644 os/various/lwip_bindings/lwipthread.h create mode 100644 os/various/lwip_bindings/readme.txt diff --git a/os/ext/lwip-1.4.1_patched.zip b/os/ext/lwip-1.4.1_patched.zip new file mode 100644 index 000000000..329c4a214 Binary files /dev/null and b/os/ext/lwip-1.4.1_patched.zip differ diff --git a/os/hal/hal.mk b/os/hal/hal.mk index 2892a7652..c0c239228 100644 --- a/os/hal/hal.mk +++ b/os/hal/hal.mk @@ -11,6 +11,7 @@ HALSRC = ${CHIBIOS}/os/hal/src/hal.c \ ${CHIBIOS}/os/hal/src/i2c.c \ ${CHIBIOS}/os/hal/src/i2s.c \ ${CHIBIOS}/os/hal/src/icu.c \ + ${CHIBIOS}/os/hal/src/mac.c \ ${CHIBIOS}/os/hal/src/mmc_spi.c \ ${CHIBIOS}/os/hal/src/pal.c \ ${CHIBIOS}/os/hal/src/pwm.c \ diff --git a/os/hal/include/hal.h b/os/hal/include/hal.h index 31ed18bc0..597bf44dc 100644 --- a/os/hal/include/hal.h +++ b/os/hal/include/hal.h @@ -54,7 +54,8 @@ #include "i2c.h" #include "i2s.h" #include "icu.h" -//#include "mac.h" +#include "mac.h" +#include "mii.h" #include "pwm.h" #include "rtc.h" #include "serial.h" diff --git a/os/hal/include/mac.h b/os/hal/include/mac.h new file mode 100644 index 000000000..8b882054a --- /dev/null +++ b/os/hal/include/mac.h @@ -0,0 +1,214 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 + along with this program. If not, see . +*/ + +/** + * @file mac.h + * @brief MAC Driver macros and structures. + * @addtogroup MAC + * @{ + */ + +#ifndef _MAC_H_ +#define _MAC_H_ + +#if HAL_USE_MAC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver constants. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver pre-compile time settings. */ +/*===========================================================================*/ + +/** + * @name MAC configuration options + * @{ + */ +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_ZERO_COPY) || defined(__DOXYGEN__) +#define MAC_USE_ZERO_COPY FALSE +#endif + +/** + * @brief Enables an event sources for incoming packets. + */ +#if !defined(MAC_USE_EVENTS) || defined(__DOXYGEN__) +#define MAC_USE_EVENTS TRUE +#endif +/** @} */ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +#if !CH_CFG_USE_SEMAPHORES || !CH_CFG_USE_EVENTS +#error "the MAC driver requires CH_CFG_USE_SEMAPHORES" +#endif + +#if MAC_USE_EVENTS && !CH_CFG_USE_EVENTS +#error "the MAC driver requires CH_CFG_USE_EVENTS" +#endif + +/*===========================================================================*/ +/* Driver data structures and types. */ +/*===========================================================================*/ + +/** + * @brief Driver state machine possible states. + */ +typedef enum { + MAC_UNINIT = 0, /**< Not initialized. */ + MAC_STOP = 1, /**< Stopped. */ + MAC_ACTIVE = 2 /**< Active. */ +} macstate_t; + +/** + * @brief Type of a structure representing a MAC driver. + */ +typedef struct MACDriver MACDriver; + +#include "mac_lld.h" + +/*===========================================================================*/ +/* Driver macros. */ +/*===========================================================================*/ + +/** + * @name Macro Functions + * @{ + */ +/** + * @brief Returns the received frames event source. + * + * @param[in] macp pointer to the @p MACDriver object + * @return The pointer to the @p EventSource structure. + * + * @api + */ +#if MAC_USE_EVENTS || defined(__DOXYGEN__) +#define macGetReceiveEventSource(macp) (&(macp)->rdevent) +#endif + +/** + * @brief Writes to a transmit descriptor's stream. + * + * @param[in] tdp pointer to a @p MACTransmitDescriptor structure + * @param[in] buf pointer to the buffer containing the data to be written + * @param[in] size number of bytes to be written + * @return The number of bytes written into the descriptor's + * stream, this value can be less than the amount + * specified in the parameter @p size if the maximum frame + * size is reached. + * + * @api + */ +#define macWriteTransmitDescriptor(tdp, buf, size) \ + mac_lld_write_transmit_descriptor(tdp, buf, size) + +/** + * @brief Reads from a receive descriptor's stream. + * + * @param[in] rdp pointer to a @p MACReceiveDescriptor structure + * @param[in] buf pointer to the buffer that will receive the read data + * @param[in] size number of bytes to be read + * @return The number of bytes read from the descriptor's stream, + * this value can be less than the amount specified in the + * parameter @p size if there are no more bytes to read. + * + * @api + */ +#define macReadReceiveDescriptor(rdp, buf, size) \ + mac_lld_read_receive_descriptor(rdp, buf, size) + +#if MAC_USE_ZERO_COPY || defined(__DOXYGEN__) +/** + * @brief Returns a pointer to the next transmit buffer in the descriptor + * chain. + * @note The API guarantees that enough buffers can be requested to fill + * a whole frame. + * + * @param[in] tdp pointer to a @p MACTransmitDescriptor structure + * @param[in] size size of the requested buffer. Specify the frame size + * on the first call then scale the value down subtracting + * the amount of data already copied into the previous + * buffers. + * @param[out] sizep pointer to variable receiving the real buffer size. + * The returned value can be less than the amount + * requested, this means that more buffers must be + * requested in order to fill the frame data entirely. + * @return Pointer to the returned buffer. + * + * @api + */ +#define macGetNextTransmitBuffer(tdp, size, sizep) \ + mac_lld_get_next_transmit_buffer(tdp, size, sizep) + +/** + * @brief Returns a pointer to the next receive buffer in the descriptor + * chain. + * @note The API guarantees that the descriptor chain contains a whole + * frame. + * + * @param[in] rdp pointer to a @p MACReceiveDescriptor structure + * @param[out] sizep pointer to variable receiving the buffer size, it is + * zero when the last buffer has already been returned. + * @return Pointer to the returned buffer. + * @retval NULL if the buffer chain has been entirely scanned. + * + * @api + */ +#define macGetNextReceiveBuffer(rdp, sizep) \ + mac_lld_get_next_receive_buffer(rdp, sizep) +#endif /* MAC_USE_ZERO_COPY */ +/** @} */ + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +#ifdef __cplusplus +extern "C" { +#endif + void macInit(void); + void macObjectInit(MACDriver *macp); + void macStart(MACDriver *macp, const MACConfig *config); + void macStop(MACDriver *macp); + void macSetAddress(MACDriver *macp, const uint8_t *p); + msg_t macWaitTransmitDescriptor(MACDriver *macp, + MACTransmitDescriptor *tdp, + systime_t time); + void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp); + msg_t macWaitReceiveDescriptor(MACDriver *macp, + MACReceiveDescriptor *rdp, + systime_t time); + void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp); + bool_t macPollLinkStatus(MACDriver *macp); +#ifdef __cplusplus +} +#endif + +#endif /* HAL_USE_MAC */ + +#endif /* _MAC_H_ */ + +/** @} */ diff --git a/os/hal/include/mii.h b/os/hal/include/mii.h new file mode 100644 index 000000000..d4b65da54 --- /dev/null +++ b/os/hal/include/mii.h @@ -0,0 +1,162 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 + along with this program. If not, see . +*/ + +/*-* + * @file mii.h + * @brief MII Driver macros and structures. + * + * @addtogroup MII + * @{ + */ + +#ifndef _MII_H_ +#define _MII_H_ + +/* + * Generic MII registers. Note, not all registers are present on all PHY + * devices and some extra registers may be present. + */ +#define MII_BMCR 0x00 /**< Basic mode control register. */ +#define MII_BMSR 0x01 /**< Basic mode status register. */ +#define MII_PHYSID1 0x02 /**< PHYS ID 1. */ +#define MII_PHYSID2 0x03 /**< PHYS ID 2. */ +#define MII_ADVERTISE 0x04 /**< Advertisement control reg. */ +#define MII_LPA 0x05 /**< Link partner ability reg. */ +#define MII_EXPANSION 0x06 /**< Expansion register. */ +#define MII_ANNPTR 0x07 /**< 1000BASE-T control. */ +#define MII_CTRL1000 0x09 /**< 1000BASE-T control. */ +#define MII_STAT1000 0x0a /**< 1000BASE-T status. */ +#define MII_ESTATUS 0x0f /**< Extended Status. */ +#define MII_PHYSTS 0x10 /**< PHY Status register. */ +#define MII_MICR 0x11 /**< MII Interrupt ctrl register. */ +#define MII_DCOUNTER 0x12 /**< Disconnect counter. */ +#define MII_FCSCOUNTER 0x13 /**< False carrier counter. */ +#define MII_NWAYTEST 0x14 /**< N-way auto-neg test reg. */ +#define MII_RERRCOUNTER 0x15 /**< Receive error counter. */ +#define MII_SREVISION 0x16 /**< Silicon revision. */ +#define MII_RESV1 0x17 /**< Reserved. */ +#define MII_LBRERROR 0x18 /**< Lpback, rx, bypass error. */ +#define MII_PHYADDR 0x19 /**< PHY address. */ +#define MII_RESV2 0x1a /**< Reserved. */ +#define MII_TPISTATUS 0x1b /**< TPI status for 10Mbps. */ +#define MII_NCONFIG 0x1c /**< Network interface config. */ + +/* + * Basic mode control register. + */ +#define BMCR_RESV 0x007f /**< Unused. */ +#define BMCR_CTST 0x0080 /**< Collision test. */ +#define BMCR_FULLDPLX 0x0100 /**< Full duplex. */ +#define BMCR_ANRESTART 0x0200 /**< Auto negotiation restart. */ +#define BMCR_ISOLATE 0x0400 /**< Disconnect DP83840 from MII. */ +#define BMCR_PDOWN 0x0800 /**< Powerdown. */ +#define BMCR_ANENABLE 0x1000 /**< Enable auto negotiation. */ +#define BMCR_SPEED100 0x2000 /**< Select 100Mbps. */ +#define BMCR_LOOPBACK 0x4000 /**< TXD loopback bit. */ +#define BMCR_RESET 0x8000 /**< Reset. */ + +/* + * Basic mode status register. + */ +#define BMSR_ERCAP 0x0001 /**< Ext-reg capability. */ +#define BMSR_JCD 0x0002 /**< Jabber detected. */ +#define BMSR_LSTATUS 0x0004 /**< Link status. */ +#define BMSR_ANEGCAPABLE 0x0008 /**< Able to do auto-negotiation. */ +#define BMSR_RFAULT 0x0010 /**< Remote fault detected. */ +#define BMSR_ANEGCOMPLETE 0x0020 /**< Auto-negotiation complete. */ +#define BMSR_MFPRESUPPCAP 0x0040 /**< Able to suppress preamble. */ +#define BMSR_RESV 0x0780 /**< Unused. */ +#define BMSR_10HALF 0x0800 /**< Can do 10mbps, half-duplex. */ +#define BMSR_10FULL 0x1000 /**< Can do 10mbps, full-duplex. */ +#define BMSR_100HALF 0x2000 /**< Can do 100mbps, half-duplex. */ +#define BMSR_100FULL 0x4000 /**< Can do 100mbps, full-duplex. */ +#define BMSR_100BASE4 0x8000 /**< Can do 100mbps, 4k packets. */ + +/* + * Advertisement control register. + */ +#define ADVERTISE_SLCT 0x001f /**< Selector bits. */ +#define ADVERTISE_CSMA 0x0001 /**< Only selector supported. */ +#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_100BASE4 0x0200 /**< Try for 100mbps 4k packets. */ +#define ADVERTISE_PAUSE_CAP 0x0400 /**< Try for pause. */ +#define ADVERTISE_PAUSE_ASYM 0x0800 /**< Try for asymetric pause. */ +#define ADVERTISE_RESV 0x1000 /**< Unused. */ +#define ADVERTISE_RFAULT 0x2000 /**< Say we can detect faults. */ +#define ADVERTISE_LPACK 0x4000 /**< Ack link partners response. */ +#define ADVERTISE_NPAGE 0x8000 /**< Next page bit. */ + +#define ADVERTISE_FULL (ADVERTISE_100FULL | ADVERTISE_10FULL | \ + ADVERTISE_CSMA) +#define ADVERTISE_ALL (ADVERTISE_10HALF | ADVERTISE_10FULL | \ + ADVERTISE_100HALF | ADVERTISE_100FULL) + +/* + * Link partner ability register. + */ +#define LPA_SLCT 0x001f /**< Same as advertise selector. */ +#define LPA_10HALF 0x0020 /**< Can do 10mbps half-duplex. */ +#define LPA_10FULL 0x0040 /**< Can do 10mbps full-duplex. */ +#define LPA_100HALF 0x0080 /**< Can do 100mbps half-duplex. */ +#define LPA_100FULL 0x0100 /**< Can do 100mbps full-duplex. */ +#define LPA_100BASE4 0x0200 /**< Can do 100mbps 4k packets. */ +#define LPA_PAUSE_CAP 0x0400 /**< Can pause. */ +#define LPA_PAUSE_ASYM 0x0800 /**< Can pause asymetrically. */ +#define LPA_RESV 0x1000 /**< Unused. */ +#define LPA_RFAULT 0x2000 /**< Link partner faulted. */ +#define LPA_LPACK 0x4000 /**< Link partner acked us. */ +#define LPA_NPAGE 0x8000 /**< Next page bit. */ + +#define LPA_DUPLEX (LPA_10FULL | LPA_100FULL) +#define LPA_100 (LPA_100FULL | LPA_100HALF | LPA_100BASE4) + +/* + * Expansion register for auto-negotiation. + */ +#define EXPANSION_NWAY 0x0001 /**< Can do N-way auto-nego. */ +#define EXPANSION_LCWP 0x0002 /**< Got new RX page code word. */ +#define EXPANSION_ENABLENPAGE 0x0004 /**< This enables npage words. */ +#define EXPANSION_NPCAPABLE 0x0008 /**< Link partner supports npage. */ +#define EXPANSION_MFAULTS 0x0010 /**< Multiple faults detected. */ +#define EXPANSION_RESV 0xffe0 /**< Unused. */ + +/* + * N-way test register. + */ +#define NWAYTEST_RESV1 0x00ff /**< Unused. */ +#define NWAYTEST_LOOPBACK 0x0100 /**< Enable loopback for N-way. */ +#define NWAYTEST_RESV2 0xfe00 /**< Unused. */ + +/* + * PHY identifiers. + */ +#define MII_DM9161_ID 0x0181b8a0 +#define MII_AM79C875_ID 0x00225540 +#define MII_KS8721_ID 0x00221610 +#define MII_STE101P_ID 0x00061C50 +#define MII_DP83848I_ID 0x20005C90 +#define MII_LAN8710A_ID 0x0007C0F1 + +#endif /* _MII_H_ */ + +/** @} */ diff --git a/os/hal/ports/STM32/LLD/mac_lld.c b/os/hal/ports/STM32/LLD/mac_lld.c index daddf27b6..92593426c 100644 --- a/os/hal/ports/STM32/LLD/mac_lld.c +++ b/os/hal/ports/STM32/LLD/mac_lld.c @@ -123,9 +123,10 @@ static void mii_find_phy(MACDriver *macp) { uint32_t i; #if STM32_MAC_PHY_TIMEOUT > 0 - halrtcnt_t start = halGetCounterValue(); - halrtcnt_t timeout = start + MS2RTT(STM32_MAC_PHY_TIMEOUT); - while (halIsCounterWithin(start, timeout)) { + rtcnt_t start = chSysGetRealtimeCounterX(); + rtcnt_t timeout = start + MS2RTC(STM32_HCLK,STM32_MAC_PHY_TIMEOUT); + rtcnt_t time = start; + while (chSysIsCounterWithinX(time, start, timeout)) { #endif for (i = 0; i < 31; i++) { macp->phyaddr = i << 11; @@ -136,10 +137,11 @@ static void mii_find_phy(MACDriver *macp) { } } #if STM32_MAC_PHY_TIMEOUT > 0 + time = chSysGetRealtimeCounterX(); } #endif /* Wrong or defective board.*/ - chSysHalt(); + osalSysHalt("MAC failure"); } #endif @@ -183,19 +185,19 @@ CH_IRQ_HANDLER(ETH_IRQHandler) { if (dmasr & ETH_DMASR_RS) { /* Data Received.*/ - chSysLockFromIsr(); + osalSysLockFromISR(); chSemResetI(ÐD1.rdsem, 0); #if MAC_USE_EVENTS chEvtBroadcastI(ÐD1.rdevent); #endif - chSysUnlockFromIsr(); + osalSysUnlockFromISR(); } if (dmasr & ETH_DMASR_TS) { /* Data Transmitted.*/ - chSysLockFromIsr(); + osalSysLockFromISR(); chSemResetI(ÐD1.tdsem, 0); - chSysUnlockFromIsr(); + osalSysUnlockFromISR(); } CH_IRQ_EPILOGUE(); @@ -266,7 +268,7 @@ void mac_lld_init(void) { /* PHY soft reset procedure.*/ mii_write(ÐD1, MII_BMCR, BMCR_RESET); #if defined(BOARD_PHY_RESET_DELAY) - halPolledDelay(BOARD_PHY_RESET_DELAY); + chSysPolledDelayX(BOARD_PHY_RESET_DELAY); #endif while (mii_read(ÐD1, MII_BMCR) & BMCR_RESET) ; @@ -308,8 +310,7 @@ void mac_lld_start(MACDriver *macp) { #endif /* ISR vector enabled.*/ - nvicEnableVector(ETH_IRQn, - CORTEX_PRIORITY_MASK(STM32_MAC_ETH1_IRQ_PRIORITY)); + nvicEnableVector(ETH_IRQn, STM32_MAC_ETH1_IRQ_PRIORITY); #if STM32_MAC_ETH1_CHANGE_PHY_STATE /* PHY in power up mode.*/ @@ -405,9 +406,9 @@ msg_t mac_lld_get_transmit_descriptor(MACDriver *macp, stm32_eth_tx_descriptor_t *tdes; if (!macp->link_up) - return RDY_TIMEOUT; + return MSG_TIMEOUT; - chSysLock(); + osalSysLock(); /* Get Current TX descriptor.*/ tdes = macp->txptr; @@ -415,8 +416,8 @@ msg_t mac_lld_get_transmit_descriptor(MACDriver *macp, /* Ensure that descriptor isn't owned by the Ethernet DMA or locked by another thread.*/ if (tdes->tdes0 & (STM32_TDES0_OWN | STM32_TDES0_LOCKED)) { - chSysUnlock(); - return RDY_TIMEOUT; + osalSysUnlock(); + return MSG_TIMEOUT; } /* Marks the current descriptor as locked using a reserved bit.*/ @@ -425,14 +426,14 @@ msg_t mac_lld_get_transmit_descriptor(MACDriver *macp, /* Next TX descriptor to use.*/ macp->txptr = (stm32_eth_tx_descriptor_t *)tdes->tdes3; - chSysUnlock(); + osalSysUnlock(); /* Set the buffer size and configuration.*/ tdp->offset = 0; tdp->size = STM32_MAC_BUFFERS_SIZE; tdp->physdesc = tdes; - return RDY_OK; + return MSG_OK; } /** @@ -445,11 +446,10 @@ msg_t mac_lld_get_transmit_descriptor(MACDriver *macp, */ void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) { - chDbgAssert(!(tdp->physdesc->tdes0 & STM32_TDES0_OWN), - "mac_lld_release_transmit_descriptor(), #1", + osalDbgAssert(!(tdp->physdesc->tdes0 & STM32_TDES0_OWN), "attempt to release descriptor already owned by DMA"); - chSysLock(); + osalSysLock(); /* Unlocks the descriptor and returns it to the DMA engine.*/ tdp->physdesc->tdes1 = tdp->offset; @@ -463,7 +463,7 @@ void mac_lld_release_transmit_descriptor(MACTransmitDescriptor *tdp) { ETH->DMATPDR = ETH_DMASR_TBUS; /* Any value is OK.*/ } - chSysUnlock(); + osalSysUnlock(); } /** @@ -481,7 +481,7 @@ msg_t mac_lld_get_receive_descriptor(MACDriver *macp, MACReceiveDescriptor *rdp) { stm32_eth_rx_descriptor_t *rdes; - chSysLock(); + osalSysLock(); /* Get Current RX descriptor.*/ rdes = macp->rxptr; @@ -501,8 +501,8 @@ msg_t mac_lld_get_receive_descriptor(MACDriver *macp, rdp->physdesc = rdes; macp->rxptr = (stm32_eth_rx_descriptor_t *)rdes->rdes3; - chSysUnlock(); - return RDY_OK; + osalSysUnlock(); + return MSG_OK; } /* Invalid frame found, purging.*/ rdes->rdes0 = STM32_RDES0_OWN; @@ -512,8 +512,8 @@ msg_t mac_lld_get_receive_descriptor(MACDriver *macp, /* Next descriptor to check.*/ macp->rxptr = rdes; - chSysUnlock(); - return RDY_TIMEOUT; + osalSysUnlock(); + return MSG_TIMEOUT; } /** @@ -527,11 +527,10 @@ msg_t mac_lld_get_receive_descriptor(MACDriver *macp, */ void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) { - chDbgAssert(!(rdp->physdesc->rdes0 & STM32_RDES0_OWN), - "mac_lld_release_receive_descriptor(), #1", + osalDbgAssert(!(rdp->physdesc->rdes0 & STM32_RDES0_OWN), "attempt to release descriptor already owned by DMA"); - chSysLock(); + osalSysLock(); /* Give buffer back to the Ethernet DMA.*/ rdp->physdesc->rdes0 = STM32_RDES0_OWN; @@ -542,7 +541,7 @@ void mac_lld_release_receive_descriptor(MACReceiveDescriptor *rdp) { ETH->DMARPDR = ETH_DMASR_RBUS; /* Any value is OK.*/ } - chSysUnlock(); + osalSysUnlock(); } /** @@ -632,8 +631,7 @@ size_t mac_lld_write_transmit_descriptor(MACTransmitDescriptor *tdp, uint8_t *buf, size_t size) { - chDbgAssert(!(tdp->physdesc->tdes0 & STM32_TDES0_OWN), - "mac_lld_write_transmit_descriptor(), #1", + osalDbgAssert(!(tdp->physdesc->tdes0 & STM32_TDES0_OWN), "attempt to write descriptor already owned by DMA"); if (size > tdp->size - tdp->offset) @@ -663,8 +661,7 @@ size_t mac_lld_read_receive_descriptor(MACReceiveDescriptor *rdp, uint8_t *buf, size_t size) { - chDbgAssert(!(rdp->physdesc->rdes0 & STM32_RDES0_OWN), - "mac_lld_read_receive_descriptor(), #1", + osalDbgAssert(!(rdp->physdesc->rdes0 & STM32_RDES0_OWN), "attempt to read descriptor already owned by DMA"); if (size > rdp->size - rdp->offset) diff --git a/os/hal/ports/STM32/LLD/mac_lld.h b/os/hal/ports/STM32/LLD/mac_lld.h index 34b724e07..7c00d4927 100644 --- a/os/hal/ports/STM32/LLD/mac_lld.h +++ b/os/hal/ports/STM32/LLD/mac_lld.h @@ -245,16 +245,16 @@ struct MACDriver { /** * @brief Transmit semaphore. */ - Semaphore tdsem; + semaphore_t tdsem; /** * @brief Receive semaphore. */ - Semaphore rdsem; + semaphore_t rdsem; #if MAC_USE_EVENTS || defined(__DOXYGEN__) /** * @brief Receive event. */ - EventSource rdevent; + event_source_t rdevent; #endif /* End of the mandatory fields.*/ /** diff --git a/os/hal/src/mac.c b/os/hal/src/mac.c new file mode 100644 index 000000000..ec8e08921 --- /dev/null +++ b/os/hal/src/mac.c @@ -0,0 +1,268 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011,2012,2013 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT 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 + along with this program. If not, see . +*/ + +/** + * @file mac.c + * @brief MAC Driver code. + * + * @addtogroup MAC + * @{ + */ + +#include "hal.h" + +#if HAL_USE_MAC || defined(__DOXYGEN__) + +/*===========================================================================*/ +/* Driver local definitions. */ +/*===========================================================================*/ + +#if MAC_USE_ZERO_COPY && !MAC_SUPPORTS_ZERO_COPY +#error "MAC_USE_ZERO_COPY not supported by this implementation" +#endif + +/*===========================================================================*/ +/* Driver exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local variables and types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Driver exported functions. */ +/*===========================================================================*/ + +/** + * @brief MAC Driver initialization. + * @note This function is implicitly invoked by @p halInit(), there is + * no need to explicitly initialize the driver. + * + * @init + */ +void macInit(void) { + + mac_lld_init(); +} + +/** + * @brief Initialize the standard part of a @p MACDriver structure. + * + * @param[out] macp pointer to the @p MACDriver object + * + * @init + */ +void macObjectInit(MACDriver *macp) { + + macp->state = MAC_STOP; + macp->config = NULL; + chSemObjectInit(&macp->tdsem, 0); + chSemObjectInit(&macp->rdsem, 0); +#if MAC_USE_EVENTS + chEvtObjectInit(&macp->rdevent); +#endif +} + +/** + * @brief Configures and activates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * @param[in] config pointer to the @p MACConfig object + * + * @api + */ +void macStart(MACDriver *macp, const MACConfig *config) { + + osalDbgCheck((macp != NULL) && (config != NULL)); + + osalSysLock(); + osalDbgAssert(macp->state == MAC_STOP, + "invalid state"); + macp->config = config; + mac_lld_start(macp); + macp->state = MAC_ACTIVE; + osalSysUnlock(); +} + +/** + * @brief Deactivates the MAC peripheral. + * + * @param[in] macp pointer to the @p MACDriver object + * + * @api + */ +void macStop(MACDriver *macp) { + + osalDbgCheck(macp != NULL); + + osalSysLock(); + osalDbgAssert((macp->state == MAC_STOP) || (macp->state == MAC_ACTIVE), + "invalid state"); + mac_lld_stop(macp); + macp->state = MAC_STOP; + osalSysUnlock(); +} + +/** + * @brief Allocates a transmission descriptor. + * @details One of the available transmission descriptors is locked and + * returned. If a descriptor is not currently available then the + * invoking thread is queued until one is freed. + * + * @param[in] macp pointer to the @p MACDriver object + * @param[out] tdp pointer to a @p MACTransmitDescriptor structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval RDY_OK the descriptor was obtained. + * @retval RDY_TIMEOUT the operation timed out, descriptor not initialized. + * + * @api + */ +msg_t macWaitTransmitDescriptor(MACDriver *macp, + MACTransmitDescriptor *tdp, + systime_t time) { + msg_t msg; + systime_t now; + + osalDbgCheck((macp != NULL) && (tdp != NULL)); + osalDbgAssert(macp->state == MAC_ACTIVE, "not active"); + + while (((msg = mac_lld_get_transmit_descriptor(macp, tdp)) != MSG_OK) && + (time > 0)) { + osalSysLock(); + now = osalOsGetSystemTimeX(); + if ((msg = chSemWaitTimeoutS(&macp->tdsem, time)) == MSG_TIMEOUT) { + osalSysUnlock(); + break; + } + if (time != TIME_INFINITE) + time -= (osalOsGetSystemTimeX() - now); + osalSysUnlock(); + } + return msg; +} + +/** + * @brief Releases a transmit descriptor and starts the transmission of the + * enqueued data as a single frame. + * + * @param[in] tdp the pointer to the @p MACTransmitDescriptor structure + * + * @api + */ +void macReleaseTransmitDescriptor(MACTransmitDescriptor *tdp) { + + osalDbgCheck(tdp != NULL); + + mac_lld_release_transmit_descriptor(tdp); +} + +/** + * @brief Waits for a received frame. + * @details Stops until a frame is received and buffered. If a frame is + * not immediately available then the invoking thread is queued + * until one is received. + * + * @param[in] macp pointer to the @p MACDriver object + * @param[out] rdp pointer to a @p MACReceiveDescriptor structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The operation status. + * @retval RDY_OK the descriptor was obtained. + * @retval RDY_TIMEOUT the operation timed out, descriptor not initialized. + * + * @api + */ +msg_t macWaitReceiveDescriptor(MACDriver *macp, + MACReceiveDescriptor *rdp, + systime_t time) { + msg_t msg; + systime_t now; + + osalDbgCheck((macp != NULL) && (rdp != NULL)); + osalDbgAssert(macp->state == MAC_ACTIVE, "not active"); + + while (((msg = mac_lld_get_receive_descriptor(macp, rdp)) != MSG_OK) && + (time > 0)) { + osalSysLock(); + now = osalOsGetSystemTimeX(); + if ((msg = chSemWaitTimeoutS(&macp->rdsem, time)) == MSG_TIMEOUT) { + osalSysUnlock(); + break; + } + if (time != TIME_INFINITE) + time -= (osalOsGetSystemTimeX() - now); + osalSysUnlock(); + } + return msg; +} + +/** + * @brief Releases a receive descriptor. + * @details The descriptor and its buffer are made available for more incoming + * frames. + * + * @param[in] rdp the pointer to the @p MACReceiveDescriptor structure + * + * @api + */ +void macReleaseReceiveDescriptor(MACReceiveDescriptor *rdp) { + + osalDbgCheck(rdp != NULL); + + mac_lld_release_receive_descriptor(rdp); +} + +/** + * @brief Updates and returns the link status. + * + * @param[in] macp pointer to the @p MACDriver object + * @return The link status. + * @retval TRUE if the link is active. + * @retval FALSE if the link is down. + * + * @api + */ +bool_t macPollLinkStatus(MACDriver *macp) { + + osalDbgCheck(macp != NULL); + osalDbgAssert(macp->state == MAC_ACTIVE, "not active"); + + return mac_lld_poll_link_status(macp); +} + +#endif /* HAL_USE_MAC */ + +/** @} */ diff --git a/os/various/lwip_bindings/arch/cc.h b/os/various/lwip_bindings/arch/cc.h new file mode 100644 index 000000000..45b302716 --- /dev/null +++ b/os/various/lwip_bindings/arch/cc.h @@ -0,0 +1,74 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * **** This file incorporates work covered by the following copyright and **** + * **** permission notice: **** + * + * Copyright (c) 2001-2004 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 + * + */ + +#ifndef __CC_H__ +#define __CC_H__ + +#include + +typedef uint8_t u8_t; +typedef int8_t s8_t; +typedef uint16_t u16_t; +typedef int16_t s16_t; +typedef uint32_t u32_t; +typedef int32_t s32_t; +typedef uint32_t mem_ptr_t; + +#define PACK_STRUCT_STRUCT __attribute__((packed)) + +#define LWIP_PLATFORM_DIAG(x) +#define LWIP_PLATFORM_ASSERT(x) { \ + osalSysHalt(x); \ +} + +#define BYTE_ORDER LITTLE_ENDIAN +#define LWIP_PROVIDE_ERRNO + +#endif /* __CC_H__ */ diff --git a/os/various/lwip_bindings/arch/perf.h b/os/various/lwip_bindings/arch/perf.h new file mode 100644 index 000000000..81ef4673b --- /dev/null +++ b/os/various/lwip_bindings/arch/perf.h @@ -0,0 +1,57 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * **** This file incorporates work covered by the following copyright and **** + * **** permission notice: **** + * + * Copyright (c) 2001-2004 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 + * + */ + +#ifndef __PERF_H__ +#define __PERF_H__ + +#define PERF_START +#define PERF_STOP(x) + +#endif /* __PERF_H__ */ diff --git a/os/various/lwip_bindings/arch/sys_arch.c b/os/various/lwip_bindings/arch/sys_arch.c new file mode 100644 index 000000000..96f17a024 --- /dev/null +++ b/os/various/lwip_bindings/arch/sys_arch.c @@ -0,0 +1,240 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * **** This file incorporates work covered by the following copyright and **** + * **** permission notice: **** + * + * Copyright (c) 2001-2004 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 + * + */ + +// see http://lwip.wikia.com/wiki/Porting_for_an_OS for instructions + +#include "hal.h" + +#include "lwip/opt.h" +#include "lwip/mem.h" +#include "lwip/sys.h" +#include "lwip/stats.h" + +#include "arch/cc.h" +#include "arch/sys_arch.h" + +void sys_init(void) { + +} + +err_t sys_sem_new(sys_sem_t *sem, u8_t count) { + + *sem = chHeapAlloc(NULL, sizeof(semaphore_t)); + if (*sem == 0) { + SYS_STATS_INC(sem.err); + return ERR_MEM; + } + else { + chSemObjectInit(*sem, (cnt_t)count); + SYS_STATS_INC_USED(sem); + return ERR_OK; + } +} + +void sys_sem_free(sys_sem_t *sem) { + + chHeapFree(*sem); + *sem = SYS_SEM_NULL; + SYS_STATS_DEC(sem.used); +} + +void sys_sem_signal(sys_sem_t *sem) { + + chSemSignal(*sem); +} + +/* CHIBIOS FIX: specific variant of this call to be called from within + a lock.*/ +void sys_sem_signal_S(sys_sem_t *sem) { + + chSemSignalI(*sem); + chSchRescheduleS(); +} + +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) { + systime_t time, tmo; + + osalSysLock(); + tmo = timeout > 0 ? (systime_t)timeout : TIME_INFINITE; + time = osalOsGetSystemTimeX(); + if (chSemWaitTimeoutS(*sem, tmo) != MSG_OK) + time = SYS_ARCH_TIMEOUT; + else + time = osalOsGetSystemTimeX() - time; + osalSysUnlock(); + return time; +} + +int sys_sem_valid(sys_sem_t *sem) { + return *sem != SYS_SEM_NULL; +} + +// typically called within lwIP after freeing a semaphore +// to make sure the pointer is not left pointing to invalid data +void sys_sem_set_invalid(sys_sem_t *sem) { + *sem = SYS_SEM_NULL; +} + +err_t sys_mbox_new(sys_mbox_t *mbox, int size) { + + *mbox = chHeapAlloc(NULL, sizeof(mailbox_t) + sizeof(msg_t) * size); + if (*mbox == 0) { + SYS_STATS_INC(mbox.err); + return ERR_MEM; + } + else { + chMBObjectInit(*mbox, (void *)(((uint8_t *)*mbox) + sizeof(mailbox_t)), size); + SYS_STATS_INC(mbox.used); + return ERR_OK; + } +} + +void sys_mbox_free(sys_mbox_t *mbox) { + cnt_t tmpcnt; + + osalSysLock(); + tmpcnt = chMBGetUsedCountI(*mbox); + osalSysUnlock(); + + if (tmpcnt != 0) { + // 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. + SYS_STATS_INC(mbox.err); + chMBReset(*mbox); + } + chHeapFree(*mbox); + *mbox = SYS_MBOX_NULL; + SYS_STATS_DEC(mbox.used); +} + +void sys_mbox_post(sys_mbox_t *mbox, void *msg) { + + chMBPost(*mbox, (msg_t)msg, TIME_INFINITE); +} + +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) { + + if (chMBPost(*mbox, (msg_t)msg, TIME_IMMEDIATE) == MSG_TIMEOUT) { + SYS_STATS_INC(mbox.err); + return ERR_MEM; + } + return ERR_OK; +} + +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) { + systime_t time, tmo; + + osalSysLock(); + tmo = timeout > 0 ? (systime_t)timeout : TIME_INFINITE; + time = osalOsGetSystemTimeX(); + if (chMBFetchS(*mbox, (msg_t *)msg, tmo) != MSG_OK) + time = SYS_ARCH_TIMEOUT; + else + time = osalOsGetSystemTimeX() - time; + osalSysUnlock(); + return time; +} + +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) { + + if (chMBFetch(*mbox, (msg_t *)msg, TIME_IMMEDIATE) == MSG_TIMEOUT) + return SYS_MBOX_EMPTY; + return 0; +} + +int sys_mbox_valid(sys_mbox_t *mbox) { + return *mbox != SYS_MBOX_NULL; +} + +// typically called within lwIP after freeing an mbox +// to make sure the pointer is not left pointing to invalid data +void sys_mbox_set_invalid(sys_mbox_t *mbox) { + *mbox = SYS_MBOX_NULL; +} + +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, + void *arg, int stacksize, int prio) { + + size_t wsz; + void *wsp; + + (void)name; + wsz = THD_WORKING_AREA_SIZE(stacksize); + wsp = chCoreAlloc(wsz); + if (wsp == NULL) + return NULL; + return (sys_thread_t)chThdCreateStatic(wsp, wsz, prio, (tfunc_t)thread, arg); +} + +sys_prot_t sys_arch_protect(void) { + + osalSysLock(); + return 0; +} + +void sys_arch_unprotect(sys_prot_t pval) { + + (void)pval; + osalSysUnlock(); +} + +u32_t sys_now(void) { + +#if OSAL_ST_FREQUENCY == 1000 + return (u32_t)osalOsGetSystemTimeX(); +#elif (OSAL_ST_FREQUENCY / 1000) >= 1 && (OSAL_ST_FREQUENCY % 1000) == 0 + return ((u32_t)osalOsGetSystemTimeX() - 1) / (OSAL_ST_FREQUENCY / 1000) + 1; +#elif (1000 / OSAL_ST_FREQUENCY) >= 1 && (1000 % OSAL_ST_FREQUENCY) == 0 + return ((u32_t)osalOsGetSystemTimeX() - 1) * (1000 / OSAL_ST_FREQUENCY) + 1; +#else + return (u32_t)(((u64_t)(osalOsGetSystemTimeX() - 1) * 1000) / OSAL_ST_FREQUENCY) + 1; +#endif +} diff --git a/os/various/lwip_bindings/arch/sys_arch.h b/os/various/lwip_bindings/arch/sys_arch.h new file mode 100644 index 000000000..8520a433d --- /dev/null +++ b/os/various/lwip_bindings/arch/sys_arch.h @@ -0,0 +1,68 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * **** This file incorporates work covered by the following copyright and **** + * **** permission notice: **** + * + * Copyright (c) 2001-2004 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 + * + */ + +#include + +#ifndef __SYS_ARCH_H__ +#define __SYS_ARCH_H__ + +typedef semaphore_t * sys_sem_t; +typedef mailbox_t * sys_mbox_t; +typedef thread_t * sys_thread_t; +typedef int sys_prot_t; + +#define SYS_MBOX_NULL (mailbox_t *)0 +#define SYS_THREAD_NULL (thread_t *)0 +#define SYS_SEM_NULL (semaphore_t *)0 + +/* let sys.h use binary semaphores for mutexes */ +#define LWIP_COMPAT_MUTEX 1 + +#endif /* __SYS_ARCH_H__ */ diff --git a/os/various/lwip_bindings/lwip.mk b/os/various/lwip_bindings/lwip.mk new file mode 100644 index 000000000..e2aa72d2f --- /dev/null +++ b/os/various/lwip_bindings/lwip.mk @@ -0,0 +1,54 @@ +# List of the required lwIP files. +LWIP = ${CHIBIOS}/os/ext/lwip + +LWBINDSRC = \ + $(CHIBIOS)/os/various/lwip_bindings/lwipthread.c \ + $(CHIBIOS)/os/various/lwip_bindings/arch/sys_arch.c + +LWNETIFSRC = \ + ${LWIP}/src/netif/etharp.c + +LWCORESRC = \ + ${LWIP}/src/core/dhcp.c \ + ${LWIP}/src/core/dns.c \ + ${LWIP}/src/core/init.c \ + ${LWIP}/src/core/mem.c \ + ${LWIP}/src/core/memp.c \ + ${LWIP}/src/core/netif.c \ + ${LWIP}/src/core/pbuf.c \ + ${LWIP}/src/core/raw.c \ + ${LWIP}/src/core/stats.c \ + ${LWIP}/src/core/sys.c \ + ${LWIP}/src/core/tcp.c \ + ${LWIP}/src/core/tcp_in.c \ + ${LWIP}/src/core/tcp_out.c \ + ${LWIP}/src/core/udp.c + +LWIPV4SRC = \ + ${LWIP}/src/core/ipv4/autoip.c \ + ${LWIP}/src/core/ipv4/icmp.c \ + ${LWIP}/src/core/ipv4/igmp.c \ + ${LWIP}/src/core/ipv4/inet.c \ + ${LWIP}/src/core/ipv4/inet_chksum.c \ + ${LWIP}/src/core/ipv4/ip.c \ + ${LWIP}/src/core/ipv4/ip_addr.c \ + ${LWIP}/src/core/ipv4/ip_frag.c \ + ${LWIP}/src/core/def.c \ + ${LWIP}/src/core/timers.c + +LWAPISRC = \ + ${LWIP}/src/api/api_lib.c \ + ${LWIP}/src/api/api_msg.c \ + ${LWIP}/src/api/err.c \ + ${LWIP}/src/api/netbuf.c \ + ${LWIP}/src/api/netdb.c \ + ${LWIP}/src/api/netifapi.c \ + ${LWIP}/src/api/sockets.c \ + ${LWIP}/src/api/tcpip.c + +LWSRC = $(LWBINDSRC) $(LWNETIFSRC) $(LWCORESRC) $(LWIPV4SRC) $(LWAPISRC) + +LWINC = \ + $(CHIBIOS)/os/various/lwip_bindings \ + ${LWIP}/src/include \ + ${LWIP}/src/include/ipv4 diff --git a/os/various/lwip_bindings/lwipthread.c b/os/various/lwip_bindings/lwipthread.c new file mode 100644 index 000000000..918404d4d --- /dev/null +++ b/os/various/lwip_bindings/lwipthread.c @@ -0,0 +1,302 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ +/* + * **** This file incorporates work covered by the following copyright and **** + * **** permission notice: **** + * + * Copyright (c) 2001-2004 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 + * + */ + +/** + * @file lwipthread.c + * @brief LWIP wrapper thread code. + * @addtogroup LWIP_THREAD + * @{ + */ + +#include "hal.h" +#include "evtimer.h" + +#include "lwipthread.h" + +#include "lwip/opt.h" + +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include +#include +#include +#include "netif/etharp.h" +#include "netif/ppp_oe.h" + +#define PERIODIC_TIMER_ID 1 +#define FRAME_RECEIVED_ID 2 + +/** + * Stack area for the LWIP-MAC thread. + */ +THD_WORKING_AREA(wa_lwip_thread, LWIP_THREAD_STACK_SIZE); + +/* + * Initialization. + */ +static void low_level_init(struct netif *netif) { + /* set MAC hardware address length */ + netif->hwaddr_len = ETHARP_HWADDR_LEN; + + /* maximum transfer unit */ + netif->mtu = 1500; + + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an Ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + + /* Do whatever else is needed to initialize interface. */ +} + +/* + * Transmits a frame. + */ +static err_t low_level_output(struct netif *netif, struct pbuf *p) { + struct pbuf *q; + MACTransmitDescriptor td; + + (void)netif; + if (macWaitTransmitDescriptor(ÐD1, &td, MS2ST(LWIP_SEND_TIMEOUT)) != MSG_OK) + return ERR_TIMEOUT; + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + /* Iterates through the pbuf chain. */ + for(q = p; q != NULL; q = q->next) + macWriteTransmitDescriptor(&td, (uint8_t *)q->payload, (size_t)q->len); + macReleaseTransmitDescriptor(&td); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.xmit); + + return ERR_OK; +} + +/* + * Receives a frame. + */ +static struct pbuf *low_level_input(struct netif *netif) { + MACReceiveDescriptor rd; + struct pbuf *p, *q; + u16_t len; + + (void)netif; + if (macWaitReceiveDescriptor(ÐD1, &rd, TIME_IMMEDIATE) == MSG_OK) { + len = (u16_t)rd.size; + +#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, len, PBUF_POOL); + + if (p != NULL) { + +#if ETH_PAD_SIZE + pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ +#endif + + /* Iterates through the pbuf chain. */ + for(q = p; q != NULL; q = q->next) + macReadReceiveDescriptor(&rd, (uint8_t *)q->payload, (size_t)q->len); + macReleaseReceiveDescriptor(&rd); + +#if ETH_PAD_SIZE + pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ +#endif + + LINK_STATS_INC(link.recv); + } + else { + macReleaseReceiveDescriptor(&rd); + LINK_STATS_INC(link.memerr); + LINK_STATS_INC(link.drop); + } + return p; + } + return NULL; +} + +/* + * Initialization. + */ +static err_t ethernetif_init(struct netif *netif) { +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = "lwip"; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, LWIP_LINK_SPEED); + + netif->state = NULL; + netif->name[0] = LWIP_IFNAME0; + netif->name[1] = LWIP_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...) */ + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} + +/** + * @brief LWIP handling thread. + * + * @param[in] p pointer to a @p lwipthread_opts structure or @p NULL + * @return The function does not return. + */ +msg_t lwip_thread(void *p) { + event_timer_t evt; + event_listener_t el0, el1; + struct ip_addr ip, gateway, netmask; + static struct netif thisif; + static const MACConfig mac_config = {thisif.hwaddr}; + + chRegSetThreadName("lwipthread"); + + /* Initializes the thing.*/ + tcpip_init(NULL, NULL); + + /* TCP/IP parameters, runtime or compile time.*/ + if (p) { + struct lwipthread_opts *opts = p; + unsigned i; + + for (i = 0; i < 6; i++) + thisif.hwaddr[i] = opts->macaddress[i]; + ip.addr = opts->address; + gateway.addr = opts->gateway; + netmask.addr = opts->netmask; + } + else { + thisif.hwaddr[0] = LWIP_ETHADDR_0; + thisif.hwaddr[1] = LWIP_ETHADDR_1; + thisif.hwaddr[2] = LWIP_ETHADDR_2; + thisif.hwaddr[3] = LWIP_ETHADDR_3; + thisif.hwaddr[4] = LWIP_ETHADDR_4; + thisif.hwaddr[5] = LWIP_ETHADDR_5; + LWIP_IPADDR(&ip); + LWIP_GATEWAY(&gateway); + LWIP_NETMASK(&netmask); + } + macStart(ÐD1, &mac_config); + netif_add(&thisif, &ip, &netmask, &gateway, NULL, ethernetif_init, tcpip_input); + + netif_set_default(&thisif); + netif_set_up(&thisif); + + /* Setup event sources.*/ + evtObjectInit(&evt, LWIP_LINK_POLL_INTERVAL); + evtStart(&evt); + chEvtRegisterMask(&evt.et_es, &el0, PERIODIC_TIMER_ID); + chEvtRegisterMask(macGetReceiveEventSource(ÐD1), &el1, FRAME_RECEIVED_ID); + chEvtAddEvents(PERIODIC_TIMER_ID | FRAME_RECEIVED_ID); + + /* Goes to the final priority after initialization.*/ + chThdSetPriority(LWIP_THREAD_PRIORITY); + + while (TRUE) { + eventmask_t mask = chEvtWaitAny(ALL_EVENTS); + if (mask & PERIODIC_TIMER_ID) { + bool_t current_link_status = macPollLinkStatus(ÐD1); + if (current_link_status != netif_is_link_up(&thisif)) { + if (current_link_status) + tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_up, + &thisif, 0); + else + tcpip_callback_with_block((tcpip_callback_fn) netif_set_link_down, + &thisif, 0); + } + } + if (mask & FRAME_RECEIVED_ID) { + struct pbuf *p; + while ((p = low_level_input(&thisif)) != NULL) { + struct eth_hdr *ethhdr = p->payload; + switch (htons(ethhdr->type)) { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_ARP: +#if PPPOE_SUPPORT + /* PPPoE packet? */ + case ETHTYPE_PPPOEDISC: + case ETHTYPE_PPPOE: +#endif /* PPPOE_SUPPORT */ + /* full packet send to tcpip_thread to process */ + if (thisif.input(p, &thisif) == ERR_OK) + break; + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); + default: + pbuf_free(p); + } + } + } + } + return 0; +} + +/** @} */ diff --git a/os/various/lwip_bindings/lwipthread.h b/os/various/lwip_bindings/lwipthread.h new file mode 100644 index 000000000..ab3540c7b --- /dev/null +++ b/os/various/lwip_bindings/lwipthread.h @@ -0,0 +1,131 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2013 Giovanni Di Sirio + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/** + * @file lwipthread.h + * @brief LWIP wrapper thread macros and structures. + * @addtogroup LWIP_THREAD + * @{ + */ + +#ifndef _LWIPTHREAD_H_ +#define _LWIPTHREAD_H_ + +#include + +/** @brief MAC thread priority.*/ +#ifndef LWIP_THREAD_PRIORITY +#define LWIP_THREAD_PRIORITY LOWPRIO +#endif + +/** @brief MAC thread stack size. */ +#if !defined(LWIP_THREAD_STACK_SIZE) || defined(__DOXYGEN__) +#define LWIP_THREAD_STACK_SIZE 576 +#endif + +/** @brief Link poll interval. */ +#if !defined(LWIP_LINK_POLL_INTERVAL) || defined(__DOXYGEN__) +#define LWIP_LINK_POLL_INTERVAL S2ST(5) +#endif + +/** @brief IP Address. */ +#if !defined(LWIP_IPADDR) || defined(__DOXYGEN__) +#define LWIP_IPADDR(p) IP4_ADDR(p, 192, 168, 1, 20) +#endif + +/** @brief IP Gateway. */ +#if !defined(LWIP_GATEWAY) || defined(__DOXYGEN__) +#define LWIP_GATEWAY(p) IP4_ADDR(p, 192, 168, 1, 1) +#endif + +/** @brief IP netmask. */ +#if !defined(LWIP_NETMASK) || defined(__DOXYGEN__) +#define LWIP_NETMASK(p) IP4_ADDR(p, 255, 255, 255, 0) +#endif + +/** @brief Transmission timeout. */ +#if !defined(LWIP_SEND_TIMEOUT) || defined(__DOXYGEN__) +#define LWIP_SEND_TIMEOUT 50 +#endif + +/** @brief Link speed. */ +#if !defined(LWIP_LINK_SPEED) || defined(__DOXYGEN__) +#define LWIP_LINK_SPEED 100000000 +#endif + +/** @brief MAC Address byte 0. */ +#if !defined(LWIP_ETHADDR_0) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_0 0xC2 +#endif + +/** @brief MAC Address byte 1. */ +#if !defined(LWIP_ETHADDR_1) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_1 0xAF +#endif + +/** @brief MAC Address byte 2. */ +#if !defined(LWIP_ETHADDR_2) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_2 0x51 +#endif + +/** @brief MAC Address byte 3. */ +#if !defined(LWIP_ETHADDR_3) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_3 0x03 +#endif + +/** @brief MAC Address byte 4. */ +#if !defined(LWIP_ETHADDR_4) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_4 0xCF +#endif + +/** @brief MAC Address byte 5. */ +#if !defined(LWIP_ETHADDR_5) || defined(__DOXYGEN__) +#define LWIP_ETHADDR_5 0x46 +#endif + +/** @brief Interface name byte 0. */ +#if !defined(LWIP_IFNAME0) || defined(__DOXYGEN__) +#define LWIP_IFNAME0 'm' +#endif + +/** @brief Interface name byte 1. */ +#if !defined(LWIP_IFNAME1) || defined(__DOXYGEN__) +#define LWIP_IFNAME1 's' +#endif + +/** + * @brief Runtime TCP/IP settings. + */ +struct lwipthread_opts { + uint8_t *macaddress; + uint32_t address; + uint32_t netmask; + uint32_t gateway; +}; + +extern THD_WORKING_AREA(wa_lwip_thread, LWIP_THREAD_STACK_SIZE); + +#ifdef __cplusplus +extern "C" { +#endif + msg_t lwip_thread(void *p); +#ifdef __cplusplus +} +#endif + +#endif /* _LWIPTHREAD_H_ */ + +/** @} */ diff --git a/os/various/lwip_bindings/readme.txt b/os/various/lwip_bindings/readme.txt new file mode 100644 index 000000000..c2df4cdc7 --- /dev/null +++ b/os/various/lwip_bindings/readme.txt @@ -0,0 +1,6 @@ +This directory contains the ChibiOS/RT "official" bindings with the lwIP +TCP/IP stack: http://savannah.nongnu.org/projects/lwip + +In order to use lwIP within ChibiOS/RT project, unzip lwIP under +./ext/lwip-1.4.0 then include $(CHIBIOS)/os/various/lwip_bindings/lwip.mk +in your makefile. -- cgit v1.2.3