Lwip2.0.3 版本的 tftp 协议

Lwip2.0.3 版本的tftp 协议笔记

Lwip2.0.3中的tftp与旧版本的lwip的部分改动挺大,新版本的提供的接口更加方便,
新版本中tftp-server.h定义了一个结构体,声明了一个初始化函数,这个函数就是给开发人员的接口,里面是四个函数接口,open,close write read,我们只需要重新建立这四个函数,与其对应即可。.h如下:

*/
struct tftp_context {
    
    
  /**
   * Open file for read/write.
   * @param fname Filename
   * @param mode Mode string from TFTP RFC 1350 (netascii, octet, mail)
   * @param write Flag indicating read (0) or write (!= 0) access
   * @returns File handle supplied to other functions
   */
  void* (*open)(const char* fname, const char* mode, u8_t write);
  /**
   * Close file handle
   * @param handle File handle returned by open()
   */
  void (*close)(void* handle);
  /**
   * Read from file 
   * @param handle File handle returned by open()
   * @param buf Target buffer to copy read data to
   * @param bytes Number of bytes to copy to buf
   * @returns >= 0: Success; < 0: Error
   */
  int (*read)(void* handle, void* buf, int bytes);
  /**
   * Write to file
   * @param handle File handle returned by open()
   * @param pbuf PBUF adjusted such that payload pointer points
   *             to the beginning of write data. In other words,
   *       TFTP headers are stripped off. begainning of actualdata
   * @returns >= 0: Success; < 0: Error
   */
  int (*write)(void* handle, struct pbuf* p);
};
extern err_t tftp_init(const struct tftp_context* ctx);

函数的具体参数的意义自己翻译一下就知道了,其中open函数无论是写还是读都会被调用,在此之前你应该很了解了tftp的传输协议的理论部分,对传输过程很清晰,官方给的库里面的结构体代表的意义应该清楚,回到上面,open函数返回的函数句柄要被其他几个函数使用,编写好四个函数后取地址传给库里的tftp_init函数

uint8_t Tftp_Context_Init(void)
{
    
    
	if(tftp_init(&tftpContext) == ERR_OK)
		return 0;
		return 1;
}

此函数被主函数初始化一下即可。
例:

#define MY_MALLOC(type,n)  (type*)malloc(sizeof(type) * n) 
	
typedef struct 
{
    
    
  uint8_t   byOpenFileFlag; // 1 : Open file succeed   0: fail

  uint8_t   W_R_Mode;   // read or write Mode ,1: write  0 :read
  
  uint32_t  First_Flash_Addr;  // address  you want to write
  
}TyTftp_IAP_Flash;

static void * Tftp_Open_File(const char* fname, const char* mode, u8_t Iswrite);
static void  Tftp_Close_File(void* handle);
static int32_t Tftp_Read_File(void* handle, void* buf, int bytes);
static int32_t Tftp_Write_File(void* handle, struct pbuf* p);


static  TyTftp_IAP_Flash   Tftp_IAP_Flash;

struct tftp_context  TftpContext =
{
    
         
	Tftp_Open_File,   
	Tftp_Close_File,
	Tftp_Read_File,    
	Tftp_Write_File,
};

static void *Tftp_Open_File(const char* fname, const char* mode, u8_t Iswrite)
{
    
       
	Tftp_IAP_Flash.W_R_Mode = Iswrite;
	
	/*compare the file name we want to read or write*/

	if(Tftp_IAP_Flash.W_R_Mode == 1)  //: is write
	{
    
    
		Tftp_IAP_Flash.byOpenFileFlag = 1;	
	}
	else if(Tftp_IAP_Flash.W_R_Mode == 0)  //:is read
	{
    
    
		Tftp_IAP_Flash.byOpenFileFlag = 1; 
	}	

	/*tftp  open file init successful*/
	if(Tftp_IAP_Flash.byOpenFileFlag == 1) 
		return &Tftp_IAP_Flash; 
	else 
		return	0 ;	
}

static int32_t Tftp_Read_File(void* handle, void* buf, int bytes)
{
    
      	
	uint16_t Count ;
	
	TyTftp_IAP_Flash * Filehandle = (TyTftp_IAP_Flash *) handle ;
	
	if(!Filehandle->byOpenFileFlag)  //未初始化
	{
    
    
	  return ERR_MEM ;
	} 
#if 0	
	/* copy data from  Address  to opening file*/
	for(Count = 0; Count < bytes; Count++  )
	{
    
    
		if(Filehandle->First_Flash_Addr <= FLASH_APP_END_ADDRESS)
		{
    
    
			((uint8_t *)buf)[Count] = *((__IO uint8_t *) Filehandle->First_Flash_Addr);
			Filehandle->First_Flash_Addr++;
		}
		else
		{
    
    
			break;
		}
	}
#endif	
	return Count;
}


static int32_t Tftp_Write_File(void* handle, struct pbuf* p)
{
    
    	
	uint16_t Count;
	int8_t byErr = ERR_OK;

	TyTftp_IAP_Flash * Filehandle = (TyTftp_IAP_Flash *) handle ; 	

	if(!Filehandle->byOpenFileFlag)
	{
    
    	  
	  return ERR_MEM ;
	}

	Count = p->len; //lenth of data : 512byte or <512

	//code

	return byErr;
}

static void Tftp_Close_File(void* handle)
{
    
    	
	Tftp_IAP_Flash.byOpenFileFlag = 0;
		
	if(Tftp_IAP_Flash.W_R_Mode == 1) 
	{
    
    
	  //code
	}
	}
}


uint8_t Tftp_Context_Init(uint16_t ReUpdate, uint8_t BootFlag)
{
    
    
	TftpFileStart(BootFlag);

	if (ReUpdate == 1)
	{
    
    
		if(tftp_init(&TftpContext) == ERR_OK)
			return 0;
	}
	return 1;
}

最后利用TFTP32软件和下位机结合实际业务进行文件的读取和写入。只需要在code处填写你自己的代码就行了,有需要可以联系我。

猜你喜欢

转载自blog.csdn.net/qq_15555275/article/details/107052429
今日推荐