#include #include #include "FreeRTOS.h" #include "board.h" #include "chip.h" #include "sfud.h" #include "romfile.h" #include "animation.h" #include "sysinfo.h" #include "mmcsd_core.h" #include "ff_stdio.h" #include "crc.h" #include "mailbox_message.h" #include "mailbox_update/mailbox_update_demo.h" #if DEVICE_TYPE_SELECT != EMMC_FLASH #include "ff_sfdisk.h" #endif #ifdef USB_SUPPORT #define USB_DEV_PLUGED 0 #define USB_DEV_UNPLUGED 1 extern int usb_wait_stor_dev_pluged(uint32_t timeout); #endif #ifdef OTA_UPDATE_SUPPORT #include "ota_update.h" const char *g_upfilename[UPFILE_TYPE_NUM] = { "amtldr.bin", "amt630hv160.bin", "bootanim.bin", "rom.bin", "image.bin", "fastboot.bin", }; uint8_t empty_chip_update_ok = 0; uint8_t upfile_updated = 0; #ifdef MAILBOX_SUPPORT static void update_status_sync(void) { if(mailbox_msg_send(MB_MSG_T_SYS_UPDATE, NULL, 0, portMAX_DELAY)) printf("%s, mailbox send fail.\n", __func__); } #endif #define UPDATE_PROGRESS_SUPPORT #define UPDATE_DONE_DISPLAY #ifdef UPDATE_PROGRESS_SUPPORT static const unsigned char font_char[] = { ',','.','a','b','c','d','e','g','i','l','m','n','o','p','r','s','t','u','w' }; static const unsigned char fontdata_16x32[] = { 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x3C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x08,0x00,0x30,0x00,0x60,0x00,/*",",12*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x3C,0x00,0x3C,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*".",14*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xE0,0x18,0x30,0x30,0x18,0x30,0x18,0x30,0x18, 0x00,0x38,0x07,0xD8,0x1C,0x18,0x30,0x18,0x60,0x18,0x60,0x18,0x60,0x18,0x60,0x19,0x30,0x79,0x1F,0x8E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"a",65*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x78,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x19,0xE0,0x1A,0x38,0x1C,0x18,0x1C,0x0C,0x18,0x0C, 0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x08,0x1C,0x18,0x1C,0x30,0x13,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"b",66*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE0,0x0E,0x10,0x0C,0x18,0x18,0x18,0x30,0x18, 0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x04,0x18,0x04,0x18,0x08,0x0C,0x10,0x03,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"c",67*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x78,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x07,0xD8,0x0C,0x38,0x18,0x18,0x18,0x18,0x30,0x18, 0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x10,0x18,0x18,0x38,0x0C,0x5E,0x07,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"d",68*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x0C,0x30,0x08,0x18,0x18,0x08,0x30,0x0C, 0x30,0x0C,0x30,0x0C,0x3F,0xFC,0x30,0x00,0x30,0x00,0x30,0x00,0x18,0x04,0x18,0x08,0x0E,0x18,0x03,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"e",69*/ // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x01,0x86,0x01,0x06,0x03,0x06,0x03,0x00,0x03,0x00,0x03,0x00,0x3F,0xF8,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00, // 0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x1F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"f",70*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xEE,0x0C,0x36,0x08,0x18,0x18,0x18,0x18,0x18, 0x18,0x18,0x08,0x18,0x0C,0x30,0x0F,0xE0,0x18,0x00,0x18,0x00,0x1F,0xC0,0x0F,0xF8,0x18,0x1C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x18,0x18,0x07,0xE0,/*"g",71*/ // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x78,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x19,0xE0,0x1A,0x30,0x1C,0x18,0x18,0x18,0x18,0x18, // 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"h",72*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0xC0,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80, 0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x1F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"i",73*/ // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x78,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x03,0xF0,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30, // 0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,0x18,0x60,0x18,0x40,0x0F,0x80,/*"j",74*/ // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x78,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x7C,0x18,0x30,0x18,0x20,0x18,0x40,0x18,0x80, // 0x19,0x80,0x1B,0x80,0x1E,0xC0,0x1C,0xC0,0x18,0x60,0x18,0x30,0x18,0x30,0x18,0x18,0x18,0x1C,0x7E,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"k",75*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x1F,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80, 0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x1F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"l",76*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xEF,0x3C,0x71,0xC6,0x61,0x86,0x61,0x86,0x61,0x86, 0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0xF3,0xCF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"m",77*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0xE0,0x7A,0x30,0x1C,0x18,0x18,0x18,0x18,0x18, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"n",78*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC0,0x0C,0x30,0x08,0x18,0x18,0x18,0x10,0x0C, 0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x30,0x0C,0x18,0x18,0x18,0x18,0x0C,0x30,0x03,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"o",79*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0xE0,0x7A,0x30,0x1C,0x18,0x18,0x08,0x18,0x0C, 0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x0C,0x18,0x18,0x1C,0x18,0x1E,0x30,0x19,0xE0,0x18,0x00,0x18,0x00,0x18,0x00,0x7E,0x00,/*"p",80*/ // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xC8,0x0C,0x78,0x18,0x38,0x18,0x18,0x30,0x18, // 0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x30,0x18,0x10,0x18,0x18,0x38,0x0C,0x78,0x07,0x98,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x7E,/*"q",81*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x1C,0x7E,0x66,0x06,0x86,0x07,0x80,0x07,0x00, 0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x7F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"r",82*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xE4,0x06,0x1C,0x0C,0x0C,0x0C,0x04,0x0C,0x04, 0x0E,0x00,0x07,0xC0,0x01,0xF0,0x00,0x78,0x00,0x1C,0x10,0x0C,0x10,0x0C,0x18,0x0C,0x1C,0x18,0x13,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"s",83*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x03,0x00,0x07,0x00,0x3F,0xF8,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00, 0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x03,0x04,0x03,0x04,0x01,0x88,0x00,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"t",84*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x78,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x38,0x0C,0x5E,0x07,0x90,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"u",85*/ // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x3E,0x18,0x0C,0x18,0x08,0x18,0x18,0x0C,0x10, // 0x0C,0x10,0x04,0x20,0x06,0x20,0x06,0x20,0x03,0x40,0x03,0x40,0x03,0xC0,0x01,0x80,0x01,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"v",86*/ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFB,0xCF,0x61,0x86,0x21,0x84,0x31,0x84,0x31,0x84, 0x31,0xC8,0x11,0xC8,0x1A,0xC8,0x1A,0x48,0x1A,0x70,0x0E,0x70,0x0C,0x70,0x0C,0x30,0x0C,0x20,0x04,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"w",87*/ // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x7C,0x0C,0x10,0x0E,0x10,0x06,0x20,0x03,0x40, // 0x03,0x40,0x01,0x80,0x01,0x80,0x01,0xC0,0x02,0x60,0x04,0x60,0x04,0x30,0x08,0x18,0x18,0x18,0x7C,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"x",88*/ // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x3E,0x18,0x18,0x18,0x10,0x08,0x10,0x0C,0x10, // 0x04,0x20,0x06,0x20,0x06,0x20,0x02,0x40,0x03,0x40,0x01,0x40,0x01,0x80,0x01,0x80,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x3E,0x00,0x3C,0x00,/*"y",89*/ // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x30,0x38,0x30,0x30,0x20,0x60,0x20,0xE0, // 0x00,0xC0,0x01,0x80,0x03,0x80,0x03,0x00,0x06,0x00,0x0E,0x04,0x0C,0x04,0x18,0x0C,0x30,0x18,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,/*"z",90*/ }; #define UPDATE_TEXT_WIDTH 400 #define UPDATE_TEXT_HEIGHT 36 #define PROGRESS_WIDTH 400 #define PROGRESS_HEIGHT 52 #define UPDATE_LOGO_WIDTH PROGRESS_WIDTH #define UPDATE_LOGO_HEIGHT (UPDATE_TEXT_HEIGHT + PROGRESS_HEIGHT) #if LCD_BPP == 32 typedef unsigned int Upcolor; #define UPDATE_TEXT_COLOR 0xffffffff; //white #define UPDATE_RECT_COLOR 0xffffffff //white #define UPDATE_BAR_COLOR 0xff00ff00; //green #elif LCD_BPP == 16 typedef unsigned short Upcolor; #define UPDATE_TEXT_COLOR 0xffff; //white #define UPDATE_RECT_COLOR 0xffff; //white #define UPDATE_BAR_COLOR 0x07e0; //green #endif static uint32_t upfile_total_size; static uint32_t upfile_left_size; static uint32_t logo_display_addr; static uint32_t pxp_display_addr; static int update_start = 0; static int update_percent = -1; static uint32_t line_width; void DrawPixel(int x, int y) { Upcolor *p = (Upcolor *)(logo_display_addr + y * line_width + x * LCD_BPP / 8); *p = UPDATE_TEXT_COLOR; } unsigned const char *GetCharDot(unsigned char c) { int i = 0; for (i = 0;i < sizeof(font_char); i++) { if(c == font_char[i]) return &fontdata_16x32[i * 64]; } return NULL; } void DrawCharToCanvas(int x, int y, unsigned char c) { unsigned short *dots = NULL; unsigned short byte; int i, b; dots = GetCharDot(c); if (!dots) { if(c != ' ') printf("%s, Character not supported.\n", __func__); return; } for (i = 0; i < 32; i++) { byte = (((dots[i] & 0xff00) >> 8 ) | ((dots[i] & 0xff) << 8)); for (b = 15; b >= 0; b--) { if(byte & (1< (height -3) || i < 2 || i > (PROGRESS_WIDTH -3)) { *p = color; } p++; } } } void update_progress_set(int percent) { int i, j, end; unsigned int memstart = logo_display_addr + UPDATE_TEXT_WIDTH * UPDATE_TEXT_HEIGHT * LCD_BPP / 8; Upcolor *p = (Upcolor *)memstart; int height = UPDATE_LOGO_HEIGHT; Upcolor color = UPDATE_BAR_COLOR; if (percent < 0 || percent > 100) return; if (!update_start || percent == update_percent) return; update_percent = percent; end = percent * (PROGRESS_WIDTH - 3) / 100; for (j = UPDATE_TEXT_HEIGHT; j < height; j++) { for (i = 0; i < PROGRESS_WIDTH; i++) { if (j > (UPDATE_TEXT_HEIGHT + 2) && j < (height -3) \ && i > 2 && i < end) { *p = color; } p++; } } CP15_clean_dcache_for_dma((unsigned int)memstart, (unsigned int)memstart + PROGRESS_WIDTH *PROGRESS_HEIGHT * LCD_BPP / 8); #if LCD_ROTATE_ANGLE != LCD_ROTATE_ANGLE_0 uint32_t out_width, out_height; #if LCD_ROTATE_ANGLE == LCD_ROTATE_ANGLE_180 out_width = UPDATE_LOGO_WIDTH; out_height = UPDATE_LOGO_HEIGHT; #else out_width = UPDATE_LOGO_HEIGHT; out_height = UPDATE_LOGO_WIDTH; #endif pxp_scaler_rotate(logo_display_addr, 0, 0, PXP_S0_FORMAT_RGB888, UPDATE_LOGO_WIDTH, UPDATE_LOGO_HEIGHT, pxp_display_addr, 0, PXP_OUT_FORMAT_ARGB888, out_width, out_height, LCD_ROTATE_ANGLE); #endif } static void update_logo_exit(void) { if (logo_display_addr) { vPortFree((void *)logo_display_addr); logo_display_addr = 0; } if (pxp_display_addr) { vPortFree((void *)pxp_display_addr); pxp_display_addr = 0; } update_start = 0; } static int update_logo_init(void) { int x, y; uint32_t width = UPDATE_LOGO_WIDTH; uint32_t height = UPDATE_LOGO_HEIGHT; if (update_start) return 0; logo_display_addr = (uint32_t)pvPortMalloc(width * height * LCD_BPP / 8); if (logo_display_addr == 0) { printf("%s malloc fail.\n", __func__); return -1; } memset((void *)logo_display_addr, 0, width *height * LCD_BPP / 8); #if LCD_ROTATE_ANGLE != LCD_ROTATE_ANGLE_0 uint32_t out_width; uint32_t out_height; pxp_display_addr = (uint32_t)pvPortMalloc(width *height * LCD_BPP / 8); if (pxp_display_addr == 0) { printf("%s malloc fail.\n", __func__); return -1; } #endif line_width = UPDATE_TEXT_WIDTH * LCD_BPP / 8; update_text_init(); update_progress_init(); CP15_clean_dcache_for_dma(logo_display_addr, logo_display_addr + width *height * LCD_BPP / 8); #if LCD_ROTATE_ANGLE != LCD_ROTATE_ANGLE_0 #if LCD_ROTATE_ANGLE == LCD_ROTATE_ANGLE_180 out_width = width; out_height = height; #else out_width = height; out_height = width; #endif ark_lcd_set_osd_format(LCD_OSD1, LCD_OSD_FORAMT_ARGB888); ark_lcd_set_osd_size(LCD_OSD1, out_width, out_height); pxp_scaler_rotate(logo_display_addr, 0, 0, PXP_S0_FORMAT_RGB565, width, height, pxp_display_addr, 0, PXP_OUT_FORMAT_RGB565, out_width, out_height, LCD_ROTATE_ANGLE); ark_lcd_set_osd_yaddr(LCD_OSD1, pxp_display_addr); y = (LCD_HEIGHT - out_height) / 2; x = (LCD_WIDTH - out_width) / 2; #else ark_lcd_set_osd_format(LCD_OSD1, LCD_OSD_FORAMT_ARGB888); ark_lcd_set_osd_size(LCD_OSD1, width, height); ark_lcd_set_osd_yaddr(LCD_OSD1, logo_display_addr); x = (LCD_WIDTH - width) / 2; y = (LCD_HEIGHT - height) / 2; #endif ark_lcd_set_osd_possition(LCD_OSD1, x, y); ark_lcd_osd_enable(LCD_OSD1, 1); ark_lcd_set_osd_sync(LCD_OSD1); update_start = 1; return 0; } #endif uint8_t get_update_status(void) { return upfile_updated & 0x1; } #ifdef MAILBOX_UPDATE_SUPPORT static int MediaUpdateMCU(const char *ufile, int filetype) { int ret = -1; FF_FILE *fp; uint8_t *buf; int rlen, leftsize; uint32_t filesize; MailboxUpdateFrame tx_frame = {0}; MailboxUpdateFrame *rx_frame = NULL; mb_rxmsg_t msg = {0}; fp = ff_fopen(ufile, "rb"); if (!fp) { printf("open %s fail.\n", ufile); return ret; } leftsize = filesize = ff_filelength(fp); if (filesize > DDR_MEDIA_USE_SIZE) { printf("The file is too large, not enough space to save.\n"); goto MediaUpdateEnd; } CP15_flush_dcache_for_dma(DDR_MEDIA_USE_ADDR, DDR_MEDIA_USE_ADDR + filesize);//防止模块使用dma,导致cache中的旧数据覆盖DDR /* start transfer image_header*/ buf = (uint8_t *)DDR_MEDIA_USE_ADDR; /* transfer all data */ while (leftsize) { rlen = ff_fread(buf, 1, OTA_RW_SIZE, fp); if (rlen < 0 || ((rlen == 0) && leftsize)) { printf("read %s data fail.\n", ufile); ret = -1; goto MediaUpdateEnd; } buf += rlen; leftsize -= rlen; } tx_frame.DataAddr = DDR_MEDIA_USE_ADDR; tx_frame.DataSize = filesize; tx_frame.TotalSize = filesize; tx_frame.FileType = filetype; // tx_frame.FrameStatus = MUFS_TFR; //一次传输所有数据,等待响应; tx_frame.FrameRspStatus = MUFRS_ACK_OK; CP15_clean_dcache_for_dma(tx_frame.DataAddr, tx_frame.DataAddr + tx_frame.DataSize); if (ret = MailboxUpdateSendFrame(MB_MSG_T_MEDIA_UPDATE, &tx_frame)) goto MediaUpdateEnd; if (!(rx_frame = MailboxUpdateReceiveFrame(MB_MSG_T_MEDIA_UPDATE, &msg, pdMS_TO_TICKS(30000)))) { ret = -1; goto MediaUpdateEnd; } if (rx_frame->FrameRspStatus == MUFRS_ACK_OK) { upfile_updated = 1; printf("burn %s ok.\n", ufile); } MediaUpdateEnd: if (fp) ff_fclose(fp); return ret; } #endif /* 获取已升级文件校验和 filesize 0:获取当前运行文件的校验和,非0值:获取烧录位置升级文件的校验和; checkmode 0:不校验 1:进行校验,校验错误返回0 2:进行校验,校验出错也返回校验值 */ uint32_t get_upfile_checksum(int filetype, size_t filesize, int checkmode) { uint32_t checksum, calc_checksum = 0xffffffff; uint8_t *buf; #if DEVICE_TYPE_SELECT != EMMC_FLASH sfud_flash *sflash = sfud_get_device(0); #endif uint32_t fileoffset; int off, size, leftsize; buf = pvPortMalloc(OTA_RW_SIZE); if (!buf) { printf("%s %d malloc %d bytes fail.\n", __func__, __LINE__, OTA_RW_SIZE); return 0; } if (!filesize) { fileoffset = get_upfile_offset(filetype, 0); filesize = get_upfile_size(filetype); } else { fileoffset = get_upfile_offset(filetype, 1); } size = filesize > OTA_RW_SIZE ? OTA_RW_SIZE : filesize; #if DEVICE_TYPE_SELECT == EMMC_FLASH emmc_read(fileoffset, size, buf); #else sfud_read(sflash, fileoffset, size, buf); #endif if (filetype == UPFILE_TYPE_APP || filetype == UPFILE_TYPE_LDR) { checksum = *(uint32_t*)(buf + APPLDR_CHECKSUM_OFFSET); *(uint32_t*)(buf + APPLDR_CHECKSUM_OFFSET) = 0; } else if (filetype == UPFILE_TYPE_ANIMATION) { BANIHEADER *header = (BANIHEADER *)buf; checksum = header->checksum; header->checksum = 0; } else if (filetype == UPFILE_TYPE_ROM) { RomHeader *header = (RomHeader *)buf; checksum = header->checksum; header->checksum = 0; } if (!checkmode) { vPortFree(buf); return checksum; } else { calc_checksum = xcrc32(buf, size, calc_checksum, HARD_CALC_CRC); } off = fileoffset + OTA_RW_SIZE; leftsize = filesize - size; while (leftsize > 0) { size = leftsize > OTA_RW_SIZE ? OTA_RW_SIZE : leftsize; #if DEVICE_TYPE_SELECT == EMMC_FLASH emmc_read(off, size, buf); #else sfud_read(sflash, off, size, buf); #endif calc_checksum = xcrc32(buf, size, calc_checksum, HARD_CALC_CRC); off += size; leftsize -= size; } vPortFree(buf); if (calc_checksum == checksum || checkmode > 1) return calc_checksum; else return 0; } /* 获取外部设备中升级文件的校验和 bchecked 0:不需要计算校验值,非0:需要计算校验值 */ static uint32_t get_mediafile_checksum(const char *ufile, int filetype, int bchecked, uint32_t *filesize) { uint32_t checksum, calc_checksum = 0xffffffff; FF_FILE *fp; uint8_t *buf; int rlen; fp = ff_fopen(ufile, "rb"); if (!fp) { printf("open %s fail.\n", ufile); return 0; } if (filesize) *filesize = ff_filelength(fp); buf = pvPortMalloc(OTA_RW_SIZE); if (!buf) { printf("%s %d malloc %d bytes fail.\n", __func__, __LINE__, OTA_RW_SIZE); ff_fclose(fp); return 0; } rlen = ff_fread(buf, 1, OTA_RW_SIZE, fp); if (rlen <= 0) { printf("read %s data fail.\n", ufile); ff_fclose(fp); vPortFree(buf); return 0; } if (filetype == UPFILE_TYPE_APP || filetype == UPFILE_TYPE_LDR) { checksum = *(uint32_t*)(buf + APPLDR_CHECKSUM_OFFSET); *(uint32_t*)(buf + APPLDR_CHECKSUM_OFFSET) = 0; } else if (filetype == UPFILE_TYPE_ANIMATION) { BANIHEADER *header = (BANIHEADER *)buf; checksum = header->checksum; header->checksum = 0; } else if (filetype == UPFILE_TYPE_ROM) { RomHeader *header = (RomHeader *)buf; checksum = header->checksum; header->checksum = 0; } if (!bchecked) { ff_fclose(fp); vPortFree(buf); return checksum; } else { calc_checksum = xcrc32(buf, rlen, calc_checksum, HARD_CALC_CRC); } while ((rlen = ff_fread(buf, 1, OTA_RW_SIZE, fp)) > 0) calc_checksum = xcrc32(buf, rlen, calc_checksum, HARD_CALC_CRC); ff_fclose(fp); vPortFree(buf); if (calc_checksum == checksum) return checksum; else return 0; } /* 烧录升级文件 fileoffset: 烧录文件偏移地址 show_progress 0:不显示进度条, 1:显示进度条 */ static int burn_update_file(int filetype, const char *ufile, size_t fileoffset, uint8_t show_progress, uint8_t do_check) { FF_FILE *fp; int leftsize, rwsize; int rlen, rwoffset; size_t filesize; int ret = 0; uint8_t *buf = NULL; uint8_t *tmp_buf = NULL; uint32_t checksum, calc_checksum = 0xffffffff; #if DEVICE_TYPE_SELECT != EMMC_FLASH sfud_flash *sflash = sfud_get_device(0); #endif fp = ff_fopen(ufile, "rb"); if (!fp) { printf("open %s fail.\n", ufile); return -1; } buf = pvPortMalloc(OTA_RW_SIZE); if (!buf) { printf("%s %d malloc %d bytes fail.\n", __func__, __LINE__, OTA_RW_SIZE); ret = -1; goto burnend; } if(do_check) { tmp_buf = pvPortMalloc(OTA_RW_SIZE); if (!tmp_buf) { printf("%s %d malloc %d bytes fail.\n", __func__, __LINE__, OTA_RW_SIZE); ret = -1; goto burnend; } } filesize = ff_filelength(fp); rlen = ff_fread(buf, 1, OTA_RW_SIZE, fp); if (rlen <= 0) { printf("read %s data fail.\n", ufile); ret = -1; goto burnend; } leftsize = filesize; rwoffset = fileoffset; while (leftsize > 0) { rwsize = leftsize > rlen ? rlen : leftsize; #if DEVICE_TYPE_SELECT == EMMC_FLASH if (emmc_write(rwoffset, rwsize, buf)) #else if (sfud_erase_write(sflash, rwoffset, rwsize, buf) != SFUD_SUCCESS) #endif { printf("%s, burn %s data fail.\n", __func__, ufile); ret = -1; goto burnend; } if (do_check) { #if DEVICE_TYPE_SELECT == EMMC_FLASH if (emmc_read(rwoffset, rwsize, tmp_buf)) #else if (sfud_read(sflash, rwoffset, rwsize, tmp_buf) != SFUD_SUCCESS) #endif { printf("%s, read %s data fail.\n", __func__, ufile); ret = -1; goto burnend; } if(leftsize == filesize) { if (filetype == UPFILE_TYPE_APP || filetype == UPFILE_TYPE_LDR) { checksum = *(uint32_t*)(buf + APPLDR_CHECKSUM_OFFSET); *(uint32_t*)(tmp_buf + APPLDR_CHECKSUM_OFFSET) = 0; } else if (filetype == UPFILE_TYPE_ANIMATION) { BANIHEADER *header = (BANIHEADER *)tmp_buf; checksum = header->checksum; header->checksum = 0; } else if (filetype == UPFILE_TYPE_ROM) { RomHeader *header = (RomHeader *)tmp_buf; checksum = header->checksum; header->checksum = 0; } } calc_checksum = xcrc32(tmp_buf, rwsize, calc_checksum, HARD_CALC_CRC); } rwoffset += rwsize; leftsize -= rwsize; #ifdef UPDATE_PROGRESS_SUPPORT if (show_progress) { upfile_left_size -= rwsize; update_progress_set(((u64)upfile_total_size - upfile_left_size) * 100 / upfile_total_size); } #endif if (!show_progress) { printf("burn %d/%d.\n", filesize - leftsize, filesize); } rlen = ff_fread(buf, 1, OTA_RW_SIZE, fp); if (rlen < 0 || ((rlen == 0) && leftsize)) { printf("read %s data fail.\n", ufile); ret = -1; goto burnend; } } #if DEVICE_TYPE_SELECT == SPI_NAND_FLASH //sfud_flush(sflash); #endif if (do_check && checksum != calc_checksum) { printf("%s, Check update file fail!\n", __func__); return -1; } burnend: #ifdef UPDATE_PROGRESS_SUPPORT if(leftsize) upfile_left_size += (filesize - leftsize); #endif if (fp) ff_fclose(fp); if (buf) vPortFree(buf); if (tmp_buf) vPortFree(tmp_buf); return ret; } /* 获取ldr, app, animation, rom升级文件单独升级时能支持的最大文件大小 */ unsigned int get_upfile_maxsize(int filetype) { if (filetype == UPFILE_TYPE_LDR) { return LOADER_MAX_SIZE; } else if (filetype == UPFILE_TYPE_APP) { return APPFILE_MAX_SIZE; } else if (filetype == UPFILE_TYPE_ANIMATION) { return ANIMFILE_MAX_SIZE; } else if (filetype == UPFILE_TYPE_ROM) { return ROMFILE_MAX_SIZE; } return 0; } /* 获取升级文件位置 toburn 0:获取当前运行文件的位置,非0:获取新升级文件要烧录的位置 */ unsigned int get_upfile_offset(int filetype, int toburn) { SysInfo *sysinfo = GetSysInfo(); if (filetype == UPFILE_TYPE_LDR) { if (!toburn) return sysinfo->loader_offset; else return (sysinfo->loader_offset == LOADER_OFFSET) ? LOADER_B_OFFSET : LOADER_OFFSET; } else if (filetype == UPFILE_TYPE_APP) { if (!toburn) return sysinfo->app_offset; else return (sysinfo->app_offset == APPFILE_OFFSET) ? APPFILE_B_OFFSET : APPFILE_OFFSET; } else if (filetype == UPFILE_TYPE_ANIMATION) { if (!toburn) return sysinfo->anim_offset; else return (sysinfo->anim_offset == ANIMFILE_OFFSET) ? ANIMFILE_B_OFFSET : ANIMFILE_OFFSET; } else if (filetype == UPFILE_TYPE_ROM) { if (!toburn) return sysinfo->rom_offset; else return (sysinfo->rom_offset == ROMFILE_OFFSET) ? ROMFILE_B_OFFSET : ROMFILE_OFFSET; } return 0xffffffff; } //获取当前运行文件的文件大小 uint32_t get_upfile_size(int filetype) { SysInfo *sysinfo = GetSysInfo(); if (filetype == UPFILE_TYPE_LDR) { return sysinfo->loader_size; } else if (filetype == UPFILE_TYPE_APP) { return sysinfo->app_size; } else if (filetype == UPFILE_TYPE_ANIMATION) { return sysinfo->anim_size; } else if (filetype == UPFILE_TYPE_ROM) { return sysinfo->rom_size; } return 0; } //校验新烧录文件并保存信息 int check_upfile_and_save(int filetype, size_t filesize, size_t fileoffset) { SysInfo *sysinfo = GetSysInfo(); SysInfo bak_sysinfo; if (!filesize) { printf("The burn file size is 0.\n"); return -1; } memcpy(&bak_sysinfo, sysinfo, sizeof(SysInfo)); if (get_upfile_checksum(filetype, filesize, 1)) { if (filetype == UPFILE_TYPE_LDR) { bak_sysinfo.loader_offset = fileoffset; bak_sysinfo.loader_size = filesize; } else if (filetype == UPFILE_TYPE_APP) { bak_sysinfo.app_offset = fileoffset; bak_sysinfo.app_size = filesize; } else if (filetype == UPFILE_TYPE_ANIMATION) { bak_sysinfo.anim_offset = fileoffset; bak_sysinfo.anim_size = filesize; } else if (filetype == UPFILE_TYPE_ROM) { bak_sysinfo.rom_offset = fileoffset; bak_sysinfo.rom_size = filesize; } memcpy(sysinfo, &bak_sysinfo, sizeof(SysInfo)); SaveSysInfo(); return 0; } return -1; } int update_from_media(char *mpath, int filetype) { char update_file[32]; size_t filesize; size_t fileoffset; uint32_t checksum; strcpy(update_file, mpath); strcat(update_file, "/"); strcat(update_file, g_upfilename[filetype]); printf("%s checksum...\n", update_file); if(filetype <= UPFILE_TYPE_ROM) { if (!(checksum = get_mediafile_checksum(update_file, filetype, 1, &filesize))) { printf("checksum fail, don't update.\n"); return 0; } if (filesize > get_upfile_maxsize(filetype)) { printf("The file is too large, not enough space to save.\n"); return -1; } if (checksum == get_upfile_checksum(filetype, 0, 0)) { printf("checksum is the same as now, don't update.\n"); return 0; } fileoffset = get_upfile_offset(filetype, 1); if (fileoffset == 0xffffffff) { printf("get_upfile_offset fail.\n"); return -1; } if (burn_update_file(filetype, update_file, fileoffset, 0, 0)) { printf("burn %s fail, don't update.\n", update_file); return -1; } printf("checksum after burn...\n"); if (!check_upfile_and_save(filetype, filesize, fileoffset)) { upfile_updated = 1; printf("burn %s ok.\n", update_file); return 0; } else { printf("checksum after burn fail.\n"); return -1; } } else if (filetype <= UPFILE_TYPE_MCU_FB) { #ifdef MAILBOX_UPDATE_SUPPORT return MediaUpdateMCU(update_file, filetype); #else printf("Should define MAILBOX_UPDATE_SUPPORT to support image.bin update.\n"); #endif } return -1; } static int save_file_to_ota(int filetype) { char update_file[32]; char ota_file[32]; FF_FILE *fp, *fota; size_t filesize; int leftsize; uint8_t *buf = NULL; size_t readlen; strcpy(update_file,"/usb/"); strcat(update_file, g_upfilename[filetype]); strcpy(ota_file, OTA_MOUNT_PATH "/"); strcat(ota_file, g_upfilename[filetype]); if (get_mediafile_checksum(update_file, filetype, 0, &filesize) == get_mediafile_checksum(ota_file, filetype, 0, NULL)) { if (get_mediafile_checksum(ota_file, filetype, 1, NULL)) { printf("%s is same with ota, not save.\n", g_upfilename[filetype]); return 0; } } fp = ff_fopen(update_file, "rb"); if (!fp) { printf("open %s fail.\n", update_file); return -1; } fota = ff_fopen(ota_file, "wb"); if (!fota) { printf("create %s in ota partition fail.\n", ota_file); ff_fclose(fp); return -1; } buf = pvPortMalloc(OTA_RW_SIZE); if (!buf) { printf("malloc OTA_RW_SIZE fail.\n"); ff_fclose(fota); ff_fclose(fp); return -1; } leftsize = filesize; while (leftsize > 0) { if (readlen = ff_fread(buf, 1, OTA_RW_SIZE, fp)) { if (ff_fwrite(buf, 1, readlen, fota) != readlen) { printf("write ota data fail.\n"); break; } else { printf("write ota data %d/%d.\n", filesize - leftsize + readlen, filesize); } } else { break; } leftsize -= readlen; } ff_fclose(fota); ff_fclose(fp); vPortFree(buf); if (leftsize == 0) { printf("save file ok.\n"); return 0; } return -1; } static void empty_chip_update_from_media(char *mpath) { char update_file[UPFILE_TYPE_NUM][32] = {0}; size_t upfile_size[UPFILE_TYPE_NUM]; size_t upfile_offset; int i; size_t filesize; uint8_t retry; SysInfo b_sysinfo; SysInfo *sysinfo = GetSysInfo(); FF_FILE *fp; memcpy(&b_sysinfo, sysinfo, sizeof(SysInfo)); #ifdef UPDATE_PROGRESS_SUPPORT upfile_total_size = 0; #endif for (i = UPFILE_TYPE_ANIMATION; i <= UPFILE_TYPE_ROM; i++) { sprintf(update_file[i], "%s/%s", mpath, g_upfilename[i]); fp = ff_fopen(update_file[i], "rb"); if (!fp) { printf("open %s fail,don't update.\n", update_file[i]); goto end; } filesize = ff_filelength(fp); ff_fclose(fp); if (filesize > get_upfile_maxsize(i)) { printf("%s is too large, not enough space to save.\n", g_upfilename[i]); goto end; } #ifdef UPDATE_PROGRESS_SUPPORT upfile_total_size += filesize; #endif upfile_size[i] = filesize; } #ifdef UPDATE_PROGRESS_SUPPORT upfile_left_size = upfile_total_size; update_logo_init(); #endif for (i = UPFILE_TYPE_ANIMATION; i <= UPFILE_TYPE_ROM; i++) { printf("burn %s start.\n", g_upfilename[i]); if (i == UPFILE_TYPE_LDR) { b_sysinfo.loader_offset = upfile_offset = LOADER_OFFSET; b_sysinfo.loader_size = upfile_size[i]; } else if (i == UPFILE_TYPE_APP) { b_sysinfo.app_offset = upfile_offset = APPFILE_OFFSET; b_sysinfo.app_size = upfile_size[i]; } else if (i == UPFILE_TYPE_ANIMATION) { b_sysinfo.anim_offset = upfile_offset = ANIMFILE_OFFSET; b_sysinfo.anim_size = upfile_size[i]; } else if (i == UPFILE_TYPE_ROM) { b_sysinfo.rom_offset = upfile_offset = ROMFILE_OFFSET; b_sysinfo.rom_size = upfile_size[i]; } retry = 0; burnretry: if (burn_update_file(i, update_file[i], upfile_offset, 1, 1)) { if (retry++ < 3) { printf("burn %s fail, retry %d.\n", g_upfilename[i], retry); goto burnretry; } else { printf("burn %s fail, don't update.\n", g_upfilename[i]); goto end; } } printf("burn %s end.\n", g_upfilename[i]); if (i == UPFILE_TYPE_ROM) empty_chip_update_ok = 1; } end: if (empty_chip_update_ok) { printf("update ok, save sysinfo.\n"); b_sysinfo.update_status = UPDATE_STATUS_END; memcpy(sysinfo, &b_sysinfo, sizeof(SysInfo)); SaveSysInfo(); #ifdef MAILBOX_SUPPORT update_status_sync(); #endif #ifdef UPDATE_PROGRESS_SUPPORT update_done(); //vTaskDelay(pdMS_TO_TICKS(10000)); #endif } else { #ifdef UPDATE_PROGRESS_SUPPORT ark_lcd_set_osd_yaddr(LCD_OSD1, ark_lcd_get_virt_addr()); ark_lcd_set_osd_sync(LCD_OSD1); update_logo_exit(); #endif printf("update from %s fail.\n", mpath); } } static void empty_chip_update_thread(void *param) { SysInfo *sysinfo = GetSysInfo(); unsigned int status = 0; for (;;) { if (empty_chip_update_ok) { vTaskDelay(portMAX_DELAY); } else { switch (sysinfo->update_media_type) { #ifdef USB_SUPPORT case UPDATE_FROM_MEDIA_USB_HOST: status = usb_wait_stor_dev_pluged(portMAX_DELAY); if (status == USB_DEV_PLUGED) { printf("usb dev inserted.\n"); empty_chip_update_from_media("/usb"); } else if (status == USB_DEV_UNPLUGED) { printf("usb removed.\n"); } break; #endif #ifdef SDMMC1_SUPPORT case UPDATE_FROM_MEDIA_SD: if (!status) { mmcsd_wait_sdio_ready_by_name("/sd",portMAX_DELAY); empty_chip_update_from_media("/sd"); } else { mmcsd_wait_sdio_unready_by_name("/sd",portMAX_DELAY); printf("card removed.\n"); } status = !status; break; #endif default: printf("Unknown update mode, please reconfigure before power on!\n"); while (1); } } } } void empty_chip_update_demo(void) { SysInfo *sysinfo = GetSysInfo(); // sysinfo->update_status = UPDATE_STATUS_START; // sysinfo->update_media_type = UPDATE_FROM_MEDIA_USB_HOST; if (sysinfo->update_status == UPDATE_STATUS_START) { printf("cpu entry empty update...\n"); if (xTaskCreate(empty_chip_update_thread, "empty_chip_update", configMINIMAL_STACK_SIZE * 4, NULL, configMAX_PRIORITIES / 2, NULL) != pdPASS) { printf("create update task fail.\n"); return; } while (1); } } #ifdef WIFI_UPDATE_SUPPORT #define USB_DEV_PLUGED 0 #define USB_DEV_UNPLUGED 1 extern int usb_wait_stor_dev_pluged(uint32_t timeout); /* 用从usb读取数据来模拟wifi接收升级数据,真实的wifi接收升级文件 需要和端app适配,需要客户自己实现 */ static void wifi_update_demo_thread(void *para) { #if DEVICE_TYPE_SELECT != EMMC_FLASH FF_Disk_t *sfdisk = FF_SFDiskInit(SF_MOUNT_PATH); if (sfdisk) #endif { unsigned int status; int filetype; for (;;) { status = usb_wait_stor_dev_pluged(portMAX_DELAY); if (status == USB_DEV_PLUGED) { printf("usb dev inserted.\n"); for (filetype = UPFILE_TYPE_LDR; filetype < UPFILE_TYPE_NUM; filetype++) { if (save_file_to_ota(filetype)) { printf("save_file_to_ota fail.\n"); } else { printf("start to update from ota...\n"); update_from_media(OTA_MOUNT_PATH, filetype); } } } else { printf("usb removed.\n"); } } } for (;;) vTaskDelay(portMAX_DELAY); } void wifi_update_demo(void) { if (xTaskCreate(wifi_update_demo_thread, "wifiupdate", configMINIMAL_STACK_SIZE * 16, NULL, 1, NULL) != pdPASS) { printf("create wifi update demo task fail.\n"); } } #endif #endif