From eab38c8effd223488a9b2c3768dd7670ab81fe5f Mon Sep 17 00:00:00 2001 From: andy <1414772332@qq.com> Date: Sat, 18 Oct 2025 23:55:18 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0tftp=E5=8D=8F=E8=AE=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1.usb连接上之后,可以使用tftp协议传输文件 2.解决写入sd卡时如果buff地址不是4字节对齐时数据错位的问题 --- Project/Src/Drive/Source/mymem.c | 30 +- Project/Src/FATS/diskio.c | 269 ++++++++---------- Project/Src/ReadMe.txt | 2 + .../net/lwip-2.1.0/src/apps/tftp/tftp_port.c | 97 +++++++ .../lwip-2.1.0/src/apps/tftp/tftp_port.tmp | 87 ------ .../tftp/{tftp_server.tmp => tftp_server.c} | 0 .../net/lwip-2.1.0/src/arch/sys_arch.c | 14 +- Project/Src/rt-thread/rtconfig.h | 13 +- 8 files changed, 246 insertions(+), 266 deletions(-) create mode 100644 Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_port.c delete mode 100644 Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_port.tmp rename Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/{tftp_server.tmp => tftp_server.c} (100%) diff --git a/Project/Src/Drive/Source/mymem.c b/Project/Src/Drive/Source/mymem.c index 23f45e0..b1b87a0 100644 --- a/Project/Src/Drive/Source/mymem.c +++ b/Project/Src/Drive/Source/mymem.c @@ -122,13 +122,11 @@ static uint32_t exmem_malloc(uint32_t size) { uint32_t nmemb; // Ҫڴ uint32_t cmemb = 0; // ڴ uint32_t i; - // if(!mallco_dev.memrdy)mallco_dev.init();//δʼ,ִгʼ + if (size == 0) return 0XFFFFFFFF; // Ҫ - - nmemb = size / exmemblksize; // ȡҪڴ - if (size % exmemblksize) - nmemb++; + // ȡҪڴ + nmemb = (size+exmemblksize-1) / exmemblksize; for (offset = exmemtblsize - 1; offset >= 0; offset--) // ڴ { if (!exmallco_dev.memmap[offset]) @@ -152,23 +150,19 @@ static uint32_t exmem_malloc(uint32_t size) { // offset:ڴַƫ // ֵ:0,ͷųɹ;1,ͷʧ; static uint8_t exmem_free(uint32_t offset) { - uint32_t i; - if (!exmallco_dev.memrdy) // δʼ,ִгʼ - { - // mallco_dev.init(); - return 1; // δʼ - } - if (offset < exmemsize) // ƫڴ. - { - uint32_t index = offset / exmemblksize; // ƫڴ - uint32_t nmemb = exmallco_dev.memmap[index]; // ڴ - for (i = 0; i < nmemb; i++) // ڴ - { + // ƫڴ. + if (offset < exmemsize) { + // ƫڴ + uint32_t index = offset / exmemblksize; + // ڴ + uint32_t nmemb = exmallco_dev.memmap[index]; + // ڴ + for (int i = 0; i < nmemb; i++) { exmallco_dev.memmap[index + i] = 0; } return 0; } else - return 2; // ƫƳ. + return 2; } //------------------------------------ڲSRAM--------------------------------------- diff --git a/Project/Src/FATS/diskio.c b/Project/Src/FATS/diskio.c index 8271a47..592ce85 100644 --- a/Project/Src/FATS/diskio.c +++ b/Project/Src/FATS/diskio.c @@ -7,193 +7,164 @@ /* storage control modules to the FatFs module with a defined API. */ /*-----------------------------------------------------------------------*/ -#include "diskio.h" /* FatFs lower layer API */ +#include "diskio.h" /* FatFs lower layer API */ #include "sdio_sd.h" #include "stdlib.h" #include "string.h" -#define SD_Card 0 //SD -#define SPI_Flash 1 //SPI Flash +#define SD_Card 0 // SD +#define SPI_Flash 1 // SPI Flash -#define SD_BLOCKSIZE 512 -extern SD_CardInfo SDCardInfo; +#define SD_BLOCKSIZE 512 +extern SD_CardInfo SDCardInfo; /*-----------------------------------------------------------------------*/ /* Get Drive Status */ /*-----------------------------------------------------------------------*/ -DSTATUS disk_status ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) -{ - DSTATUS stat = STA_NOINIT; +DSTATUS disk_status( + BYTE pdrv /* Physical drive nmuber to identify the drive */ +) { + DSTATUS stat = STA_NOINIT; - switch (pdrv) { + switch (pdrv) { - case SD_Card : - stat &= ~STA_NOINIT; - return stat; + case SD_Card: + stat &= ~STA_NOINIT; + return stat; - case SPI_Flash : - return stat; - } - return STA_NOINIT; + case SPI_Flash: + return stat; + } + return STA_NOINIT; } - - /*-----------------------------------------------------------------------*/ /* Inidialize a Drive */ /*-----------------------------------------------------------------------*/ -DSTATUS disk_initialize ( - BYTE pdrv /* Physical drive nmuber to identify the drive */ -) -{ - DSTATUS stat = STA_NOINIT; - - switch (pdrv) { - - case SD_Card : - if( SD_Init()==SD_OK ) //SDʼ - { - stat &= ~STA_NOINIT; - return stat; - } - - case SPI_Flash : - return stat; - - } - return STA_NOINIT; +DSTATUS disk_initialize( + BYTE pdrv /* Physical drive nmuber to identify the drive */ +) { + DSTATUS stat = STA_NOINIT; + switch (pdrv) { + case SD_Card: + if (SD_Init() == SD_OK) // SDʼ + { + stat &= ~STA_NOINIT; + return stat; + } + case SPI_Flash: + return stat; + } + return STA_NOINIT; } - - /*-----------------------------------------------------------------------*/ /* Read Sector(s) */ /*-----------------------------------------------------------------------*/ -DRESULT disk_read ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - BYTE *buff, /* Data buffer to store read data */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to read */ -) -{ - SD_Error SD_state = SD_OK; - BYTE *pbuff=buff; - if ((uint32_t)pbuff&0x3) - { - pbuff=malloc(SD_BLOCKSIZE*count); - } - - switch (pdrv) { - - case SD_Card: - SD_state=SD_ReadMultiBlocks(pbuff,(uint64_t)sector*SD_BLOCKSIZE,SD_BLOCKSIZE,count); - if(SD_state==SD_OK) - { - SD_state=SD_WaitReadOperation(); - while(SD_GetStatus() != SD_TRANSFER_OK); - } - if (pbuff!=buff) - { - memcpy(buff,pbuff,SD_BLOCKSIZE*count); - free(pbuff); - } - if(SD_state==SD_OK) - return RES_OK; - else - return RES_PARERR; - - case SPI_Flash : - return RES_PARERR; - } - return RES_PARERR; +DRESULT disk_read(BYTE pdrv, /* Physical drive nmuber to identify the drive */ + BYTE *buff, /* Data buffer to store read data */ + DWORD sector, /* Start sector in LBA */ + UINT count /* Number of sectors to read */ +) { + SD_Error SD_state = SD_OK; + BYTE *pbuff = buff; + if ((uint32_t)pbuff & 0x3) { + pbuff = malloc(SD_BLOCKSIZE * count); + } + switch (pdrv) { + case SD_Card: + SD_state = SD_ReadMultiBlocks(pbuff, (uint64_t)sector * SD_BLOCKSIZE, + SD_BLOCKSIZE, count); + if (SD_state == SD_OK) { + SD_state = SD_WaitReadOperation(); + while (SD_GetStatus() != SD_TRANSFER_OK) + ; + } + if (pbuff != buff) { + memcpy(buff, pbuff, SD_BLOCKSIZE * count); + free(pbuff); + } + if (SD_state == SD_OK) + return RES_OK; + else + return RES_PARERR; + case SPI_Flash: + return RES_PARERR; + } + return RES_PARERR; } - - /*-----------------------------------------------------------------------*/ /* Write Sector(s) */ /*-----------------------------------------------------------------------*/ -DRESULT disk_write ( - BYTE pdrv, /* Physical drive nmuber to identify the drive */ - const BYTE *buff, /* Data to be written */ - DWORD sector, /* Start sector in LBA */ - UINT count /* Number of sectors to write */ -) -{ - SD_Error SD_state = SD_OK; - - switch (pdrv) { - - case SD_Card: - SD_state=SD_WriteMultiBlocks((uint8_t *)buff,(uint64_t)sector*SD_BLOCKSIZE,SD_BLOCKSIZE,count); - if(SD_state==SD_OK) - { - SD_state=SD_WaitWriteOperation(); - while(SD_GetStatus() != SD_TRANSFER_OK); - - if(SD_state==SD_OK) - return RES_OK; - else - return RES_PARERR; - } - - case SPI_Flash : - return RES_PARERR; - } - return RES_PARERR; +DRESULT disk_write(BYTE pdrv, /* Physical drive nmuber to identify the drive */ + const BYTE *buff, /* Data to be written */ + DWORD sector, /* Start sector in LBA */ + UINT count /* Number of sectors to write */ +) { + SD_Error SD_state = SD_OK; + BYTE *pbuff = (BYTE *)buff; + if ((uint32_t)pbuff & 0x3) { + pbuff = malloc(SD_BLOCKSIZE * count); + memcpy(pbuff, buff, SD_BLOCKSIZE * count); + } + switch (pdrv) { + case SD_Card: + SD_state = SD_WriteMultiBlocks( + (uint8_t *)pbuff, (uint64_t)sector * SD_BLOCKSIZE, SD_BLOCKSIZE, count); + if (SD_state == SD_OK) { + SD_state = SD_WaitWriteOperation(); + while (SD_GetStatus() != SD_TRANSFER_OK) + ; + if (pbuff != buff) { + free(pbuff); + } + if (SD_state == SD_OK) + return RES_OK; + else + return RES_PARERR; + } + case SPI_Flash: + return RES_PARERR; + } + return RES_PARERR; } - - /*-----------------------------------------------------------------------*/ /* Miscellaneous Functions */ /*-----------------------------------------------------------------------*/ -DRESULT disk_ioctl ( - BYTE pdrv, /* Physical drive nmuber (0..) */ - BYTE cmd, /* Control code */ - void *buff /* Buffer to send/receive control data */ -) -{ - DRESULT res = RES_PARERR; - - switch (pdrv) { - case SD_Card : - switch (cmd) - { - case GET_SECTOR_COUNT: - *(DWORD * )buff = SDCardInfo.CardCapacity/SD_BLOCKSIZE; - break; - - // Get R/W sector size (WORD) - case GET_SECTOR_SIZE : - *(WORD * )buff = SD_BLOCKSIZE; - break; - - // Get erase block size in unit of sector (DWORD) - case GET_BLOCK_SIZE : - *(DWORD * )buff = SD_BLOCKSIZE; - break; - - } - return RES_OK; - - case SPI_Flash : - return res; - } - return RES_PARERR; +DRESULT disk_ioctl(BYTE pdrv, /* Physical drive nmuber (0..) */ + BYTE cmd, /* Control code */ + void *buff /* Buffer to send/receive control data */ +) { + DRESULT res = RES_PARERR; + switch (pdrv) { + case SD_Card: + switch (cmd) { + case GET_SECTOR_COUNT: + *(DWORD *)buff = SDCardInfo.CardCapacity / SD_BLOCKSIZE; + break; + // Get R/W sector size (WORD) + case GET_SECTOR_SIZE: + *(WORD *)buff = SD_BLOCKSIZE; + break; + // Get erase block size in unit of sector (DWORD) + case GET_BLOCK_SIZE: + *(DWORD *)buff = SD_BLOCKSIZE; + break; + } + return RES_OK; + case SPI_Flash: + return res; + } + return RES_PARERR; } /*-----------------------------------------------------------------------*/ /* ʱȡﲻʹã0 */ /*-----------------------------------------------------------------------*/ -DWORD get_fattime(void) { - - return 0; - -} +DWORD get_fattime(void) { return 0; } diff --git a/Project/Src/ReadMe.txt b/Project/Src/ReadMe.txt index 6ce8bdd..b8b40bb 100644 --- a/Project/Src/ReadMe.txt +++ b/Project/Src/ReadMe.txt @@ -501,3 +501,5 @@ ԭӦڵ֮ǰʹ˻apiȻapiֻ߳е 2025.10.17 appصʧܿΪ޸˴ڽṹ壬appлʹǰĴڽṹ +2025.10.18 + f_writeдݵʱbuff4ֽڶ룬sdͨdmaݻλ diff --git a/Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_port.c b/Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_port.c new file mode 100644 index 0000000..b98a8c2 --- /dev/null +++ b/Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_port.c @@ -0,0 +1,97 @@ +/* + * File : tftp_port.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Change Logs: + * Date Author Notes + * 2017-08-17 armink first version. + */ + +#include "bsp_init.h" +#include +#include +#include + +static struct tftp_context ctx; + +static void *tftp_open(const char *fname, const char *mode, u8_t write) { + FIL *file = malloc(sizeof(FIL)); + FRESULT ret; + if (file == NULL) { + return NULL; + } + if (!rt_strcmp(mode, "octet")) { + if (write) { + ret = f_open(file, fname, FA_CREATE_ALWAYS | FA_WRITE); + } else { + ret = f_open(file, fname, FA_READ); + } + } else { + rt_kprintf("tftp: No support this mode(%s).", mode); + } + if (ret != FR_OK) { + rt_kprintf("ftp: open file %s failed,ret=%d\n", fname, ret); + free(file); + file = NULL; + } + + return file; +} + +static int tftp_write(void *handle, struct pbuf *p) { + FIL *file = (FIL *)handle; + UINT wb = 0; + FRESULT ret; + uint8_t *buf = p->payload; + ret = f_write(file, p->payload, p->len, &wb); + if (ret != FR_OK) { + wb = -1; + } + return (int)wb; +} + +static void tftp_close(void *handle) { + f_close((FIL *)handle); + free(handle); +} + +static int tftp_read(void *handle, void *buffer, int len) { + UINT rb = 0; + FIL *file = (FIL *)handle; + FRESULT ret; + ret = f_read(file, buffer, len, &rb); + if (ret != FR_OK) { + rb = -1; + } + return (int)rb; +} + +static int tftp_server() { + ctx.open = tftp_open; + ctx.close = tftp_close; + ctx.read = tftp_read; + ctx.write = tftp_write; + + if (tftp_init(&ctx) == ERR_OK) { + rt_kprintf("TFTP server start successfully.\n"); + } else { + rt_kprintf("TFTP server start failed.\n"); + } + return 0; +} +extern_init(tftp, tftp_server); diff --git a/Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_port.tmp b/Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_port.tmp deleted file mode 100644 index 129cc7d..0000000 --- a/Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_port.tmp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * File : tftp_port.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Change Logs: - * Date Author Notes - * 2017-08-17 armink first version. - */ - - -#include -#include -#include - -static struct tftp_context ctx; - -static void* tftp_open(const char* fname, const char* mode, u8_t write) -{ - int fd = -1; - - if (!rt_strcmp(mode, "octet")) - { - if (write) - { - fd = open(fname, O_WRONLY | O_CREAT, 0); - } - else - { - fd = open(fname, O_RDONLY, 0); - } - } - else - { - rt_kprintf("tftp: No support this mode(%s).", mode); - } - - return (void *) fd; -} - -static int tftp_write(void* handle, struct pbuf* p) -{ - int fd = (int) handle; - - return write(fd, p->payload, p->len); -} - -#if defined(RT_USING_FINSH) -#include - -static void tftp_server(uint8_t argc, char **argv) -{ - ctx.open = tftp_open; - ctx.close = (void (*)(void *)) close; - ctx.read = (int (*)(void *, void *, int)) read; - ctx.write = tftp_write; - - if (tftp_init(&ctx) == ERR_OK) - { - rt_kprintf("TFTP server start successfully.\n"); - } - else - { - rt_kprintf("TFTP server start failed.\n"); - } -} -FINSH_FUNCTION_EXPORT(tftp_server, start tftp server.); - -#if defined(FINSH_USING_MSH) -MSH_CMD_EXPORT(tftp_server, start tftp server.); -#endif /* defined(FINSH_USING_MSH) */ - -#endif /* defined(RT_USING_FINSH) */ diff --git a/Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_server.tmp b/Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_server.c similarity index 100% rename from Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_server.tmp rename to Project/Src/rt-thread/components/net/lwip-2.1.0/src/apps/tftp/tftp_server.c diff --git a/Project/Src/rt-thread/components/net/lwip-2.1.0/src/arch/sys_arch.c b/Project/Src/rt-thread/components/net/lwip-2.1.0/src/arch/sys_arch.c index 9d1b27a..d2def70 100644 --- a/Project/Src/rt-thread/components/net/lwip-2.1.0/src/arch/sys_arch.c +++ b/Project/Src/rt-thread/components/net/lwip-2.1.0/src/arch/sys_arch.c @@ -721,29 +721,31 @@ void mem_init(void) void *mem_calloc(mem_size_t count, mem_size_t size) { - // return rt_calloc(count, size); void *r = mymalloc_exm(size * count); memset(r, 0, size * count); return r; } + +// lwip ִֻ֧bufתСתСֱӷԭַ +// ʹrealloc·䣬pbufµַݲȥ +// ڼ void *mem_trim(void *mem, mem_size_t size) { - // return rt_realloc(mem, size); /* not support trim yet */ - mem = myrealloc(mem, size); return mem; } +// static void *p_last; void *mem_malloc(mem_size_t size) { - // return rt_malloc(size); - return mymalloc_exm(size); + void *p = 0; + p = mymalloc_exm(size); + return p; } void mem_free(void *mem) { - // rt_free(mem); myfree(mem); } diff --git a/Project/Src/rt-thread/rtconfig.h b/Project/Src/rt-thread/rtconfig.h index 16ae9d1..ec1c4cf 100644 --- a/Project/Src/rt-thread/rtconfig.h +++ b/Project/Src/rt-thread/rtconfig.h @@ -218,16 +218,17 @@ #define RT_LWIP_TCP #define RT_LWIP_UDP #define RT_LWIP_ICMP -// #define RT_LWIP_DEBUG -#define RT_LWIP_TCPIP_DEBUG -#define RT_LWIP_NETIF_DEBUG -#define RT_LWIP_ETHARP_DEBUG -#define RT_LWIP_IP_DEBUG -#define RT_LWIP_UDP_DEBUG #define RT_LWIP_DHCP #define RT_LWIP_IGMP #define RT_LWIP_RAW +// #define RT_LWIP_DEBUG +// #define RT_LWIP_TCPIP_DEBUG +// #define RT_LWIP_NETIF_DEBUG +// #define RT_LWIP_ETHARP_DEBUG +// #define RT_LWIP_IP_DEBUG +// #define RT_LWIP_UDP_DEBUG +#define RT_LWIP_PBUF_DEBUG // <<< end of configuration section >>> #endif