提交 3b5c2e2f 编写于 作者: B bernard

Merge branch 'master' of https://github.com/RT-Thread/rt-thread

......@@ -19,65 +19,78 @@ static struct rt_device sdcard_device;
static struct dfs_partition part;
/* Local Function Prototypes */
static bool LPC17xx_SD_Init (void);
static uint8_t LPC17xx_SD_SendCmd (uint8_t cmd, uint32_t arg);
static bool LPC17xx_SD_ReadSector (uint32_t sector, uint8_t *buff, uint32_t count);
static bool LPC17xx_SD_ReadDataBlock ( uint8_t *buff, uint32_t cnt);
static bool LPC17xx_SD_WriteSector (uint32_t sector, const uint8_t *buff, uint32_t count);
static bool LPC17xx_SD_WirteDataBlock (const uint8_t *buff, uint8_t token);
static bool LPC17xx_SD_ReadCfg (SDCFG *cfg);
static bool LPC17xx_SD_WaitForReady (void);
static bool LPC17xx_SD_Init(void);
static uint8_t LPC17xx_SD_SendCmd(uint8_t cmd, uint32_t arg);
static bool LPC17xx_SD_ReadSector(uint32_t sector, uint8_t *buff, uint32_t count);
static bool LPC17xx_SD_ReadDataBlock(uint8_t *buff, uint32_t cnt);
static bool LPC17xx_SD_WriteSector(uint32_t sector, const uint8_t *buff, uint32_t count);
static bool LPC17xx_SD_WirteDataBlock(const uint8_t *buff, uint8_t token);
static bool LPC17xx_SD_ReadCfg(SDCFG *cfg);
static bool LPC17xx_SD_WaitForReady(void);
/* wait until the card is not busy */
static bool LPC17xx_SD_WaitForReady (void)
static bool LPC17xx_SD_WaitForReady(void)
{
uint8_t res;
/* timeout should be large enough to make sure the write operaion can be completed. */
uint32_t timeout = 400000;
LPC17xx_SPI_SendByte(0xFF);
do {
do
{
res = LPC17xx_SPI_RecvByte();
} while ((res != 0xFF) && timeout--);
}
while ((res != 0xFF) && timeout--);
return (res == 0xFF ? true : false);
}
/* Initialize SD/MMC card. */
static bool LPC17xx_SD_Init (void)
static bool LPC17xx_SD_Init(void)
{
uint32_t i, timeout;
uint8_t cmd, ct, ocr[4];
bool ret = false;
/* Initialize SPI interface and enable Flash Card SPI mode. */
LPC17xx_SPI_Init ();
LPC17xx_SPI_Init();
/* At least 74 clock cycles are required prior to starting bus communication */
for (i = 0; i < 80; i++) { /* 80 dummy clocks */
LPC17xx_SPI_SendByte (0xFF);
for (i = 0; i < 80; i++) /* 80 dummy clocks */
{
LPC17xx_SPI_SendByte(0xFF);
}
ct = CT_NONE;
if (LPC17xx_SD_SendCmd (GO_IDLE_STATE, 0) == 0x1)
if (LPC17xx_SD_SendCmd(GO_IDLE_STATE, 0) == 0x1)
{
timeout = 50000;
if (LPC17xx_SD_SendCmd(CMD8, 0x1AA) == 1) { /* SDHC */
if (LPC17xx_SD_SendCmd(CMD8, 0x1AA) == 1) /* SDHC */
{
/* Get trailing return value of R7 resp */
for (i = 0; i < 4; i++) ocr[i] = LPC17xx_SPI_RecvByte();
if (ocr[2] == 0x01 && ocr[3] == 0xAA) { /* The card can work at vdd range of 2.7-3.6V */
if (ocr[2] == 0x01 && ocr[3] == 0xAA) /* The card can work at vdd range of 2.7-3.6V */
{
/* Wait for leaving idle state (ACMD41 with HCS bit) */
while (timeout-- && LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 1UL << 30));
/* Check CCS bit in the OCR */
if (timeout && LPC17xx_SD_SendCmd(READ_OCR, 0) == 0) {
if (timeout && LPC17xx_SD_SendCmd(READ_OCR, 0) == 0)
{
for (i = 0; i < 4; i++) ocr[i] = LPC17xx_SPI_RecvByte();
ct = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;
}
} else { /* SDSC or MMC */
if (LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 0) <= 1) {
ct = CT_SD1; cmd = SD_SEND_OP_COND; /* SDSC */
} else {
ct = CT_MMC; cmd = SEND_OP_COND; /* MMC */
}
else /* SDSC or MMC */
{
if (LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 0) <= 1)
{
ct = CT_SD1;
cmd = SD_SEND_OP_COND; /* SDSC */
}
else
{
ct = CT_MMC;
cmd = SEND_OP_COND; /* MMC */
}
/* Wait for leaving idle state */
while (timeout-- && LPC17xx_SD_SendCmd(cmd, 0));
......@@ -86,11 +99,17 @@ static bool LPC17xx_SD_Init (void)
ct = CT_NONE;
}
}
else { /* SDSC or MMC */
if (LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 0) <= 1) {
ct = CT_SD1; cmd = SD_SEND_OP_COND; /* SDSC */
} else {
ct = CT_MMC; cmd = SEND_OP_COND; /* MMC */
else /* SDSC or MMC */
{
if (LPC17xx_SD_SendCmd(SD_SEND_OP_COND, 0) <= 1)
{
ct = CT_SD1;
cmd = SD_SEND_OP_COND; /* SDSC */
}
else
{
ct = CT_MMC;
cmd = SEND_OP_COND; /* MMC */
}
/* Wait for leaving idle state */
while (timeout-- && LPC17xx_SD_SendCmd(cmd, 0));
......@@ -102,16 +121,22 @@ static bool LPC17xx_SD_Init (void)
CardType = ct;
LPC17xx_SPI_Release();
if (ct) { /* Initialization succeeded */
if (ct) /* Initialization succeeded */
{
ret = true;
if ( ct == CT_MMC ) {
if (ct == CT_MMC)
{
LPC17xx_SPI_SetSpeed(SPI_SPEED_20MHz);
} else {
}
else
{
LPC17xx_SPI_SetSpeed(SPI_SPEED_20MHz);
}
} else { /* Initialization failed */
LPC17xx_SPI_Select ();
LPC17xx_SD_WaitForReady ();
}
else /* Initialization failed */
{
LPC17xx_SPI_Select();
LPC17xx_SD_WaitForReady();
LPC17xx_SPI_DeInit();
}
......@@ -124,11 +149,12 @@ static bool LPC17xx_SD_Init (void)
arg: argument for the cmd
return the received response of the commond
*****************************************************************************/
static uint8_t LPC17xx_SD_SendCmd (uint8_t cmd, uint32_t arg)
static uint8_t LPC17xx_SD_SendCmd(uint8_t cmd, uint32_t arg)
{
uint32_t r1, n;
if (cmd & 0x80) { /* ACMD<n> is the command sequence of CMD55-CMD<n> */
if (cmd & 0x80) /* ACMD<n> is the command sequence of CMD55-CMD<n> */
{
cmd &= 0x7F;
r1 = LPC17xx_SD_SendCmd(APP_CMD, 0); /* CMD55 */
if (r1 > 1) return r1; /* cmd send failed */
......@@ -137,26 +163,28 @@ static uint8_t LPC17xx_SD_SendCmd (uint8_t cmd, uint32_t arg)
/* Select the card and wait for ready */
LPC17xx_SPI_DeSelect();
LPC17xx_SPI_Select();
if (LPC17xx_SD_WaitForReady() == false ) return 0xFF;
LPC17xx_SPI_SendByte (0xFF); /* prepare 8 clocks */
LPC17xx_SPI_SendByte (cmd);
LPC17xx_SPI_SendByte (arg >> 24);
LPC17xx_SPI_SendByte (arg >> 16);
LPC17xx_SPI_SendByte (arg >> 8);
LPC17xx_SPI_SendByte (arg);
if (LPC17xx_SD_WaitForReady() == false) return 0xFF;
LPC17xx_SPI_SendByte(0xFF); /* prepare 8 clocks */
LPC17xx_SPI_SendByte(cmd);
LPC17xx_SPI_SendByte(arg >> 24);
LPC17xx_SPI_SendByte(arg >> 16);
LPC17xx_SPI_SendByte(arg >> 8);
LPC17xx_SPI_SendByte(arg);
/* Checksum, should only be valid for the first command.CMD0 */
n = 0x01; /* Dummy CRC + Stop */
if (cmd == GO_IDLE_STATE) n = 0x95; /* Valid CRC for CMD0(0) */
if (cmd == CMD8) n = 0x87; /* Valid CRC for CMD8(0x1AA) */
LPC17xx_SPI_SendByte(n);
if (cmd == STOP_TRAN) LPC17xx_SPI_RecvByte (); /* Skip a stuff byte when stop reading */
if (cmd == STOP_TRAN) LPC17xx_SPI_RecvByte(); /* Skip a stuff byte when stop reading */
n = 10; /* Wait for a valid response in timeout of 10 attempts */
do {
r1 = LPC17xx_SPI_RecvByte ();
} while ((r1 & 0x80) && --n);
do
{
r1 = LPC17xx_SPI_RecvByte();
}
while ((r1 & 0x80) && --n);
return (r1); /* Return with the response value */
}
......@@ -166,21 +194,27 @@ static uint8_t LPC17xx_SD_SendCmd (uint8_t cmd, uint32_t arg)
buff <- [sector, sector+1, ... sector+count-1]
if success, return true, otherwise return false
*****************************************************************************/
static bool LPC17xx_SD_ReadSector (uint32_t sector, uint8_t *buff, uint32_t count)
static bool LPC17xx_SD_ReadSector(uint32_t sector, uint8_t *buff, uint32_t count)
{
/* Convert to byte address if needed */
if (!(CardType & CT_BLOCK)) sector *= SD_SECTOR_SIZE;
if (count == 1) { /* Single block read */
if (count == 1) /* Single block read */
{
if ((LPC17xx_SD_SendCmd(READ_BLOCK, sector) == 0)
&& LPC17xx_SD_ReadDataBlock(buff, SD_SECTOR_SIZE))
count = 0;
} else { /* Multiple block read */
if (LPC17xx_SD_SendCmd(READ_MULT_BLOCK, sector) == 0) {
do {
}
else /* Multiple block read */
{
if (LPC17xx_SD_SendCmd(READ_MULT_BLOCK, sector) == 0)
{
do
{
if (!LPC17xx_SD_ReadDataBlock(buff, SD_SECTOR_SIZE)) break;
buff += SD_SECTOR_SIZE;
} while (--count);
}
while (--count);
LPC17xx_SD_SendCmd(STOP_TRAN, 0); /* STOP_TRANSMISSION */
}
}
......@@ -194,29 +228,33 @@ static bool LPC17xx_SD_ReadSector (uint32_t sector, uint8_t *buff, uint32_t coun
buff: Data buffer to store received data
cnt: Byte count (must be multiple of 4, normally 512)
*****************************************************************************/
static bool LPC17xx_SD_ReadDataBlock ( uint8_t *buff, uint32_t cnt)
static bool LPC17xx_SD_ReadDataBlock(uint8_t *buff, uint32_t cnt)
{
uint8_t token;
uint32_t timeout;
timeout = 20000;
do { /* Wait for data packet in timeout of 100ms */
do /* Wait for data packet in timeout of 100ms */
{
token = LPC17xx_SPI_RecvByte();
} while ((token == 0xFF) && timeout--);
if(token != 0xFE) return false; /* If not valid data token, return with error */
}
while ((token == 0xFF) && timeout--);
if (token != 0xFE) return false; /* If not valid data token, return with error */
#if USE_FIFO
LPC17xx_SPI_RecvBlock_FIFO (buff, cnt);
LPC17xx_SPI_RecvBlock_FIFO(buff, cnt);
#else
do { /* Receive the data block into buffer */
*buff++ = LPC17xx_SPI_RecvByte ();
*buff++ = LPC17xx_SPI_RecvByte ();
*buff++ = LPC17xx_SPI_RecvByte ();
*buff++ = LPC17xx_SPI_RecvByte ();
} while (cnt -= 4);
do /* Receive the data block into buffer */
{
*buff++ = LPC17xx_SPI_RecvByte();
*buff++ = LPC17xx_SPI_RecvByte();
*buff++ = LPC17xx_SPI_RecvByte();
*buff++ = LPC17xx_SPI_RecvByte();
}
while (cnt -= 4);
#endif /* USE_FIFO */
LPC17xx_SPI_RecvByte (); /* Discard CRC */
LPC17xx_SPI_RecvByte ();
LPC17xx_SPI_RecvByte(); /* Discard CRC */
LPC17xx_SPI_RecvByte();
return true; /* Return with success */
}
......@@ -226,27 +264,33 @@ static bool LPC17xx_SD_ReadDataBlock ( uint8_t *buff, uint32_t cnt)
buff -> [sector, sector+1, ... sector+count-1]
if success, return true, otherwise return false
*****************************************************************************/
static bool LPC17xx_SD_WriteSector (uint32_t sector, const uint8_t *buff, uint32_t count)
static bool LPC17xx_SD_WriteSector(uint32_t sector, const uint8_t *buff, uint32_t count)
{
if (!(CardType & CT_BLOCK)) sector *= 512; /* Convert to byte address if needed */
if (count == 1) { /* Single block write */
if (count == 1) /* Single block write */
{
if ((LPC17xx_SD_SendCmd(WRITE_BLOCK, sector) == 0)
&& LPC17xx_SD_WirteDataBlock(buff, TOKEN_SINGLE_BLOCK))
count = 0;
} else { /* Multiple block write */
}
else /* Multiple block write */
{
if (CardType & CT_SDC) LPC17xx_SD_SendCmd(SET_WR_BLK_ERASE_COUNT, count);
if (LPC17xx_SD_SendCmd(WRITE_MULT_BLOCK, sector) == 0) {
do {
if (LPC17xx_SD_SendCmd(WRITE_MULT_BLOCK, sector) == 0)
{
do
{
if (!LPC17xx_SD_WirteDataBlock(buff, TOKEN_MULTI_BLOCK)) break;
buff += 512;
} while (--count);
#if 1
}
while (--count);
#if 1
if (!LPC17xx_SD_WirteDataBlock(0, TOKEN_STOP_TRAN)) /* STOP_TRAN token */
count = 1;
#else
#else
LPC17xx_SPI_SendByte(TOKEN_STOP_TRAN);
#endif
#endif
}
}
LPC17xx_SPI_Release();
......@@ -260,24 +304,26 @@ static bool LPC17xx_SD_WriteSector (uint32_t sector, const uint8_t *buff, uint32
0xFC -> multi block
0xFD -> Stop
*****************************************************************************/
static bool LPC17xx_SD_WirteDataBlock (const uint8_t *buff, uint8_t token)
static bool LPC17xx_SD_WirteDataBlock(const uint8_t *buff, uint8_t token)
{
uint8_t resp, i;
i = i; // avoid warning
LPC17xx_SPI_SendByte (token); /* send data token first*/
LPC17xx_SPI_SendByte(token); /* send data token first*/
if (token != TOKEN_STOP_TRAN) {
if (token != TOKEN_STOP_TRAN)
{
#if USE_FIFO
LPC17xx_SPI_SendBlock_FIFO (buff);
LPC17xx_SPI_SendBlock_FIFO(buff);
#else
/* Send data. */
for (i = 512/4; i ; i--) {
LPC17xx_SPI_SendByte (*buff++);
LPC17xx_SPI_SendByte (*buff++);
LPC17xx_SPI_SendByte (*buff++);
LPC17xx_SPI_SendByte (*buff++);
for (i = 512 / 4; i ; i--)
{
LPC17xx_SPI_SendByte(*buff++);
LPC17xx_SPI_SendByte(*buff++);
LPC17xx_SPI_SendByte(*buff++);
LPC17xx_SPI_SendByte(*buff++);
}
#endif /* USE_FIFO */
LPC17xx_SPI_SendByte(0xFF); /* 16-bit CRC (Dummy) */
......@@ -287,7 +333,7 @@ static bool LPC17xx_SD_WirteDataBlock (const uint8_t *buff, uint8_t token)
if ((resp & 0x1F) != 0x05) /* If not accepted, return with error */
return false;
if ( LPC17xx_SD_WaitForReady() == false) /* Wait while Flash Card is busy. */
if (LPC17xx_SD_WaitForReady() == false) /* Wait while Flash Card is busy. */
return false;
}
......@@ -295,7 +341,7 @@ static bool LPC17xx_SD_WirteDataBlock (const uint8_t *buff, uint8_t token)
}
/* Read MMC/SD Card device configuration. */
static bool LPC17xx_SD_ReadCfg (SDCFG *cfg)
static bool LPC17xx_SD_ReadCfg(SDCFG *cfg)
{
uint8_t i;
uint16_t csize;
......@@ -303,26 +349,29 @@ static bool LPC17xx_SD_ReadCfg (SDCFG *cfg)
bool retv = false;
/* Read the OCR - Operations Condition Register. */
if (LPC17xx_SD_SendCmd (READ_OCR, 0) != 0x00) goto x;
for (i = 0; i < 4; i++) cfg->ocr[i] = LPC17xx_SPI_RecvByte ();
if (LPC17xx_SD_SendCmd(READ_OCR, 0) != 0x00) goto x;
for (i = 0; i < 4; i++) cfg->ocr[i] = LPC17xx_SPI_RecvByte();
/* Read the CID - Card Identification. */
if ((LPC17xx_SD_SendCmd (SEND_CID, 0) != 0x00) ||
(LPC17xx_SD_ReadDataBlock (cfg->cid, 16) == false))
if ((LPC17xx_SD_SendCmd(SEND_CID, 0) != 0x00) ||
(LPC17xx_SD_ReadDataBlock(cfg->cid, 16) == false))
goto x;
/* Read the CSD - Card Specific Data. */
if ((LPC17xx_SD_SendCmd (SEND_CSD, 0) != 0x00) ||
(LPC17xx_SD_ReadDataBlock (cfg->csd, 16) == false))
if ((LPC17xx_SD_SendCmd(SEND_CSD, 0) != 0x00) ||
(LPC17xx_SD_ReadDataBlock(cfg->csd, 16) == false))
goto x;
cfg -> sectorsize = SD_SECTOR_SIZE;
/* Get number of sectors on the disk (DWORD) */
if ((cfg->csd[0] >> 6) == 1) { /* SDC ver 2.00 */
if ((cfg->csd[0] >> 6) == 1) /* SDC ver 2.00 */
{
csize = cfg->csd[9] + ((uint16_t)cfg->csd[8] << 8) + 1;
cfg -> sectorcnt = (uint32_t)csize << 10;
} else { /* SDC ver 1.XX or MMC*/
}
else /* SDC ver 1.XX or MMC*/
{
n = (cfg->csd[5] & 15) + ((cfg->csd[10] & 128) >> 7) + ((cfg->csd[9] & 3) << 1) + 2; // 19
csize = (cfg->csd[8] >> 6) + ((uint16_t)cfg->csd[7] << 2) + ((uint16_t)(cfg->csd[6] & 3) << 10) + 1; // 3752
cfg -> sectorcnt = (uint32_t)csize << (n - 9); // 3842048
......@@ -331,20 +380,29 @@ static bool LPC17xx_SD_ReadCfg (SDCFG *cfg)
cfg->size = cfg -> sectorcnt * cfg -> sectorsize; // 512*3842048=1967128576Byte (1.83GB)
/* Get erase block size in unit of sector (DWORD) */
if (CardType & CT_SD2) { /* SDC ver 2.00 */
if (LPC17xx_SD_SendCmd(SD_STATUS /*ACMD13*/, 0) == 0) { /* Read SD status */
if (CardType & CT_SD2) /* SDC ver 2.00 */
{
if (LPC17xx_SD_SendCmd(SD_STATUS /*ACMD13*/, 0) == 0) /* Read SD status */
{
LPC17xx_SPI_RecvByte();
if (LPC17xx_SD_ReadDataBlock(csd, 16)) { /* Read partial block */
if (LPC17xx_SD_ReadDataBlock(csd, 16)) /* Read partial block */
{
for (n = 64 - 16; n; n--) LPC17xx_SPI_RecvByte(); /* Purge trailing data */
cfg->blocksize = 16UL << (csd[10] >> 4);
retv = true;
}
}
} else { /* SDC ver 1.XX or MMC */
if ((LPC17xx_SD_SendCmd(SEND_CSD, 0) == 0) && LPC17xx_SD_ReadDataBlock(csd, 16)) { /* Read CSD */
if (CardType & CT_SD1) { /* SDC ver 1.XX */
}
else /* SDC ver 1.XX or MMC */
{
if ((LPC17xx_SD_SendCmd(SEND_CSD, 0) == 0) && LPC17xx_SD_ReadDataBlock(csd, 16)) /* Read CSD */
{
if (CardType & CT_SD1) /* SDC ver 1.XX */
{
cfg->blocksize = (((csd[10] & 63) << 1) + ((uint16_t)(csd[11] & 128) >> 7) + 1) << ((csd[13] >> 6) - 1);
} else { /* MMC */
}
else /* MMC */
{
// cfg->blocksize = ((uint16_t)((buf[10] & 124) >> 2) + 1) * (((buf[11] & 3) << 3) + ((buf[11] & 224) >> 5) + 1);
cfg->blocksize = ((uint16_t)((cfg->csd[10] & 124) >> 2) + 1) * (((cfg->csd[10] & 3) << 3) + ((cfg->csd[11] & 224) >> 5) + 1);
}
......@@ -352,7 +410,8 @@ static bool LPC17xx_SD_ReadCfg (SDCFG *cfg)
}
}
x: LPC17xx_SPI_Release();
x:
LPC17xx_SPI_Release();
return (retv);
}
......@@ -371,7 +430,7 @@ static rt_err_t rt_sdcard_close(rt_device_t dev)
return RT_EOK;
}
static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size)
static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size)
{
bool status;
......@@ -383,7 +442,7 @@ static rt_size_t rt_sdcard_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_
return 0;
}
static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size)
static rt_size_t rt_sdcard_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
{
bool status;
......@@ -397,6 +456,18 @@ static rt_size_t rt_sdcard_write (rt_device_t dev, rt_off_t pos, const void* buf
static rt_err_t rt_sdcard_control(rt_device_t dev, rt_uint8_t cmd, void *args)
{
if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME)
{
struct rt_device_blk_geometry *geometry;
geometry = (struct rt_device_blk_geometry *)args;
if (geometry == RT_NULL) return -RT_ERROR;
geometry->bytes_per_sector = SDCfg.sectorsize;
geometry->block_size = SDCfg.blocksize;
geometry->sector_count = SDCfg.sectorcnt;
}
return RT_EOK;
}
......@@ -408,7 +479,7 @@ void rt_hw_sdcard_init()
rt_uint8_t *sector;
/* get the first sector to read partition table */
sector = (rt_uint8_t*) rt_malloc (512);
sector = (rt_uint8_t *) rt_malloc(512);
if (sector == RT_NULL)
{
rt_kprintf("allocate partition sector buffer failed\n");
......
......@@ -31,7 +31,8 @@
#define CT_BLOCK 0x08
/* MMC device configuration */
typedef struct tagSDCFG{
typedef struct tagSDCFG
{
uint32_t sernum; // serial number
uint32_t size; // size=sectorsize*sectorcnt
uint32_t sectorcnt; //
......
......@@ -431,14 +431,16 @@ static rt_size_t rt_serial_write(struct rt_device *dev,
if (dev->open_flag & RT_DEVICE_FLAG_INT_TX)
{
_serial_int_tx(serial, buffer, size);
return _serial_int_tx(serial, buffer, size);
}
else if (dev->open_flag & RT_DEVICE_FLAG_DMA_TX)
{
_serial_dma_tx(serial, buffer, size);
return _serial_dma_tx(serial, buffer, size);
}
else
{
return _serial_poll_tx(serial, buffer, size);
}
}
static rt_err_t rt_serial_control(struct rt_device *dev,
......
......@@ -2,7 +2,7 @@ from building import *
cwd = GetCurrentDir()
src = ['spi_core.c', 'spi_dev.c']
CPPPATH = [cwd + '/../include']
CPPPATH = [cwd, cwd + '/../include']
src_device = []
......
......@@ -35,7 +35,7 @@
#define SSID_NAME "AP_SSID"
#define SSID_PASSWORD "AP_passwd"
//#define WIFI_DEBUG_ON
// #define WIFI_DEBUG_ON
// #define ETH_RX_DUMP
// #define ETH_TX_DUMP
......@@ -64,8 +64,8 @@ struct spi_wifi_eth
struct rt_mailbox spi_tx_mb;
struct rt_mailbox eth_rx_mb;
int spi_tx_mb_pool[SPI_TX_POOL_SIZE];
int eth_rx_mb_pool[SPI_TX_POOL_SIZE];
int spi_tx_mb_pool[SPI_TX_POOL_SIZE + 1];
int eth_rx_mb_pool[SPI_RX_POOL_SIZE + 1];
int spi_wifi_cmd_mb_pool[3];
struct rt_mailbox spi_wifi_cmd_mb;
......@@ -73,7 +73,7 @@ struct spi_wifi_eth
ALIGN(4)
rt_uint8_t spi_tx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_TX_POOL_SIZE];
ALIGN(4)
rt_uint8_t spi_rx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_TX_POOL_SIZE];
rt_uint8_t spi_rx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_RX_POOL_SIZE];
ALIGN(4)
uint8_t spi_hw_rx_buffer[MAX_BUFFER_SIZE];
......@@ -176,9 +176,9 @@ static rt_err_t spi_wifi_transfer(struct spi_wifi_eth *dev)
if (resp.S2M_len)
{
WIFI_DEBUG("resp.S2M_len: %d\n", resp.S2M_len);
if (resp.S2M_len > sizeof(struct spi_data_packet))
if (resp.S2M_len > MAX_SPI_PACKET_SIZE)
{
WIFI_DEBUG("resp.S2M_len > sizeof(struct spi_data_packet), drop!\n");
WIFI_DEBUG("resp.S2M_len %d > %d(MAX_SPI_PACKET_SIZE), drop!\n", resp.S2M_len, MAX_SPI_PACKET_SIZE);
resp.S2M_len = 0;//drop
}
......@@ -211,7 +211,7 @@ _bad_resp_magic:
rt_mp_free((void *)data_packet);
}
if ((resp.S2M_len) && (resp.S2M_len <= MAX_DATA_LEN))
if ((resp.S2M_len) && (resp.S2M_len <= MAX_SPI_PACKET_SIZE))
{
data_packet = (struct spi_data_packet *)wifi_device->spi_hw_rx_buffer;
if (data_packet->data_type == data_type_eth_data)
......@@ -258,24 +258,33 @@ _bad_resp_magic:
#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP)
static void packet_dump(const char *msg, const struct pbuf *p)
{
rt_uint32_t i;
const struct pbuf* q;
rt_uint32_t i,j;
rt_uint8_t *ptr = p->payload;
rt_kprintf("%s %d byte\n", msg, p->tot_len);
for (i = 0; i < p->tot_len; i++)
i=0;
for(q=p; q != RT_NULL; q= q->next)
{
if ((i % 8) == 0)
ptr = q->payload;
for(j=0; j<q->len; j++)
{
if( (i%8) == 0 )
{
rt_kprintf(" ");
}
if ((i % 16) == 0)
if( (i%16) == 0 )
{
rt_kprintf("\r\n");
}
rt_kprintf("%02x ", *ptr);
rt_kprintf("%02x ",*ptr);
i++;
ptr++;
}
}
rt_kprintf("\n\n");
}
#endif /* dump */
......@@ -377,7 +386,7 @@ static rt_err_t spi_wifi_eth_control(rt_device_t dev, rt_uint8_t cmd, void *args
strncpy(cmd_join->ssid, SSID_NAME, SSID_NAME_LENGTH_MAX);
strncpy(cmd_join->passwd, SSID_PASSWORD, PASSWORD_LENGTH_MAX);
cmd_join->security = WPA2_SECURITY | TKIP_ENABLED | AES_ENABLED;
cmd_join->security = WPA_SECURITY | TKIP_ENABLED | AES_ENABLED;
// cmd_join->security = WPA_SECURITY | TKIP_ENABLED;
data_packet->data_type = data_type_cmd;
data_packet->data_len = sizeof(struct cmd_join) + member_offset(struct spi_wifi_cmd, buffer);
......@@ -418,7 +427,7 @@ rt_err_t spi_wifi_eth_tx(rt_device_t dev, struct pbuf *p)
pbuf_copy_partial(p, data_packet->buffer, data_packet->data_len, 0);
rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet);
eth_device_ready((struct eth_device *)dev);
rt_event_send(&spi_wifi_data_event, 1);
}
else
return -RT_ERROR;
......@@ -442,7 +451,10 @@ struct pbuf *spi_wifi_eth_rx(rt_device_t dev)
return RT_NULL;
}
#ifdef ETH_RX_DUMP
if(p)
packet_dump("RX dump", p);
#endif /* ETH_RX_DUMP */
return p;
}
......@@ -489,8 +501,8 @@ rt_err_t rt_hw_wifi_init(const char *spi_device_name)
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0 and Mode 3 */
cfg.max_hz = 1000000; /* 50M */
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
cfg.max_hz = 15 * 1000000; /* 30M */
rt_spi_configure(spi_wifi_device.rt_spi_device, &cfg);
}
......
......@@ -57,6 +57,7 @@ struct response
/* spi slave configure. */
#define MAX_DATA_LEN 1520
#define SPI_TX_POOL_SIZE 2
#define SPI_RX_POOL_SIZE 2
// align check
#if (MAX_DATA_LEN & 0x03) != 0
......@@ -78,6 +79,16 @@ struct spi_data_packet
char buffer[MAX_DATA_LEN];
};
/* tools */
#define node_entry(node, type, member) \
((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
#define member_offset(type, member) \
((unsigned long)(&((type *)0)->member))
#define MAX_SPI_PACKET_SIZE (member_offset(struct spi_data_packet, buffer) + MAX_DATA_LEN)
/********************************* RW009 **************************************/
struct spi_wifi_cmd
{
uint32_t cmd;
......@@ -99,12 +110,6 @@ extern void spi_wifi_hw_init(void);
extern void spi_wifi_int_cmd(rt_bool_t cmd);
extern rt_bool_t spi_wifi_is_busy(void);
/* tools */
#define node_entry(node, type, member) \
((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
#define member_offset(type, member) \
((unsigned long)(&((type *)0)->member))
#define SSID_NAME_LENGTH_MAX (32)
#define PASSWORD_LENGTH_MAX (32)
......@@ -119,5 +124,4 @@ struct cmd_join
uint32_t security;
};
#endif // SPI_WIFI_H_INCLUDED
......@@ -119,7 +119,7 @@ void finsh_set_device(const char* device_name)
{
/* close old finsh device */
rt_device_close(shell->device);
rt_device_set_rx_indicate(dev, RT_NULL);
rt_device_set_rx_indicate(shell->device, RT_NULL);
}
shell->device = dev;
......
......@@ -43,4 +43,6 @@ typedef unsigned long long uint64_t;
#define LONG_MIN (-LONG_MAX - 1)
#define ULONG_MAX (~0UL)
#define SIZE_MAX ULONG_MAX
#endif
......@@ -7,7 +7,7 @@ objs = []
list = os.listdir(os.path.join(RTT_ROOT, 'components', 'net'))
# the default version of LWIP is 1.4.1
if not GetDepend('RT_USING_LWIP132') and not GetDepend('RT_USING_LWIP140'):
if not GetDepend('RT_USING_LWIP132') and not GetDepend('RT_USING_LWIP140') and not GetDepend('RT_USING_LWIP_HEAD'):
AddDepend('RT_USING_LWIP141')
for d in list:
......
此差异已折叠。
/*
* Copyright (c) 2001, 2002 Swedish Institute of Computer Science.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
src/ - The source code for the lwIP TCP/IP stack.
doc/ - The documentation for lwIP.
See also the FILES file in each subdirectory.
INTRODUCTION
lwIP is a small independent implementation of the TCP/IP protocol
suite that has been developed by Adam Dunkels at the Computer and
Networks Architectures (CNA) lab at the Swedish Institute of Computer
Science (SICS).
The focus of the lwIP TCP/IP implementation is to reduce the RAM usage
while still having a full scale TCP. This making lwIP suitable for use
in embedded systems with tens of kilobytes of free RAM and room for
around 40 kilobytes of code ROM.
FEATURES
* IP (Internet Protocol) including packet forwarding over multiple network
interfaces
* ICMP (Internet Control Message Protocol) for network maintenance and debugging
* IGMP (Internet Group Management Protocol) for multicast traffic management
* UDP (User Datagram Protocol) including experimental UDP-lite extensions
* TCP (Transmission Control Protocol) with congestion control, RTT estimation
and fast recovery/fast retransmit
* Specialized raw/native API for enhanced performance
* Optional Berkeley-like socket API
* DNS (Domain names resolver)
* SNMP (Simple Network Management Protocol)
* DHCP (Dynamic Host Configuration Protocol)
* AUTOIP (for IPv4, conform with RFC 3927)
* PPP (Point-to-Point Protocol)
* ARP (Address Resolution Protocol) for Ethernet
LICENSE
lwIP is freely available under a BSD license.
DEVELOPMENT
lwIP has grown into an excellent TCP/IP stack for embedded devices,
and developers using the stack often submit bug fixes, improvements,
and additions to the stack to further increase its usefulness.
Development of lwIP is hosted on Savannah, a central point for
software development, maintenance and distribution. Everyone can
help improve lwIP by use of Savannah's interface, CVS and the
mailing list. A core team of developers will commit changes to the
CVS source tree.
The lwIP TCP/IP stack is maintained in the 'lwip' CVS module and
contributions (such as platform ports) are in the 'contrib' module.
See doc/savannah.txt for details on CVS server access for users and
developers.
Last night's CVS tar ball can be downloaded from:
http://savannah.gnu.org/cvs.backups/lwip.tar.gz [CHANGED - NEEDS FIXING]
The current CVS trees are web-browsable:
http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/lwip/
http://savannah.nongnu.org/cgi-bin/viewcvs/lwip/contrib/
Submit patches and bugs via the lwIP project page:
http://savannah.nongnu.org/projects/lwip/
DOCUMENTATION
The original out-dated homepage of lwIP and Adam Dunkels' papers on
lwIP are at the official lwIP home page:
http://www.sics.se/~adam/lwip/
Self documentation of the source code is regularly extracted from the
current CVS sources and is available from this web page:
http://www.nongnu.org/lwip/
There is now a constantly growin wiki about lwIP at
http://lwip.wikia.com/wiki/LwIP_Wiki
Also, there are mailing lists you can subscribe at
http://savannah.nongnu.org/mail/?group=lwip
plus searchable archives:
http://lists.nongnu.org/archive/html/lwip-users/
http://lists.nongnu.org/archive/html/lwip-devel/
Reading Adam's papers, the files in docs/, browsing the source code
documentation and browsing the mailing list archives is a good way to
become familiar with the design of lwIP.
Adam Dunkels <adam@sics.se>
Leon Woestenberg <leon.woestenberg@gmx.net>
Import('RTT_ROOT')
from building import *
src = Split("""
src/api/api_lib.c
src/api/api_msg.c
src/api/err.c
src/api/netbuf.c
src/api/netdb.c
src/api/netifapi.c
src/api/sockets.c
src/api/tcpip.c
src/api/pppapi.c
src/arch/sys_arch.c
src/core/def.c
src/core/dhcp.c
src/core/dns.c
src/core/init.c
src/core/mem.c
src/core/memp.c
src/core/netif.c
src/core/pbuf.c
src/core/raw.c
src/core/stats.c
src/core/sys.c
src/core/tcp.c
src/core/tcp_in.c
src/core/tcp_out.c
src/core/timers.c
src/core/udp.c
src/core/inet_chksum.c
src/netif/etharp.c
src/netif/ethernetif.c
src/netif/slipif.c
src/core/ipv4/autoip.c
src/core/ipv4/icmp.c
src/core/ipv4/igmp.c
src/core/ipv4/ip4.c
src/core/ipv4/ip4_addr.c
src/core/ipv4/ip_frag.c
""")
ipv6_src = Split("""
src/core/ipv6/dhcp6.c
src/core/ipv6/ethip6.c
src/core/ipv6/icmp6.c
src/core/ipv6/inet6.c
src/core/ipv6/ip6_addr.c
src/core/ipv6/ip6.c
src/core/ipv6/ip6_frag.c
src/core/ipv6/mld6.c
src/core/ipv6/nd6.c
""")
snmp_src = Split("""
src/core/snmp/asn1_dec.c
src/core/snmp/asn1_enc.c
src/core/snmp/mib2.c
src/core/snmp/mib_structs.c
src/core/snmp/msg_in.c
src/core/snmp/msg_out.c
""")
ppp_src = Split("""
src/netif/ppp/auth.c
src/netif/ppp/ccp.c
src/netif/ppp/chap_ms.c
src/netif/ppp/chap_md5.c
src/netif/ppp/chap_new.c
src/netif/ppp/demand.c
src/netif/ppp/eap.c
src/netif/ppp/ecp.c
src/netif/ppp/eui64.c
src/netif/ppp/fsm.c
src/netif/ppp/ipcp.c
src/netif/ppp/ipv6cp.c
src/netif/ppp/lcp.c
src/netif/ppp/magic.c
src/netif/ppp/multilink.c
src/netif/ppp/ppp.c
src/netif/ppp/pppcrypt.c
src/netif/ppp/pppoe.c
src/netif/ppp/pppol2tp.c
src/netif/ppp/upap.c
src/netif/ppp/utils.c
src/netif/ppp/vj.c
src/netif/ppp/polarssl/des.c
src/netif/ppp/polarssl/md4.c
src/netif/ppp/polarssl/md5.c
src/netif/ppp/polarssl/sha1.c
""")
# The set of source files associated with this SConscript file.
path = [GetCurrentDir() + '/src',
GetCurrentDir() + '/src/include',
GetCurrentDir() + '/src/include/ipv4',
GetCurrentDir() + '/src/include/ipv6',
GetCurrentDir() + '/src/arch/include',
GetCurrentDir() + '/src/include/netif']
if GetDepend(['RT_LWIP_IPV6']):
src += ipv6_src
if GetDepend(['RT_LWIP_SNMP']):
src += snmp_src
if GetDepend(['RT_LWIP_PPP']):
src += ppp_src
path += [GetCurrentDir() + '/src/netif/ppp']
# For testing apps
if GetDepend(['RT_USING_NETUTILS']):
src += Glob('./apps/*.c')
group = DefineGroup('LwIP', src, depend = ['RT_USING_LWIP', 'RT_USING_LWIP_HEAD'], CPPPATH = path)
Return('group')
This file lists major changes between release versions that require
ports or applications to be changed. Use it to update a port or an
application written for an older version of lwIP to correctly work
with newer versions.
(CVS HEAD)
* [Enter new changes just after this line - do not remove this line]
++ Application changes:
* Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for
compatibility to old applications, but will be removed in the future).
* Renamed mem_realloc() to mem_trim() to prevent confusion with realloc()
+++ Raw API:
* Changed the semantics of tcp_close() (since it was rather a
shutdown before): Now the application does *NOT* get any calls to the recv
callback (aside from NULL/closed) after calling tcp_close()
* When calling tcp_abort() from a raw API TCP callback function,
make sure you return ERR_ABRT to prevent accessing unallocated memory.
(ERR_ABRT now means the applicaiton has called tcp_abort!)
+++ Netconn API:
* Changed netconn_receive() and netconn_accept() to return
err_t, not a pointer to new data/netconn.
+++ Socket API:
* LWIP_SO_RCVTIMEO: when accept() or recv() time out, they
now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT.
* Added a minimal version of posix fctl() to have a
standardised way to set O_NONBLOCK for nonblocking sockets.
+++ all APIs:
* correctly implemented SO(F)_REUSEADDR
++ Port changes
+++ new files:
* Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h:
* Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains
the actual application programmer's API
* Separated timer implementation from sys.h/.c, moved to timers.h/.c;
Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you
still want to use your own timer implementation for NO_SYS==0 (as before).
+++ sys layer:
* Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/
sys_sem_t;
* Converted sys_mbox_new/sys_sem_new to take pointers and return err_t;
* Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use
binary semaphores instead of mutexes - as before)
+++ new options:
* Don't waste memory when chaining segments, added option TCP_OVERSIZE to
prevent creating many small pbufs when calling tcp_write with many small
blocks of data. Instead, pbufs are allocated larger than needed and the
space is used for later calls to tcp_write.
* Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs
in tcp_write/udp_send.
* Added an additional option LWIP_ETHERNET to support ethernet without ARP
(necessary for pure PPPoE)
* Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may
be used to place these pools into user-defined memory by using external
declaration.
* Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT
+++ new pools:
* Netdb uses a memp pool for allocating memory when getaddrinfo() is called,
so MEMP_NUM_NETDB has to be set accordingly.
* DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so
MEMP_NUM_LOCALHOSTLIST has to be set accordingly.
* Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have
to be set accordingly.
* PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES
has to be set accordingly
* Integrated loopif into netif.c - loopif does not have to be created by the
port any more, just define LWIP_HAVE_LOOPIF to 1.
* Added define LWIP_RAND() for lwip-wide randomization (needs to be defined
in cc.h, e.g. used by igmp)
* Added printf-formatter X8_F to printf u8_t as hex
* The heap now may be moved to user-defined memory by defining
LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address
* added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work
with user-allocated structs instead of calling mem_malloc
* Added const char* name to mem- and memp-stats for easier debugging.
* Calculate the TCP/UDP checksum while copying to only fetch data once:
Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum
* Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to
more than one pcb.
* Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned
off any more, if this is set to 0, only one packet (the most recent one) is
queued (like demanded by RFC 1122).
++ Major bugfixes/improvements
* Implemented tcp_shutdown() to only shut down one end of a connection
* Implemented shutdown() at socket- and netconn-level
* Added errorset support to select() + improved select speed overhead
* Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x)
* Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1
* Use macros defined in ip_addr.h to work with IP addresses
* Implemented many nonblocking socket/netconn functions
* Fixed ARP input processing: only add a new entry if a request was directed as us
* mem_realloc() to mem_trim() to prevent confusion with realloc()
* Some improvements for AutoIP (don't route/forward link-local addresses, don't break
existing connections when assigning a routable address)
* Correctly handle remote side overrunning our rcv_wnd in ooseq case
* Removed packing from ip_addr_t, the packed version is now only used in protocol headers
* Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0
* Added support for static ARP table entries
(STABLE-1.3.2)
* initial version of this file
#include <rtthread.h>
#include <lwip/netdb.h>
#include <lwip/sockets.h>
#define SERV_PORT 12345
#define SERVADDR "4006:e024:680:c6e:223:8bff:fe59:de90" // Do not use link-local address, lwip-head did not implement it.
#define BUF_SIZE 1024
static const char send_data[] = "This is TCP Client from RT-Thread.";
void tcpclient6(void)
{
char* recv_data;
int sockfd, bytes_received;
struct sockaddr_in6 server_addr6;
int status = 0;
recv_data = rt_malloc(BUF_SIZE);
if(recv_data == RT_NULL)
{
rt_kprintf("No memory\n");
return ;
}
if((sockfd = socket(PF_INET6, SOCK_STREAM, 0)) == -1)
{
rt_kprintf("Socket error\n");
rt_free(recv_data);
return ;
}
memset(&server_addr6, 0, sizeof(server_addr6));
server_addr6.sin6_family = AF_INET6;
server_addr6.sin6_port = htons(SERV_PORT);
if(inet_pton(AF_INET6, SERVADDR, &server_addr6.sin6_addr.s6_addr) != 1)
{
rt_kprintf("inet_pton() error\n");
rt_free(recv_data);
return ;
}
status = connect(sockfd, (struct sockaddr *)&server_addr6, sizeof(server_addr6));
if(status < 0)
{
rt_kprintf("Connect error:%d\n", status);
rt_free(recv_data);
return ;
}
while(1)
{
bytes_received = recv(sockfd, recv_data, BUF_SIZE -1, 0);
if(bytes_received <= 0)
{
closesocket(sockfd);
rt_free(recv_data);
break;
}
recv_data[bytes_received] = '\0';
if(strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0)
{
closesocket(sockfd);
rt_free(recv_data);
break;
}
else
{
rt_kprintf("\nReceived data = %s ", recv_data);
}
send(sockfd, send_data, strlen(send_data), 0);
}
return;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(tcpclient6, startup tcp client via ipv6);
#endif
#include <rtthread.h>
#include <finsh.h>
#include <lwip/api.h>
#define TCP_ECHO_PORT 10001
void tcpecho6(void)
{
struct netconn *conn, *newconn;
err_t err;
conn = netconn_new(NETCONN_TCP_IPV6);
netconn_bind_ip6(conn, IP6_ADDR_ANY, TCP_ECHO_PORT);
netconn_listen(conn);
while(1)
{
err = netconn_accept(conn, &newconn);
if(err == ERR_OK)
{
struct netbuf *buf;
void *data;
u16_t len;
while(netconn_recv(newconn, &buf) == ERR_OK)
{
do
{
netbuf_data(buf, &data, &len);
err = netconn_write(newconn, data, len, NETCONN_COPY);
if(err != ERR_OK)
rt_kprintf("netconn_write() error\n");
}while(netbuf_next(buf) >= 0);
netbuf_delete(buf);
}
netconn_delete(newconn);
}
}
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(tcpecho6, startup tcp echo server via ipv6);
#endif
#include <rtthread.h>
#include <lwip/sockets.h>
#define SERV_PORT 10001
#define BUF_SIZE 1024
#define BACKLOG 5
static const char send_data[] = "This is TCP Server from RT-Thread.";
void tcpserver6(void)
{
int sockfd, clientfd;
struct sockaddr_in6 server_addr6, client_addr6;
int bytes_received;
char *recv_data;
rt_uint32_t sin_size;
rt_bool_t stop = RT_FALSE;
recv_data = rt_malloc(BUF_SIZE);
if(recv_data == RT_NULL)
{
rt_kprintf("No memory\n");
return ;
}
if((sockfd = socket(PF_INET6, SOCK_STREAM, 0)) == -1)
{
rt_kprintf("Socket error\n");
rt_free(recv_data);
return ;
}
server_addr6.sin6_family = AF_INET6;
memcpy(server_addr6.sin6_addr.s6_addr, IP6_ADDR_ANY, 16);
server_addr6.sin6_port = htons(SERV_PORT);
if(bind(sockfd, (struct sockaddr *)&server_addr6, sizeof(struct sockaddr)) == -1)
{
rt_kprintf("Bind error\n");
rt_free(recv_data);
return ;
}
if(listen(sockfd, BACKLOG) == -1)
{
rt_kprintf("Listen error\n");
rt_free(recv_data);
return ;
}
rt_sprintf(recv_data, "%4d", SERV_PORT);
rt_kprintf("\nTCPServer Waiting for client on port %s...\n", recv_data);
while(stop != RT_TRUE)
{
sin_size = sizeof(struct sockaddr_in6);
clientfd = accept(sockfd, (struct sockaddr *)&client_addr6, &sin_size);
rt_kprintf("I got a connection from (IP:%s, PORT:%d\n)", inet6_ntoa(client_addr6.sin6_addr), ntohs(client_addr6.sin6_port));
while(1)
{
send(clientfd, send_data, strlen(send_data), 0);
bytes_received = recv(clientfd, recv_data, BUF_SIZE, 0);
if(bytes_received <= 0)
{
closesocket(clientfd);
break;
}
recv_data[bytes_received] = '\0';
if(strcmp(recv_data, "q") == 0 || strcmp(recv_data, "Q") == 0)
{
closesocket(clientfd);
break;
}
else if(strcmp(recv_data, "exit") == 0)
{
closesocket(clientfd);
stop = RT_TRUE;
break;
}
else
{
rt_kprintf("RECEIVED DATA = %s\n", recv_data);
}
}
}
closesocket(sockfd);
rt_free(recv_data);
return ;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(tcpserver6, start tcp server via ipv6 );
#endif
#include <rtthread.h>
#include <lwip/netdb.h>
#include <lwip/sockets.h>
#define SERV_PORT 22345
#define SERVADDR "4006:e024:680:c6e:223:8bff:fe59:de90"
#define BUF_SIZE 1024
static const char send_data[] = "This is UDP Client from RT-Thread.";
void udpclient6(void)
{
char *recv_data;
int sockfd;
struct sockaddr_in6 server_addr6, client_addr6;
socklen_t clientlen;
recv_data = rt_malloc(BUF_SIZE);
if(recv_data == RT_NULL)
{
rt_kprintf("No memory\n");
return ;
}
if((sockfd = socket(PF_INET6, SOCK_DGRAM, 0)) == -1)
{
rt_kprintf("Socket error\n");
rt_free(recv_data);
return ;
}
memset(&server_addr6, 0, sizeof(server_addr6));
server_addr6.sin6_family = AF_INET6;
server_addr6.sin6_port = htons(SERV_PORT);
if(inet_pton(AF_INET6, SERVADDR, &server_addr6.sin6_addr.s6_addr) != 1)
{
rt_kprintf("inet_pton() error\n");
rt_free(recv_data);
return ;
}
if(sendto(sockfd, send_data, sizeof(recv_data), 0, (struct sockaddr *)&server_addr6, sizeof(server_addr6)) < 0)
{
rt_kprintf("Sendto error\n");
rt_free(recv_data);
return ;
}
rt_kprintf("Waiting for a reply...\n");
clientlen = sizeof(client_addr6);
if(recvfrom(sockfd, recv_data, BUF_SIZE, 0, (struct sockaddr *)&client_addr6, &clientlen) < 0)
{
rt_kprintf("Recvfrom error\n");
rt_free(recv_data);
return ;
}
rt_kprintf("got '%s'\n", recv_data);
closesocket(sockfd);
}
#ifdef RT_USING_FINSH
#include <finsh.h>
FINSH_FUNCTION_EXPORT(udpclient6, start udp server via ipv6);
#endif
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
IPv6 support in lwIP is very experimental.
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册