1.Misfunctional behavior
Bootloader开机后,会尝试与远端的自动程序升级终端握手。目前这个过程是这样的:接收到首帧后,首帧反馈信息不符合YModem协议:
Out之后的In不对,检查一下此时SecureCrt是否在等待回应:
yes, It still waiting...
2.分析
2.1 检查代码的可能位置
1.1.64已经可以看到收到发出了"C" 。这个"C",导致上位机发出 YModem首帧。相关代码:
void TryToLoadApp(void)
{
//等待時間
#define WAIT_TIME 1000
#define WAIT_SPAN 200
int16_t RetryCnt = WAIT_TIME/WAIT_SPAN;
if((EE_Key_1 == MAGIC_BYTE1) && (EE_Key_2 == MAGIC_BYTE2))
{
RetryCnt = 30000/WAIT_SPAN;
//不清除,因爲這種狀態會被自然清理掉。
}
while(EUSART1_is_rx_ready()) getch(); //讀完緩衝區裏的所有遺留字符。
do
{
while(!EUSART1_is_rx_ready())
{
putch('C');
HAL_Delay(WAIT_SPAN);
if((RetryCnt--)<=0) break;
}
if(!EUSART1_is_rx_ready())
{
if(IsAppExisted()) JumpToRealApp(); //default jump
}
}while(!EUSART1_is_rx_ready());
}
这个函数已经退出。明白了,在putch('c')之后,那个WAIT_SPAN的长延时不妥。115200的波特率,10/115200的延时,对方的数据就会来。这是86us。所以,这里的等待检测时间需要达到50us级。
修改=》内存空间超限。。。
2.2 为什么0x600以内的地址空间,编译工具无法使用?
post quesiton at Microchip's forum...
Microchip Forum Question about XC8-CC's
https://forum.microchip.com/s/topic/a5C3l000000Bpr8EAC/t391265
此问题已经有答案。我现在又多出来1.5KBytes左右的ROM空间可用。
2.3 将等待时间缩短至50us
现在15帧似乎回送成功了。但是还是多追加了几个"C"、"C"
2.4 根本机制发现,是代码速度跟不上485
最终开机代码改为如下模式:
void TryToLoadApp(void)
{
//等待時間
#define WAIT_TIME 1000 /*單位ms*/
#define WAIT_SPAN 50 /*單位us, DO NOT CHANGE!!! =115200BPS*/
#define OUTPUT_SPAN (200*1000/WAIT_SPAN) /*單位WAIT_SPAN = 50us*/
uint32_t RetryCnt = WAIT_TIME/WAIT_SPAN*1000;
if((EE_Key_1 == MAGIC_BYTE1) && (EE_Key_2 == MAGIC_BYTE2))
{
RetryCnt <<=5;
//不清除,因爲這種狀態會被自然清理掉。
}
while(EUSART1_is_rx_ready()) getch(); //讀完緩衝區裏的所有遺留字符。
do
{
while(!EUSART1_is_rx_ready())
{
if((RetryCnt--)<=0) break;
if((RetryCnt&0x7ff)==0) putch('C'); //about 200ms delay。。。
HAL_usDelay(WAIT_SPAN);
}
if(!EUSART1_is_rx_ready())
{
if(IsAppExisted()) JumpToRealApp(); //default jump
}
}while(!EUSART1_is_rx_ready());
uint8_t ymodemHeader[7] = {0x01, 0x00, 0xff, 'g', 'p', 'b', 't'};
uint8_t idx=0;
uint8_t dumb;
uint16_t cnts=0;
//嘗試讀取ymodem協議字符串
if(EUSART1_is_rx_ready())
{
uint8_t nullLoop=0;
while(1)
{
if(EUSART1_is_rx_ready())
{
dumb = getch();
if(idx<7)
{
if(ymodemHeader[idx++]!=dumb) idx|=0xf0;
}
cnts++;
}
else
{
HAL_usDelay(50);
if(++nullLoop>100) break;
}
}
}
if(idx==0x07) EE_DUMB = ACK;
else if(cnts>=128) EE_DUMB = NAK;
else EE_DUMB = 0;
xlog("idx=%d, cnts=%d, DUMB=%c", idx, cnts, EE_DUMB);
}
3.结论
为了解析人手工输入的命令并能够在开机时;并能够自动进入YModem接收模式,之前对这些特征字符串是这样解析的:
流式命令析取工具
https://mp.csdn.net/mp_blog/creation/editor/131644811
在嵌入式环境中,你始终要对时间要警醒——单片机可能无法在指定时间内完成你所设定的动作。那个命令析取工具,应付人手输入,应该可以,但是应付115200bps的485数字流,来不及。
————————————————
版权声明:本文为CSDN博主「子正」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/twicave/article/details/131676650
|