motor_f407/User/lib/bootload/ymodem.h

181 lines
6.3 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* @file ymodem.h
* @author xsh
* @date 2024-02-18 19:32:46
* @brief
* @copyright Copyright (c) 2024 by xxx, All Rights Reserved.
*/
#ifndef __YMODEM_H__
#define __YMODEM_H__
#include "lib.h"
enum rym_code
{
RYM_CODE_NONE = 0x00,
RYM_CODE_SOH = 0x01, /* start of 128-byte data packet */
RYM_CODE_STX = 0x02, /* start of 1024-byte data packet */
RYM_CODE_EOT = 0x04, /* end of transmission */
RYM_CODE_ACK = 0x06, /* acknowledge */
RYM_CODE_NAK = 0x15, /* negative acknowledge */
RYM_CODE_CAN = 0x18, /* two of these in succession aborts transfer */
RYM_CODE_C = 0x43, /* 'C' == 0x43, request 16-bit CRC */
};
typedef enum rym_code rym_code_e;
/* RYM error code
*
* We use the rt_err_t to return error values. We take use of current error
* codes available in RTT and append ourselves.
*/
/* timeout on handshake */
#define RYM_ERR_TMO 0x70
/* wrong code, wrong SOH, STX etc. */
#define RYM_ERR_CODE 0x71
/* wrong sequence number */
#define RYM_ERR_SEQ 0x72
/* wrong CRC checksum */
#define RYM_ERR_CRC 0x73
/* not enough data received */
#define RYM_ERR_DSZ 0x74
/* the transmission is aborted by user */
#define RYM_ERR_CAN 0x75
/* how many ticks wait for chars between packet. */
#ifndef RYM_WAIT_CHR_TICK
#define RYM_WAIT_CHR_TICK (OSEL_TICK_RATE_HZ * 3)
#endif
/* how many ticks wait for between packet. */
#ifndef RYM_WAIT_PKG_TICK
#define RYM_WAIT_PKG_TICK (OSEL_TICK_RATE_HZ * 3)
#endif
/* how many ticks between two handshake code. */
#ifndef RYM_CHD_INTV_TICK
#define RYM_CHD_INTV_TICK (OSEL_TICK_RATE_HZ * 3)
#endif
/* how many CAN be sent when user active end the session. */
#ifndef RYM_END_SESSION_SEND_CAN_NUM
#define RYM_END_SESSION_SEND_CAN_NUM 0x03
#endif
/* Exported constants --------------------------------------------------------*/
/* Packet structure defines */
#define PACKET_HEADER_SIZE ((uint32_t)3)
#define PACKET_DATA_INDEX ((uint32_t)4)
#define PACKET_START_INDEX ((uint32_t)1)
#define PACKET_NUMBER_INDEX ((uint32_t)2)
#define PACKET_CNUMBER_INDEX ((uint32_t)3)
#define PACKET_TRAILER_SIZE ((uint32_t)2)
#define PACKET_OVERHEAD_SIZE (PACKET_HEADER_SIZE + PACKET_TRAILER_SIZE - 1)
#define PACKET_SIZE ((uint32_t)128)
#define PACKET_1K_SIZE ((uint32_t)1024)
#define _RYM_SOH_PKG_SZ (PACKET_SIZE + PACKET_HEADER_SIZE + PACKET_TRAILER_SIZE)
#define _RYM_STX_PKG_SZ (PACKET_1K_SIZE + PACKET_HEADER_SIZE + PACKET_TRAILER_SIZE)
#define _RYM_PKG_SZ _RYM_STX_PKG_SZ // 这里定义的是数据包的大小
/* 因为data是需要写入到flash里面如果不对齐会出现UNALIGNED异常
* /-------- Packet in IAP memory ------------------------------------------\
* | 0 | 1 | 2 | 3 | 4 | ... | n+4 | n+5 | n+6 |
* |------------------------------------------------------------------------|
* | unused | start | number | !num | data[0] | ... | data[n] | crc0 | crc1 |
* \------------------------------------------------------------------------/
* the first byte is left unused for memory alignment reasons */
#define FILE_NAME_LENGTH ((uint32_t)64)
#define FILE_SIZE_LENGTH ((uint32_t)16)
#define NEGATIVE_BYTE ((uint8_t)0xFF)
#define ABORT1 ((uint8_t)0x41) /* 'A' == 0x41, abort by user */
#define ABORT2 ((uint8_t)0x61) /* 'a' == 0x61, abort by user */
#define MAX_ERRORS ((uint32_t)5)
enum rym_stage
{
RYM_STAGE_NONE,
/* set when C is send */
RYM_STAGE_ESTABLISHING,
/* set when we've got the packet 0 and sent ACK and second C */
RYM_STAGE_ESTABLISHED,
/* set when the sender respond to our second C and recviever got a real
* data packet. */
RYM_STAGE_TRANSMITTING,
/* set when the sender send a EOT */
RYM_STAGE_FINISHING,
/* set when transmission is really finished, i.e., after the NAK, C, final
* NULL packet stuff. */
RYM_STAGE_FINISHED,
};
/* when receiving files, the buf will be the data received from ymodem protocol
* and the len is the data size.
*
* TODO:
* When sending files, the len is the buf size in RYM. The callback need to
* fill the buf with data to send. Returning RYM_CODE_EOT will terminate the
* transfer and the buf will be discarded. Any other return values will cause
* the transfer continue.
*/
typedef enum rym_code (*rym_callback)(uint8_t *buf, uint32_t len);
/** recv a file on device dev with ymodem session ctx.
*
* If an error happens, you can get where it is failed from ctx->stage.
*
* @param on_begin The callback will be invoked when the first packet arrived.
* This packet often contain file names and the size of the file, if the sender
* support it. So if you want to save the data to a file, you may need to
* create the file on need. It is the on_begin's responsibility to parse the
* data content. The on_begin can be NULL, in which case the transmission will
* continue without any side-effects.
*
* @param on_data The callback will be invoked on the packets received. The
* callback should save the data to the destination. The return value will be
* sent to the sender and in turn, only RYM_{ACK,CAN} is valid. When on_data is
* NULL, RYM will barely send ACK on every packet and have no side-effects.
*
* @param on_end The callback will be invoked when one transmission is
* finished. The data should be 128 bytes of NULL. You can do some cleaning job
* in this callback such as closing the file. The return value of this callback
* is ignored. As above, this parameter can be NULL if you don't need such
* function.
*
* @param handshake_timeout the timeout when hand shaking. The unit is in
* second.
*/
BOOL rym_config(rym_callback on_begin, rym_callback on_data,
rym_callback on_end, rym_callback on_transmit,
int handshake_timeout);
/**
* @brief Initializes the YMODEM protocol for receiving data.
*
* @return BOOL Returns TRUE if initialization is successful, FALSE otherwise.
*/
BOOL rym_init(void);
/**
* @brief Receives data using the YMODEM protocol.
*
* @param p Pointer to the buffer where the received data will be stored.
* @param size The size of the buffer.
* @return uint16_t The number of bytes received.
*/
uint16_t rym_receive(void *p, uint16_t size);
/**
* @brief Processes the received data using the YMODEM protocol.
*/
void rym_process(void);
/**
* @brief Checks if a timeout has occurred during the YMODEM protocol.
*
* @return BOOL Returns TRUE if a timeout has occurred, FALSE otherwise.
*/
BOOL rym_timeout(void);
#endif