//------------------------------------------------------------------------------- // File Name: boottasks.c // Brief: // Version: 1.1.0 // Create Date: 2020/07/31 // Create by: Marshal Lee // Copyright: // Copyright (c) 2019, GetonAgain Co., LTD. // All rights reserved. // // Modify by: Marshal Lee // Modify Date: 2020/07/31 //------------------------------------------------------------------------------- #include "boottasks.h" #if (CUR_CORE_BOARD == CORE_BOARD_BOOT) #include "trigger.h" #include "shell.h" #include "delay.h" #include "xmodem.h" #include "serial.h" #include "inout.h" #include "norflash.h" #include "stiap.h" #include "stapp.h" #include "smec98sp.h" #include "operator.h" void InitBootloader(void); int WaitForInput(void); void BootMainTask(void) { int rslt; InitTrigger(); // 初始化定时触发功能 InitShell(); // 初始化Shell命令 printf("\r\n================== Bootloader ==================\r\n"); do {// 上电2秒内,检测加密芯片是否正常 #if (USE_SMEC != 0) rslt = SMEC_Detection(); #else rslt = 0; #endif if (rslt == 0) { break; } else {// 加密芯片不正常,指示灯1长3短 printf("Err: Encryption chip access failed!\r\n"); SetLedOn(); DelayMs(2000); SetLedOff(); DelayMs(300); SetLedOn(); DelayMs(200); SetLedOff(); DelayMs(300); SetLedOn(); DelayMs(200); SetLedOff(); DelayMs(300); SetLedOn(); DelayMs(200); SetLedOff(); DelayMs(2000); } }while(1); InitBootloader(); printf("Bootloader init ok\r\n"); rslt = WaitForInput(); if (rslt == 0) // 没有输入 { UpdateApp(); // 升级主控文件 JumpToApp(); // 进入APP } else { DelayMs(100); printf("Get input, enter update\r\n"); } //---------------------------- InitOperator(); // 初始化操作箱 do { TriggerTask(); // ShellTask(); OperatorTaskWhenBoot(); #if (0) // 测试循环速度 static u32 timer = 0; static u32 temp; static int runcount = 0; runcount++; temp = GetMsSoftTimer(); if (temp - timer >= 1000) { timer = temp; printf("run circle = %d/s\r\n", runcount); runcount = 0; } #endif }while(1); } //-------------------------------------------------- int WaitForInput(void) { int rslt; int timer, tptimer; int steps; printf("Press ENTER into bootloader\r\n"); DelayMs(100); rslt = 0; steps = 0; timer = GetMsSoftTimer(); do { TriggerTask(); // if (ShellTask() >= 0) // 如果串口有命令,那么执行响应 { #if (0) if (GetHistoryNum() > 0) { char input[20]; int tmprst = GetHistoryCmd(0, &input[0]); if (tmprst == 0 && strcmp(input, "ver") == 0) { rslt = 1; break; } } #else rslt = 1; break; #endif } tptimer = GetMsSoftTimer(); if (tptimer - timer > steps) { PutChar('.'); steps += 100; } if (tptimer - timer > 1000) // 1秒内没有输入 { rslt = 0; break; } }while(1); printf("\r\n"); return rslt; } //-------------------------------------------------- void LoadApp(char * para1, char * para2); void JpToApp(char * para1, char * para2); //--------------------------------------------------- void InitBootloader(void) { printf("Begin bootloader task\r\n"); InitNorSpi(); // 初始化 nor flash 访问 SPI SNFlashInit(SetNorSpiNssOn, SetNorSpiNssOff, NorSpiReadByte, NorSpiWriteByte); // 初始化nor flash 并注册读写函数 AddShellCmd("LOADAPP", "load the app", LoadApp); AddShellCmd("JUMPTOAPP", "jump to app", JpToApp); AddTriggerToList(100, SetLedToggle, NULL); // 100ms 闪灯任务 } #if (CONSOLE_PORT == COMM_USART1) #define CLEAN_RS_BUFF Usart1CleanRsBuf #define IS_SDBUF_EMPTY IsUsart1SendBufEmpty #define GET_DATA Usart1GetData #define SEND_DATA Usart1SendData #define GET_RS_LEN Usart1GetRsLen #endif // 从串口,网络或存储器 下载APP void LoadApp(char * para1, char * para2) { int rsv = 'x'; int com = 1; int rslt = 0; // IAPCleanUpdateArea(); // 擦除nand APP 存储区域, if (para1 != NULL) { if (strcmp(para1, "") == 0 || strcmp(para1, "x") == 0 || strcmp(para1, "X") == 0 || 0 ) { rsv = 'x'; // xmodem if (para2 != NULL) { com = atoi(para2); if (com <= 0 || com > 2) { com = 1; } } } else if (strcmp(para1, "t") == 0 || strcmp(para1, "T") == 0 || 0 ) { rsv = 't'; // 网络 } else if (strcmp(para1, "s") == 0 || strcmp(para1, "S") == 0 || 0 ) { rsv = 's'; // 串口 } else { } } if (rsv == 'x') { int timer; XmodemCtrl xctrl; printf("receive by xmodem start\r\n"); if (com == 1) { SetPauseStatus(1); // 关闭终端 CLEAN_RS_BUFF(); // 读空接收buff // 等到发送buff为空 timer = GetMsSoftTimer(); // 记录时间 do { if (IS_SDBUF_EMPTY() == TRUE) { break; } if (GetMsSoftTimer() - timer > 2000) // 判断是否超时 { SetPauseStatus(0); // 打开终端 } }while(1); // 注册函数 xctrl.XmodemInBuff = GET_DATA; xctrl.XmodemOutBuff = SEND_DATA; xctrl.XmodemGetInBuffLen = GET_RS_LEN; xctrl.XmodemCleanBuff = CLEAN_RS_BUFF; xctrl.InitSave = InitSaveApp; xctrl.SaveData = SaveAppData; xctrl.savedsize = 0; rslt = XmodemReceive(&xctrl); // 等到发送buff为空 timer = GetMsSoftTimer(); // 记录时间 do { if (IS_SDBUF_EMPTY() == TRUE) { break; } if (GetMsSoftTimer() - timer > 2000) // 判断是否超时 { SetPauseStatus(0); // 打开终端 } }while(1); CLEAN_RS_BUFF(); // 读空接收buff SetPauseStatus(0); // 打开终端 OutDebugBufInfo(); } else { // 暂时不支持 printf("1. not support com port=%d\r\n", com); } printf("\r\nreceive by xmodem end\r\n"); if (rslt == 1) { printf("receive done, check is save data correct\r\n"); rslt = IsAppReceiveDone(); // 判断是否接收完成,并读取数据量 if (rslt == xctrl.savedsize) { StartAppUpdate(0); // 验证是否保存成功 } else { printf("receive size not equ, xctrl.savedsize=%d, received=%d\r\n", xctrl.savedsize, rslt); } } else { printf("receive not finish\r\n"); } } else { // 暂时不支持 printf("2. not support comm type=%c\r\n", rsv); } } void JpToApp(char * para1, char * para2) { JumpToApp(); // 进入APP } #endif