STM32 tftp file transfer for Internet of Things

Source: Internet
Author: User
Tags file transfer protocol





    • Testimonials: Focus on IoT application development and share IoT technology experience.
    • Software platform: IAR6.5
    • TCP/IP protocol stack: LWIP1.4.1
    • Hardware platform: STM32F103C8T6 Cable Communication Board (click here to Buy)





1. TCP/IP protocol stack LWIP



1.1, lwIP understanding




lwIP is a small open-source TCP/IP developed by Adam Dunkels of the Swedish Computer Science Institute (SICS) The protocol stack, which is light Weight (lightweight) IP protocol, can be run with or without operating system support. lwIP provides three APIs, namelyRAW API, LWIPAPI,BSD API. WhichRAW API puts protocol stacks and applications into one processinside, the interface is based on the function callback technology to achieve, suitable for operation without operating system, such as single-chip microcomputer. This article uses the raw API of LWIP to realize the communication of the network layer.


1.2, TFTP in the implementation of LWIP



As for the transplant of LWIP, it is not more in this article, readers can find a lot of information on the Internet or in another topic in detail, where we focus on its application. The implementation of a TFTP server in lwIP is very simple, according to the raw API programming method, at the time of initialization to create a UDP PCB (TFTP using UDP protocol communication), and bound 69 port (TFTP default communication port), and finally specify the UDP The data receive callback function of the PCB.



The above method of creating a TFTP server needs to be performed after lwIP is initialized and the NIC is started:






 LwIP_Config();
    printf("ipaddr:%d.%d.%d.%d\r\n", net_ip[0], net_ip[1], net_ip[2], net_ip[3]);

    tftpd_init();
To create a TFTP server in the Tftpd_init function:








void tftpd_init(void)
{
  err_t err;
  unsigned port = 69;

  /* create a new UDP PCB structure  */
  UDPpcb = udp_new();
  if (!UDPpcb)
  {  /* Error creating PCB. Out of Memory  */
    return;
  }

  /* Bind this PCB to port 69  */
  err = udp_bind(UDPpcb, IP_ADDR_ANY, port);
  if (err != ERR_OK)
  {    /* Unable to bind to port  */
    return;
  }

  /* TFTP server start  */
  udp_recv(UDPpcb, recv_callback_tftp, NULL);
}
OK, here is the completion of the TFTP server was established in the LWIP, the next major thing is to protocol interpretation according to the TFTP protocol, data processing.





2. TFTP protocol analysis



2.1. Basic process of TFTP communication (from the network)






2.2. TFTP message Format (excerpt from the network)






2.3. TFTP protocol understanding



What useful information do we learn from the two images above?


    • Each time the file transfer, first need to initiate a request, according to the request frame operation code to determine whether to read a file or write a file.
    • Each frame has an opcode to identify read-write.
    • The length of the packet has a block number that is used to denote the order of the packets.
    • The data in the packet has a length of 512 bytes (in the back of the software we can see that this length can be set).


3. Implement TFTP file transfer



3.1. File Transfer Protocol implementation



With the Protocol analysis in section 2nd, we have a basic understanding of the Protocol for TFTP communication, where we implement the server-side code for TFTP.



When the listener callback function is triggered, the operation code is first obtained from the request frame:






typedef enum {
  TFTP_RRQ = 1,
  TFTP_WRQ = 2,
  TFTP_DATA = 3,
  TFTP_ACK = 4,
  TFTP_ERROR = 5
} tftp_opcode;

tftp_opcode tftp_decode_op(char *buf)
{
  return (tftp_opcode)(buf[1]);
}
according to the operation code for the corresponding processing:








tftp_opcode op = tftp_decode_op(pkt_buf->payload);

switch (op)
  {

    case TFTP_RRQ:    /* TFTP RRQ (read request) */
      tftp_extract_filename(FileName, pkt_buf->payload);
      tftp_process_read(upcb, addr, port, FileName);
      break;

    case TFTP_WRQ:    /* TFTP WRQ (write request) */ 
      tftp_extract_filename(FileName, pkt_buf->payload);
      //Add FLASH here tftp_process_write(upcb, addr, port, FileName);
      break;

    default:
      /* sEndTransfera generic access violation message */
      tftp_send_error_message(upcb, addr, port, TFTP_ERR_ACCESS_VIOLATION);
      /* TFTP unknown request op */
      /* no need to use tftp_cleanup_wr because no "tftp_connection_args" struct has been malloc'd   */
      udp_remove(upcb);

      break;
  }
here, when the STM32 receives a write request, the file name is read by the Tftp_extract_filename function. The next step is to complete the transfer of the file data via the Tftp_process_write function:









int tftp_process_write(struct udp_pcb *upcb, struct ip_addr *to, int to_port, char *FileName)
{
  ... ...
  udp_recv(upcb, wrq_recv_callback, args);
  tftp_send_ack_packet(upcb, to, to_port, args->block);

  return 0;
}

after setting the data transfer callback function, reply to an ACK according to the TFTP protocol, then the TFTP client begins to transfer the file data, thus triggering the call Wrq_recv_callback
void wrq_recv_callback (void * _args, struct udp_pcb * upcb, struct pbuf * pkt_buf, struct ip_addr * addr, u16_t port)
{
  tftp_connection_args * args = (tftp_connection_args *) _ args;
  int n = 0;

  if (pkt_buf-> len! = pkt_buf-> tot_len)
  {
    return;
  }

  / * Does this packet have any valid data to write? * /
  if ((pkt_buf-> len> TFTP_DATA_PKT_HDR_LEN) &&
      (tftp_extract_block (pkt_buf-> payload) == (args-> block + 1)))
  {
    / * Process the received data here pkt_buf-> payload * /

    / * update our block number to match the block number just received * /
    args-> block ++;
    / * update total bytes * /
    (args-> tot_bytes) + = (pkt_buf-> len-TFTP_DATA_PKT_HDR_LEN);

    / * This is a valid pkt but it has no data. This would occur if the file being
       written is an exact multiple of 512 bytes. In this case, the args-> block
       value must still be updated, but we can skip everything else. * /
  }
  else if (tftp_extract_block (pkt_buf-> payload) == (args-> block + 1))
  {
    / * update our block number to match the block number just received * /
    args-> block ++;
  }

  / * SEndTransferthe appropriate ACK pkt (the block number sent in the ACK pkt echoes
   * the block number of the DATA pkt we just received-see RFC1350)
   * NOTE !: If the DATA pkt we received did not have the appropriate block
   * number, then the args-> block (our block number) is never updated and
   * we simply sEndTransfera "duplicate ACK" which has the same block number as the
   * last ACK pkt we sent. This lets the host know that we are still waiting
   * on block number args-> block + 1. * /
  tftp_send_ack_packet (upcb, addr, port, args-> block);

  / * If the last write returned less than the maximum TFTP data pkt length,
   * then we've received the whole file and so we can quit (this is how TFTP
   * signals the EndTransferof a transfer!)
   * /
  if (pkt_buf-> len <TFTP_DATA_PKT_LEN_MAX)
  {
    tftp_cleanup_wr (upcb, args);
    pbuf_free (pkt_buf);
  }
  else
  {
    pbuf_free (pkt_buf);
    return;
  }

}
ok! This STM32 completes the entire TFTP protocol file reception.





3.2. Save File data



After receiving the complete file data, we need to write the data to STM32 Flash and save it.



Because the STM32 memory is small, it is impossible to open up a large memory space to save the file data and write to Flash,



So we need to write flash while receiving.



First, after receiving the write operation request, erase the flash of the storage area:





case TFTP_WRQ: / * TFTP WRQ (write request) * /
. ...
       FlashDestination = HtmlDataAddress;
/ * Erase the needed pages where the user application will be loaded * /
       / * Define the number of page to be erased * /
       NbrOfPage = FLASH_PagesMask (HtmlTotalSize); // Erase HTML area

       / * Erase the FLASH pages * /
       FLASH_Unlock ();
       for (EraseCounter = 0; (EraseCounter <NbrOfPage) && (FLASHStatus == FLASH_COMPLETE); EraseCounter ++)
        {
          FLASHStatus = FLASH_ErasePage (HtmlSizeAddress + (PageSize * EraseCounter));
        }
       FLASH_Lock ();
In the process of file data transfer, write the <=512byte data to Flash:


     filedata = (uint32_t)pkt_buf->payload + TFTP_DATA_PKT_HDR_LEN;
     FLASH_Unlock();
     for (n = 0;n < (pkt_buf->len - TFTP_DATA_PKT_HDR_LEN);n += 4)
     {
      /* Program the data received into STM32F10x Flash */
      FLASH_ProgramWord(FlashDestination, *(uint32_t*)filedata);

       if (*(uint32_t*)FlashDestination != *(uint32_t*)filedata)
        {
          /* End session */
	 tftp_send_error_message(upcb, addr, port, FLASH_VERIFICATION_FAILED);
         /* close the connection */
         tftp_cleanup_wr(upcb, args); /* close the connection */
        }
        FlashDestination += 4;
        filedata += 4;
     }
     FLASH_Lock();
here, the STM32 receives the file data transmitted by the TFTP client and saves it to the area where the flash address is flashdestination.





3.3. Demo operation



Connect the communication board to the router in the same local domain as the computer and properly configure the IP information. Open the software Tftpd32.exe on the computer side:






Clicking the "Upload" button will send the file Html.bin file to the STM32 Communication Board:





You can read the contents of the file in the STM32 Communication board and use TFTP to transfer the HTML file in the next blog IoT Web development.





4. TFTP application



TFTP is the main implementation of file transfer, in the firmware upgrade, program debugging greatly improve efficiency, has important significance.



In the Web application development will realize its powerful role. Welcome to the next blog about STM32 's web development.



STM32 tftp file transfer for Internet of Things


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.