在main.c中加入一個工作
extern PT_THREAD(ui(struct pt *pt));
add_task(0, ui);
while (1)
{
scheduler();
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
將bdg_parser.c也放入
/*
* dbg_parser.c
*
* Created on: 2023年2月8日
* Author: wallace
*/
#include <stdio.h>
#include <string.h>
#include "main.h"
#include "pt.h"
#include "coroutine.h"
/* Forward declaration — defined later in this file */
static void Uart2TransmitDMA(unsigned char *src, int size);
static int Get_Uart2Value(unsigned char *Value);
/*
return 0:Failed, 1:Successful
str : Pointer to pointer to the string
res : Pointer to the valiable to store the value */
int xatoi(char **str, long *res)
{
unsigned long val;
unsigned char c, r, s = 0;
*res = 0;
while ((c = **str) == ' ')
(*str)++; /* Skip leading spaces */
if (c == '-')
{ /* negative? */
s = 1;
c = *(++(*str));
}
if (c == '0')
{
c = *(++(*str));
switch (c)
{
case 'x': /* hexdecimal */
r = 16;
c = *(++(*str));
break;
case 'b': /* binary */
r = 2;
c = *(++(*str));
break;
default:
if (c <= ' ')
return 1; /* single zero */
if (c < '0' || c > '9')
return 0; /* invalid char */
r = 8; /* octal */
}
}
else
{
if (c < '0' || c > '9')
return 0; /* EOL or invalid char */
r = 10; /* decimal */
}
val = 0;
while (c > ' ')
{
if (c >= 'a')
c -= 0x20;
c -= '0';
if (c >= 17)
{
c -= 7;
if (c <= 9)
return 0; /* invalid char */
}
if (c >= r)
return 0; /* invalid char for current radix */
val = val * r + c;
c = *(++(*str));
}
if (s)
val = 0 - val; /* apply sign if needed */
*res = val;
return 1;
}
// Moved from ui.c
#define PT_DBG_PARSER 0
#define PT_DBG_TX 1
#define PT_DBG_RX 2
#define PT_MODEM 3
unsigned char Line[128];
int sLength = 0;
char *p_ptr;
const char console_ready[] = ">";
long p[5];
#define p1 p[0]
#define p2 p[1]
#define p3 p[2]
#define p4 p[3]
#define p5 p[4]
struct timer tx_timer;
int i, j, k;
unsigned char *pc;
int count;
struct pt pt_temp[16];
#define TX_BUF_SIZE (256U)
static uint8_t tx_buffer[TX_BUF_SIZE]; /* DMA staging buffer — used only inside tx_output */
static uint8_t fmt_buffer[TX_BUF_SIZE]; /* format buffer for callers */
static const uint8_t *tx_src; /* source data pointer */
static uint16_t tx_total; /* total bytes to send */
/* ---- Xmodem transport interface ----------------------------------------- */
typedef struct
{
int (*get_byte)(uint8_t *dst); /* non-blocking: 1=got byte, 0=empty */
void (*flush_rx)(void); /* discard buffered RX */
void (*start_tx)(const uint8_t *buf, uint16_t len); /* initiate (possibly async) TX */
int (*tx_idle)(void); /* 1 = TX hardware fully done */
} xmodem_io_t;
static const xmodem_io_t *xmodem_io; /* assigned before spawning xmodem_rx / xmodem_tx */
// static struct timer tx_output_timer;
static PT_THREAD(tx_output(struct pt *pt))
{
static uint16_t offset;
static uint16_t chunk;
PT_BEGIN(pt);
offset = 0;
while (offset < tx_total)
{
chunk = tx_total - offset;
if (chunk > TX_BUF_SIZE)
chunk = (uint16_t)TX_BUF_SIZE;
memcpy(tx_buffer, tx_src + offset, chunk);
Uart2TransmitDMA(tx_buffer, chunk);
#if 1
PT_YIELD(pt);
#else
timer_set(&tx_output_timer, 1);
PT_WAIT_UNTIL(pt, timer_expired(&tx_output_timer));
#endif
PT_WAIT_UNTIL(pt, !LL_DMA_IsEnabledStream(DMA1, LL_DMA_STREAM_6));
PT_WAIT_UNTIL(pt, LL_USART_IsActiveFlag_TC(USART2));
offset += chunk;
}
PT_END(pt);
}
/* ---- xmodem_send: chunked TX through the xmodem_io vtable --------------- */
static PT_THREAD(xmodem_send(struct pt *pt))
{
static uint16_t offset;
static uint16_t chunk;
PT_BEGIN(pt);
offset = 0;
while (offset < tx_total)
{
chunk = tx_total - offset;
if (chunk > TX_BUF_SIZE)
chunk = (uint16_t)TX_BUF_SIZE;
memcpy(tx_buffer, tx_src + offset, chunk);
xmodem_io->start_tx(tx_buffer, chunk);
PT_WAIT_UNTIL(pt, xmodem_io->tx_idle());
offset += chunk;
}
PT_END(pt);
}
/* ---- rx_byte: wait for one byte with timeout -----------------------------
* Set rx_byte_dst and rx_byte_timeout before spawning.
* After the spawn, rx_byte_ok == 1 means a byte was stored; 0 means timeout. */
static uint8_t *rx_byte_dst;
static uint16_t rx_byte_timeout;
static uint8_t rx_byte_ok;
static struct timer rx_byte_timer;
static PT_THREAD(rx_byte(struct pt *pt))
{
PT_BEGIN(pt);
timer_set(&rx_byte_timer, rx_byte_timeout);
PT_WAIT_UNTIL(pt, xmodem_io->get_byte(rx_byte_dst) || timer_expired(&rx_byte_timer));
rx_byte_ok = (uint8_t)(!timer_expired(&rx_byte_timer));
PT_END(pt);
}
/* ---- UART2 RX: circular DMA (DMA1 Stream 5, Channel 4) ------------------ */
#define UART2_RX_DMA_BUF_SIZE 128
static unsigned char RxBuffer[UART2_RX_DMA_BUF_SIZE];
static unsigned short uart2_rx_tail = 0;
void EnableUart2Receive(void)
{
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_5, (uint32_t)RxBuffer);
LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_5, (uint32_t)&USART2->DR);
LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_5, UART2_RX_DMA_BUF_SIZE);
LL_USART_EnableDMAReq_RX(USART2);
LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_5);
}
void Reset_Uart2Buffer(void)
{
uart2_rx_tail = (unsigned short)(UART2_RX_DMA_BUF_SIZE -
LL_DMA_GetDataLength(DMA1, LL_DMA_STREAM_5)) &
(UART2_RX_DMA_BUF_SIZE - 1);
}
static int Get_Uart2Value(unsigned char *Value)
{
unsigned short head = (unsigned short)(UART2_RX_DMA_BUF_SIZE -
LL_DMA_GetDataLength(DMA1, LL_DMA_STREAM_5)) &
(UART2_RX_DMA_BUF_SIZE - 1);
if (head == uart2_rx_tail)
return 0;
*Value = RxBuffer[uart2_rx_tail];
uart2_rx_tail = (uart2_rx_tail + 1u) & (UART2_RX_DMA_BUF_SIZE - 1);
return -1;
}
/* ---- UART2 TX: normal DMA (DMA1 Stream 6, Channel 4) -------------------- */
static void Uart2TransmitDMA(unsigned char *src, int size)
{
/* Ensure previous DMA transfer is complete */
while (LL_DMA_IsEnabledStream(DMA1, LL_DMA_STREAM_6))
;
LL_DMA_ClearFlag_TC6(DMA1);
LL_DMA_ClearFlag_HT6(DMA1);
LL_DMA_ClearFlag_TE6(DMA1);
LL_USART_ClearFlag_TC(USART2); /* clear stale TC before new transfer */
LL_DMA_SetMemoryAddress(DMA1, LL_DMA_STREAM_6, (uint32_t)src);
LL_DMA_SetPeriphAddress(DMA1, LL_DMA_STREAM_6, (uint32_t)&USART2->DR);
LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_6, (uint32_t)size);
LL_USART_EnableDMAReq_TX(USART2);
LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_6);
}
/* ---- UART2 xmodem transport implementation ------------------------------ */
static int xio_uart2_get_byte(uint8_t *dst) { return Get_Uart2Value(dst); }
static void xio_uart2_flush_rx(void) { Reset_Uart2Buffer(); }
static void xio_uart2_start_tx(const uint8_t *buf, uint16_t len) { Uart2TransmitDMA((unsigned char *)buf, (int)len); }
static int xio_uart2_tx_idle(void)
{
return !LL_DMA_IsEnabledStream(DMA1, LL_DMA_STREAM_6) &&
LL_USART_IsActiveFlag_TC(USART2);
}
const xmodem_io_t xmodem_io_uart2 = {
xio_uart2_get_byte,
xio_uart2_flush_rx,
xio_uart2_start_tx,
xio_uart2_tx_idle,
};
PT_THREAD(ui(struct pt *pt))
{
static unsigned char *ptrLine;
static unsigned char c;
PT_BEGIN(pt);
Reset_Uart2Buffer();
EnableUart2Receive();
Line[0] = 0;
ptrLine = &Line[0];
while (!Idle_enable)
{
if (Get_Uart2Value(&c))
{
if ('\n' == c)
{
// skip
}
else if ('\r' == c)
{
extern PT_THREAD(dbg_parser(struct pt * pt));
*ptrLine = 0;
sLength = (int)(ptrLine - &Line[0]);
ptrLine = &Line[0];
PT_SPAWN(pt, &pt_temp[PT_DBG_PARSER], dbg_parser(&pt_temp[PT_DBG_PARSER]));
}
else if ('\b' == c)
{
if (ptrLine > &Line[0])
ptrLine--;
}
else
{
*ptrLine++ = c;
}
}
else
{
PT_YIELD(pt);
}
}
PT_END(pt);
}
#define XMODEM_SOH (0x01)
#define XMODEM_STX (0x02)
#define XMODEM_EOT (0x04)
#define XMODEM_ACK (0x06)
#define XMODEM_NAK (0x15)
#define XMODEM_CAN (0x18)
static uint8_t *xmodem_dst;
static uint32_t xmodem_max;
static uint32_t xmodem_received;
static uint32_t xmodem_stored;
static int xmodem_overflow;
static int xmodem_result;
static const uint8_t *xmodem_src;
static uint32_t xmodem_size;
static uint32_t xmodem_sent;
static int xmodem_tx_result;
static uint16_t xmodem_crc16_update(uint16_t crc, uint8_t data)
{
crc ^= (uint16_t)data << 8;
for (uint8_t i = 0; i < 8; i++)
{
if (crc & 0x8000)
crc = (crc << 1) ^ 0x1021;
else
crc <<= 1;
}
return crc;
}
static PT_THREAD(xmodem_rx(struct pt *pt))
{
static uint8_t c;
static uint8_t blk;
static uint8_t blk_inv;
static uint8_t d; /* data/CRC byte — static so it survives yields */
static uint16_t crc_calc;
static uint16_t crc_recv;
static uint16_t i;
static uint16_t block_size;
static uint8_t expected_blk;
static uint8_t retries;
PT_BEGIN(pt);
xmodem_io->flush_rx(); /* discard any stale RX bytes before handshake */
xmodem_received = 0;
xmodem_stored = 0;
xmodem_overflow = 0;
xmodem_result = -1;
expected_blk = 1;
retries = 0;
/* Handshake: send 'C' until the sender responds */
while (1)
{
fmt_buffer[0] = 'C';
tx_src = fmt_buffer;
tx_total = 1;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
rx_byte_dst = &c;
rx_byte_timeout = 1000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
if (rx_byte_ok)
goto xmodem_got_first;
if (++retries >= 30)
{
xmodem_result = -2; // timeout
PT_EXIT(pt);
}
}
xmodem_got_first:
retries = 0;
while (1)
{
if (c == XMODEM_EOT)
{
fmt_buffer[0] = XMODEM_ACK;
tx_src = fmt_buffer;
tx_total = 1;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
xmodem_result = 0;
PT_EXIT(pt);
}
if (c == XMODEM_CAN)
{
xmodem_result = -3; // canceled by sender
PT_EXIT(pt);
}
if (c != XMODEM_SOH && c != XMODEM_STX)
{
/* Ignore stray byte — wait for the next one */
rx_byte_dst = &c;
rx_byte_timeout = 1000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
continue;
}
block_size = (c == XMODEM_SOH) ? 128 : 1024;
/* Block number */
rx_byte_dst = &blk;
rx_byte_timeout = 1000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
if (!rx_byte_ok)
goto xmodem_nak;
/* Block number inverse */
rx_byte_dst = &blk_inv;
rx_byte_timeout = 1000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
if (!rx_byte_ok)
goto xmodem_nak;
if ((uint8_t)(blk + blk_inv) != 0xFF)
goto xmodem_nak;
/* Data bytes */
crc_calc = 0;
for (i = 0; i < block_size; i++)
{
rx_byte_dst = &d;
rx_byte_timeout = 1000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
if (!rx_byte_ok)
goto xmodem_nak;
crc_calc = xmodem_crc16_update(crc_calc, d);
if (xmodem_stored < xmodem_max)
xmodem_dst[xmodem_stored++] = d;
else
xmodem_overflow = 1;
xmodem_received++;
}
/* CRC16 high byte */
rx_byte_dst = &d;
rx_byte_timeout = 1000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
if (!rx_byte_ok)
goto xmodem_nak;
crc_recv = (uint16_t)d << 8;
/* CRC16 low byte */
rx_byte_dst = &d;
rx_byte_timeout = 1000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
if (!rx_byte_ok)
goto xmodem_nak;
crc_recv |= d;
if (crc_recv != crc_calc)
goto xmodem_nak;
/* Accept expected block, or ACK a duplicate */
if (blk == expected_blk)
{
expected_blk++;
retries = 0;
fmt_buffer[0] = XMODEM_ACK;
tx_src = fmt_buffer;
tx_total = 1;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
}
else if (blk == (uint8_t)(expected_blk - 1))
{
retries = 0;
fmt_buffer[0] = XMODEM_ACK;
tx_src = fmt_buffer;
tx_total = 1;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
}
else
{
goto xmodem_nak;
}
/* Wait for the next block's SOH/STX */
rx_byte_dst = &c;
rx_byte_timeout = 3000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
if (!rx_byte_ok)
{
/* Prompt sender to retransmit */
fmt_buffer[0] = XMODEM_NAK;
tx_src = fmt_buffer;
tx_total = 1;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
}
continue;
xmodem_nak:
if (++retries >= 10)
{
fmt_buffer[0] = XMODEM_CAN;
tx_src = fmt_buffer;
tx_total = 1;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
xmodem_result = -4; // too many errors
PT_EXIT(pt);
}
fmt_buffer[0] = XMODEM_NAK;
tx_src = fmt_buffer;
tx_total = 1;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
/* Flush any stray bytes, then loop to top */
rx_byte_dst = &c;
rx_byte_timeout = 3000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
}
PT_END(pt);
}
static PT_THREAD(xmodem_tx(struct pt *pt))
{
static uint8_t c;
static uint8_t blk;
static uint8_t retries;
static uint16_t crc;
static uint16_t i;
static uint8_t pkt[3 + 128 + 2];
static uint32_t offset;
PT_BEGIN(pt);
xmodem_sent = 0;
xmodem_tx_result = -1;
/* Wait for receiver 'C' (CRC mode) or NAK */
retries = 0;
while (1)
{
rx_byte_dst = &c;
rx_byte_timeout = 1000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
if (rx_byte_ok)
goto xmodem_tx_got_first;
if (++retries >= 30)
{
xmodem_tx_result = -2; // timeout
PT_EXIT(pt);
}
}
xmodem_tx_got_first:
if (!(c == 'C' || c == XMODEM_NAK))
{
if (c == XMODEM_CAN)
{
xmodem_tx_result = -3;
PT_EXIT(pt);
}
// ignore stray bytes and keep waiting
PT_RESTART(pt);
}
blk = 1;
offset = 0;
while (offset < xmodem_size)
{
// Build 128-byte block
pkt[0] = XMODEM_SOH;
pkt[1] = blk;
pkt[2] = (uint8_t)(0xFF - blk);
crc = 0;
for (i = 0; i < 128; i++)
{
uint8_t d = 0x1A; // CPM EOF padding
if ((offset + i) < xmodem_size)
d = xmodem_src[offset + i];
pkt[3 + i] = d;
crc = xmodem_crc16_update(crc, d);
}
pkt[3 + 128] = (uint8_t)(crc >> 8);
pkt[3 + 128 + 1] = (uint8_t)(crc & 0xFF);
retries = 0;
while (1)
{
// Send packet directly from pkt (no copy needed)
tx_src = pkt;
tx_total = sizeof(pkt);
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
// Wait for ACK/NAK
rx_byte_dst = &c;
rx_byte_timeout = 10000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
if (!rx_byte_ok)
c = XMODEM_NAK;
if (c == XMODEM_ACK)
break;
if (c == XMODEM_CAN)
{
xmodem_tx_result = -3;
PT_EXIT(pt);
}
if (++retries >= 10)
{
// Abort
fmt_buffer[0] = XMODEM_CAN;
tx_src = fmt_buffer;
tx_total = 1;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
xmodem_tx_result = -4;
PT_EXIT(pt);
}
}
offset += 128;
xmodem_sent = (offset > xmodem_size) ? xmodem_size : offset;
blk++;
}
// Send EOT until ACK
retries = 0;
while (1)
{
fmt_buffer[0] = XMODEM_EOT;
tx_src = fmt_buffer;
tx_total = 1;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], xmodem_send(&pt_temp[PT_DBG_TX]));
rx_byte_dst = &c;
rx_byte_timeout = 10000;
PT_SPAWN(pt, &pt_temp[PT_DBG_RX], rx_byte(&pt_temp[PT_DBG_RX]));
if (rx_byte_ok && c == XMODEM_ACK)
{
xmodem_tx_result = 0;
PT_EXIT(pt);
}
if (++retries >= 10)
{
xmodem_tx_result = -5;
PT_EXIT(pt);
}
}
PT_END(pt);
}
struct timer dbg_timer;
PT_THREAD(dbg_parser(struct pt *pt))
{
PT_BEGIN(pt);
// timer_set(&dbg_timer, 10);
// PT_WAIT_UNTIL(pt, timer_expired(&dbg_timer));
p_ptr = (char *)&Line[0];
switch (*p_ptr++)
{
case '?': // ? -- Show information
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE,
"Build: %s %s\r\n"
"Commands: ? | md/mf/mw/mr | xs <addr> [max] | xr <addr> <size>\r\n",
__DATE__, __TIME__);
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
break; // end ?
case 'm': // m?
switch (*p_ptr++)
{
case 'd': // md <addr> <count> -- memory dump
if (!xatoi(&p_ptr, &p1))
break;
if (!xatoi(&p_ptr, &p2))
p2 = 0x80;
do
{
pc = (unsigned char *)p1;
count = (int)p2;
k = 0;
while (k < count)
{
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "%08lX ", (long unsigned int)pc);
for (i = 0; i < 16; i++)
{
j = snprintf((char *)&fmt_buffer[tx_total], TX_BUF_SIZE - tx_total, " %02X", pc[i]);
tx_total = (uint16_t)(tx_total + j);
}
fmt_buffer[tx_total++] = ' ';
for (i = 0; i < 16; i++)
fmt_buffer[tx_total++] = (unsigned char)((pc[i] >= ' ' && pc[i] <= '~') ? pc[i] : '.');
fmt_buffer[tx_total++] = '\r';
fmt_buffer[tx_total++] = '\n';
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
k += 0x10;
pc += 0x10;
}
} while (0);
break;
case 'f': // mf [addr] [value] [size] -- fill memory
if (!xatoi(&p_ptr, &p1))
break;
if (!xatoi(&p_ptr, &p2))
break;
if (!xatoi(&p_ptr, &p3))
break;
do
{
int i;
uint8_t *tp = (uint8_t *)p1;
uint8_t val = p2;
for (i = 0; i < p3; i++)
*tp++ = val;
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "Fill memory.\r\n");
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
} while (0);
break;
case 'w': // mw <address> <count> [data] - memory write
if (!xatoi(&p_ptr, &p1))
break;
if (!xatoi(&p_ptr, &p2))
p2 = 0;
do
{
unsigned char *ptemp;
ptemp = (unsigned char *)p1;
while (p2)
{
if (!xatoi(&p_ptr, &p3))
break;
*ptemp++ = p3;
p2--;
};
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "Write memory.\r\n");
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
} while (0);
break;
case 's': // ms <tick> - delay ticks
if (!xatoi(&p_ptr, &p1))
break;
do
{
timer_set(&dbg_timer, p1);
PT_WAIT_UNTIL(pt, timer_expired(&dbg_timer));
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "Delay %lu ticks.\r\n", (unsigned long)p1);
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
} while (0);
break;
case 'r': // mr -- nvic reset
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "NVIC Reset!\r\n");
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
NVIC_SystemReset();
break;
}
break; // end m?
case 'x': // x
switch (*p_ptr++)
{
case 'r': // xr <addr> [max] -- XMODEM receive to memory (CRC)
if (!xatoi(&p_ptr, &p1))
break;
if (!xatoi(&p_ptr, &p2))
p2 = 0x1000;
xmodem_dst = (uint8_t *)p1;
xmodem_max = (uint32_t)p2;
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "XMODEM RX: start (CRC), dst=%08lX max=%lu\r\n", (unsigned long)p1, (unsigned long)p2);
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
xmodem_io = &xmodem_io_uart2;
PT_SPAWN(pt, &pt_temp[PT_MODEM], xmodem_rx(&pt_temp[PT_MODEM]));
if (xmodem_result == 0 && !xmodem_overflow)
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "XMODEM RX OK: stored=%lu bytes\r\n", (unsigned long)xmodem_stored);
else if (xmodem_result == 0 && xmodem_overflow)
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "XMODEM RX OK (truncated): stored=%lu max=%lu total=%lu\r\n", (unsigned long)xmodem_stored, (unsigned long)xmodem_max, (unsigned long)xmodem_received);
else
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "XMODEM RX FAIL: err=%d stored=%lu total=%lu\r\n", xmodem_result, (unsigned long)xmodem_stored, (unsigned long)xmodem_received);
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
break;
case 's': // xs <addr> <size> -- XMODEM send from memory
if (!xatoi(&p_ptr, &p1))
break;
if (!xatoi(&p_ptr, &p2))
break;
xmodem_src = (const uint8_t *)p1;
xmodem_size = (uint32_t)p2;
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "XMODEM TX: receiver start now (CRC), src=%08lX size=%lu\r\n", (unsigned long)p1, (unsigned long)p2);
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
xmodem_io = &xmodem_io_uart2;
PT_SPAWN(pt, &pt_temp[PT_MODEM], xmodem_tx(&pt_temp[PT_MODEM]));
if (xmodem_tx_result == 0)
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "XMODEM TX OK: sent=%lu bytes\r\n", (unsigned long)xmodem_sent);
else
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "XMODEM TX FAIL: err=%d sent=%lu\r\n", xmodem_tx_result, (unsigned long)xmodem_sent);
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
break;
case '?': // x? -- show xmodem usage
tx_total = (uint16_t)snprintf((char *)fmt_buffer, TX_BUF_SIZE, "XMODEM Commands:\r\nxr <addr> [max] -- receive to memory (CRC)\r\nxs <addr> <size> -- send from memory\r\n");
tx_src = fmt_buffer;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
break;
}
break; // x
}
fmt_buffer[0] = '>';
tx_src = fmt_buffer;
tx_total = 1;
PT_SPAWN(pt, &pt_temp[PT_DBG_TX], tx_output(&pt_temp[PT_DBG_TX]));
PT_END(pt);
}
它是使用FatFs作者的命令器為主,再加上一個ui工作。
然後就叫AI寫xmodem收發,用LL函式庫。主要是測試能不能用,有沒有問題。
就完成一個不使用中斷的直譯器,以及大量資料傳輸的簡單架構。