/** * \brief Send the files through XMODEM protocol * * \param usart Base address of the USART instance. * \param p_buffer Pointer to send buffer * \param ul_length transfer file size */ void xmodem_send_file(usart_if usart, int8_t *p_buffer, uint32_t ul_length) { uint8_t c_char, uc_sno = 1; int32_t l_done; uint32_t ul_timeout = (sysclk_get_peripheral_hz() / 10); if (ul_length & (PKTLEN_128-1)) { ul_length += PKTLEN_128; ul_length &= ~(PKTLEN_128-1); } /* Startup synchronization... */ /* Wait to receive a NAK or 'C' from receiver. */ l_done = 0; while(!l_done) { usart_serial_getchar(usart, &c_char); switch (c_char) { case XMDM_NAK: l_done = 1; break; case 'C': l_done = 1; break; case 'q': /* ELS addition, not part of XMODEM spec. */ return; default: break; } } l_done = 0; uc_sno = 1; while (!l_done) { c_char = xmodem_send_packet(usart, (uint8_t *)p_buffer, uc_sno); switch(c_char) { case XMDM_ACK: ++uc_sno; ul_length -= PKTLEN_128; p_buffer += PKTLEN_128; break; case XMDM_NAK: break; case XMDM_CAN: case XMDM_EOT: default: l_done = -1; break; } if (!ul_length) { usart_serial_putchar(usart, XMDM_EOT); /* Flush the ACK */ usart_serial_getchar(usart, &c_char); break; } } }
static void w89k_load (struct serial *desc, char *file, int hashmark) { bfd *abfd; asection *s; char *buffer; int i; buffer = alloca (XMODEM_PACKETSIZE); abfd = bfd_openr (file, 0); if (!abfd) { printf_filtered ("Unable to open file %s\n", file); return; } if (bfd_check_format (abfd, bfd_object) == 0) { printf_filtered ("File is not an object file\n"); return; } for (s = abfd->sections; s; s = s->next) if (s->flags & SEC_LOAD) { bfd_size_type section_size; printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma, s->vma + s->_raw_size); gdb_flush (gdb_stdout); monitor_printf (w89k_cmds.load, s->vma); if (w89k_cmds.loadresp) monitor_expect (w89k_cmds.loadresp, NULL, 0); xmodem_init_xfer (desc); section_size = bfd_section_size (abfd, s); for (i = 0; i < section_size; i += XMODEM_DATASIZE) { int numbytes; numbytes = min (XMODEM_DATASIZE, section_size - i); bfd_get_section_contents (abfd, s, buffer + XMODEM_DATAOFFSET, i, numbytes); xmodem_send_packet (desc, buffer, numbytes, hashmark); if (hashmark) { putchar_unfiltered ('#'); gdb_flush (gdb_stdout); } } /* Per-packet (or S-record) loop */ xmodem_finish_xfer (desc); monitor_expect_prompt (NULL, 0); putchar_unfiltered ('\n'); } /* Loadable sections */ if (hashmark) putchar_unfiltered ('\n'); }