This is Webservice SDK for mbed. LPCXpresso1769/LPC1768/FRDM-K64F/LPC4088
Fork of libMiMic by
Revision 69:8c5f220441f5, committed 2014-05-29
- Comitter:
- nyatla
- Date:
- Thu May 29 14:29:15 2014 +0000
- Parent:
- 68:f7def7eb5504
- Child:
- 70:2ed02b798004
- Commit message:
- r354????; LPC4088?????
Changed in this revision
--- a/core/NyLPC_cMiMicEnv.c Thu May 22 12:59:50 2014 +0000 +++ b/core/NyLPC_cMiMicEnv.c Thu May 29 14:29:15 2014 +0000 @@ -0,0 +1,35 @@ +#include "NyLPC_cMiMicEnv.h" +#include "../uip/NyLPC_cUipService_protected.h" + +const static char* VERSION="MiMic/1.5.0"; +const static char* MCU="LPC176x"; +const static char* UNKNOWN="UNKNOWN"; + + +static const char* PNAME_LPCXPRESSO1769="LPCXpresso1769"; +static const char* PNAME_MBED="mbed"; + + + +const char* NyLPC_cMiMicEnv_getStrProperty(NyLPC_TUInt16 i_id) +{ + switch(i_id){ + case NyLPC_cMiMicEnv_VERSION: + return VERSION; + case NyLPC_cMiMicEnv_SHORT_NAME: + switch(*(NyLPC_cUipService_refDeviceName())){ + case 'L': + return PNAME_LPCXPRESSO1769; + case 'D': + return PNAME_MBED; + default: + return UNKNOWN; + } + case NyLPC_cMiMicEnv_ETHERNET_PHY: + return NyLPC_cUipService_refDeviceName(); + case NyLPC_cMiMicEnv_MCU_NAME: + return MCU; + default: + return UNKNOWN; + } +}
--- a/core/NyLPC_cMiMicEnv.h Thu May 22 12:59:50 2014 +0000 +++ b/core/NyLPC_cMiMicEnv.h Thu May 29 14:29:15 2014 +0000 @@ -11,10 +11,15 @@ #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +#include "NyLPC_stdlib.h" -#define NyLPC_cMiMicEnv_VERSION "MiMic/1.4.73" +#define NyLPC_cMiMicEnv_VERSION 1 +#define NyLPC_cMiMicEnv_SHORT_NAME 2 +#define NyLPC_cMiMicEnv_ETHERNET_PHY 3 +#define NyLPC_cMiMicEnv_MCU_NAME 4 +const char* NyLPC_cMiMicEnv_getStrProperty(NyLPC_TUInt16 i_id); #ifdef __cplusplus }
--- a/core/driver/ethernet/NyLPC_IEthernetDevice.h Thu May 22 12:59:50 2014 +0000 +++ b/core/driver/ethernet/NyLPC_IEthernetDevice.h Thu May 29 14:29:15 2014 +0000 @@ -22,6 +22,10 @@ /**RXが到達した*/ #define NyLPC_TiEthernetDevice_EVENT_ON_RX 2 +/** + * ヒント値。NyLPC_TcEthernetMM_HINT_CTRL_PACKETと同じ。 + */ +#define NyLPC_TcEthernetMM_HINT_CTRL_PACKET 0 typedef void (*NyLPC_TiEthernetDevice_onEvent)(void* i_param,NyLPC_TiEthernetDevice_EVENT i_type); @@ -164,4 +168,3 @@ #endif /* __cplusplus */ #endif -
--- a/core/driver/ethernet/NyLPC_cEthernetMM.c Thu May 22 12:59:50 2014 +0000 +++ b/core/driver/ethernet/NyLPC_cEthernetMM.c Thu May 29 14:29:15 2014 +0000 @@ -6,6 +6,7 @@ #define NUM_OF_512_BUF 3 #define NUM_OF_256_BUF 4 #define NUM_OF_128_BUF 16 +#define NUM_OF_64_BUF 4 /** * FULLサイズのEthernetFrame送信メモリのサイズ。 @@ -16,7 +17,7 @@ /** * TXメモリブロックの配置 - * 9246バイト + * 9518バイト */ struct TTxMemoryBlock { @@ -36,6 +37,10 @@ struct NyLPC_TTxBufferHeader h; NyLPC_TUInt8 b[128]; }buf_128[NUM_OF_128_BUF];//(4+128)*16=1584 + struct{ + struct NyLPC_TTxBufferHeader h; + NyLPC_TUInt8 b[64]; + }buf_64[NUM_OF_64_BUF];//(4+64)*4=272 }; /** * メモリブロックの配置 @@ -50,8 +55,8 @@ int NyLPC_cEthernetMM_dbg_getNumofUsedTx(void) { int x; - NyLPC_TUInt8 r1,r2,r3,r4; - r1=r2=r3=r4=0; + NyLPC_TUInt8 r1,r2,r3,r4,r5; + r1=r2=r3=r4=r5=0; for(x=0;x<NUM_OF_MAX_BUF;x++){ if(_mem_addr->buf_max[x].h.is_lock || _mem_addr->buf_max[x].h.ref>0){ r1++; @@ -76,7 +81,13 @@ continue; } } - return r1+r2+r3+r4; + for(x=0;x<NUM_OF_64_BUF;x++){ + if(_mem_addr->buf_64[x].h.is_lock || _mem_addr->buf_64[x].h.ref>0){ + r5++; + continue; + } + } + return r1+r2+r3+r4+r5; } @@ -101,6 +112,10 @@ _mem_addr->buf_128[x].h.is_lock=NyLPC_TUInt8_FALSE; _mem_addr->buf_128[x].h.ref=0; } + for(x=0;x<NUM_OF_64_BUF;x++){ + _mem_addr->buf_64[x].h.is_lock=NyLPC_TUInt8_FALSE; + _mem_addr->buf_64[x].h.ref=0; + } } /** @@ -108,59 +123,73 @@ */ struct NyLPC_TTxBufferHeader* NyLPC_cEthernetMM_alloc(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) { - int buf_type; int i; //ヒントから、割り当てるメモリブロックを決定 - if(i_hint<=128){ - buf_type=0; - }else if(i_hint<=256){ - buf_type=1; - }else if(i_hint<=512){ - buf_type=2; - }else{ - buf_type=3; - } - switch(buf_type){ - case 3: - for(i=0;i<NUM_OF_MAX_BUF;i++){ + + //特殊ブロック + if(i_hint==NyLPC_TcEthernetMM_HINT_CTRL_PACKET){ + for(i=0;i<NUM_OF_64_BUF;i++){ //未参照かつ送信中でないもの。 - if(_mem_addr->buf_max[i].h.ref>0 || _mem_addr->buf_max[i].h.is_lock){ + if(_mem_addr->buf_64[i].h.ref>0 || _mem_addr->buf_64[i].h.is_lock){ continue; } - _mem_addr->buf_max[i].h.ref++; - *o_size=MAX_TX_ETHERNET_FRAME_SIZE; - return &(_mem_addr->buf_max[i].h); + _mem_addr->buf_64[i].h.ref++; + *o_size=64; + return &(_mem_addr->buf_64[i].h); } - case 2: - for(i=0;i<NUM_OF_512_BUF;i++){ - //未参照かつ送信中でないもの。 - if(_mem_addr->buf_512[i].h.ref>0 || _mem_addr->buf_512[i].h.is_lock){ - continue; - } - *o_size=512; - _mem_addr->buf_512[i].h.ref++; - return &(_mem_addr->buf_512[i].h); + return NULL; + } + + //汎用ブロック + if(i_hint<=128){ + goto ALLOC_128; + }else if(i_hint<=256){ + goto ALLOC_256; + }else if(i_hint<=512){ + goto ALLOC_512; + }else{ + goto ALLOC_MAX; + } + +ALLOC_MAX: + for(i=0;i<NUM_OF_MAX_BUF;i++){ + //未参照かつ送信中でないもの。 + if(_mem_addr->buf_max[i].h.ref>0 || _mem_addr->buf_max[i].h.is_lock){ + continue; } - case 1: - for(i=0;i<NUM_OF_256_BUF;i++){ - //未参照かつ送信中でないもの。 - if(_mem_addr->buf_256[i].h.ref>0 || (_mem_addr->buf_256[i].h.is_lock)){ - continue; - } - *o_size=256; - _mem_addr->buf_256[i].h.ref++; - return &(_mem_addr->buf_256[i].h); + _mem_addr->buf_max[i].h.ref++; + *o_size=MAX_TX_ETHERNET_FRAME_SIZE; + return &(_mem_addr->buf_max[i].h); + } +ALLOC_512: + for(i=0;i<NUM_OF_512_BUF;i++){ + //未参照かつ送信中でないもの。 + if(_mem_addr->buf_512[i].h.ref>0 || _mem_addr->buf_512[i].h.is_lock){ + continue; } - default: - for(i=0;i<NUM_OF_128_BUF;i++){ - //未参照かつ送信中でないもの。 - if(_mem_addr->buf_128[i].h.ref>0 || (_mem_addr->buf_128[i].h.is_lock)){ - continue; - } - *o_size=128; - _mem_addr->buf_128[i].h.ref++; - return &(_mem_addr->buf_128[i].h); + *o_size=512; + _mem_addr->buf_512[i].h.ref++; + return &(_mem_addr->buf_512[i].h); + } +ALLOC_256: + for(i=0;i<NUM_OF_256_BUF;i++){ + //未参照かつ送信中でないもの。 + if(_mem_addr->buf_256[i].h.ref>0 || (_mem_addr->buf_256[i].h.is_lock)){ + continue; } + *o_size=256; + _mem_addr->buf_256[i].h.ref++; + return &(_mem_addr->buf_256[i].h); + } +ALLOC_128: + for(i=0;i<NUM_OF_128_BUF;i++){ + //未参照かつ送信中でないもの。 + if(_mem_addr->buf_128[i].h.ref>0 || (_mem_addr->buf_128[i].h.is_lock)){ + continue; + } + *o_size=128; + _mem_addr->buf_128[i].h.ref++; + return &(_mem_addr->buf_128[i].h); } return NULL; } @@ -174,4 +203,3 @@ return; } -
--- a/core/driver/ethernet/NyLPC_cEthernetMM.h Thu May 22 12:59:50 2014 +0000 +++ b/core/driver/ethernet/NyLPC_cEthernetMM.h Thu May 29 14:29:15 2014 +0000 @@ -35,6 +35,11 @@ #endif /* __cplusplus */ /** + * NyLPC_cEthernetMM_allocのヒント値。 + * コントロールパケット用のサイズ要求をするときに使用します。 + */ +#define NyLPC_TcEthernetMM_HINT_CTRL_PACKET 0 +/** * @file * このファイルは、イーサネットメモリマネージャクラスを定義します。 */ @@ -49,6 +54,13 @@ #define NyLPC_cEthernetMM_finalize(i) /** * メモリを割り当てます。 + * @param i_hint + * 割り当てるメモリサイズのヒント。 + * 数値の場合、128バイト以上のもっともhintに近いメモリを割り当てます。 + * 以下の定義値の場合、特別な領域を優先して返します。たぶん。 + * <ul> + * <li>NyLPC_TcEthernetMM_HINT_CTRL_PACKET - 64 + * </ul> * @return * 割り当て不能な場合はNULLが帰ります。 * @bug @@ -65,4 +77,3 @@ #endif /* __cplusplus */ #endif -
--- a/core/driver/ethernet/lpc17xx/EthDev_LPC17xx.c Thu May 22 12:59:50 2014 +0000 +++ b/core/driver/ethernet/lpc17xx/EthDev_LPC17xx.c Thu May 29 14:29:15 2014 +0000 @@ -9,9 +9,11 @@ #include "LPC17xx.h" #include "EthDev_LPC17xx.h" #include "NyLPC_os.h" +#include "LPC17xx.h" /* If no buffers are available, then wait this long before looking again.... */ -#define emacBUFFER_WAIT_DELAY_MS 3 -#define emacBUFFER_WAIT_EMPTY_DELAY_MS 10 +#define emacBUFFER_WAIT_DELAY_MS 3 +#define emacBUFFER_WAIT_EMPTY_DELAY_MS 10 +#define emacSHORT_DELAY_MS 10 //-------------------------------------------------- // common function. //-------------------------------------------------- @@ -191,6 +193,80 @@ LPC_EMAC->RxConsumeIndex = lIndex; } } + + +/*-----------------------------------------------------------*/ + + +/*-----------------------------------------------------------*/ +#define ETHDEV_PHY_DEF_ADR 0x0100 /* Default PHY device address */ + +NyLPC_TBool EthDev_LPC17xx_prvWritePHY( long lPhyReg, long lValue ) +{ + const long lMaxTime = 10; + long x; + + LPC_EMAC->MCMD = 0; + LPC_EMAC->MADR = ETHDEV_PHY_DEF_ADR | lPhyReg; + LPC_EMAC->MWTD = lValue; + + for( x = 0; x < lMaxTime; x++ ) + { + if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 ) + { + /* Operation has finished. */ + break; + } + + NyLPC_cThread_sleep( emacSHORT_DELAY_MS ); + } + + if( x < lMaxTime ) + { + return NyLPC_TBool_TRUE; + } + else + { + return NyLPC_TBool_FALSE; + } +} +/*-----------------------------------------------------------*/ + +unsigned short EthDev_LPC17xx_prvReadPHY( unsigned int ucPhyReg, NyLPC_TBool* plStatus ) +{ + long x; + const long lMaxTime = 10; + + LPC_EMAC->MCMD = 1; + LPC_EMAC->MADR = ETHDEV_PHY_DEF_ADR | ucPhyReg; + LPC_EMAC->MCMD = MCMD_READ; + + for( x = 0; x < lMaxTime; x++ ) + { + /* Operation has finished. */ + if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 ) + { + break; + } + NyLPC_cThread_sleep( emacSHORT_DELAY_MS ); + } + + LPC_EMAC->MCMD = 0; + + if( x >= lMaxTime ) + { + *plStatus = NyLPC_TBool_FALSE; + } + + return( LPC_EMAC->MRDD ); +} + + + + + + + + #endif -
--- a/core/driver/ethernet/lpc17xx/EthDev_LPC17xx.h Thu May 22 12:59:50 2014 +0000 +++ b/core/driver/ethernet/lpc17xx/EthDev_LPC17xx.h Thu May 29 14:29:15 2014 +0000 @@ -319,14 +319,18 @@ -void EthDev_LPC17xx_prevTxDescriptor(void); -void EthDev_LPC17xx_prevRxDescriptor(void); void EthDev_LPC17xx_processTx(void); void EthDev_LPC17xx_sendTxEthFrame(struct NyLPC_TTxBufferHeader* i_buf,unsigned short i_size); - void* EthDev_LPC17xx_getRxEthFrame(unsigned short* o_len_of_data); void EthDev_LPC17xx_nextRxEthFrame(void); +void EthDev_LPC17xx_prevTxDescriptor(void); +void EthDev_LPC17xx_prevRxDescriptor(void); +NyLPC_TBool EthDev_LPC17xx_prvWritePHY( long lPhyReg, long lValue ); +unsigned short EthDev_LPC17xx_prvReadPHY( unsigned int ucPhyReg, NyLPC_TBool* plStatus ); + + + #ifdef __cplusplus } #endif /* __cplusplus */ @@ -335,4 +339,3 @@ /*---------------------------------------------------------------------------- * end of file *---------------------------------------------------------------------------*/ -
--- a/core/driver/ethernet/lpc17xx/EtherDev_DP83848C.c Thu May 22 12:59:50 2014 +0000 +++ b/core/driver/ethernet/lpc17xx/EtherDev_DP83848C.c Thu May 29 14:29:15 2014 +0000 @@ -100,7 +100,7 @@ #define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ #define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ #define PHY_AUTO_NEG_COMPLETE 0x0020 /* Auto negotiation have finished. */ -#define ETHDEV_PHY_DEF_ADR 0x0100 /* Default PHY device address */ +//#define ETHDEV_PHY_DEF_ADR 0x0100 /* Default PHY device address */ #ifndef configEMAC_INTERRUPT_PRIORITY @@ -116,16 +116,7 @@ /* Hardware specific bit definitions. */ #define emacPINSEL2_VALUE ( 0x50150105 ) -/* If no buffers are available, then wait this long before looking again.... */ -#define emacBUFFER_WAIT_DELAY_MS 3 -#define emacBUFFER_WAIT_EMPTY_MS 10 -/* ...and don't look more than this many times. */ -#define emacBUFFER_WAIT_ATTEMPTS ( 30 ) - -/* Index to the Tx descriptor that is always used first for every Tx. The second -descriptor is then used to re-send in order to speed up the uIP Tx process. */ -#define emacTX_DESC_INDEX ( 0 ) /*-----------------------------------------------------------*/ @@ -138,15 +129,8 @@ * parameters. */ static NyLPC_TBool prvSetupLinkStatus( void ); -/* - * Send lValue to the lPhyReg within the PHY. - */ -static NyLPC_TBool prvWritePHY( long lPhyReg, long lValue ); -/* - * Read a value from ucPhyReg within the PHY. *plStatus will be set to - * pdFALSE if there is an error. - */ -static unsigned short prvReadPHY( unsigned int ucPhyReg, long *plStatus ); + + @@ -189,8 +173,8 @@ //Reset MCU Interface. and wait for reset. prvSetupEMACHardware(); //Check peripheral name - ulID1 = prvReadPHY( PHY_REG_IDR1, &lReturn ); - ulID2 = prvReadPHY( PHY_REG_IDR2, &lReturn ); + ulID1 = EthDev_LPC17xx_prvReadPHY( PHY_REG_IDR1, &lReturn ); + ulID2 = EthDev_LPC17xx_prvReadPHY( PHY_REG_IDR2, &lReturn ); if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) != DP83848C_ID) { return NyLPC_TBool_FALSE; @@ -332,14 +316,14 @@ LPC_EMAC->SUPP = SUPP_SPEED; /* Put the PHY in reset mode */ - prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII ); + EthDev_LPC17xx_prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII ); NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5); /* Wait for hardware reset to end. */ for( x = 0; x < 100; x++ ) { NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5 ); - us = prvReadPHY( PHY_REG_BMCR, &lDummy ); + us = EthDev_LPC17xx_prvReadPHY( PHY_REG_BMCR, &lDummy ); if( !( us & MCFG_RES_MII ) ) { /* Reset complete */ @@ -347,70 +331,6 @@ } } } -/*-----------------------------------------------------------*/ - - -/*-----------------------------------------------------------*/ - -static NyLPC_TBool prvWritePHY( long lPhyReg, long lValue ) -{ - const long lMaxTime = 10; - long x; - - LPC_EMAC->MCMD = 0; - LPC_EMAC->MADR = ETHDEV_PHY_DEF_ADR | lPhyReg; - LPC_EMAC->MWTD = lValue; - - for( x = 0; x < lMaxTime; x++ ) - { - if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 ) - { - /* Operation has finished. */ - break; - } - - NyLPC_cThread_sleep( emacSHORT_DELAY_MS ); - } - - if( x < lMaxTime ) - { - return NyLPC_TBool_TRUE; - } - else - { - return NyLPC_TBool_FALSE; - } -} -/*-----------------------------------------------------------*/ - -static unsigned short prvReadPHY( unsigned int ucPhyReg, NyLPC_TBool* plStatus ) -{ - long x; - const long lMaxTime = 10; - - LPC_EMAC->MCMD = 1; - LPC_EMAC->MADR = ETHDEV_PHY_DEF_ADR | ucPhyReg; - LPC_EMAC->MCMD = MCMD_READ; - - for( x = 0; x < lMaxTime; x++ ) - { - /* Operation has finished. */ - if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 ) - { - break; - } - NyLPC_cThread_sleep( emacSHORT_DELAY_MS ); - } - - LPC_EMAC->MCMD = 0; - - if( x >= lMaxTime ) - { - *plStatus = NyLPC_TBool_FALSE; - } - - return( LPC_EMAC->MRDD ); -} /*------------------------------------------------ * Private function depend on device. * デバイス依存部分 @@ -431,13 +351,13 @@ NyLPC_TBool lDummy; /* Auto negotiate the configuration. */ - if( prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) ) + if( EthDev_LPC17xx_prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) ) { NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5 ); for( x = 0; x < 10; x++ ) { - us = prvReadPHY( PHY_REG_BMSR, &lDummy ); + us = EthDev_LPC17xx_prvReadPHY( PHY_REG_BMSR, &lDummy ); if( us & PHY_AUTO_NEG_COMPLETE ) { @@ -458,7 +378,7 @@ /* Wait with timeout for the link to be established. */ for( x = 0; x < 10; x++ ) { - usLinkStatus = prvReadPHY( PHY_REG_STS, &lReturn ); + usLinkStatus = EthDev_LPC17xx_prvReadPHY( PHY_REG_STS, &lReturn ); if( usLinkStatus & emacLINK_ESTABLISHED ) { /* Link is established. */ @@ -517,4 +437,3 @@ } #endif -
--- a/core/driver/ethernet/lpc17xx/EtherDev_LAN8720.c Thu May 22 12:59:50 2014 +0000 +++ b/core/driver/ethernet/lpc17xx/EtherDev_LAN8720.c Thu May 29 14:29:15 2014 +0000 @@ -90,7 +90,7 @@ #define PHY_SPEED_FDUPLX 0x0010 /* Full Duplex */ #define PHY_SPEED_100 0x0008 /* 100Mbit */ -#define ETHDEV_PHY_DEF_ADR 0x0100 /* Default PHY device address */ + #ifndef configEMAC_INTERRUPT_PRIORITY #define configEMAC_INTERRUPT_PRIORITY 5 @@ -106,14 +106,6 @@ #define emacPINSEL2_VALUE ( 0x50150105 ) - -/* ...and don't look more than this many times. */ -#define emacBUFFER_WAIT_ATTEMPTS ( 30 ) - -/* Index to the Tx descriptor that is always used first for every Tx. The second -descriptor is then used to re-send in order to speed up the uIP Tx process. */ -#define emacTX_DESC_INDEX ( 0 ) - /*-----------------------------------------------------------*/ /* Setup the IO and peripherals required for Ethernet communication.*/ @@ -125,15 +117,8 @@ * parameters. */ static long prvSetupLinkStatus( void ); -/* - * Send lValue to the lPhyReg within the PHY. - */ -static long prvWritePHY( long lPhyReg, long lValue ); -/* - * Read a value from ucPhyReg within the PHY. *plStatus will be set to - * pdFALSE if there is an error. - */ -static unsigned short prvReadPHY( unsigned int ucPhyReg, NyLPC_TBool* o_status); + + static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param); @@ -174,8 +159,8 @@ //Reset MCU Interface. and wait for reset. prvSetupEMACHardware(); //Check peripheral name - ulID1 = prvReadPHY( PHY_REG_IDR1, &ret ); - ulID2 = prvReadPHY( PHY_REG_IDR2, &ret ); + ulID1 = EthDev_LPC17xx_prvReadPHY( PHY_REG_IDR1, &ret ); + ulID2 = EthDev_LPC17xx_prvReadPHY( PHY_REG_IDR2, &ret ); if( ( (ulID1 << 16UL ) | ( ulID2 & 0xFFF0UL ) ) != LAN8720_ID) { return NyLPC_TBool_FALSE; @@ -321,14 +306,14 @@ LPC_EMAC->SUPP = SUPP_SPEED; /* Put the PHY in reset mode */ - prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII ); + EthDev_LPC17xx_prvWritePHY( PHY_REG_BMCR, MCFG_RES_MII ); NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5); /* Wait for hardware reset to end. */ for( x = 0; x < 100; x++ ) { NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5 ); - us = prvReadPHY( PHY_REG_BMCR, &lDummy ); + us = EthDev_LPC17xx_prvReadPHY( PHY_REG_BMCR, &lDummy ); if( !( us & MCFG_RES_MII ) ) { /* Reset complete */ @@ -336,70 +321,8 @@ } } } -/*-----------------------------------------------------------*/ -/*-----------------------------------------------------------*/ - -static NyLPC_TBool prvWritePHY( long lPhyReg, long lValue ) -{ - const long lMaxTime = 10; - long x; - - LPC_EMAC->MCMD = 0; - LPC_EMAC->MADR = ETHDEV_PHY_DEF_ADR | lPhyReg; - LPC_EMAC->MWTD = lValue; - - for( x = 0; x < lMaxTime; x++ ) - { - if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 ) - { - /* Operation has finished. */ - break; - } - - NyLPC_cThread_sleep( emacSHORT_DELAY_MS); - } - - if( x < lMaxTime ) - { - return NyLPC_TBool_TRUE; - } - else - { - return NyLPC_TBool_FALSE; - } -} -/*-----------------------------------------------------------*/ - -static unsigned short prvReadPHY( unsigned int ucPhyReg, NyLPC_TBool *o_status) -{ - long x; - const long lMaxTime = 10; - - LPC_EMAC->MCMD = 1; - LPC_EMAC->MADR = ETHDEV_PHY_DEF_ADR | ucPhyReg; - LPC_EMAC->MCMD = MCMD_READ; - - for( x = 0; x < lMaxTime; x++ ) - { - /* Operation has finished. */ - if( ( LPC_EMAC->MIND & MIND_BUSY ) == 0 ) - { - break; - } - NyLPC_cThread_sleep( emacSHORT_DELAY_MS); - } - - LPC_EMAC->MCMD = 0; - - if( x >= lMaxTime ) - { - *o_status =NyLPC_TBool_FALSE; - } - - return( LPC_EMAC->MRDD ); -} /** * Private function depend on configulation. * デバイス依存部分 @@ -414,13 +337,13 @@ long x; NyLPC_TBool lDummy; /* Auto negotiate the configuration. */ - if( prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) ) + if( EthDev_LPC17xx_prvWritePHY( PHY_REG_BMCR, PHY_AUTO_NEG ) ) { NyLPC_cThread_sleep( emacSHORT_DELAY_MS * 5 ); for( x = 0; x < 10; x++ ) { - us = prvReadPHY( PHY_REG_PHY_CTRL, &lDummy ); + us = EthDev_LPC17xx_prvReadPHY( PHY_REG_PHY_CTRL, &lDummy ); if( us & PHY_AUTO_NEG_COMPLETE ) { break; @@ -439,7 +362,7 @@ /* Wait with timeout for the link to be established. */ for( x = 0; x < 10; x++ ) { - usLinkStatus = prvReadPHY (PHY_REG_PHY_CTRL, &lReturn ); + usLinkStatus = EthDev_LPC17xx_prvReadPHY (PHY_REG_PHY_CTRL, &lReturn ); if( usLinkStatus & PHY_AUTO_NEG_COMPLETE ) { /* Link is established. */ @@ -501,4 +424,3 @@ #endif -
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/driver/ethernet/lpc4088/EthDev.c Thu May 29 14:29:15 2014 +0000 @@ -0,0 +1,21 @@ +#include "NyLPC_config.h" +#if NyLPC_MCU==NyLPC_MCU_LPC4088 + +#include "../EthDev.h" +#include "EtherDev_LPC4088_protected.h" + + + +const struct TiEthernetDevice* getEthernetDevicePnP(void) +{ + const struct TiEthernetDevice* ret; + if(EthDev_LPC4088_getInterface(&ret)){ + return ret; + } + return NULL; +} + + +#endif + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/driver/ethernet/lpc4088/EthDev_LPC4088.c Thu May 29 14:29:15 2014 +0000 @@ -0,0 +1,606 @@ +#include "NyLPC_config.h" +#if NyLPC_MCU==NyLPC_MCU_LPC4088 +#include "NyLPC_os.h" +#include "copy_of_ethernet_api.h" +#include "NyLPC_IEthernetDevice.h" +#include "NyLPC_cEthernetMM.h" + + + +#define emacSHORT_DELAY_MS 10 +#ifndef configEMAC_INTERRUPT_PRIORITY + #define configEMAC_INTERRUPT_PRIORITY 5 +#endif +//////////////////////////////////////////////////////////////////////////////// +// Ethernet Memory +//////////////////////////////////////////////////////////////////////////////// + +#define AHB_SRAM_BANK1_BASE 0x20004000UL +#define RX_DESC_BASE (AHB_SRAM_BANK1_BASE ) +#define RX_STAT_BASE (RX_DESC_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_DESC_TypeDef */ +#define TX_DESC_BASE (RX_STAT_BASE + NUM_RX_FRAG*(2*4)) /* 2 * uint32_t, see RX_STAT_TypeDef */ +#define TX_STAT_BASE (TX_DESC_BASE + NUM_TX_FRAG*(2*4)) /* 2 * uint32_t, see TX_DESC_TypeDef */ +#define ETH_BUF_BASE (TX_STAT_BASE + NUM_TX_FRAG*(1*4)) /* 1 * uint32_t, see TX_STAT_TypeDef */ + +/** + * 消費メモリ量は、 + * descriptor = NUM_RX_FRAG*16+NUM_TX_FRAG*12. + * EthnetBuf=ETH_FRAG_SIZE*NUM_RX_FRAG + */ + +/* RX and TX descriptor and status definitions. */ +#define RX_DESC_PACKET(i) (*(unsigned int *)(RX_DESC_BASE + 8*i)) +#define RX_DESC_CTRL(i) (*(unsigned int *)(RX_DESC_BASE+4 + 8*i)) +#define RX_STAT_INFO(i) (*(unsigned int *)(RX_STAT_BASE + 8*i)) +#define RX_STAT_HASHCRC(i) (*(unsigned int *)(RX_STAT_BASE+4 + 8*i)) +#define TX_DESC_PACKET(i) (*(unsigned int *)(TX_DESC_BASE + 8*i)) +#define TX_DESC_CTRL(i) (*(unsigned int *)(TX_DESC_BASE+4 + 8*i)) +#define TX_STAT_INFO(i) (*(unsigned int *)(TX_STAT_BASE + 4*i)) +#define ETH_BUF(i) ( ETH_BUF_BASE + ETH_FRAG_SIZE*i ) +#define ETH_TX_BUF_BASE ((void*)(ETH_BUF_BASE+ETH_FRAG_SIZE*NUM_RX_FRAG)) + + +#define emacWAIT_FOR_LINK_TO_ESTABLISH_MS 500 + +//////////////////////////////////////////////////////////////////////////////// +// Ethernet interdface functions +//////////////////////////////////////////////////////////////////////////////// +static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param); +static void stop(void); +static void* getRxEthFrame(unsigned short* o_len_of_data); +static void nextRxEthFrame(void); +static struct NyLPC_TTxBufferHeader* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size); +static void releaseTxBuf(struct NyLPC_TTxBufferHeader* i_buf); +static void sendTxEthFrame(struct NyLPC_TTxBufferHeader* i_buf,unsigned short i_size); +static void processTx(void); + +//////////////////////////////////////////////////////////////////////////////// +// Private +//////////////////////////////////////////////////////////////////////////////// +static void emacIsrHandler(unsigned long i_status); +static unsigned int clockselect(void); +static int ethernet_link(void); +static int phy_write(unsigned int PhyReg, unsigned short Data); +static int phy_read(unsigned int PhyReg); +static void prevTxDescriptor(void); +static void prevRxDescriptor(void); +static NyLPC_TUInt32 waitForTxEthFrameEmpty(void); + +/*-----------------------------------------------------------*/ + + +const static struct TiEthernetDevice _interface_LAN8720= +{ + "LAN8720", + start, + stop, + getRxEthFrame, + nextRxEthFrame, + allocTxBuf, + releaseTxBuf, + sendTxEthFrame, + processTx +}; +const static struct TiEthernetDevice _interface_DP83848C= +{ + "DP83848C", + start, + stop, + getRxEthFrame, + nextRxEthFrame, + allocTxBuf, + releaseTxBuf, + sendTxEthFrame, + processTx +}; + +static void* _event_param; +static NyLPC_TiEthernetDevice_onEvent _event_handler; +static unsigned int phy_id; + +/* + * EthernetDeviceのファクトリー関数。インターフェイスを生成できればtrue + * + */ +NyLPC_TBool EthDev_LPC4088_getInterface( + const struct TiEthernetDevice** o_dev) +{ + int regv, tout; + unsigned int clock = clockselect(); + + LPC_SC->PCONP |= 0x40000000; /* Power Up the EMAC controller. */ + LPC_IOCON->P1_0 &= ~0x07; /* ENET I/O config */ + LPC_IOCON->P1_0 |= 0x01; /* ENET_TXD0 */ + LPC_IOCON->P1_1 &= ~0x07; + LPC_IOCON->P1_1 |= 0x01; /* ENET_TXD1 */ + LPC_IOCON->P1_4 &= ~0x07; + LPC_IOCON->P1_4 |= 0x01; /* ENET_TXEN */ + LPC_IOCON->P1_8 &= ~0x07; + LPC_IOCON->P1_8 |= 0x01; /* ENET_CRS */ + LPC_IOCON->P1_9 &= ~0x07; + LPC_IOCON->P1_9 |= 0x01; /* ENET_RXD0 */ + LPC_IOCON->P1_10 &= ~0x07; + LPC_IOCON->P1_10 |= 0x01; /* ENET_RXD1 */ + LPC_IOCON->P1_14 &= ~0x07; + LPC_IOCON->P1_14 |= 0x01; /* ENET_RX_ER */ + LPC_IOCON->P1_15 &= ~0x07; + LPC_IOCON->P1_15 |= 0x01; /* ENET_REF_CLK */ + LPC_IOCON->P1_16 &= ~0x07; /* ENET/PHY I/O config */ + LPC_IOCON->P1_16 |= 0x01; /* ENET_MDC */ + LPC_IOCON->P1_17 &= ~0x07; + LPC_IOCON->P1_17 |= 0x01; /* ENET_MDIO */ + + /* Reset all EMAC internal modules. */ + LPC_EMAC->MAC1 = MAC1_RES_TX | MAC1_RES_MCS_TX | MAC1_RES_RX | MAC1_RES_MCS_RX | MAC1_SIM_RES | MAC1_SOFT_RES; + LPC_EMAC->Command = CR_REG_RES | CR_TX_RES | CR_RX_RES | CR_PASS_RUNT_FRM; +for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ + + /* Initialize MAC control registers. */ + LPC_EMAC->MAC1 = MAC1_PASS_ALL; + LPC_EMAC->MAC2 = MAC2_CRC_EN | MAC2_PAD_EN; + LPC_EMAC->MAXF = ETH_MAX_FLEN; + LPC_EMAC->CLRT = CLRT_DEF; + LPC_EMAC->IPGR = IPGR_DEF; + + /* Enable Reduced MII interface. */ + LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; /* Set clock */ + LPC_EMAC->MCFG |= MCFG_RES_MII; /* and reset */ + LPC_EMAC->Command = CR_RMII | CR_PASS_RUNT_FRM |CR_PASS_RX_FILT; /* Enable Reduced MII interface. */ + +for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ + + LPC_EMAC->MCFG = (clock << 0x2) & MCFG_CLK_SEL; + LPC_EMAC->MCMD = 0; + LPC_EMAC->SUPP = SUPP_RES_RMII; /* Reset Reduced MII Logic. */ +for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ + LPC_EMAC->SUPP = SUPP_SPEED; + + phy_write(PHY_REG_BMCR, PHY_BMCR_RESET); /* perform PHY reset */ + for(tout = 0x20000; ; tout--) { /* Wait for hardware reset to end. */ + regv = phy_read(PHY_REG_BMCR); + if(regv < 0 || tout == 0) { + return NyLPC_TBool_FALSE; /* Error */ + } + if(!(regv & PHY_BMCR_RESET)) { + break; /* Reset complete. */ + } + } + + phy_id = (phy_read(PHY_REG_IDR1) << 16); + phy_id |= (phy_read(PHY_REG_IDR2) & 0XFFF0); + + switch(phy_id){ + case DP83848C_ID: + *o_dev=&_interface_DP83848C; + break; + case LAN8720_ID: + *o_dev=&_interface_LAN8720; + break; + default: + return NyLPC_TBool_FALSE; /* Error */ + } + LPC_EMAC->TxProduceIndex = 0; + LPC_EMAC->RxConsumeIndex = 0; + return NyLPC_TBool_TRUE; +} + + + +static NyLPC_TBool start(const struct NyLPC_TEthAddr* i_eth_addr,NyLPC_TiEthernetDevice_onEvent i_handler,void* i_param) +{ + int i; + //ISRw割り込み設定 + NyLPC_cIsr_setEnetISR(emacIsrHandler); + _event_handler=i_handler; + _event_param=i_param; + /* Set the Ethernet MAC Address registers */ + LPC_EMAC->SA0 = (((uint32_t)(i_eth_addr->addr[0])) << 8 ) | i_eth_addr->addr[1]; + LPC_EMAC->SA1 = (((uint32_t)(i_eth_addr->addr[2])) << 8 ) | i_eth_addr->addr[3]; + LPC_EMAC->SA2 = (((uint32_t)(i_eth_addr->addr[4])) << 8 ) | i_eth_addr->addr[5]; + + //TXメモリマネージャの準備 + NyLPC_cEthernetMM_initialize(ETH_TX_BUF_BASE); + /* Initialize Tx and Rx DMA Descriptors */ + prevRxDescriptor(); + prevTxDescriptor(); + //wait for link up + for(i=0;i<5;i++){ + if(ethernet_link()!=0){ + break; + } + NyLPC_cThread_sleep(emacWAIT_FOR_LINK_TO_ESTABLISH_MS); + } + + //setup Link + ethernet_set_link(-1, 0); + + LPC_EMAC->RxFilterCtrl = RFC_UCAST_EN | RFC_MCAST_EN | RFC_BCAST_EN | RFC_PERFECT_EN; + /* Receive Broadcast, Perfect Match Packets */ + + //Ethernetの割込み開始設定 + NyLPC_cIsr_enterCritical(); + { + LPC_EMAC->IntEnable = INT_RX_DONE | INT_TX_DONE; /* Enable EMAC interrupts. */ + LPC_EMAC->IntClear = 0xFFFF; /* Reset all interrupts */ + + LPC_EMAC->Command |= (CR_RX_EN | CR_TX_EN); /* Enable receive and transmit mode of MAC Ethernet core */ + LPC_EMAC->MAC1 |= MAC1_REC_EN; + + NVIC_SetPriority( ENET_IRQn, configEMAC_INTERRUPT_PRIORITY ); + NVIC_EnableIRQ( ENET_IRQn ); + } + NyLPC_cIsr_exitCritical(); + + return NyLPC_TBool_TRUE; +} + + +static void stop(void) +{ + NyLPC_cIsr_enterCritical(); + { + LPC_EMAC->IntEnable &= ~(INT_RX_DONE | INT_TX_DONE); + LPC_EMAC->IntClear = 0xFFFF; + + NVIC_DisableIRQ( ENET_IRQn ); + } + NyLPC_cIsr_exitCritical(); + LPC_EMAC->Command &= ~( CR_RX_EN | CR_TX_EN ); + LPC_EMAC->MAC1 &= ~MAC1_REC_EN; + //ISR割り込み解除 + NyLPC_cIsr_setEnetISR(NULL); + //TXメモリマネージャの終了 + NyLPC_cEthernetMM_finalize(); +} + +static struct NyLPC_TTxBufferHeader* allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) +{ + return NyLPC_cEthernetMM_alloc(i_hint,o_size); +} +static void releaseTxBuf(struct NyLPC_TTxBufferHeader* i_buf) +{ + NyLPC_cEthernetMM_release(i_buf); +} + + +/** +*/ +static void processTx(void) +{ + waitForTxEthFrameEmpty(); +} + + + +/** + * Ethernetパケットを送信します。 + * allocTxBufで得たバッファか、NyLPC_TTxBufferHeaderのペイロード部分を指定すること。 + * <p>関数仕様</p> + * この関数は、i_bufが + * </div> + */ +static void sendTxEthFrame(struct NyLPC_TTxBufferHeader* i_buf,unsigned short i_size) +{ + NyLPC_TUInt32 IndexNext,Index; + + //サイズ0なら送信の必要なし + if(i_size == 0) + { + return; + } + //送信デスクリプタの反映 + IndexNext =waitForTxEthFrameEmpty(); + + //送信対象のメモリブロックを送信中に設定。 +// b=(i_buf+1); + //送信中のメモリブロックなら無視 + if(i_buf->is_lock){ + return; + } + //送信中にセット + i_buf->is_lock=NyLPC_TUInt8_TRUE; + + //送信データのセット + Index = LPC_EMAC->TxProduceIndex; + if (i_size > ETH_FRAG_SIZE){ + i_size = ETH_FRAG_SIZE; + } + //送信処理 + TX_DESC_PACKET( Index ) = ( unsigned long )(i_buf+1); + //See UM10360.pdf Table 181. Transmit descriptor control word + TX_DESC_CTRL( Index ) = ((i_size-1) | TCTRL_LAST | TCTRL_INT ); + LPC_EMAC->TxProduceIndex = IndexNext; + return; +} +/** + * 送信デスクリプタを準備します。 + */ +static void prevTxDescriptor(void) +{ + long x; + //デスクリプタの設定 + for( x = 0; x < NUM_TX_FRAG; x++ ) + { + TX_DESC_PACKET( x ) = ( unsigned long ) NULL; + TX_DESC_CTRL( x ) = 0; + TX_STAT_INFO( x ) = 0; + } + /* Set LPC_EMAC Transmit Descriptor Registers. */ + LPC_EMAC->TxDescriptor =TX_DESC_BASE; + LPC_EMAC->TxStatus = TX_STAT_BASE; + LPC_EMAC->TxDescriptorNumber = NUM_TX_FRAG - 1; +} +static void prevRxDescriptor(void) +{ + int x; + //デスクリプタの設定 + for( x = 0; x < NUM_RX_FRAG; x++ ) + { + /* Allocate the next Ethernet buffer to this descriptor. */ + RX_DESC_PACKET(x) = ETH_BUF(x); + RX_DESC_CTRL(x) = RCTRL_INT | ( ETH_FRAG_SIZE - 1 ); + RX_STAT_INFO(x) = 0; + RX_STAT_HASHCRC(x) = 0; + } + + /* Set LPC_EMAC Receive Descriptor Registers. */ + LPC_EMAC->RxDescriptor = RX_DESC_BASE; + LPC_EMAC->RxStatus = RX_STAT_BASE; + LPC_EMAC->RxDescriptorNumber = NUM_RX_FRAG - 1; + +} + + +/** + * 受信キューの先頭にあるRXフレームのポインタを返します。 + * 関数は、受信キューのポインタを操作しません。続けて読み出したとしても、同じポインターを返します。 + * 制限として、返却したポインタの内容は、一時的に書き換え可としてください。(この制限は将来削除します。) + * @return + * 成功した場合、受信データを格納したバッファポインターです。 + * 次回nextRxEthFrameを呼び出すまで有効です。 + */ +static void* getRxEthFrame(unsigned short* o_len_of_data) +{ + if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex ) + { + //受信データを返却する。 + *o_len_of_data = (unsigned short)(( RX_STAT_INFO( LPC_EMAC->RxConsumeIndex ) & RINFO_SIZE ) - 3); + return ( unsigned char * ) RX_DESC_PACKET( LPC_EMAC->RxConsumeIndex ); + } + return NULL; +} + + +/** + * 受信キューを進行します。 + */ +static void nextRxEthFrame(void) +{ + long lIndex; + if( LPC_EMAC->RxProduceIndex != LPC_EMAC->RxConsumeIndex ) + { + //キューすすめる。 + lIndex = LPC_EMAC->RxConsumeIndex; + lIndex++; + if( lIndex >= NUM_RX_FRAG ) + { + lIndex = 0; + } + LPC_EMAC->RxConsumeIndex = lIndex; + } +} +/******************************************************************************** + * Private functions + *******************************************************************************/ + + + +/** + * 送信中のイーサフレームを処理する機会を与えて、送信キューが空くまで待ちます。 + * LPC1769の場合は、非同期に更新したディスクリプタの内容から、送信メモリのフラグを更新します。 + * @return + * 次に書き込むことが出来る送信キュー。 + */ +static NyLPC_TUInt32 waitForTxEthFrameEmpty(void) +{ + NyLPC_TUInt32 IndexNext; + struct NyLPC_TTxBufferHeader *b; + void* p; + NyLPC_TUInt32 i; + + //送信キューの決定 + IndexNext = (LPC_EMAC->TxProduceIndex + 1)%NUM_TX_FRAG; + + //送信キューフルが解除されるまで待ち + while(IndexNext == LPC_EMAC->TxConsumeIndex) + { + // + NyLPC_cThread_sleep(emacSHORT_DELAY_MS); + } + + //(TxProduceIndex+1)→TxConsumeIndexにあるデータのsentフラグを消去 + for(i=IndexNext;i!=LPC_EMAC->TxConsumeIndex;i=(i+1)%NUM_TX_FRAG) + { + p=(void*)TX_DESC_PACKET(i); + if(p!=NULL){ + b=((struct NyLPC_TTxBufferHeader*)p)-1; + b->is_lock=NyLPC_TUInt8_FALSE; + TX_DESC_PACKET(i)=0; + } + } + p=(void*)TX_DESC_PACKET(i); + if(p!=NULL){ + b=((struct NyLPC_TTxBufferHeader*)p)-1; + b->is_lock=NyLPC_TUInt8_FALSE; + TX_DESC_PACKET(i)=0; + } + return IndexNext; +} + +//-------------------------------------------------------------------------------- +// ISR +//-------------------------------------------------------------------------------- + +static void ethernet_set_link(int speed, int duplex) { + unsigned short phy_data; + int tout; + + if((speed < 0) || (speed > 1)) { + phy_data = PHY_AUTO_NEG; + } else { + phy_data = (((unsigned short) speed << 13) | + ((unsigned short) duplex << 8)); + } + + phy_write(PHY_REG_BMCR, phy_data); + + for (tout = 100; tout; tout--) { __NOP(); } /* A short delay */ + + switch(phy_id) { + case DP83848C_ID: + phy_data = phy_read(PHY_REG_STS); + + if(phy_data & PHY_STS_DUPLEX) { + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } else { + LPC_EMAC->MAC2 &= ~MAC2_FULL_DUP; + LPC_EMAC->Command &= ~CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + if(phy_data & PHY_STS_SPEED) { + LPC_EMAC->SUPP &= ~SUPP_SPEED; + } else { + LPC_EMAC->SUPP |= SUPP_SPEED; + } + break; + + case LAN8720_ID: + phy_data = phy_read(PHY_REG_SCSR); + + if (phy_data & PHY_SCSR_DUPLEX) { + LPC_EMAC->MAC2 |= MAC2_FULL_DUP; + LPC_EMAC->Command |= CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_FULL_DUP; + } else { + LPC_EMAC->Command &= ~CR_FULL_DUP; + LPC_EMAC->IPGT = IPGT_HALF_DUP; + } + + if(phy_data & PHY_SCSR_100MBIT) { + LPC_EMAC->SUPP |= SUPP_SPEED; + } else { + LPC_EMAC->SUPP &= ~SUPP_SPEED; + } + + break; + } +} + +static int phy_write(unsigned int PhyReg, unsigned short Data) { + unsigned int timeOut; + + LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; + LPC_EMAC->MWTD = Data; + + for(timeOut = 0; timeOut < MII_WR_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_EMAC->MIND & MIND_BUSY) == 0) { + return 0; + } + } + + return -1; +} + + +static int phy_read(unsigned int PhyReg) { + unsigned int timeOut; + + LPC_EMAC->MADR = DP83848C_DEF_ADR | PhyReg; + LPC_EMAC->MCMD = MCMD_READ; + + for(timeOut = 0; timeOut < MII_RD_TOUT; timeOut++) { /* Wait until operation completed */ + if((LPC_EMAC->MIND & MIND_BUSY) == 0) { + LPC_EMAC->MCMD = 0; + return LPC_EMAC->MRDD; /* Return a 16-bit value. */ + } + } + + return -1; +} + + +//extern unsigned int SystemFrequency; +static unsigned int clockselect(void) +{ + if(SystemCoreClock < 10000000) { + return 1; + } else if(SystemCoreClock < 15000000) { + return 2; + } else if(SystemCoreClock < 20000000) { + return 3; + } else if(SystemCoreClock < 25000000) { + return 4; + } else if(SystemCoreClock < 35000000) { + return 5; + } else if(SystemCoreClock < 50000000) { + return 6; + } else if(SystemCoreClock < 70000000) { + return 7; + } else if(SystemCoreClock < 80000000) { + return 8; + } else if(SystemCoreClock < 90000000) { + return 9; + } else if(SystemCoreClock < 100000000) { + return 10; + } else if(SystemCoreClock < 120000000) { + return 11; + } else if(SystemCoreClock < 130000000) { + return 12; + } else if(SystemCoreClock < 140000000) { + return 13; + } else if(SystemCoreClock < 150000000) { + return 15; + } else if(SystemCoreClock < 160000000) { + return 16; + } else { + return 0; + } +} + +static int ethernet_link(void) +{ + + if (phy_id == DP83848C_ID) { + return (phy_read(PHY_REG_STS) & PHY_STS_LINK); + } + else { // LAN8720_ID + return (phy_read(PHY_REG_BMSR) & PHY_BMSR_LINK); + } +} +//-------------------------------------------------------------------------------- +// ISR +//-------------------------------------------------------------------------------- + + +/** + * EMACからのハンドラ + */ +static void emacIsrHandler(unsigned long i_status) +{ + if( i_status & INT_RX_DONE ) + { + _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_RX); + } + if( i_status & INT_TX_DONE ) + { + _event_handler(_event_param,NyLPC_TiEthernetDevice_EVENT_ON_TX); + } +} + +#endif + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/driver/ethernet/lpc4088/EtherDev_LPC4088_protected.h Thu May 29 14:29:15 2014 +0000 @@ -0,0 +1,23 @@ +/* + * This is part of EthDev_LPC17xx.h + */ + +#ifndef EtherDev_LPC4088_protected_h +#define EtherDev_LPC4088_protected_h +#include "NyLPC_stdlib.h" +#include "../NyLPC_IEthernetDevice.h" +#include "EthDev_LPC17xx.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +NyLPC_TBool EthDev_LPC4088_getInterface( + const struct TiEthernetDevice** o_dev); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/driver/ethernet/lpc4088/copy_of_ethernet_api.h Thu May 29 14:29:15 2014 +0000 @@ -0,0 +1,310 @@ +//Copy from mbed HAL +//https://github.com/mbedmicro/mbed/blob/master/libraries/mbed/targets/hal/TARGET_NXP/TARGET_LPC408X/ethernet_api.c + +#include <string.h> + +#include "ethernet_api.h" +#include "cmsis.h" +#include "mbed_interface.h" +#include "toolchain.h" +#include "error.h" + +#define NUM_RX_FRAG 3 /* Num.of RX Fragments. */ +#define NUM_TX_FRAG 16 /* Num.of TX Fragments. */ +#define ETH_FRAG_SIZE 1536 /* Packet Fragment size 1536 Bytes */ + +#define ETH_MAX_FLEN 1536 /* Max. Ethernet Frame Size */ + +#define ETHERNET_ADDR_SIZE 6 + +PACKED struct RX_DESC_TypeDef { /* RX Descriptor struct */ + unsigned int Packet; + unsigned int Ctrl; +}; +typedef struct RX_DESC_TypeDef RX_DESC_TypeDef; + +PACKED struct RX_STAT_TypeDef { /* RX Status struct */ + unsigned int Info; + unsigned int HashCRC; +}; +typedef struct RX_STAT_TypeDef RX_STAT_TypeDef; + +PACKED struct TX_DESC_TypeDef { /* TX Descriptor struct */ + unsigned int Packet; + unsigned int Ctrl; +}; +typedef struct TX_DESC_TypeDef TX_DESC_TypeDef; + +PACKED struct TX_STAT_TypeDef { /* TX Status struct */ + unsigned int Info; +}; +typedef struct TX_STAT_TypeDef TX_STAT_TypeDef; + +/* MAC Configuration Register 1 */ +#define MAC1_REC_EN 0x00000001 /* Receive Enable */ +#define MAC1_PASS_ALL 0x00000002 /* Pass All Receive Frames */ +#define MAC1_RX_FLOWC 0x00000004 /* RX Flow Control */ +#define MAC1_TX_FLOWC 0x00000008 /* TX Flow Control */ +#define MAC1_LOOPB 0x00000010 /* Loop Back Mode */ +#define MAC1_RES_TX 0x00000100 /* Reset TX Logic */ +#define MAC1_RES_MCS_TX 0x00000200 /* Reset MAC TX Control Sublayer */ +#define MAC1_RES_RX 0x00000400 /* Reset RX Logic */ +#define MAC1_RES_MCS_RX 0x00000800 /* Reset MAC RX Control Sublayer */ +#define MAC1_SIM_RES 0x00004000 /* Simulation Reset */ +#define MAC1_SOFT_RES 0x00008000 /* Soft Reset MAC */ + +/* MAC Configuration Register 2 */ +#define MAC2_FULL_DUP 0x00000001 /* Full Duplex Mode */ +#define MAC2_FRM_LEN_CHK 0x00000002 /* Frame Length Checking */ +#define MAC2_HUGE_FRM_EN 0x00000004 /* Huge Frame Enable */ +#define MAC2_DLY_CRC 0x00000008 /* Delayed CRC Mode */ +#define MAC2_CRC_EN 0x00000010 /* Append CRC to every Frame */ +#define MAC2_PAD_EN 0x00000020 /* Pad all Short Frames */ +#define MAC2_VLAN_PAD_EN 0x00000040 /* VLAN Pad Enable */ +#define MAC2_ADET_PAD_EN 0x00000080 /* Auto Detect Pad Enable */ +#define MAC2_PPREAM_ENF 0x00000100 /* Pure Preamble Enforcement */ +#define MAC2_LPREAM_ENF 0x00000200 /* Long Preamble Enforcement */ +#define MAC2_NO_BACKOFF 0x00001000 /* No Backoff Algorithm */ +#define MAC2_BACK_PRESSURE 0x00002000 /* Backoff Presurre / No Backoff */ +#define MAC2_EXCESS_DEF 0x00004000 /* Excess Defer */ + +/* Back-to-Back Inter-Packet-Gap Register */ +#define IPGT_FULL_DUP 0x00000015 /* Recommended value for Full Duplex */ +#define IPGT_HALF_DUP 0x00000012 /* Recommended value for Half Duplex */ + +/* Non Back-to-Back Inter-Packet-Gap Register */ +#define IPGR_DEF 0x00000012 /* Recommended value */ + +/* Collision Window/Retry Register */ +#define CLRT_DEF 0x0000370F /* Default value */ + +/* PHY Support Register */ +#define SUPP_SPEED 0x00000100 /* Reduced MII Logic Current Speed */ +//#define SUPP_RES_RMII 0x00000800 /* Reset Reduced MII Logic */ +#define SUPP_RES_RMII 0x00000000 /* Reset Reduced MII Logic */ + +/* Test Register */ +#define TEST_SHCUT_PQUANTA 0x00000001 /* Shortcut Pause Quanta */ +#define TEST_TST_PAUSE 0x00000002 /* Test Pause */ +#define TEST_TST_BACKP 0x00000004 /* Test Back Pressure */ + +/* MII Management Configuration Register */ +#define MCFG_SCAN_INC 0x00000001 /* Scan Increment PHY Address */ +#define MCFG_SUPP_PREAM 0x00000002 /* Suppress Preamble */ +#define MCFG_CLK_SEL 0x0000003C /* Clock Select Mask */ +#define MCFG_RES_MII 0x00008000 /* Reset MII Management Hardware */ + +/* MII Management Command Register */ +#define MCMD_READ 0x00000001 /* MII Read */ +#define MCMD_SCAN 0x00000002 /* MII Scan continuously */ + +#define MII_WR_TOUT 0x00050000 /* MII Write timeout count */ +#define MII_RD_TOUT 0x00050000 /* MII Read timeout count */ + +/* MII Management Address Register */ +#define MADR_REG_ADR 0x0000001F /* MII Register Address Mask */ +#define MADR_PHY_ADR 0x00001F00 /* PHY Address Mask */ + +/* MII Management Indicators Register */ +#define MIND_BUSY 0x00000001 /* MII is Busy */ +#define MIND_SCAN 0x00000002 /* MII Scanning in Progress */ +#define MIND_NOT_VAL 0x00000004 /* MII Read Data not valid */ +#define MIND_MII_LINK_FAIL 0x00000008 /* MII Link Failed */ + +/* Command Register */ +#define CR_RX_EN 0x00000001 /* Enable Receive */ +#define CR_TX_EN 0x00000002 /* Enable Transmit */ +#define CR_REG_RES 0x00000008 /* Reset Host Registers */ +#define CR_TX_RES 0x00000010 /* Reset Transmit Datapath */ +#define CR_RX_RES 0x00000020 /* Reset Receive Datapath */ +#define CR_PASS_RUNT_FRM 0x00000040 /* Pass Runt Frames */ +#define CR_PASS_RX_FILT 0x00000080 /* Pass RX Filter */ +#define CR_TX_FLOW_CTRL 0x00000100 /* TX Flow Control */ +#define CR_RMII 0x00000200 /* Reduced MII Interface */ +#define CR_FULL_DUP 0x00000400 /* Full Duplex */ + +/* Status Register */ +#define SR_RX_EN 0x00000001 /* Enable Receive */ +#define SR_TX_EN 0x00000002 /* Enable Transmit */ + +/* Transmit Status Vector 0 Register */ +#define TSV0_CRC_ERR 0x00000001 /* CRC error */ +#define TSV0_LEN_CHKERR 0x00000002 /* Length Check Error */ +#define TSV0_LEN_OUTRNG 0x00000004 /* Length Out of Range */ +#define TSV0_DONE 0x00000008 /* Tramsmission Completed */ +#define TSV0_MCAST 0x00000010 /* Multicast Destination */ +#define TSV0_BCAST 0x00000020 /* Broadcast Destination */ +#define TSV0_PKT_DEFER 0x00000040 /* Packet Deferred */ +#define TSV0_EXC_DEFER 0x00000080 /* Excessive Packet Deferral */ +#define TSV0_EXC_COLL 0x00000100 /* Excessive Collision */ +#define TSV0_LATE_COLL 0x00000200 /* Late Collision Occured */ +#define TSV0_GIANT 0x00000400 /* Giant Frame */ +#define TSV0_UNDERRUN 0x00000800 /* Buffer Underrun */ +#define TSV0_BYTES 0x0FFFF000 /* Total Bytes Transferred */ +#define TSV0_CTRL_FRAME 0x10000000 /* Control Frame */ +#define TSV0_PAUSE 0x20000000 /* Pause Frame */ +#define TSV0_BACK_PRESS 0x40000000 /* Backpressure Method Applied */ +#define TSV0_VLAN 0x80000000 /* VLAN Frame */ + +/* Transmit Status Vector 1 Register */ +#define TSV1_BYTE_CNT 0x0000FFFF /* Transmit Byte Count */ +#define TSV1_COLL_CNT 0x000F0000 /* Transmit Collision Count */ + +/* Receive Status Vector Register */ +#define RSV_BYTE_CNT 0x0000FFFF /* Receive Byte Count */ +#define RSV_PKT_IGNORED 0x00010000 /* Packet Previously Ignored */ +#define RSV_RXDV_SEEN 0x00020000 /* RXDV Event Previously Seen */ +#define RSV_CARR_SEEN 0x00040000 /* Carrier Event Previously Seen */ +#define RSV_REC_CODEV 0x00080000 /* Receive Code Violation */ +#define RSV_CRC_ERR 0x00100000 /* CRC Error */ +#define RSV_LEN_CHKERR 0x00200000 /* Length Check Error */ +#define RSV_LEN_OUTRNG 0x00400000 /* Length Out of Range */ +#define RSV_REC_OK 0x00800000 /* Frame Received OK */ +#define RSV_MCAST 0x01000000 /* Multicast Frame */ +#define RSV_BCAST 0x02000000 /* Broadcast Frame */ +#define RSV_DRIB_NIBB 0x04000000 /* Dribble Nibble */ +#define RSV_CTRL_FRAME 0x08000000 /* Control Frame */ +#define RSV_PAUSE 0x10000000 /* Pause Frame */ +#define RSV_UNSUPP_OPC 0x20000000 /* Unsupported Opcode */ +#define RSV_VLAN 0x40000000 /* VLAN Frame */ + +/* Flow Control Counter Register */ +#define FCC_MIRR_CNT 0x0000FFFF /* Mirror Counter */ +#define FCC_PAUSE_TIM 0xFFFF0000 /* Pause Timer */ + +/* Flow Control Status Register */ +#define FCS_MIRR_CNT 0x0000FFFF /* Mirror Counter Current */ + +/* Receive Filter Control Register */ +#define RFC_UCAST_EN 0x00000001 /* Accept Unicast Frames Enable */ +#define RFC_BCAST_EN 0x00000002 /* Accept Broadcast Frames Enable */ +#define RFC_MCAST_EN 0x00000004 /* Accept Multicast Frames Enable */ +#define RFC_UCAST_HASH_EN 0x00000008 /* Accept Unicast Hash Filter Frames */ +#define RFC_MCAST_HASH_EN 0x00000010 /* Accept Multicast Hash Filter Fram.*/ +#define RFC_PERFECT_EN 0x00000020 /* Accept Perfect Match Enable */ +#define RFC_MAGP_WOL_EN 0x00001000 /* Magic Packet Filter WoL Enable */ +#define RFC_PFILT_WOL_EN 0x00002000 /* Perfect Filter WoL Enable */ + +/* Receive Filter WoL Status/Clear Registers */ +#define WOL_UCAST 0x00000001 /* Unicast Frame caused WoL */ +#define WOL_BCAST 0x00000002 /* Broadcast Frame caused WoL */ +#define WOL_MCAST 0x00000004 /* Multicast Frame caused WoL */ +#define WOL_UCAST_HASH 0x00000008 /* Unicast Hash Filter Frame WoL */ +#define WOL_MCAST_HASH 0x00000010 /* Multicast Hash Filter Frame WoL */ +#define WOL_PERFECT 0x00000020 /* Perfect Filter WoL */ +#define WOL_RX_FILTER 0x00000080 /* RX Filter caused WoL */ +#define WOL_MAG_PACKET 0x00000100 /* Magic Packet Filter caused WoL */ + +/* Interrupt Status/Enable/Clear/Set Registers */ +#define INT_RX_OVERRUN 0x00000001 /* Overrun Error in RX Queue */ +#define INT_RX_ERR 0x00000002 /* Receive Error */ +#define INT_RX_FIN 0x00000004 /* RX Finished Process Descriptors */ +#define INT_RX_DONE 0x00000008 /* Receive Done */ +#define INT_TX_UNDERRUN 0x00000010 /* Transmit Underrun */ +#define INT_TX_ERR 0x00000020 /* Transmit Error */ +#define INT_TX_FIN 0x00000040 /* TX Finished Process Descriptors */ +#define INT_TX_DONE 0x00000080 /* Transmit Done */ +#define INT_SOFT_INT 0x00001000 /* Software Triggered Interrupt */ +#define INT_WAKEUP 0x00002000 /* Wakeup Event Interrupt */ + +/* Power Down Register */ +#define PD_POWER_DOWN 0x80000000 /* Power Down MAC */ + +/* RX Descriptor Control Word */ +#define RCTRL_SIZE 0x000007FF /* Buffer size mask */ +#define RCTRL_INT 0x80000000 /* Generate RxDone Interrupt */ + +/* RX Status Hash CRC Word */ +#define RHASH_SA 0x000001FF /* Hash CRC for Source Address */ +#define RHASH_DA 0x001FF000 /* Hash CRC for Destination Address */ + +/* RX Status Information Word */ +#define RINFO_SIZE 0x000007FF /* Data size in bytes */ +#define RINFO_CTRL_FRAME 0x00040000 /* Control Frame */ +#define RINFO_VLAN 0x00080000 /* VLAN Frame */ +#define RINFO_FAIL_FILT 0x00100000 /* RX Filter Failed */ +#define RINFO_MCAST 0x00200000 /* Multicast Frame */ +#define RINFO_BCAST 0x00400000 /* Broadcast Frame */ +#define RINFO_CRC_ERR 0x00800000 /* CRC Error in Frame */ +#define RINFO_SYM_ERR 0x01000000 /* Symbol Error from PHY */ +#define RINFO_LEN_ERR 0x02000000 /* Length Error */ +#define RINFO_RANGE_ERR 0x04000000 /* Range Error (exceeded max. size) */ +#define RINFO_ALIGN_ERR 0x08000000 /* Alignment Error */ +#define RINFO_OVERRUN 0x10000000 /* Receive overrun */ +#define RINFO_NO_DESCR 0x20000000 /* No new Descriptor available */ +#define RINFO_LAST_FLAG 0x40000000 /* Last Fragment in Frame */ +#define RINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +//#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_CRC_ERR | RINFO_SYM_ERR | RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) +#define RINFO_ERR_MASK (RINFO_FAIL_FILT | RINFO_SYM_ERR | RINFO_LEN_ERR | RINFO_ALIGN_ERR | RINFO_OVERRUN) + + +/* TX Descriptor Control Word */ +#define TCTRL_SIZE 0x000007FF /* Size of data buffer in bytes */ +#define TCTRL_OVERRIDE 0x04000000 /* Override Default MAC Registers */ +#define TCTRL_HUGE 0x08000000 /* Enable Huge Frame */ +#define TCTRL_PAD 0x10000000 /* Pad short Frames to 64 bytes */ +#define TCTRL_CRC 0x20000000 /* Append a hardware CRC to Frame */ +#define TCTRL_LAST 0x40000000 /* Last Descriptor for TX Frame */ +#define TCTRL_INT 0x80000000 /* Generate TxDone Interrupt */ + +/* TX Status Information Word */ +#define TINFO_COL_CNT 0x01E00000 /* Collision Count */ +#define TINFO_DEFER 0x02000000 /* Packet Deferred (not an error) */ +#define TINFO_EXCESS_DEF 0x04000000 /* Excessive Deferral */ +#define TINFO_EXCESS_COL 0x08000000 /* Excessive Collision */ +#define TINFO_LATE_COL 0x10000000 /* Late Collision Occured */ +#define TINFO_UNDERRUN 0x20000000 /* Transmit Underrun */ +#define TINFO_NO_DESCR 0x40000000 /* No new Descriptor available */ +#define TINFO_ERR 0x80000000 /* Error Occured (OR of all errors) */ + +/* ENET Device Revision ID */ +#define OLD_EMAC_MODULE_ID 0x39022000 /* Rev. ID for first rev '-' */ + +/* DP83848C PHY Registers */ +#define PHY_REG_BMCR 0x00 /* Basic Mode Control Register */ +#define PHY_REG_BMSR 0x01 /* Basic Mode Status Register */ +#define PHY_REG_IDR1 0x02 /* PHY Identifier 1 */ +#define PHY_REG_IDR2 0x03 /* PHY Identifier 2 */ +#define PHY_REG_ANAR 0x04 /* Auto-Negotiation Advertisement */ +#define PHY_REG_ANLPAR 0x05 /* Auto-Neg. Link Partner Abitily */ +#define PHY_REG_ANER 0x06 /* Auto-Neg. Expansion Register */ +#define PHY_REG_ANNPTR 0x07 /* Auto-Neg. Next Page TX */ + +/* PHY Extended Registers */ +#define PHY_REG_STS 0x10 /* Status Register */ +#define PHY_REG_MICR 0x11 /* MII Interrupt Control Register */ +#define PHY_REG_MISR 0x12 /* MII Interrupt Status Register */ +#define PHY_REG_FCSCR 0x14 /* False Carrier Sense Counter */ +#define PHY_REG_RECR 0x15 /* Receive Error Counter */ +#define PHY_REG_PCSR 0x16 /* PCS Sublayer Config. and Status */ +#define PHY_REG_RBR 0x17 /* RMII and Bypass Register */ +#define PHY_REG_LEDCR 0x18 /* LED Direct Control Register */ +#define PHY_REG_PHYCR 0x19 /* PHY Control Register */ +#define PHY_REG_10BTSCR 0x1A /* 10Base-T Status/Control Register */ +#define PHY_REG_CDCTRL1 0x1B /* CD Test Control and BIST Extens. */ +#define PHY_REG_EDCR 0x1D /* Energy Detect Control Register */ + +#define PHY_REG_SCSR 0x1F /* PHY Special Control/Status Register */ + +#define PHY_FULLD_100M 0x2100 /* Full Duplex 100Mbit */ +#define PHY_HALFD_100M 0x2000 /* Half Duplex 100Mbit */ +#define PHY_FULLD_10M 0x0100 /* Full Duplex 10Mbit */ +#define PHY_HALFD_10M 0x0000 /* Half Duplex 10MBit */ +#define PHY_AUTO_NEG 0x3000 /* Select Auto Negotiation */ + +#define DP83848C_DEF_ADR 0x0100 /* Default PHY device address */ +#define DP83848C_ID 0x20005C90 /* PHY Identifier - DP83848C */ + +#define LAN8720_ID 0x0007C0F0 /* PHY Identifier - LAN8720 */ + +#define PHY_STS_LINK 0x0001 /* PHY Status Link Mask */ +#define PHY_STS_SPEED 0x0002 /* PHY Status Speed Mask */ +#define PHY_STS_DUPLEX 0x0004 /* PHY Status Duplex Mask */ + +#define PHY_BMCR_RESET 0x8000 /* PHY Reset */ + +#define PHY_BMSR_LINK 0x0004 /* PHY BMSR Link valid */ + +#define PHY_SCSR_100MBIT 0x0008 /* Speed: 1=100 MBit, 0=10Mbit */ +#define PHY_SCSR_DUPLEX 0x0010 /* PHY Duplex Mask */ \ No newline at end of file
--- a/core/include/NyLPC_config.h Thu May 22 12:59:50 2014 +0000 +++ b/core/include/NyLPC_config.h Thu May 29 14:29:15 2014 +0000 @@ -124,6 +124,11 @@ #undef NyLPC_ARCH #define NyLPC_ARCH NyLPC_ARCH_MBEDRTOS +#ifdef TARGET_LPC4088 +#undef NyLPC_MCU +#define NyLPC_MCU NyLPC_MCU_LPC4088 +#endif + #ifdef __cplusplus } #endif /* __cplusplus */
--- a/core/net/NyLPC_cNet.c Thu May 22 12:59:50 2014 +0000 +++ b/core/net/NyLPC_cNet.c Thu May 29 14:29:15 2014 +0000 @@ -28,10 +28,6 @@ #include "../uip/NyLPC_cUipService_protected.h" -const char* NyLPC_cNet_PlatformName; - -static const char* PNAME_LPCXPRESSO1769="LPCXpresso1769"; -static const char* PNAME_MBED="mbed"; void NyLPC_cNet_initialize(NyLPC_TcNet_t* i_inst) { @@ -44,23 +40,13 @@ void NyLPC_cNet_start(NyLPC_TcNet_t* i_inst,const NyLPC_TcNetConfig_t* i_ref_config) { NyLPC_cUipService_start(&(i_ref_config->super)); - //プラットフォーム名を推測(デバイス名の初めの1文字だけ見る。) - switch(*(NyLPC_cUipService_refDeviceName())){ - case 'L': - NyLPC_cNet_PlatformName=PNAME_LPCXPRESSO1769; - break; - case 'D': - NyLPC_cNet_PlatformName=PNAME_MBED; - break; - default: - break; - } return; } void NyLPC_cNet_stop(NyLPC_TcNet_t* i_inst) { NyLPC_cUipService_stop(); + return; } /**
--- a/core/net/NyLPC_cNet.h Thu May 22 12:59:50 2014 +0000 +++ b/core/net/NyLPC_cNet.h Thu May 29 14:29:15 2014 +0000 @@ -37,10 +37,7 @@ */ typedef struct NyLPC_TcNet NyLPC_TcNet_t; -/** - * Platformを示す文字列 - */ -extern const char* NyLPC_cNet_PlatformName; + struct NyLPC_TcNet
--- a/core/net/httpd/mod/NyLPC_cMocMiMicSetting.c Thu May 22 12:59:50 2014 +0000 +++ b/core/net/httpd/mod/NyLPC_cMocMiMicSetting.c Thu May 29 14:29:15 2014 +0000 @@ -390,10 +390,12 @@ //Flashの内容から if(!NyLPC_cHttpdConnection_sendResponseBodyF(i_connection, "{" - "\"application\":\""MOD_VERSION";"NyLPC_cMiMicEnv_VERSION";%s\"," + "\"application\":\""MOD_VERSION";%s;%s(%s)\"," "\"landev\":\"%s\",", - NyLPC_cNet_PlatformName, - NyLPC_cUipService_refDeviceName() + NyLPC_cMiMicEnv_getStrProperty(NyLPC_cMiMicEnv_VERSION), + NyLPC_cMiMicEnv_getStrProperty(NyLPC_cMiMicEnv_SHORT_NAME), + NyLPC_cMiMicEnv_getStrProperty(NyLPC_cMiMicEnv_MCU_NAME), + NyLPC_cMiMicEnv_getStrProperty(NyLPC_cMiMicEnv_ETHERNET_PHY) )) { NyLPC_OnErrorGoto(Error); @@ -493,8 +495,8 @@ } if(NyLPC_cHttpdConnection_getMethod(i_connection)==NyLPC_THttpMethodType_GET){ NyLPC_cHttpdConnection_sendResponseBodyF(i_connection, - "{\"application\":\""MOD_VERSION";%s\",\"result\":%u}", - NyLPC_cNet_PlatformName,ret?0x00000000:0x80000000); + "{\"application\":\""MOD_VERSION"\",\"result\":%u}", + ret?0x00000000:0x80000000); } } }
--- a/core/net/httpd/mod/NyLPC_cModRemoteMcu.c Thu May 22 12:59:50 2014 +0000 +++ b/core/net/httpd/mod/NyLPC_cModRemoteMcu.c Thu May 29 14:29:15 2014 +0000 @@ -491,7 +491,7 @@ } //JSONを書く。 if(NyLPC_cHttpdConnection_getMethod(i_connection)==NyLPC_THttpMethodType_GET){ - NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,"{\"application\":\""MVM_VERSION";%s\"}",NyLPC_cNet_PlatformName); + NyLPC_cHttpdConnection_sendResponseBodyF(i_connection,"{\"application\":\""MVM_VERSION"\"}"); } return; }
--- a/core/uip/NyLPC_cIPv4.c Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cIPv4.c Thu May 29 14:29:15 2014 +0000 @@ -127,7 +127,7 @@ } static NyLPC_TcUdpSocket_t* cSocketTbl_getMatchMulticastUdpSocket( NyLPC_TcPtrTbl_t* i_inst, - struct NyLPC_TIPv4Addr* i_mcast_ip, + const struct NyLPC_TIPv4Addr* i_mcast_ip, NyLPC_TUInt16 i_lport) { NyLPC_TcBaseSocket_t** p=(NyLPC_TcBaseSocket_t**)(i_inst->buf); @@ -288,9 +288,10 @@ * Static関数 */ -static NyLPC_TBool tcp_rx( +static void* tcp_rx( NyLPC_TcIPv4_t* i_inst, - NyLPC_TcIPv4Payload_t* i_ipp); + const NyLPC_TcIPv4Payload_t* i_ipp); + static NyLPC_TBool udp_rx( NyLPC_TcIPv4_t* i_inst, NyLPC_TcIPv4Payload_t* i_ipp); @@ -301,6 +302,8 @@ void NyLPC_cIPv4_initialize( NyLPC_TcIPv4_t* i_inst) { + //IP制御パケットの為に40バイト以上のシステムTXメモリが必要。 + NyLPC_ArgAssert(NyLPC_cUipService_SYS_TX_BUF_SIZE>40); //内部テーブルの初期化 cSocketTbl_initialize(&(i_inst->_socket_tbl),(void**)(i_inst->_socket_array_buf)); //instanceの初期化 @@ -398,7 +401,7 @@ * @return * TRUEなら、i_rxに応答パケットをセットして返します。 */ -NyLPC_TBool NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,void* i_rx,NyLPC_TUInt16 i_rx_size) +void* NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,const void* i_rx,NyLPC_TUInt16 i_rx_size) { NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; NyLPC_TcIPv4Payload_t ipv4; @@ -409,7 +412,7 @@ NyLPC_cIPv4Payload_initialize(&ipv4); //IPフラグメントを読出し用にセットする。 - if(!NyLPC_cIPv4Payload_setRxBuf(&ipv4,i_rx,i_rx_size)) + if(!NyLPC_cIPv4Payload_attachRxBuf(&ipv4,i_rx,i_rx_size)) { NyLPC_OnErrorGoto(ERROR_DROP); } @@ -423,14 +426,11 @@ udp_rx(i_inst,&ipv4);//r return NyLPC_TBool_FALSE; case UIP_PROTO_ICMP: - if(!NyLPC_cIPv4IComp_rx(&(inst->_icomp),&ipv4)){ - NyLPC_OnErrorGoto(ERROR_DROP); - } - return NyLPC_TBool_TRUE; + return NyLPC_cIPv4IComp_rx(&(inst->_icomp),&ipv4); } - return NyLPC_TBool_FALSE; + return NULL; ERROR_DROP: - return NyLPC_TBool_FALSE; + return NULL; } NyLPC_TUInt16 NyLPC_cIPv4_getNewPortNumber(NyLPC_TcIPv4_t* i_inst) @@ -455,9 +455,9 @@ **********************************************************************/ -static NyLPC_TBool tcp_rx( +static void* tcp_rx( NyLPC_TcIPv4_t* i_inst, - NyLPC_TcIPv4Payload_t* i_ipp) + const NyLPC_TcIPv4Payload_t* i_ipp) { NyLPC_TcTcpSocket_t* sock; NyLPC_TcTcpListener_t* listener; @@ -480,28 +480,24 @@ { //既存の接続を処理 return NyLPC_cTcpSocket_parseRx(sock,i_ipp); + } - }else{ - //未知の接続 - if(!NyLPC_cPtrTbl_hasEmpty(&(i_inst->_socket_tbl))){ - //ソケットテーブルが不十分。RST送信 - NyLPC_cIPv4Payload_setTcpReverseRstAck(i_ipp); - return NyLPC_TBool_TRUE; - } - //このポートに対応したListenerを得る。 - listener=cSocketTbl_getListenerByPeerPort(&(i_inst->_socket_tbl),i_ipp->payload.tcp->destport); - if(listener==NULL){ - //Listen対象ではない。RST送信 - NyLPC_cIPv4Payload_setTcpReverseRstAck(i_ipp); - return NyLPC_TBool_TRUE; - } - //リスナにソケットのバインドを依頼する。 - NyLPC_cTcpListener_synPacket(listener,i_ipp); - return NyLPC_TBool_FALSE;//LISTEN成功。送信データなし + //未知の接続 + if(!NyLPC_cPtrTbl_hasEmpty(&(i_inst->_socket_tbl))){ + //ソケットテーブルが不十分。RST送信 + return NyLPC_cTcpSocket_allocTcpReverseRstAck(i_ipp); } - return NyLPC_TBool_TRUE; + //このポートに対応したListenerを得る。 + listener=cSocketTbl_getListenerByPeerPort(&(i_inst->_socket_tbl),i_ipp->payload.tcp->destport); + if(listener==NULL){ + //Listen対象ではない。RST送信 + return NyLPC_cTcpSocket_allocTcpReverseRstAck(i_ipp); + } + //リスナにソケットのバインドを依頼する。 + NyLPC_cTcpListener_synPacket(listener,i_ipp); + return NULL;//LISTEN成功。送信データなし DROP: - return NyLPC_TBool_FALSE; + return NULL; }
--- a/core/uip/NyLPC_cIPv4.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cIPv4.h Thu May 29 14:29:15 2014 +0000 @@ -195,9 +195,9 @@ * @param i_rx_size * i_rxに格納したデータのサイズです。 * @return - * i_rxに応答パケットを格納したかどうかを返します + * 応答パケットを格納したメモリです。 */ -NyLPC_TBool NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,void* i_rx,NyLPC_TUInt16 i_rx_size); +void* NyLPC_cIPv4_rx(NyLPC_TcIPv4_t* i_inst,const void* i_rx,NyLPC_TUInt16 i_rx_size); /** * この関数は、定期的にインスタンスへ実行機会を与える関数です。 * TCPの再送、無通信タイムアウトなどを処理します。
--- a/core/uip/NyLPC_cIPv4Arp.c Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cIPv4Arp.c Thu May 29 14:29:15 2014 +0000 @@ -54,6 +54,7 @@ */ #include "NyLPC_cIPv4Arp.h" #include "NyLPC_uip.h" +#include "NyLPC_cUipService_protected.h" #include <string.h> @@ -162,13 +163,24 @@ * global variable uip_len. */ + +/** + * ARPパケットの読出し用構造体 + */ +struct TArpPacketPtr +{ + struct NyLPC_TEthernetIIHeader header; + struct NyLPC_TArpHeader arp; +}PACK_STRUCT_END; + /** * arpパケットを処理します。 */ -NyLPC_TBool NyLPC_cIPv4Arp_incomingArp(NyLPC_TcIPv4Arp_t* i_inst,struct NyLPC_TArpHeader* i_arp, NyLPC_TUInt16 i_len) +void* NyLPC_cIPv4Arp_rx(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TArpHeader* i_arp, NyLPC_TUInt16 i_len, NyLPC_TUInt16* o_tx_len) { + struct NyLPC_TArpHeader* arp_tx; if (i_len < sizeof(struct NyLPC_TArpHeader)) { - return 0; + return NULL; } const NyLPC_TcIPv4Config_t* cfg=i_inst->_cfg; switch (i_arp->opcode) { @@ -179,17 +191,30 @@ table, since it is likely that we will do more communication with this host in the future. */ uip_arp_update(i_inst,&(i_arp->sipaddr), &i_arp->shwaddr); + //イーサネットヘッダもいじくるから + arp_tx=(struct NyLPC_TArpHeader*)NyLPC_cUipService_allocSysTxBuf(); /* The reply opcode is 2. */ - i_arp->opcode = NyLPC_HTONS(2); - - memcpy(i_arp->dhwaddr.addr, i_arp->shwaddr.addr, 6); - memcpy(i_arp->shwaddr.addr, cfg->eth_mac.addr, 6); + arp_tx->hwtype =i_arp->hwtype; + arp_tx->protocol =i_arp->protocol; + arp_tx->hwlen =i_arp->hwlen; + arp_tx->protolen =i_arp->protolen; + arp_tx->opcode = NyLPC_HTONS(2); + memcpy(arp_tx->dhwaddr.addr, i_arp->shwaddr.addr, 6); + memcpy(arp_tx->shwaddr.addr, cfg->eth_mac.addr, 6); + arp_tx->dipaddr = i_arp->sipaddr; + arp_tx->sipaddr = cfg->ip_addr; + *o_tx_len=NyLPC_TEthernetIIHeader_setArpTx((((struct NyLPC_TEthernetIIHeader*)arp_tx)-1),&(i_inst->_cfg->eth_mac)); - i_arp->dipaddr = i_arp->sipaddr; - i_arp->sipaddr = cfg->ip_addr; - - return NyLPC_TBool_TRUE; +// /* The reply opcode is 2. */ +// i_arp->opcode = NyLPC_HTONS(2); +// +// memcpy(i_arp->dhwaddr.addr, i_arp->shwaddr.addr, 6); +// memcpy(i_arp->shwaddr.addr, cfg->eth_mac.addr, 6); +// +// i_arp->dipaddr = i_arp->sipaddr; +// i_arp->sipaddr = cfg->ip_addr; + return arp_tx; } break; case NyLPC_HTONS(ARP_REPLY): @@ -197,9 +222,9 @@ if (NyLPC_TIPv4Addr_isEqual(&(i_arp->dipaddr),&(cfg->ip_addr))) { uip_arp_update(i_inst,&(i_arp->sipaddr), &i_arp->shwaddr); } - return NyLPC_TBool_TRUE; + break; } - return NyLPC_TBool_FALSE; + return NULL; } /** * Prepend Ethernet header to an outbound IP packet and see if we need
--- a/core/uip/NyLPC_cIPv4Arp.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cIPv4Arp.h Thu May 29 14:29:15 2014 +0000 @@ -95,7 +95,14 @@ #define NyLPC_cIPv4Arp_finalize(i_inst) void NyLPC_cIPv4Arp_periodic(NyLPC_TcIPv4Arp_t* i_inst); void NyLPC_cIPv4Arp_incomingIp(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TEthernetIIHeader* i_eth,struct NyLPC_TIPv4Addr i_ip_src); -NyLPC_TBool NyLPC_cIPv4Arp_incomingArp(NyLPC_TcIPv4Arp_t* i_inst,struct NyLPC_TArpHeader* i_arp, NyLPC_TUInt16 i_len); +/** + * ARPメッセージを処理します。 + * @param o_tx_len + * 戻り値がある場合そのサイズ + * @return + * 応答パケットを格納したcUipService_allocBufで確保したメモリ + */ +void* NyLPC_cIPv4Arp_rx(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TArpHeader* i_arp, NyLPC_TUInt16 i_len, NyLPC_TUInt16* o_tx_len); const struct NyLPC_TEthAddr* NyLPC_cIPv4Arp_IPv4toEthAddr(NyLPC_TcIPv4Arp_t* i_inst,const struct NyLPC_TIPv4Addr i_ip_addr);
--- a/core/uip/NyLPC_cIPv4IComp.c Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cIPv4IComp.c Thu May 29 14:29:15 2014 +0000 @@ -54,7 +54,6 @@ */ #include "NyLPC_cIPv4IComp_protected.h" #include "NyLPC_cUipService_protected.h" - #define ICMP_ECHO_REPLY 0 #define ICMP_ECHO 8 @@ -72,12 +71,18 @@ { return; } - +/** + * ヘッダブロックの後ろにあるIPペイロードのアドレスを返します。 + */ +#define NyLPC_TIPv4Header_getHeaderSize(i) (((i)->vhl & 0x0f)*4) -NyLPC_TBool NyLPC_cIPv4IComp_rx( - NyLPC_TcIPv4IComp_t* i_inst, - NyLPC_TcIPv4Payload_t* i_ipp) +void* NyLPC_cIPv4IComp_rx( + const NyLPC_TcIPv4IComp_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_ipp) { + NyLPC_TUInt16 tx_size; + struct NyLPC_TIPv4Header* tx; + struct NyLPC_TIcmpHeader* payload; const struct NyLPC_TIPv4Addr* my_ip=&(i_inst->_ref_config->ip_addr); if (NyLPC_TIPv4Addr_isEqual(&(i_inst->_ref_config->ip_addr),&NyLPC_TIPv4Addr_ZERO)) @@ -97,10 +102,36 @@ { return NyLPC_TBool_FALSE; } - //返送サイズの制限 - if(NyLPC_NTOHS(i_ipp->header->len16)>NyLPC_TcUipService_SIZE_OF_REPLY_BUF-sizeof(struct NyLPC_TEthernetIIHeader)){ + //返送パケットの取得 + tx=(struct NyLPC_TIPv4Header*)NyLPC_cUipService_allocTxBuf(NyLPC_NTOHS(i_ipp->header->len16),&tx_size); + if(tx==NULL){ + return NyLPC_TBool_FALSE; + } + //パケットサイズのチェック + if(tx_size<NyLPC_NTOHS(i_ipp->header->len16)){ + NyLPC_cUipService_releaseTxBuf(tx); return NyLPC_TBool_FALSE; } + //返送パケットの構築 + ; + + //複製 + memcpy(tx,i_ipp->header,NyLPC_NTOHS(i_ipp->header->len16)); + + //ペイロードの編集 + payload=(struct NyLPC_TIcmpHeader*)(((NyLPC_TUInt8*)tx)+NyLPC_TIPv4Header_getHeaderSize(tx)); + payload->type = ICMP_ECHO_REPLY; + //update checksum + if (payload->icmpchksum >= NyLPC_HTONS(0xffff - (ICMP_ECHO << 8))) { + payload->icmpchksum += NyLPC_HTONS(ICMP_ECHO << 8) + 1; + } else { + payload->icmpchksum += NyLPC_HTONS(ICMP_ECHO << 8); + } + //IPヘッダの編集 + tx->destipaddr=tx->srcipaddr; + tx->srcipaddr=*my_ip; +/* + //チェックサムの再計算 i_ipp->payload.icmp->type = ICMP_ECHO_REPLY; if (i_ipp->payload.icmp->icmpchksum >= NyLPC_HTONS(0xffff - (ICMP_ECHO << 8))) { @@ -111,5 +142,7 @@ //OUT/INアドレスの反転 i_ipp->header->destipaddr=i_ipp->header->srcipaddr; i_ipp->header->srcipaddr=*my_ip; - return NyLPC_TBool_TRUE; +*/ + return tx; + }
--- a/core/uip/NyLPC_cIPv4IComp_protected.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cIPv4IComp_protected.h Thu May 29 14:29:15 2014 +0000 @@ -73,11 +73,12 @@ /** * この関数は、ICOMP IPv4パケットを処理します。 * @return - * TRUEなら、ペイロードに返送すべきTXパケットを出力します。 + * イーサネットパケットを格納したメモリを返します。 + * このメモリはNyLPC_cUipService_allocTxBufで取得されたメモリです。 */ -NyLPC_TBool NyLPC_cIPv4IComp_rx( - NyLPC_TcIPv4IComp_t* i_inst, - NyLPC_TcIPv4Payload_t* i_ipp); +void* NyLPC_cIPv4IComp_rx( + const NyLPC_TcIPv4IComp_t* i_inst, + const NyLPC_TcIPv4Payload_t* i_ipp); #ifdef __cplusplus }
--- a/core/uip/NyLPC_cIPv4Payload.c Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cIPv4Payload.c Thu May 29 14:29:15 2014 +0000 @@ -58,64 +58,6 @@ -static NyLPC_TUInt16 ipv4id=39; - - - - -static void writeTxIpHeader( - struct NyLPC_TIPv4Header* i_struct, - NyLPC_TUInt8 i_proto); - - - -/** - * IPヘッダを送信パケット用に設定する。 - * ipcecksumには0を設定する。 - * この関数は、パケットサイズ,ローカルIP/リモートIPの設定はしない。 - */ -static void writeTxIpHeader( - struct NyLPC_TIPv4Header* i_struct, - NyLPC_TUInt8 i_proto) -{ - //IPパケットのセット - i_struct->proto=i_proto; - i_struct->ttl = UIP_DEFAULT_IP_TTL; - ++ipv4id;//パケットidのインクリメント - i_struct->tos = 0; - i_struct->ipoffset=NyLPC_htons(0); - i_struct->ipid16= NyLPC_htons(ipv4id); - i_struct->ipchksum = 0; -} -/** - * TCPヘッダに値をセットする。checksum,wndは0初期化する。 - */ -static void setTcpTxHeader(struct NyLPC_TTcpHeader* i_struct,NyLPC_TUInt8 i_flag,const struct uip_conn* i_conn) -{ - i_struct->flags = i_flag; - //sorce & destination port - i_struct->srcport = i_conn->lport; - i_struct->destport = i_conn->rport; - //ACK number - i_struct->ackno32 = NyLPC_htonl(i_conn->rcv_nxt32); - //Seq Number - i_struct->seqno32 = NyLPC_htonl(i_conn->snd_nxt32); - //uip_func_tcp_send_noconn(BUF); - i_struct->urgp[0] = i_struct->urgp[1] = 0; - i_struct->tcpchksum= 0; -} -/** - * UDPヘッダに値をセットする。checksumは0初期化する。 - */ -static void setUdpTxHeader(struct NyLPC_TUdpHeader* i_struct,const struct uip_udp_conn* i_conn,NyLPC_TUInt16 i_dest_port) -{ - //sorce & destination port - i_struct->srcport = i_conn->lport; - i_struct->destport = i_dest_port; - //uip_func_tcp_send_noconn(BUF); - i_struct->udpchksum= 0; -} - /********************************************************************************* * public 関数 @@ -133,10 +75,10 @@ * IPパケットを格納したバッファをセットして、ペイロードのポインタを返します。 * 失敗時はFALSE */ -NyLPC_TBool NyLPC_cIPv4Payload_setRxBuf(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf,NyLPC_TUInt16 i_flagment_size) +NyLPC_TBool NyLPC_cIPv4Payload_attachRxBuf(NyLPC_TcIPv4Payload_t* i_inst,const void* i_buf,NyLPC_TUInt16 i_flagment_size) { - i_inst->header=(struct NyLPC_TIPv4Header*)i_buf; - i_inst->payload.rawbuf=(NyLPC_TUInt8*)i_buf+(i_inst->header->vhl & 0x0f)*4; + i_inst->header=(const struct NyLPC_TIPv4Header*)i_buf; + i_inst->payload.rawbuf=(const NyLPC_TUInt8*)i_buf+(i_inst->header->vhl & 0x0f)*4; //IPパケットのバージョンチェック if((i_inst->header->vhl & 0xf0)!=0x40){ NyLPC_OnErrorGoto(Error); @@ -174,102 +116,14 @@ } */ -/** - * セット済みのバッファを、TCPの送信ペイロードへ初期化します。 - */ -void* NyLPC_cIPv4Payload_initTcpTx(NyLPC_TcIPv4Payload_t* i_inst,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt8 i_tcph_word,NyLPC_TUInt16 i_tcp_payload_size) -{ - i_inst->header->vhl=0x40|(0x0f&i_iph_word); - i_inst->payload.rawbuf=((NyLPC_TUInt8*)(i_inst->header))+i_iph_word*4; - i_inst->payload.tcp->tcpoffset=(i_tcph_word<<4); - i_inst->header->len16=NyLPC_htons(i_tcp_payload_size+((i_iph_word+i_tcph_word)*4)); - return i_inst->payload.rawbuf+(i_tcph_word*4); -} -/** - * コネクション情報から、TCPのコントロールヘッダをセットします。 - */ -void NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(NyLPC_TcIPv4Payload_t* i_inst,const struct uip_conn* i_conn,NyLPC_TUInt8 i_flag) +const void* NyLPC_cIPv4Payload_detachBuf(NyLPC_TcIPv4Payload_t* i_inst) { - //IPv4のTxヘッダを書き込む。 - i_inst->header->destipaddr=i_conn->ripaddr; - i_inst->header->srcipaddr =*(i_conn->lipaddr); - writeTxIpHeader(i_inst->header,UIP_PROTO_TCP); - //TCPのTxヘッダを書き込む - setTcpTxHeader(i_inst->payload.tcp,i_flag,i_conn); - return; -} - -/** - * 送信バッファをセットする。 - * - */ -void NyLPC_cIPv4Payload_setTxBuf(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf) -{ - i_inst->header=(struct NyLPC_TIPv4Header*)i_buf; -} -void* NyLPC_cIPv4Payload_detachBuf(NyLPC_TcIPv4Payload_t* i_inst) -{ - void* r=i_inst->header; + const void* r=i_inst->header; NyLPC_ArgAssert(r!=NULL); i_inst->header=NULL; return r; } - -/** - * 入力したTCP/IPペイロードをRSTレスポンスに変換する。 - */ -void NyLPC_cIPv4Payload_setTcpReverseRstAck( - NyLPC_TcIPv4Payload_t* i_inst) -{ - struct NyLPC_TIPv4Addr src_addr,dest_addr; - NyLPC_TUInt32 ack,seq; - NyLPC_TUInt16 src_port,dest_port; - struct NyLPC_TTcpHeader* tcp=i_inst->payload.tcp; - - //送信元IP,Portを退避 - src_addr=i_inst->header->srcipaddr; - dest_addr=i_inst->header->destipaddr; - dest_port=tcp->destport; - src_port=tcp->srcport; - //送信元sq,ackを退避 - ack=tcp->ackno32; - seq=tcp->seqno32; - //パケットマップの設定 - NyLPC_cIPv4Payload_initTcpTx(i_inst,0x05,((UIP_TCPH_LEN) / 4),0); - //ipの設定 - i_inst->header->destipaddr=src_addr; - i_inst->header->srcipaddr=dest_addr; - writeTxIpHeader(i_inst->header,UIP_PROTO_TCP); - //TCP設定 - tcp->flags = TCP_RST | TCP_ACK; - tcp->tcpoffset = 5<<4; - tcp->seqno32=ack; - tcp->ackno32=NyLPC_htonl(NyLPC_ntohl(seq)+1); - tcp->srcport=dest_port; - tcp->destport=src_port; - tcp->urgp[0] = tcp->urgp[1] = 0; - tcp->wnd16=0; - i_inst->header->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(i_inst->header)); - i_inst->payload.tcp->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(i_inst->header)); - return; -} - -void NyLPC_cIPv4Payload_setTcpWnd( - NyLPC_TcIPv4Payload_t* i_inst, - NyLPC_TUInt16 i_wnd) -{ - i_inst->payload.tcp->wnd16=NyLPC_htons(i_wnd); -} -/** - * パケットを閉じで完成させる。 - */ -void NyLPC_cIPv4Payload_closeTcpTxPacket( - NyLPC_TcIPv4Payload_t* i_inst) -{ - i_inst->payload.tcp->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(i_inst->header)); - i_inst->header->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(i_inst->header)); -} /* なんだっけっこれ? //1の補数v1にv2を加算する。 static NyLPC_TUInt16 add16c(NyLPC_TUInt16 i_v1,NyLPC_TUInt16 i_v2) @@ -286,90 +140,5 @@ return (t<i_v1)?t:t-1; } */ -/** - * o_instに、同一なバッファを参照するインスタンスを生成します。 - */ -void NyLPC_cIPv4Payload_copyTo( - const NyLPC_TcIPv4Payload_t* i_inst, - NyLPC_TcIPv4Payload_t* o_inst) -{ - o_inst->buf_len=i_inst->buf_len; - o_inst->header=i_inst->header; - o_inst->payload=i_inst->payload; -} - -/** - * ACK番号を更新する。 - * @param i_ackno - * ネットワークオーダーのACK番号 - */ -void NyLPC_cIPv4Payload_updateAckNo( - NyLPC_TcIPv4Payload_t* i_inst, - NyLPC_TUInt32 i_ackno) -{ - NyLPC_Assert(i_inst->header!=NULL); -/* union{ - NyLPC_TUInt32 l; - NyLPC_TUInt8 b[4]; - }old_ack,new_ack; - NyLPC_TUInt16 v1; - //checksumの計算 - old_ack.l=i_inst->payload.tcp->ackno32;//古いACK番号 - new_ack.l=i_ackno;//新しいACK番号 - v1=NyLPC_ntohs(~(i_inst->payload.tcp->tcpchksum));//1の補数を取って、ホストオーダーに戻す。 - //減算 - v1=sub16c(v1,(old_ack.b[0]<<8)+old_ack.b[1]); - v1=sub16c(v1,(old_ack.b[2]<<8)+old_ack.b[3]); - //加算 - v1=add16c(v1,(new_ack.b[0]<<8)+new_ack.b[1]); - v1=add16c(v1,(new_ack.b[2]<<8)+new_ack.b[3]); - v1=~NyLPC_htons(v1);*/ -NyLPC_Trace(); - i_inst->payload.tcp->ackno32=i_ackno; -NyLPC_Trace(); - i_inst->payload.tcp->tcpchksum = 0; -NyLPC_Trace(); - i_inst->payload.tcp->tcpchksum = ~(NyLPC_TIPv4Header_makeTcpChecksum(i_inst->header)); -NyLPC_Trace(); - -/* - if((i_inst->payload.tcp->tcpchksum!=v1)){ - NyLPC_Warning(); - }*/ -} - -///////////////UDP////////////// - -/** - * UDPの送信バッファを初期化します。 - */ -void* NyLPC_cIPv4Payload_initUdpTx(NyLPC_TcIPv4Payload_t* i_inst,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_tcp_payload_size) -{ - i_inst->header->vhl=0x40|(0x0f&i_iph_word); - i_inst->payload.rawbuf=((NyLPC_TUInt8*)(i_inst->header))+i_iph_word*4; - i_inst->header->len16=NyLPC_htons(i_tcp_payload_size+(i_iph_word*4+8)); - i_inst->payload.udp->udplen=NyLPC_htons(i_tcp_payload_size+(8)); - return i_inst->payload.rawbuf+8; -} - -/** - * コネクション情報から、UDPのコントロールヘッダをセットします。 - */ -void NyLPC_cIPv4Payload_setUdpTxHeaderByConnection(NyLPC_TcIPv4Payload_t* i_inst,const struct uip_udp_conn* i_conn,const struct NyLPC_TIPv4Addr* i_dest_ip,NyLPC_TUInt16 i_dest_port) -{ - //IPv4のTxヘッダを書き込む。 - i_inst->header->destipaddr=*i_dest_ip; - i_inst->header->srcipaddr =i_conn->lipaddr; - writeTxIpHeader(i_inst->header,UIP_PROTO_UDP); - //UDPのTxヘッダを書き込む - setUdpTxHeader(i_inst->payload.udp,i_conn,NyLPC_htons(i_dest_port)); - return; -} -void NyLPC_cIPv4Payload_closeUdpTxPacket( - NyLPC_TcIPv4Payload_t* i_inst) -{ - i_inst->payload.udp->udpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(i_inst->header)); - i_inst->header->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(i_inst->header)); -}
--- a/core/uip/NyLPC_cIPv4Payload.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cIPv4Payload.h Thu May 29 14:29:15 2014 +0000 @@ -71,17 +71,21 @@ struct NyLPC_TcIPv4Payload { //IPヘッダへのポインタです。バッファの先頭アドレスと同一です。 - struct NyLPC_TIPv4Header* header; + const struct NyLPC_TIPv4Header* header; union{ //IPヘッダ終了位置のポインタです。 - NyLPC_TUInt8* rawbuf; - struct NyLPC_TIcmpHeader* icmp; - struct NyLPC_TTcpHeader* tcp; - struct NyLPC_TUdpHeader* udp; + const NyLPC_TUInt8* rawbuf; + const struct NyLPC_TIcmpHeader* icmp; + const struct NyLPC_TTcpHeader* tcp; + const struct NyLPC_TUdpHeader* udp; }payload; - NyLPC_TUInt16 buf_len; +// NyLPC_TUInt16 buf_len; }; + + + + #ifdef __cplusplus } #endif /* __cplusplus */
--- a/core/uip/NyLPC_cIPv4Payload_protected.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cIPv4Payload_protected.h Thu May 29 14:29:15 2014 +0000 @@ -86,34 +86,16 @@ -void NyLPC_cIPv4Payload_setTxBuf(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf); -void* NyLPC_cIPv4Payload_detachBuf(NyLPC_TcIPv4Payload_t* i_inst); +void NyLPC_cIPv4Payload_attachTxBuf(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf); +const void* NyLPC_cIPv4Payload_detachBuf(NyLPC_TcIPv4Payload_t* i_inst); -/** - * ペーロードサイズゼロ、オプションなしのTCPコントロールパケットをセットします。 - */ -void NyLPC_cIPv4Payload_setTcpCtrl(NyLPC_TcIPv4Payload_t* i_inst,const NyLPC_TcTcpSocket_t* i_conn,NyLPC_TUInt8 i_tcp_flag); -void* NyLPC_cIPv4Payload_initTcpTx(NyLPC_TcIPv4Payload_t* i_inst,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt8 i_tcph_word,NyLPC_TUInt16 i_tcp_payload_size); -NyLPC_TBool NyLPC_cIPv4Payload_setRxBuf(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf,NyLPC_TUInt16 i_flagment_size); +NyLPC_TBool NyLPC_cIPv4Payload_attachRxBuf(NyLPC_TcIPv4Payload_t* i_inst,const void* i_buf,NyLPC_TUInt16 i_flagment_size); void NyLPC_cIPv4Payload_setTcpReverseRstAck( NyLPC_TcIPv4Payload_t* i_inst); - -void NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(NyLPC_TcIPv4Payload_t* i_inst,const struct uip_conn* i_conn,NyLPC_TUInt8 i_flag); - -void NyLPC_cIPv4Payload_setTcpWnd( +void NyLPC_cIPv4Payload_setTcpReverseRstAck2( NyLPC_TcIPv4Payload_t* i_inst, - NyLPC_TUInt16 i_wnd); + const NyLPC_TcIPv4Payload_t* i_src); -void NyLPC_cIPv4Payload_closeTcpTxPacket( - NyLPC_TcIPv4Payload_t* i_inst); - -void NyLPC_cIPv4Payload_updateAckNo( - NyLPC_TcIPv4Payload_t* i_inst, - NyLPC_TUInt32 i_ackno); - -void NyLPC_cIPv4Payload_copyTo( - const NyLPC_TcIPv4Payload_t* i_inst, - NyLPC_TcIPv4Payload_t* o_inst); @@ -129,6 +111,11 @@ void NyLPC_cIPv4Payload_closeUdpTxPacket( NyLPC_TcIPv4Payload_t* i_inst); + +void NyLPC_TcIPv4TxPacket_initialize_icomp(NyLPC_TcIPv4Payload_t* i_inst,void* i_buf,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_tcp_payload_size); + + + #ifdef __cplusplus } #endif /* __cplusplus */
--- a/core/uip/NyLPC_cTcpSocket.c Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cTcpSocket.c Thu May 29 14:29:15 2014 +0000 @@ -75,45 +75,155 @@ static void sendRst(NyLPC_TcTcpSocket_t* i_inst); + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Packet writer +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + + /** - * ソケットステータスを元に、IPパケットを構成します。 - * この関数は、ロック状態でコールしてください。 + * TCPヘッダに値をセットする。checksum,wndは0初期化する。 */ -static void setPacket(const NyLPC_TcTcpSocket_t* i_inst,NyLPC_TcIPv4Payload_t* i_payload,NyLPC_TUInt8 i_tcpf,const void* i_buf,NyLPC_TUInt16 i_len) +static void setTcpTxHeader(struct NyLPC_TTcpHeader* i_struct,NyLPC_TUInt8 i_flag,const struct uip_conn* i_conn) +{ + i_struct->flags = i_flag; + //sorce & destination port + i_struct->srcport = i_conn->lport; + i_struct->destport = i_conn->rport; + //ACK number + i_struct->ackno32 = NyLPC_htonl(i_conn->rcv_nxt32); + //Seq Number + i_struct->seqno32 = NyLPC_htonl(i_conn->snd_nxt32); + //uip_func_tcp_send_noconn(BUF); + i_struct->urgp[0] = i_struct->urgp[1] = 0; + i_struct->tcpchksum= 0; +} + +static void setTxPacket(const NyLPC_TcTcpSocket_t* i_inst,void* i_tx_buf,NyLPC_TUInt8 i_tcpf,const void* i_buf,NyLPC_TUInt16 i_len) { - void* buf; - switch(i_tcpf){ - case TCP_PSH|TCP_ACK: - buf=NyLPC_cIPv4Payload_initTcpTx(i_payload,0x05,((UIP_TCPH_LEN) / 4),i_len); - NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(i_payload,&(i_inst->uip_connr),TCP_ACK|TCP_PSH); - //bufの書き込み - memcpy(buf,i_buf,i_len); - break; - case TCP_ACK: - case TCP_FIN|TCP_ACK: - case TCP_RST|TCP_ACK: - NyLPC_cIPv4Payload_initTcpTx(i_payload,0x05,((UIP_TCPH_LEN) / 4),0); - NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(i_payload,&(i_inst->uip_connr),i_tcpf); - break; - case TCP_SYN|TCP_ACK: - NyLPC_cIPv4Payload_initTcpTx(i_payload,0x05,((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4),0); - NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(i_payload,&(i_inst->uip_connr),i_tcpf); - //MSSの設定(OPTION領域のアドレス0) - NyLPC_TTcpHeader_setMmsOpt((NyLPC_TUInt8*)(i_payload->payload.tcp+1),i_inst->uip_connr.default_mss); - break; - case TCP_SYN: - NyLPC_cIPv4Payload_initTcpTx(i_payload,0x05,((UIP_TCPH_LEN + TCP_OPT_MSS_LEN) / 4),0); - NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(i_payload,&(i_inst->uip_connr),i_tcpf); - //MSSの設定(OPTION領域のアドレス0) - NyLPC_TTcpHeader_setMmsOpt((NyLPC_TUInt8*)(i_payload->payload.tcp+1),i_inst->uip_connr.default_mss); - break; - default: - NyLPC_Abort(); + struct NyLPC_TIPv4Header* iph; + struct NyLPC_TTcpHeader* tcph; + NyLPC_TUInt8 iph_word=0x05; + NyLPC_TUInt8 tcph_word=(UIP_TCPH_LEN) / 4; + //IPヘッダの更新 + iph=(struct NyLPC_TIPv4Header*)i_tx_buf; + iph->vhl=0x40|(0x0f&iph_word); + iph->destipaddr=i_inst->uip_connr.ripaddr; + iph->srcipaddr =*(i_inst->uip_connr.lipaddr); + NyLPC_TIPv4Header_writeTxIpHeader(iph,UIP_PROTO_TCP); + //TCPヘッダの更新 + tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)i_tx_buf)+NyLPC_TIPv4Header_getHeaderLength(iph)); + + + //SYNが有るならMSSの書き込み + if((TCP_SYN & i_tcpf)){ + tcph_word+=((TCP_OPT_MSS_LEN) / 4); + NyLPC_TTcpHeader_setMmsOpt(((NyLPC_TUInt8*)(tcph+1)),i_inst->uip_connr.default_mss); } - NyLPC_cIPv4Payload_setTcpWnd(i_payload,NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))); - NyLPC_cIPv4Payload_closeTcpTxPacket(i_payload); + tcph->tcpoffset=(tcph_word<<4); + setTcpTxHeader(tcph,i_tcpf,&(i_inst->uip_connr)); + + //最終的なパケットサイズと必要ならペイロードを書き込み + if(i_buf!=NULL){ + iph->len16=NyLPC_htons(i_len+(iph_word+tcph_word)*4); + memcpy(((NyLPC_TUInt8*)i_tx_buf)+((iph_word+tcph_word)*4),i_buf,i_len); + }else{ + iph->len16=NyLPC_htons((iph_word+tcph_word)*4); + } + //WND設定 + tcph->wnd16=NyLPC_htons(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))); + //Checksumの生成 + tcph->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); + iph->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(iph)); return; } + +/** + * IP/TCPヘッダが40バイト固定として、i_tx_buf+40の位置にあるペイロードに対するIP/TCPヘッダを書き込みます。 + */ +static void setTxPacketHeader(const NyLPC_TcTcpSocket_t* i_inst,void* i_tx_buf,NyLPC_TUInt8 i_tcpf,NyLPC_TUInt16 i_len) +{ + struct NyLPC_TIPv4Header* iph; + struct NyLPC_TTcpHeader* tcph; + NyLPC_TUInt8 iph_word=0x05; + NyLPC_TUInt8 tcph_word=(UIP_TCPH_LEN) / 4; + //IPヘッダの更新 + iph=(struct NyLPC_TIPv4Header*)i_tx_buf; + iph->vhl=0x40|(0x0f&iph_word); + iph->destipaddr=i_inst->uip_connr.ripaddr; + iph->srcipaddr =*(i_inst->uip_connr.lipaddr); + NyLPC_TIPv4Header_writeTxIpHeader(iph,UIP_PROTO_TCP); + + //TCPヘッダの更新 + tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)i_tx_buf)+NyLPC_TIPv4Header_getHeaderLength(iph)); + tcph->tcpoffset=(tcph_word<<4); + setTcpTxHeader(tcph,i_tcpf,&(i_inst->uip_connr)); + + //最終的なパケットサイズと必要ならペイロードを書き込み + iph->len16=NyLPC_htons(i_len+(iph_word+tcph_word)*4); + //WND設定 + tcph->wnd16=NyLPC_htons(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))); + //Checksumの生成 + tcph->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); + iph->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(iph)); + return; +} + + + + + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Mainclass::private +// +//////////////////////////////////////////////////////////////////////////////////////////////////// + +/** + * ACK番号を更新する。 + * @param i_ackno + * ネットワークオーダーのACK番号 + */ +static void updateAckNo(void* i_tx_buf,NyLPC_TUInt32 i_ackno) +{ + struct NyLPC_TIPv4Header* iph=(struct NyLPC_TIPv4Header*)i_tx_buf; + struct NyLPC_TTcpHeader* tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)i_tx_buf)+NyLPC_TIPv4Header_getHeaderLength(iph)); + +/* union{ + NyLPC_TUInt32 l; + NyLPC_TUInt8 b[4]; + }old_ack,new_ack; + NyLPC_TUInt16 v1; + //checksumの計算 + old_ack.l=i_inst->payload.tcp->ackno32;//古いACK番号 + new_ack.l=i_ackno;//新しいACK番号 + v1=NyLPC_ntohs(~(i_inst->payload.tcp->tcpchksum));//1の補数を取って、ホストオーダーに戻す。 + //減算 + v1=sub16c(v1,(old_ack.b[0]<<8)+old_ack.b[1]); + v1=sub16c(v1,(old_ack.b[2]<<8)+old_ack.b[3]); + //加算 + v1=add16c(v1,(new_ack.b[0]<<8)+new_ack.b[1]); + v1=add16c(v1,(new_ack.b[2]<<8)+new_ack.b[3]); + v1=~NyLPC_htons(v1);*/ +NyLPC_Trace(); + tcph->ackno32=i_ackno; +NyLPC_Trace(); + tcph->tcpchksum = 0; +NyLPC_Trace(); + tcph->tcpchksum = ~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); +NyLPC_Trace(); + +/* + if((i_inst->payload.tcp->tcpchksum!=v1)){ + NyLPC_Warning(); + }*/ +} + + + /** * 指定した送信パケットがACK済であるか調べる。 */ @@ -161,7 +271,7 @@ l=0; while(i_inst->txbuf.rp!=i_inst->txbuf.wp){ - dlist[l]=NyLPC_cIPv4Payload_detachBuf(&(q[i_inst->txbuf.rp].data)); + dlist[l]=q[i_inst->txbuf.rp].packet; l++; i_inst->txbuf.rp=(i_inst->txbuf.rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; } @@ -187,7 +297,7 @@ NyLPC_ArgAssert(i_inst!=NULL); rp=i_inst->txbuf.rp; while(rp!=i_inst->txbuf.wp){ - NyLPC_cIPv4Payload_updateAckNo(&(q[rp].data),i_ackno); + updateAckNo(q[rp].packet,i_ackno); rp=(rp+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ; } } @@ -269,7 +379,7 @@ DEBUG_RTO_LOG(i_inst); while(rp!=i_inst->txbuf.wp){ - o_dlist[n]=NyLPC_cIPv4Payload_getBuf(&(q[rp].data)); + o_dlist[n]=q[rp].packet; if(q[rp].ackno==i_sq){ //i_inst->txbuf.rp->rpのパケットのRTOからbaseRTOの値を再計算。 estimateRTO(i_inst,i_inst->txbuf.rp,n+1); @@ -338,7 +448,7 @@ i_inst->tcpstateflags=UIP_CLOSED; i_inst->txbuf.rp=i_inst->txbuf.wp=0; for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){ - NyLPC_cIPv4Payload_initialize(&(i_inst->txbuf.txq[i].data)); + i_inst->txbuf.txq[i].packet=NULL; } //管理リストへ登録。 return NyLPC_cIPv4_addSocket(&(srv->_tcpv4),&(i_inst->_super)); @@ -359,7 +469,7 @@ resetTxQWithUnlock(i_inst); } for(i=0;i<NyLPC_TcTcpSocket_NUMBER_OF_TXQ;i++){ - NyLPC_cIPv4Payload_finalize(&(i_inst->txbuf.txq[i].data)); + i_inst->txbuf.txq[i].packet=NULL; } NyLPC_cFifoBuffer_finalize(&(i_inst->rxbuf)); // NyLPC_cMutex_finalize(&(i_inst->_smutex)); @@ -464,7 +574,7 @@ void* buf; NyLPC_TUInt32 next_ack; //送信バッファを取得 - //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 + //@bug オブションパケット送信時に4バイト足りないメモリ要求しない?問題になってないけど。 for(;;){ buf=NyLPC_cUipService_allocTxBuf(i_len+(SIZE_OF_IPv4_TCPIP_HEADER),&s); if(buf!=NULL){ @@ -497,8 +607,6 @@ NyLPC_cUipService_releaseTxBuf(buf); return -1; } - //IPv4ペイロードの書き込み - NyLPC_cIPv4Payload_setTxBuf(&(txq->data),buf); //送信バッファを基準とした送信サイズを計算 s-=SIZE_OF_IPv4_TCPIP_HEADER; @@ -520,7 +628,9 @@ txq->tick_of_sent=NyLPC_cStopwatch_now(); //パケットの書き込み - setPacket(i_inst,&(txq->data),i_tcpf,i_buf,s); + setTxPacket(i_inst,buf,i_tcpf,i_buf,s); + txq->packet=buf; + //シーケンス番号の更新 i_inst->uip_connr.snd_nxt32=next_ack; //Peerのウインドウサイズを更新 @@ -538,25 +648,17 @@ */ static void sendRst(NyLPC_TcTcpSocket_t* i_inst) { - NyLPC_TcIPv4Payload_t ipv4; - NyLPC_TUInt16 s; void* buf; NyLPC_Assert(i_inst->tcpstateflags==UIP_CLOSED); //ペイロードライタの初期化 - NyLPC_cIPv4Payload_initialize(&ipv4); - //IPヘッダ+10バイトくらい。 //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 - do{ - buf=NyLPC_cUipService_allocTxBuf((SIZE_OF_IPv4_TCPIP_HEADER)+5,&s); - }while(buf==NULL); + buf=NyLPC_cUipService_allocSysTxBuf(); lockResource(i_inst); - NyLPC_cIPv4Payload_setTxBuf(&ipv4,buf); i_inst->uip_connr.snd_nxt32++; - setPacket(i_inst,&ipv4,TCP_RST|TCP_ACK,buf,0); unlockResource(i_inst); - + setTxPacket(i_inst,buf,TCP_RST|TCP_ACK,NULL,0); NyLPC_cUipService_sendIPv4Tx(buf); NyLPC_cUipService_releaseTxBuf(buf); NyLPC_cIPv4Payload_finalize(&ipv4); @@ -570,7 +672,7 @@ * 十分な空き領域がない場合、失敗する。 * この関数は、ロックして実行してください。 */ -static NyLPC_TBool addRecvData(NyLPC_TcTcpSocket_t* i_inst,void* i_data,NyLPC_TUInt16 i_data_size) +static NyLPC_TBool addRecvData(NyLPC_TcTcpSocket_t* i_inst,const void* i_data,NyLPC_TUInt16 i_data_size) { //受信データサイズを確認 if(NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))>=i_data_size){ @@ -773,21 +875,14 @@ */ void NyLPC_cTcpSocket_pseek(NyLPC_TcTcpSocket_t* i_inst,NyLPC_TUInt16 i_seek) { - NyLPC_TcIPv4Payload_t ipv4payload; void* buf; - NyLPC_TUInt16 s; NyLPC_ArgAssert(i_seek<=NyLPC_cFifoBuffer_getLength(&(i_inst->rxbuf))); if(i_seek==0){ return; } - //ペイロードライタの初期化 - NyLPC_cIPv4Payload_initialize(&ipv4payload); //ACK送信バッファの取得 - //@bug バッファが取れるまで通信がブロックするの。ここはなんとかしないと。 - do{ - buf=NyLPC_cUipService_allocTxBuf((SIZE_OF_IPv4_TCPIP_HEADER)+5,&s); - }while(buf==NULL); + buf=NyLPC_cUipService_allocSysTxBuf(); //MUTEX LOCK lockResource(i_inst); @@ -795,14 +890,12 @@ //受信バッファを読み出しシーク NyLPC_cFifoBuffer_pop(&(i_inst->rxbuf),i_seek); //ACKパケットの生成 - NyLPC_cIPv4Payload_setTxBuf(&ipv4payload,buf); - setPacket(i_inst,&ipv4payload,TCP_ACK,buf,0); + setTxPacket(i_inst,buf,TCP_ACK,NULL,0); unlockResource(i_inst); //ACK送信 NyLPC_cUipService_sendIPv4Tx(buf); NyLPC_cUipService_releaseTxBuf(buf); - //ペイロードライタの破棄 - NyLPC_cIPv4Payload_finalize(&ipv4payload); + } /** @@ -917,16 +1010,16 @@ //ここから先はi_bufの所有権はインスタンスになってる。 //IPv4ペイロードの書き込み - NyLPC_cIPv4Payload_setTxBuf(&(txq->data),buf); + //allocをした時点でwin,mssは考慮されているので、そのままそうしんしる。 + //ACK番号の計算 txq->rto32=i_inst->uip_connr.current_rto32; txq->tick_of_sent=NyLPC_cStopwatch_now(); - //パケットヘッダの生成 - NyLPC_cIPv4Payload_initTcpTx(&(txq->data),0x05,((UIP_TCPH_LEN) / 4),i_len); - NyLPC_cIPv4Payload_setTcpTxHeaderByConnection(&(txq->data),&(i_inst->uip_connr),TCP_ACK|TCP_PSH); - NyLPC_cIPv4Payload_setTcpWnd(&(txq->data),NyLPC_cFifoBuffer_getSpace(&(i_inst->rxbuf))); - NyLPC_cIPv4Payload_closeTcpTxPacket(&(txq->data)); + //パケットヘッダの生成(ヘッダ長はpreadで定義した値(4+6)*4=40です。) + setTxPacketHeader(i_inst,buf,TCP_ACK|TCP_PSH,i_len); + txq->packet=buf; + //シーケンス番号の更新 i_inst->uip_connr.snd_nxt32=i_inst->uip_connr.snd_nxt32+i_len; //Peerのウインドウサイズを更新 @@ -1116,7 +1209,8 @@ }else{ //規定時間内なら、再送処理 for(i=rp;i!=i_inst->txbuf.wp;i=(i+1)%NyLPC_TcTcpSocket_NUMBER_OF_TXQ){ - NyLPC_cUipService_sendIPv4Tx(NyLPC_cIPv4Payload_getBuf(&(q[i].data))); +// NyLPC_cUipService_sendIPv4Tx(NyLPC_cIPv4Payload_getBuf(&(q[i].data))); + NyLPC_cUipService_sendIPv4Tx(q[i].packet); } unlockResource(i_inst); } @@ -1158,33 +1252,28 @@ return; } -/** - * この関数は、rxパケットを処理して、ソケットの状態を更新します。 - * uipサービスタスクが実行する関数です。 - * o_ippのペイロードに、応答ペイロードを設定することがあります。 - * この関数はNyLPC_cTcpSocket_periodicと排他実行すること。 - */ -NyLPC_TBool NyLPC_cTcpSocket_parseRx( + +void* NyLPC_cTcpSocket_parseRx( NyLPC_TcTcpSocket_t* i_inst, - NyLPC_TcIPv4Payload_t* o_ipp) + const NyLPC_TcIPv4Payload_t* i_ipp) { int i,s; NyLPC_TUInt16 tmp16; NyLPC_TUInt16 data_size; - NyLPC_TUInt8 in_tcpflag=o_ipp->payload.tcp->flags; - void* tcp_data_offset; + NyLPC_TUInt8 in_tcpflag=i_ipp->payload.tcp->flags; + const void* tcp_data_offset; NyLPC_TBool is_new_packet; int num_of_noack; void* dlist[NyLPC_TcTcpSocket_NUMBER_OF_TXQ]; - NyLPC_TBool ret; + void* ret; //パラメータの計算 - tmp16=NyLPC_TTcpHeader_getHeaderLength(o_ipp->payload.tcp); + tmp16=NyLPC_TTcpHeader_getHeaderLength(i_ipp->payload.tcp); //TCPペイロードの長さは、IPパケットの長さ-(IPヘッダ+TCPヘッダ) - data_size=NyLPC_TIPv4Header_getPacketLength(o_ipp->header)-NyLPC_TIPv4Header_getHeaderLength(o_ipp->header)-tmp16; + data_size=NyLPC_TIPv4Header_getPacketLength(i_ipp->header)-NyLPC_TIPv4Header_getHeaderLength(i_ipp->header)-tmp16; //TCPデータオフセット - tcp_data_offset=o_ipp->payload.rawbuf+tmp16; + tcp_data_offset=i_ipp->payload.rawbuf+tmp16; //インスタンスをロックする。 lockResource(i_inst); @@ -1197,18 +1286,18 @@ } - is_new_packet=NyLPC_ntohl(o_ipp->payload.tcp->seqno32)==i_inst->uip_connr.rcv_nxt32; + is_new_packet=NyLPC_ntohl(i_ipp->payload.tcp->seqno32)==i_inst->uip_connr.rcv_nxt32; //OPTIONの反映 //MSSの取得 - if(NyLPC_TTcpHeader_getTcpMmsOpt(o_ipp->payload.tcp,&tmp16)){ + if(NyLPC_TTcpHeader_getTcpMmsOpt(i_ipp->payload.tcp,&tmp16)){ //取得で着たら更新 i_inst->uip_connr.peer_mss=tmp16; } //受信パケットを元に、未ACKパケットの数を計算 - num_of_noack=getNumOfSending(i_inst,o_ipp->payload.tcp->ackno32);//i_inst->txbuf.num_of_txq; + num_of_noack=getNumOfSending(i_inst,i_ipp->payload.tcp->ackno32);//i_inst->txbuf.num_of_txq; //ステータス毎のACK応答 switch(i_inst->tcpstateflags) @@ -1298,7 +1387,7 @@ //connect関数実行中しか起動しないステータス if(num_of_noack==0){ i_inst->tcpstateflags=UIP_ESTABLISHED; - i_inst->uip_connr.rcv_nxt32=NyLPC_ntohl(o_ipp->payload.tcp->seqno32)+1; + i_inst->uip_connr.rcv_nxt32=NyLPC_ntohl(i_ipp->payload.tcp->seqno32)+1; }else{ //それ以外のパケットはドロップする。 break;//goto DROP; @@ -1309,13 +1398,13 @@ goto DROP; } //ウインドウサイズを更新 - i_inst->uip_connr.peer_win=NyLPC_ntohs(o_ipp->payload.tcp->wnd16); + i_inst->uip_connr.peer_win=NyLPC_ntohs(i_ipp->payload.tcp->wnd16); //送信キューから、Peerが受信したデータを削除する。 if(in_tcpflag & TCP_ACK){ //再送パケットキューから送信済みのデータを回収(後で開放) NyLPC_Trace(); - s=updateTxQByIndex(i_inst,o_ipp->payload.tcp->ackno32,dlist); + s=updateTxQByIndex(i_inst,i_ipp->payload.tcp->ackno32,dlist); NyLPC_Trace(); }else{ s=0; @@ -1327,14 +1416,14 @@ } //送信キューのない - ret=NyLPC_TBool_FALSE; if(((in_tcpflag&(TCP_FIN|TCP_SYN))!=0x00) || ((!is_new_packet) && (data_size>0))) { - setPacket(i_inst,o_ipp,TCP_ACK,NULL,0); - ret=NyLPC_TBool_TRUE; + //ソケットからPureACKを生成 as setPacket(i_inst,i_ipp,TCP_ACK,NULL,0); + ret=NyLPC_cUipService_allocSysTxBuf(); + setTxPacket(i_inst,ret,TCP_ACK,NULL,0); }else{ - ret=NyLPC_TBool_FALSE; + ret=NULL; } unlockResource(i_inst); //取り外したTXメモリの開放 @@ -1348,13 +1437,56 @@ //ACKしたパケットを送信キューから削除 unlockResource(i_inst); NyLPC_Trace(); - return NyLPC_TBool_FALSE; + return NULL; +} + + +/** + * 入力されたパケットからRSTパケットを生成して返す。 + */ +void* NyLPC_cTcpSocket_allocTcpReverseRstAck( + const NyLPC_TcIPv4Payload_t* i_src) +{ + struct NyLPC_TIPv4Header* iph; + struct NyLPC_TTcpHeader* tcph; + NyLPC_TUInt8 iph_word=0x05; + NyLPC_TUInt8 tcph_word=(UIP_TCPH_LEN) / 4; + void* txb=NyLPC_cUipService_allocSysTxBuf(); + //IPヘッダの更新 + iph=(struct NyLPC_TIPv4Header*)txb; + iph->vhl=0x40|(0x0f&iph_word); + iph->destipaddr=i_src->header->srcipaddr; + iph->srcipaddr =i_src->header->destipaddr; + NyLPC_TIPv4Header_writeTxIpHeader(iph,UIP_PROTO_TCP); + + //TCPヘッダの更新 + tcph=(struct NyLPC_TTcpHeader*)(((NyLPC_TUInt8*)txb)+NyLPC_TIPv4Header_getHeaderLength(iph)); + + tcph->tcpoffset=(tcph_word<<4); + + tcph->flags = TCP_RST | TCP_ACK; + //sorce & destination port + tcph->srcport = i_src->payload.tcp->destport; + tcph->destport = i_src->payload.tcp->srcport; + //ACK number + tcph->ackno32 = NyLPC_htonl(NyLPC_ntohl(i_src->payload.tcp->seqno32)+1); + //Seq Number + tcph->seqno32 = i_src->payload.tcp->ackno32; + //uip_func_tcp_send_noconn(BUF); + tcph->urgp[0] = tcph->urgp[1] = 0; + tcph->tcpchksum= 0; + + + //最終的なパケットサイズと必要ならペイロードを書き込み + iph->len16=NyLPC_htons((iph_word+tcph_word)*4); + //WND設定 + tcph->wnd16=0; + //Checksumの生成 + tcph->tcpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(iph)); + iph->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(iph)); + return txb; } - - - -
--- a/core/uip/NyLPC_cTcpSocket.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cTcpSocket.h Thu May 29 14:29:15 2014 +0000 @@ -75,7 +75,7 @@ NyLPC_TUInt32 tick_of_sent; //このパケットのRTO(秒間隔) NyLPC_TUInt32 rto32; - NyLPC_TcIPv4Payload_t data; + void* packet; //パケットのACK番号。この番号を受信できれば、再送パケットは消去可能である。 NyLPC_TUInt32 ackno; };
--- a/core/uip/NyLPC_cTcpSocket_protected.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cTcpSocket_protected.h Thu May 29 14:29:15 2014 +0000 @@ -65,11 +65,12 @@ * TCPペイロードを処理して、応答パケットをペイロードに返します。 * uipサービスタスクが実行する関数です。 * @return - * 応答ペイロードの有無を返します。 + * 応答パケットを格納したメモリブロックを返します。 + * このメモリは、NyLPC_cUipService_allocSysTxBuf関数で確保されたメモリです。 */ -NyLPC_TBool NyLPC_cTcpSocket_parseRx( +void* NyLPC_cTcpSocket_parseRx( NyLPC_TcTcpSocket_t* i_inst, - NyLPC_TcIPv4Payload_t* o_ipp); + const NyLPC_TcIPv4Payload_t* i_ipp); /** * 定期的に実行する関数。最低でも1s単位で実行してください。 @@ -102,6 +103,9 @@ void NyLPC_cTcpSocket_stopService(NyLPC_TcTcpSocket_t* i_inst); +void* NyLPC_cTcpSocket_allocTcpReverseRstAck( + const NyLPC_TcIPv4Payload_t* i_src); + #ifdef __cplusplus } #endif /* __cplusplus */
--- a/core/uip/NyLPC_cUdpSocket.c Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cUdpSocket.c Thu May 29 14:29:15 2014 +0000 @@ -66,6 +66,39 @@ #define SIZE_OF_IPv4_UDPIP_HEADER 28 + + + +/** + * IP+UDPヘッダサイズを0x05*4+8バイトとして、UDPの送信バッファをセットします。 + */ +static void setUdpTxBufHeader(const NyLPC_TcUdpSocket_t* i_inst,void*i_buf,const struct NyLPC_TIPv4Addr* i_dest_ip,NyLPC_TUInt16 i_dest_port,NyLPC_TUInt8 i_iph_word,NyLPC_TUInt16 i_payload_size) +{ + struct NyLPC_TIPv4Header* header=(struct NyLPC_TIPv4Header*)i_buf; + struct NyLPC_TUdpHeader* udp =(struct NyLPC_TUdpHeader*)(((NyLPC_TUInt8*)i_buf)+i_iph_word*4); + + header->vhl=0x40|(0x0f&i_iph_word); + header->len16=NyLPC_htons(i_payload_size+(i_iph_word*4+8)); + udp->udplen=NyLPC_htons(i_payload_size+(8)); + //IPv4のTxヘッダを書き込む。 + header->destipaddr=*i_dest_ip; + header->srcipaddr =i_inst->uip_udp_conn.lipaddr; + + NyLPC_TIPv4Header_writeTxIpHeader(header,UIP_PROTO_UDP); + + //UDPのTxヘッダを書き込む + //sorce & destination port + udp->srcport = i_inst->uip_udp_conn.lport; + udp->destport = NyLPC_htons(i_dest_port); + udp->udpchksum= 0; + + udp->udpchksum=~(NyLPC_TIPv4Header_makeTcpChecksum(header)); + header->ipchksum = ~(NyLPC_TIPv4Header_makeIpChecksum(header)); +} + + + + NyLPC_TBool NyLPC_cUdpSocket_initialize(NyLPC_TcUdpSocket_t* i_inst,NyLPC_TUInt16 i_port,void* i_rbuf,NyLPC_TUInt16 i_rbuf_len) { NyLPC_TcUipService_t* srv=_NyLPC_TcUipService_inst; @@ -111,37 +144,36 @@ /** * この関数は、rxパケットを処理して、ソケットの状態を更新します。 * uipサービスタスクが実行する関数です。 - * o_ippのペイロードに、応答ペイロードを設定することがあります。 * この関数はNyLPC_cTcpSocket_periodicと排他実行すること。 */ NyLPC_TBool NyLPC_cUdpSocket_parseRx( NyLPC_TcUdpSocket_t* i_inst, - NyLPC_TcIPv4Payload_t* o_ipp) + const NyLPC_TcIPv4Payload_t* i_ipp) { NyLPC_TUInt16 tmp16; struct NyLPC_TIPv4RxInfo dheader; - void* data_offset; + const void* data_offset; //ブロードキャストの場合、フラグを確認 - if(NyLPC_TIPv4Addr_isEqual(&(o_ipp->header->destipaddr),&NyLPC_TIPv4Addr_BROADCAST)){ + if(NyLPC_TIPv4Addr_isEqual(&(i_ipp->header->destipaddr),&NyLPC_TIPv4Addr_BROADCAST)){ if(!NyLPC_TUInt8_isBitOn(i_inst->uip_udp_conn.flags,NyLPC_cUdpSocket_FLAG_BROADCAST)){ goto DROP; } } //パラメータの計算 - tmp16=NyLPC_TUdpHeader_getHeaderLength(o_ipp->payload.tcp); + tmp16=NyLPC_TUdpHeader_getHeaderLength(i_ipp->payload.tcp); //UDPペイロードの長さは、IPパケットの長さ-(IPヘッダ+UDPヘッダ) - dheader.size=NyLPC_TIPv4Header_getPacketLength(o_ipp->header)-NyLPC_TIPv4Header_getHeaderLength(o_ipp->header)-tmp16; - dheader.peer_ip=o_ipp->header->srcipaddr; - dheader.peer_port=NyLPC_ntohs(o_ipp->payload.udp->srcport); - dheader.ip=o_ipp->header->destipaddr; - dheader.port=NyLPC_ntohs(o_ipp->payload.udp->destport); + dheader.size=NyLPC_TIPv4Header_getPacketLength(i_ipp->header)-NyLPC_TIPv4Header_getHeaderLength(i_ipp->header)-tmp16; + dheader.peer_ip=i_ipp->header->srcipaddr; + dheader.peer_port=NyLPC_ntohs(i_ipp->payload.udp->srcport); + dheader.ip=i_ipp->header->destipaddr; + dheader.port=NyLPC_ntohs(i_ipp->payload.udp->destport); if(i_inst->as_handler.rx!=NULL){ - if(!i_inst->as_handler.rx(i_inst,o_ipp->payload.rawbuf+tmp16,&dheader)){ + if(!i_inst->as_handler.rx(i_inst,i_ipp->payload.rawbuf+tmp16,&dheader)){ return NyLPC_TBool_FALSE;//UDPはReturnパケットなし } } //TCPデータオフセット - data_offset=o_ipp->payload.rawbuf+tmp16; + data_offset=i_ipp->payload.rawbuf+tmp16; //インスタンスをロックする。 lockResource(i_inst); @@ -259,7 +291,6 @@ NyLPC_TBool NyLPC_cUdpSocket_psend(NyLPC_TcUdpSocket_t* i_inst,const struct NyLPC_TIPv4Addr* i_addr,NyLPC_TUInt16 i_port,void* i_buf_ptr,int i_len) { void* buf; - NyLPC_TcIPv4Payload_t ipp; //ブロードキャストの場合、フラグを確認 if(NyLPC_TIPv4Addr_isEqual(i_addr,&NyLPC_TIPv4Addr_BROADCAST)){ if(!NyLPC_TUInt8_isBitOn(i_inst->uip_udp_conn.flags,NyLPC_cUdpSocket_FLAG_BROADCAST)){ @@ -269,15 +300,10 @@ //先頭ポインタは、i_buf-sizeof(SIZE_OF_IPv4_TCPIP_HEADER)固定 buf=(NyLPC_TUInt8*)i_buf_ptr-SIZE_OF_IPv4_UDPIP_HEADER; - NyLPC_cIPv4Payload_initialize(&ipp); lockResource(i_inst); //IPv4ペイロードの書き込み - NyLPC_cIPv4Payload_setTxBuf(&ipp,buf); - //パケットヘッダの生成 - NyLPC_cIPv4Payload_initUdpTx(&ipp,0x05,i_len); - NyLPC_cIPv4Payload_setUdpTxHeaderByConnection(&ipp,&(i_inst->uip_udp_conn),i_addr,i_port); - NyLPC_cIPv4Payload_closeUdpTxPacket(&ipp); + setUdpTxBufHeader(i_inst,buf,i_addr,i_port,0x05,i_len); unlockResource(i_inst); // !(BroadCast || Multicast)の場合は送信前にARPテーブルをチェックする。 if(!(NyLPC_TIPv4Addr_isEqual(i_addr,&NyLPC_TIPv4Addr_BROADCAST) || NyLPC_TIPv4Addr_isEqualWithMask(i_addr,&NyLPC_TIPv4Addr_MULTICAST,&NyLPC_TIPv4Addr_MULTICAST_MASK))){ @@ -288,7 +314,6 @@ } NyLPC_cUipService_sendIPv4Tx(buf); NyLPC_cUipService_releaseTxBuf(buf); - NyLPC_cIPv4Payload_finalize(&ipp); return NyLPC_TBool_TRUE; }
--- a/core/uip/NyLPC_cUdpSocket_protected.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cUdpSocket_protected.h Thu May 29 14:29:15 2014 +0000 @@ -22,7 +22,7 @@ */ NyLPC_TBool NyLPC_cUdpSocket_parseRx( NyLPC_TcUdpSocket_t* i_inst, - NyLPC_TcIPv4Payload_t* o_ipp); + const NyLPC_TcIPv4Payload_t* i_ipp); /** * uipサービスタスクが実行する関数です。
--- a/core/uip/NyLPC_cUipService.c Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cUipService.c Thu May 29 14:29:15 2014 +0000 @@ -106,9 +106,10 @@ static NyLPC_TBool sendIPv4Tx(struct NyLPC_TTxBufferHeader* i_eth_buf); -static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf); + //static void sendArpReqest(const struct TEthPacket* i_eth_packet); -static void sendRawEthFrame(void* i_buf,NyLPC_TUInt16 i_len); +static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len); +static void releaseTxBufNL(void* i_buf); /**メッセージなし*/ #define TTaskMessage_MSG_NULL 0x0000 @@ -256,9 +257,6 @@ NyLPC_cIPv4Arp_initialize(&(inst->_arp),inst->_ref_config); NyLPC_cStopwatch_startExpire(&(inst->_arp_sw),1);//1度ARPを起動するため。 NyLPC_cStopwatch_startExpire(&(inst->_periodic_sw),PERIODIC_TIMER); - //InBuffer初期化 - inst->stx.h.is_lock=NyLPC_TUInt8_FALSE; - inst->stx.h.ref=0; //EtherNETデバイス初期化 while(!NyLPC_iEthernetDevice_start(inst->_ethif,&(inst->_ref_config->eth_mac),ethernet_handler,inst)); NyLPC_TUInt16_setBit(inst->_status,NyLPC_TcUipService_STATUSBIT_IS_RUNNING); @@ -277,7 +275,7 @@ NyLPC_TUInt16 rx_len,tx_len; struct TEthPacket* ethbuf; NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - NyLPC_TBool r; + void* r; (void)pvParameters; for( ;; ) { @@ -304,27 +302,28 @@ //ARPテーブルの更新 //uip_arp_ipin(&(ethbuf->header),ethbuf->data.ipv4.srcipaddr); NyLPC_cIPv4Arp_incomingIp(&inst->_arp,&(ethbuf->header),ethbuf->data.ipv4.srcipaddr); - //Ethernet Device UnLock(パケット解析の為に一時的な解除) + //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除) NyLPC_cMutex_unlock(&(inst->_mutex)); //IPパケットの処理 r=NyLPC_cIPv4_rx(&(inst->_tcpv4),&(ethbuf->data.ipv4),rx_len); + if(r!=NULL){ + //IPパケットとして送信 + NyLPC_cUipService_sendIPv4Tx(r); + } //ロックの復帰 NyLPC_cMutex_lock(&(inst->_mutex)); - if(!r){ - //応答データは存在しない。 - break; + if(r!=NULL){ + releaseTxBufNL(r); } - //IPパケットをTxバッファに転写して送信 - copyAndSendIPv4Tx(ethbuf); - ethbuf=NULL; break; case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_ARP): - //if(uip_arp_arpin(&(ethbuf->data.arp),rx_len)){ - if(NyLPC_cIPv4Arp_incomingArp(&inst->_arp,&(ethbuf->data.arp),rx_len)){ - tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac)); - } - if(tx_len>0){ - sendRawEthFrame(ethbuf,tx_len); + //Ethernet Device UnLock(NyLPC_cIPv4_rxがallocをコールする可能性があるので一時的にロック解除) + NyLPC_cMutex_unlock(&(inst->_mutex)); + r=NyLPC_cIPv4Arp_rx(&inst->_arp,&(ethbuf->data.arp),rx_len,&tx_len); + NyLPC_cMutex_lock(&(inst->_mutex)); + if(r!=NULL){ + sendRawEthFrameNL(r,tx_len); + releaseTxBufNL(r); } break; case NyLPC_HTONS(NyLPC_TEthernetIIHeader_TYPE_IPV6): @@ -377,22 +376,26 @@ /** * IPv4パケットのpeerIPを問い合わせるARPパケットを送信します。 + * allocを中でコールするから要UNLOCK状態 */ -static void sendArpReqest(const struct NyLPC_TIPv4Addr* i_addr) +void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr) { NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; + struct NyLPC_TTxBufferHeader* p; NyLPC_TUInt16 tx_len; struct TEthPacket* ethbuf; - //ACK送信用の自己バッファが空くまで待つ - while(inst->stx.h.is_lock){ - NyLPC_iEthernetDevice_processTx(inst->_ethif); - } + //システムTxBufを得る + ethbuf=(struct TEthPacket*)NyLPC_cUipService_allocSysTxBuf(); //ARPパケットを作る。 - ethbuf=(struct TEthPacket*)(inst->stx.buf); NyLPC_TArpHeader_setArpRequest(&(ethbuf->data.arp),inst->_ref_config->ip_addr,&(inst->_ref_config->eth_mac),i_addr); tx_len=NyLPC_TEthernetIIHeader_setArpTx(&(ethbuf->header),&(inst->_ref_config->eth_mac)); //送信 - NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,&(inst->stx.h),tx_len); + p=((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)ethbuf)-1))-1; + + NyLPC_cMutex_lock(&(inst->_mutex)); + NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,p,tx_len); + NyLPC_iEthernetDevice_releaseTxBuf(inst->_ethif,p); + NyLPC_cMutex_unlock(&(inst->_mutex)); } @@ -410,30 +413,18 @@ NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; struct NyLPC_TTxBufferHeader* p=((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_eth_payload)-1))-1; NyLPC_cMutex_lock(&(inst->_mutex)); - //IPパケットの送信を試行 - if(!sendIPv4Tx(p)){ - //ARPリクエストを代わりに送信 - sendArpReqest(&((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr); + if(sendIPv4Tx(p)){ + NyLPC_cMutex_unlock(&(inst->_mutex)); + return; } NyLPC_cMutex_unlock(&(inst->_mutex)); + //ARPリクエストを代わりに送信 + NyLPC_cUipService_sendArpRequest(&((struct NyLPC_TIPv4Header*)i_eth_payload)->destipaddr); return; } - -/** - * 指定したIPアドレスに対してARPRequestを送信します。 - */ -void NyLPC_cUipService_sendArpRequest(const struct NyLPC_TIPv4Addr* i_addr) -{ - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - NyLPC_cMutex_lock(&(inst->_mutex)); - sendArpReqest(i_addr); - NyLPC_cMutex_unlock(&(inst->_mutex)); - return; -} - /** * ARPテーブルに指定したIPがあるかを返します。 */ @@ -443,21 +434,32 @@ return NyLPC_cIPv4Arp_IPv4toEthAddr(&inst->_arp,*i_addr)!=NULL; } +/** + * システム用の送信ペイロードを返します。 + * 関数は必ず成功します。 + */ +void* NyLPC_cUipService_allocSysTxBuf(void) +{ + NyLPC_TUInt16 s; + NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; + struct NyLPC_TTxBufferHeader* ethbuf; + //排他処理をして、メモリを取得する。SYSTEMメモリはEthernetドライバの解放待ちのみなのでまとめてLOCKしておk + NyLPC_cMutex_lock(&(inst->_mutex)); + for(;;){ + ethbuf=(struct NyLPC_TTxBufferHeader*)NyLPC_iEthernetDevice_allocTxBuf(inst->_ethif,NyLPC_TcEthernetMM_HINT_CTRL_PACKET,&s); + if(ethbuf==NULL){ + NyLPC_cThread_yield(); + continue; + } + break; + } + NyLPC_cMutex_unlock(&(inst->_mutex)); + //イーサネットバッファのアドレスを計算 + return &(((struct TEthPacket*)(ethbuf+1))->data); +} -/** - * 送信ペイロードメモリを返します。 - * この関数は、リエントラントを許容します。 - * @param i_hint - * 取得したいメモリサイズを指定します。(このサイズは、イーサネットヘッダのサイズを含みません。) - * このサイズよりも小さなサイズが割り当てられることがあります。 - * @param o_size - * イーサネットヘッダを除いたペイロード部分の長さ - * @return - * 成功:IPペイロードのためのメモリブロックを返します。/失敗:NULL - * 返されるメモリはブロックの[TEthPacket][payload]の構造で、[payload]のアドレスが返されます。 - */ void* NyLPC_cUipService_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size) { NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; @@ -497,11 +499,29 @@ /********** * イーサネットHWのコントロール関数 */ - +/** + * "IPv4パケットを格納した"イーサフレームを送信します。 + * コール前に、必ずロックしてから呼び出してください。 + *//* +static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf) +{ + NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; + NyLPC_TUInt16 s; + //送信する。 + s=NyLPC_htons(i_buf->data.ipv4.len16)+sizeof(struct NyLPC_TEthernetIIHeader); + memcpy(inst->stx.buf,i_buf,s); + if(!sendIPv4Tx(&(inst->stx.h))){ + //失敗した場合はARPリクエストに変換して再送 +//@todo unchecked PASS! + sendArpReqest(&i_buf->data.ipv4.destipaddr); + } + return; +}*/ /** * "IPv4パケットを格納した"イーサフレームを送信します。 * コール前に、必ずロックしてから呼び出してください。 */ +/* static void copyAndSendIPv4Tx(const struct TEthPacket* i_buf) { NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; @@ -520,35 +540,37 @@ } return; } - +*/ /** - * uipタスクが所有するTXバッファを使用してデータを送信します。 - * この関数は、i_bufをコピーします。 + * イーサネットフレームを送信します。 + * この関数はiptaskで実行される関数からのみ使用てください。 * @i_buf * イーサネットフレームを格納したメモリです。 * @i_len * イーサネットペイロードのサイズです。 */ -static void sendRawEthFrame(void* i_buf,NyLPC_TUInt16 i_len) +static void sendRawEthFrameNL(void* i_buf,NyLPC_TUInt16 i_len) { - NyLPC_TcUipService_t* inst=_NyLPC_TcUipService_inst; - - //ACK送信用の自己バッファが空くまで待つ - while(inst->stx.h.is_lock){ - NyLPC_iEthernetDevice_processTx(inst->_ethif); - } - //64バイトを超えるとかありえない。 - if(i_len+sizeof(struct NyLPC_TEthernetIIHeader)>NyLPC_TcUipService_SIZE_OF_REPLY_BUF){ - return; - } - //送信する。 - memcpy(inst->stx.buf,i_buf,i_len); - NyLPC_iEthernetDevice_sendTxEthFrame(inst->_ethif,&(inst->stx.h),i_len); + NyLPC_iEthernetDevice_sendTxEthFrame( + _NyLPC_TcUipService_inst->_ethif, + ((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_buf)-1))-1, + i_len); return; } - +/** + * ロック状態で使用できるreleaseTxBuf。 + * この関数はiptaskで実行される関数からのみ使用してください。 + */ +static void releaseTxBufNL(void* i_buf) +{ + //ペイロードの位置から、メモリブロックを再生。 + NyLPC_iEthernetDevice_releaseTxBuf( + _NyLPC_TcUipService_inst->_ethif, + ((struct NyLPC_TTxBufferHeader*)(((struct NyLPC_TEthernetIIHeader*)i_buf)-1))-1); + return; +} /** * マルチキャスとアドレスへ変換する。 */
--- a/core/uip/NyLPC_cUipService.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cUipService.h Thu May 29 14:29:15 2014 +0000 @@ -85,7 +85,7 @@ * mdns 256+96(MIN) * upnp 256+160(MIN) */ -#define NyLPC_TcUipService_config_STACK_SIZE (256+192) +#define NyLPC_TcUipService_config_STACK_SIZE (256+192+128) /** 登録できるリスナの最大数*/ #define NyLPC_TcUipService_config_MAX_LISTENER 4
--- a/core/uip/NyLPC_cUipService_protected.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_cUipService_protected.h Thu May 29 14:29:15 2014 +0000 @@ -38,7 +38,8 @@ extern "C" { #endif /* __cplusplus */ -#define NyLPC_TcUipService_SIZE_OF_REPLY_BUF 128 +//#define NyLPC_TcUipService_SIZE_OF_REPLY_BUF 128 + struct NyLPC_TcUipService @@ -57,12 +58,12 @@ /** (Ethernetメモリ排他制御用)*/ NyLPC_TcMutex_t _mutex; const struct TiEthernetDevice* _ethif; - /** ipタスクが使う小サイズ送信バッファ*/ - struct - { - struct NyLPC_TTxBufferHeader h; - NyLPC_TUInt8 buf[NyLPC_TcUipService_SIZE_OF_REPLY_BUF]; - }stx; +// /** ipタスクが使う小サイズ送信バッファ*/ +// struct +// { +// struct NyLPC_TTxBufferHeader h; +// NyLPC_TUInt8 buf[NyLPC_TcUipService_SIZE_OF_REPLY_BUF]; +// }stx; }; @@ -98,6 +99,11 @@ * cTcpSocketからコールする関数 **********************************************************************/ +/** + * NyLPC_cUipService_allocTxBufが返却するメモリサイズ。 + * + */ +#define NyLPC_cUipService_SYS_TX_BUF_SIZE (64-sizeof(struct NyLPC_TEthernetIIHeader)) /** @@ -124,6 +130,15 @@ void* NyLPC_cUipService_allocTxBuf(NyLPC_TUInt16 i_hint,NyLPC_TUInt16* o_size); /** + * システム用の小さな送信ペイロードメモリを返します。 + * この関数は、リエントラントを許容します。 + * 返却するメモリブロックのサイズが小さいこと、メモリが確実に返される点がNyLPC_cUipService_allocTxBufと異なります。 + * この関数が返すメモリのサイズは、NyLPC_cUipService_SYS_TX_BUF_SIZEの値です。 + * 関数を使用するコードでは開始時に1度だけNyLPC_cUipService_SYS_TX_BUF_SIZEの値を確認して下さい。 + */ +void* NyLPC_cUipService_allocSysTxBuf(void); + +/** * allocTxbufで確保したメモリを開放します。 */ void* NyLPC_cUipService_releaseTxBuf(void* i_buf);
--- a/core/uip/NyLPC_uip.c Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_uip.c Thu May 29 14:29:15 2014 +0000 @@ -234,6 +234,26 @@ // sum = chksum(sum, &uip_buf[UIP_IPH_LEN + UIP_LLH_LEN], i_len_of_data); return (sum == 0) ? 0xffff : NyLPC_htons(sum); } + +static NyLPC_TUInt16 pid=0x3939; +/** + * IPヘッダを送信パケット用に設定する。 + * ipid16にはコールされるたびに新しい値を設定する。 + * ipcecksumには0を設定する。 + * この関数は、パケットサイズ,ローカルIP/リモートIPの設定はしない。 + */ +void NyLPC_TIPv4Header_writeTxIpHeader( + struct NyLPC_TIPv4Header* i_struct, + NyLPC_TUInt8 i_proto) +{ + //IPパケットのセット + i_struct->proto=i_proto; + i_struct->ttl = UIP_DEFAULT_IP_TTL; + i_struct->tos = 0; + i_struct->ipid16=(pid++); + i_struct->ipoffset=0;//NyLPC_HTONS(0|0x4000); + i_struct->ipchksum = 0; +} /*-------------------------------------------------------------------------------- * * struct NyLPC_TIPv6Header
--- a/core/uip/NyLPC_uip.h Thu May 22 12:59:50 2014 +0000 +++ b/core/uip/NyLPC_uip.h Thu May 29 14:29:15 2014 +0000 @@ -256,12 +256,21 @@ /** * IPヘッダの長さを返す。 */ -#define NyLPC_TIPv4Header_getHeaderLength(i_iph) ((i_iph->vhl & 0x0f)*4) +#define NyLPC_TIPv4Header_getHeaderLength(i_iph) (((i_iph)->vhl & 0x0f)*4) /** * IPパケット全体の長さを返す。 */ #define NyLPC_TIPv4Header_getPacketLength(i_iph) (NyLPC_ntohs((i_iph)->len16)) +/** + * IPヘッダを送信パケット用に設定する。 + * ipid16にはコールされるたびに新しい値を設定する。 + * ipcecksumには0を設定する。 + * この関数は、パケットサイズ,ローカルIP/リモートIPの設定はしない。 + */ +void NyLPC_TIPv4Header_writeTxIpHeader( + struct NyLPC_TIPv4Header* i_struct, + NyLPC_TUInt8 i_proto); /********************************************************************** * * struct NyLPC_TIPv6Header
--- a/mbed/LocalFileSystem2.cpp Thu May 22 12:59:50 2014 +0000 +++ b/mbed/LocalFileSystem2.cpp Thu May 29 14:29:15 2014 +0000 @@ -2,6 +2,7 @@ #include "utils/PlatformInfo.h" namespace MiMic { +#ifdef TARGET_LPC1768 /** * This module is LocalFileSystem class which is not stopped on LPCXpresso. * It uses instead of LocalFileSystem. @@ -22,6 +23,7 @@ { return this->_is_enable?LocalFileSystem::opendir(name):NULL; } +#else + +#endif } - -
--- a/mbed/LocalFileSystem2.h Thu May 22 12:59:50 2014 +0000 +++ b/mbed/LocalFileSystem2.h Thu May 29 14:29:15 2014 +0000 @@ -2,12 +2,14 @@ #include "mbed.h" - -namespace MiMic { +#include "FATFileSystem.h" +namespace MiMic +{ /** * This module is LocalFileSystem class which is not stopped on LPCXpresso. * It uses instead of LocalFileSystem. */ +#ifdef TARGET_LPC1768 class LocalFileSystem2 : public LocalFileSystem { private: @@ -18,5 +20,13 @@ virtual int remove(const char *filename); virtual DirHandle *opendir(const char *name); }; +#else + class LocalFileSystem2 : public FileSystemLike + { + public: + LocalFileSystem2(const char* n):FileSystemLike(n){} + virtual FileHandle *open(const char *filename, int flags){return NULL;} + }; +#endif }