2024-09-28 14:24:04 +08:00
|
|
|
|
/****************************************************************************
|
|
|
|
|
|
|
|
|
|
Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
|
|
|
|
|
|
|
|
|
|
This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
|
|
|
|
|
be copied by any method or incorporated into another program without
|
|
|
|
|
the express written consent of Aerospace C.Power. This Information or any portion
|
|
|
|
|
thereof remains the property of Aerospace C.Power. The Information contained herein
|
|
|
|
|
is believed to be accurate and Aerospace C.Power assumes no responsibility or
|
|
|
|
|
liability for its use in any way and conveys no license or title under
|
|
|
|
|
any patent or copyright and makes no representation or warranty that this
|
|
|
|
|
Information is free from patent or copyright infringement.
|
|
|
|
|
|
|
|
|
|
****************************************************************************/
|
|
|
|
|
#include "os_types.h"
|
|
|
|
|
|
|
|
|
|
#include "ahb.h"
|
|
|
|
|
#include "apb.h"
|
|
|
|
|
#include "flash.h"
|
|
|
|
|
#include "common.h"
|
|
|
|
|
#include "decomp.h"
|
|
|
|
|
#include "watchdog.h"
|
|
|
|
|
|
|
|
|
|
#include "iot_mtd.h"
|
|
|
|
|
#include "iot_img_hdr.h"
|
|
|
|
|
#include "iot_system.h"
|
|
|
|
|
#include "iot_flash_layout.h"
|
|
|
|
|
|
|
|
|
|
#include "iot_crc_api.h"
|
|
|
|
|
#include "iot_errno_api.h"
|
|
|
|
|
|
|
|
|
|
#include "sbl_boot.h"
|
|
|
|
|
#include "sbl_boot_hw.h"
|
|
|
|
|
#include "sbl_printf.h"
|
|
|
|
|
|
|
|
|
|
/* Timer reg */
|
|
|
|
|
#define GP_TMR_BASE_ADDR 0x44003000
|
|
|
|
|
#define GTMR0_CTRL_CFG_ADDR (GP_TMR_BASE_ADDR + 0x04)
|
|
|
|
|
#define GTMR0_CFG_ADDR (GP_TMR_BASE_ADDR + 0x08)
|
|
|
|
|
#define GTMR0_INT_STS_ADDR (GP_TMR_BASE_ADDR + 0x0c)
|
|
|
|
|
#define GTMR0_CLR_ADDR (GP_TMR_BASE_ADDR + 0x14)
|
|
|
|
|
#define GTMR0_CNT_DONE (0x2)
|
|
|
|
|
|
|
|
|
|
//FW address mapping
|
|
|
|
|
#define FW_FLASH_ADDR 0x1c020000
|
|
|
|
|
#define FW_RAM_ADDR 0x18000000
|
|
|
|
|
|
|
|
|
|
extern uint32_t g_is_first_run;
|
|
|
|
|
extern char sbl_fw_uncp[PARAM_VAL_LEN_MAX];
|
|
|
|
|
|
|
|
|
|
extern void os_mem_cpy(void *dst, const void *src, uint32_t len);
|
|
|
|
|
extern void os_mem_move(void *dst, const void *src, uint32_t len);
|
|
|
|
|
extern int32_t os_mem_cmp(const void *dst, const void *src, uint32_t len);
|
|
|
|
|
extern void os_mem_set(void *ptr, uint8_t value, uint32_t len);
|
|
|
|
|
|
|
|
|
|
extern str_format_context log_ctxt;
|
|
|
|
|
extern int format_str_v(const str_format_context *ctxt, const char *format,
|
|
|
|
|
va_list ap);
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_boot_hw_init(): hardware init.
|
|
|
|
|
* @return -1: failed; 0: succeed.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t sbl_boot_hw_init(void)
|
|
|
|
|
{
|
|
|
|
|
flash_init(0);
|
|
|
|
|
|
|
|
|
|
sbl_printf_init(format_str_v, &log_ctxt);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_wdg_ena(): enable watchdog.
|
|
|
|
|
* @return none.
|
|
|
|
|
*/
|
|
|
|
|
void sbl_wdg_ena(void)
|
|
|
|
|
{
|
|
|
|
|
uint32_t cpu = 0;
|
|
|
|
|
|
|
|
|
|
apb_enable(APB_WDG0);
|
|
|
|
|
wdg_set_cmp(cpu, SET_WDG_INTC_CMP);
|
|
|
|
|
wdg_set_timeout_cmp(cpu, SET_WDG_TIMEOUT_CMP);
|
|
|
|
|
wdg_set_cpurst_cmp(cpu, SET_WDG_CPURST_CMP);
|
|
|
|
|
wdg_set_fullrst_cmp(cpu, SET_WDG_FULLRST_CMP);
|
|
|
|
|
wdg_cnt_enable(cpu);
|
|
|
|
|
wdg_enable(cpu);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_wdg_disable(): disable watchdog.
|
|
|
|
|
* @return none.
|
|
|
|
|
*/
|
|
|
|
|
void sbl_wdg_disable(void)
|
|
|
|
|
{
|
|
|
|
|
uint32_t cpu = 0;
|
|
|
|
|
|
|
|
|
|
wdg_cnt_disable(cpu);
|
|
|
|
|
wdg_disable(cpu);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_scratch_reg_set(): set scratch regsiter with watchdog reset flag.
|
|
|
|
|
* @return none.
|
|
|
|
|
*/
|
|
|
|
|
void sbl_scratch_reg_set(void)
|
|
|
|
|
{
|
|
|
|
|
ahb_scratch_r0_set(WDT_RESET_FLAG);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_check_reset_by_wdg(): judge reset cause is watchdog or not.
|
|
|
|
|
* @return 1 -> is watchdog reset, 0 -> not 1.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t sbl_check_reset_by_wdg(void)
|
|
|
|
|
{
|
|
|
|
|
if (ahb_scratch_r0_get() == WDT_RESET_FLAG) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_timer_run: start gp-timer.
|
|
|
|
|
* @param ms: timeout counter, unit is ms.
|
|
|
|
|
* @return none.
|
|
|
|
|
*/
|
|
|
|
|
void sbl_timer_run(int ms)
|
|
|
|
|
{
|
|
|
|
|
REG32(GTMR0_CFG_ADDR) = ms;
|
|
|
|
|
REG32(GTMR0_CTRL_CFG_ADDR) = (1<<4) | (1<<1); /*(1MHz enable)*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_timer_clr: clear gp-timer interrupt flag.
|
|
|
|
|
* @return none.
|
|
|
|
|
*/
|
|
|
|
|
void sbl_timer_clr(void)
|
|
|
|
|
{
|
|
|
|
|
REG32(GTMR0_CLR_ADDR) = (1<<0) | (1<<1); /* intc and cnt clr */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_timer_cnt_done: get gp-timer cnt_done interrupt state.
|
|
|
|
|
* @return none.
|
|
|
|
|
*/
|
|
|
|
|
int sbl_timer_cnt_done(void)
|
|
|
|
|
{
|
|
|
|
|
return (REG32(GTMR0_INT_STS_ADDR) & GTMR0_CNT_DONE) ? 1 : 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_fastboot_flag_set: set(save) fastboot flag.
|
|
|
|
|
* @param fboot: fastboot flag.
|
|
|
|
|
* @return none.
|
|
|
|
|
*/
|
|
|
|
|
void sbl_fastboot_flag_set(uint32_t fboot)
|
|
|
|
|
{
|
|
|
|
|
/* kl2 not support rom passing fastboot flag */
|
|
|
|
|
(void)fboot;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_fastboot_flag_get: get fastboot flag.
|
|
|
|
|
* @return 1 -> is fast boot mode, 0 -> not 1.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t sbl_fastboot_flag_get(void)
|
|
|
|
|
{
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief image_check() Check for valid fw at the specified address.
|
|
|
|
|
* @param addr: addr to check.
|
|
|
|
|
* @param hdr: pointer to store header information.
|
|
|
|
|
* @param crc_flag: CRC check mark or not.
|
|
|
|
|
* @return -1: no valid header; 0: valid header.
|
|
|
|
|
*/
|
|
|
|
|
static int image_check(uint32_t addr, imgHdr *hdr, uint8_t crc_flag)
|
|
|
|
|
{
|
|
|
|
|
char block[HEADER_TOLTAL_SIZE];
|
|
|
|
|
uint8_t *src = (uint8_t *)addr;
|
|
|
|
|
uint32_t len_total = 0;
|
|
|
|
|
uint8_t reason = 0;
|
|
|
|
|
|
|
|
|
|
/* clear i/dcache */
|
|
|
|
|
ahb_cache_clear();
|
|
|
|
|
os_mem_cpy(block, src, sizeof(imgHdr));
|
|
|
|
|
img_header_construct(hdr, block);
|
|
|
|
|
|
|
|
|
|
if (iot_imghdr_get_guard(hdr) != IMAGE_GUARD) {
|
|
|
|
|
reason = 1;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (crc_flag) {
|
|
|
|
|
uint32_t img_crc = iot_imghdr_get_imgCRC(hdr);
|
|
|
|
|
len_total = iot_imghdr_get_imgSize(hdr);
|
|
|
|
|
len_total = IMAGE_LEN_FOR_CRC(len_total);
|
|
|
|
|
uint32_t crc = iot_getcrc32((uint8_t *)addr + HEADER_TOLTAL_SIZE, len_total);
|
|
|
|
|
if (crc != img_crc) {
|
|
|
|
|
reason = 2;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
sbl_printf("image_check error, addr:0x%x, reason:%d\r\n", addr, reason);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief image_copy(): copy firmware to specified address.
|
|
|
|
|
* @param src & dst: source and destination addresses(partition start location).
|
|
|
|
|
* @param hdr: pointer to store header information.
|
|
|
|
|
* @param header_move: if you copy the header,
|
|
|
|
|
you need to erase the header information of the source address.
|
|
|
|
|
* @return -1: no valid header; 0: valid header.
|
|
|
|
|
*/
|
|
|
|
|
static int image_copy(uint8_t *src, uint8_t *dst, imgHdr *hdr, uint8_t header_move)
|
|
|
|
|
{
|
|
|
|
|
int rc = 0;
|
|
|
|
|
flash_write_param_t param = {0};
|
|
|
|
|
uint32_t len_image = 0;
|
|
|
|
|
uint32_t len_copy = 0;
|
|
|
|
|
uint8_t *addr_crc = NULL;
|
|
|
|
|
uint8_t *src_copy = src;
|
|
|
|
|
uint8_t *dst_copy = dst;
|
|
|
|
|
uint8_t reason = 0;
|
|
|
|
|
|
|
|
|
|
len_image = iot_imghdr_get_imgSize(hdr);
|
|
|
|
|
len_image = IMAGE_LEN_FOR_CRC(len_image);
|
|
|
|
|
if (header_move) {
|
|
|
|
|
len_copy = len_image + HEADER_TOLTAL_SIZE;
|
|
|
|
|
addr_crc = dst_copy + HEADER_TOLTAL_SIZE;
|
|
|
|
|
} else {
|
|
|
|
|
src_copy += HEADER_TOLTAL_SIZE;
|
|
|
|
|
dst_copy += HEADER_TOLTAL_SIZE;
|
|
|
|
|
len_copy = len_image;
|
|
|
|
|
addr_crc = dst_copy;
|
|
|
|
|
}
|
|
|
|
|
/*write to the FW addr in flash*/
|
|
|
|
|
param.read_mode = MOD_SFC_READ_QUAD_IO_FAST;
|
|
|
|
|
param.write_mode = MOD_SFC_PROG_QUAD;
|
|
|
|
|
param.is_erase = 1;
|
|
|
|
|
param.sw_mode = MOD_SW_MODE_DIS;
|
|
|
|
|
param.erase_mode = MODE_ERASE_SECTOR;
|
|
|
|
|
rc = flash_write(src_copy, (uint32_t)dst_copy, len_copy, ¶m);
|
|
|
|
|
if(rc != 0 ) {
|
|
|
|
|
reason = 1;
|
|
|
|
|
goto err;
|
|
|
|
|
} else {
|
|
|
|
|
sbl_printf("fw image copied into flash \r\n");
|
|
|
|
|
if (iot_imghdr_get_imgCRC(hdr) != 0 ) {
|
|
|
|
|
uint32_t img_crc = iot_imghdr_get_imgCRC(hdr);
|
|
|
|
|
uint32_t crc = iot_getcrc32(addr_crc, len_image);
|
|
|
|
|
if ( crc != img_crc) {
|
|
|
|
|
reason = 2;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (header_move) {
|
|
|
|
|
if (flash_erase((uint32_t)src, ¶m) != ERR_OK) {
|
|
|
|
|
reason = 3;
|
|
|
|
|
goto err;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
err:
|
|
|
|
|
sbl_printf("image_copy error, reason:%d\r\n", reason);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief get_fw_addr_info(): get firmware storage and running address.
|
|
|
|
|
* @param fw_addr: pointer to save storage address.
|
|
|
|
|
* @param run_addr: pointer to save run address.
|
|
|
|
|
* @param flash_size: flash size, see flash_size_t.
|
|
|
|
|
* @param start_part: pointer of sbl_start_part.
|
|
|
|
|
* @return -1: no valid header; 0: valid header.
|
|
|
|
|
*/
|
|
|
|
|
static int get_fw_addr_info(uint32_t *fw_addr, uint32_t *run_addr,
|
|
|
|
|
uint8_t flash_size, uint32_t start_part)
|
|
|
|
|
{
|
|
|
|
|
int ret = 0;
|
|
|
|
|
imgHdr hdr = {0};
|
|
|
|
|
|
|
|
|
|
#if RUN_IN_PSRAM
|
|
|
|
|
*run_addr = FW_RAM_ADDR;
|
|
|
|
|
#else
|
|
|
|
|
*run_addr = FW_FLASH_ADDR + HEADER_TOLTAL_SIZE;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
/* get firmware address */
|
|
|
|
|
if (start_part == 0) { //fw1
|
|
|
|
|
iot_layout_get_part_offset(PART_NUM_FW1, fw_addr);
|
|
|
|
|
} else { //fw2
|
|
|
|
|
iot_layout_get_part_offset(PART_NUM_FW2, fw_addr);
|
|
|
|
|
}
|
|
|
|
|
*fw_addr += FLASH_BASE_ADDRESS;
|
|
|
|
|
|
|
|
|
|
/* check image integrity */
|
|
|
|
|
if (g_is_first_run) {
|
|
|
|
|
if (image_check(*fw_addr, &hdr, 1) < 0) {
|
|
|
|
|
ret = -1;
|
|
|
|
|
goto out;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
sbl_printf("get fw addr:0x%x, run addr:0x%x\r\n", *fw_addr, *run_addr);
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief fw_image_decompress_to_psram(): decompress image to psram.
|
|
|
|
|
* @param fw_addr: firmware address.
|
|
|
|
|
* @param run_addr: run address.
|
|
|
|
|
* @return -1: failed; 0: succeed.
|
|
|
|
|
*/
|
|
|
|
|
int fw_image_decompress_to_psram(uint32_t fw_addr, uint32_t run_addr)
|
|
|
|
|
{
|
|
|
|
|
uint8_t *src = NULL;
|
|
|
|
|
uint8_t *dst = NULL;
|
|
|
|
|
int rc = 0;
|
|
|
|
|
imgHdr hdr = {0};
|
|
|
|
|
|
|
|
|
|
/* the compressed or valid data does not contain a header */
|
|
|
|
|
src = (uint8_t *)fw_addr + HEADER_TOLTAL_SIZE;
|
|
|
|
|
dst = (uint8_t *)run_addr;
|
|
|
|
|
|
|
|
|
|
if (image_check(fw_addr, &hdr, 0) < 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
rc = fw_image_decompress(src, dst, iot_imghdr_get_imgSize(&hdr));
|
|
|
|
|
|
|
|
|
|
if(rc != 0 ){
|
|
|
|
|
os_mem_cpy(dst, src, iot_imghdr_get_imgSize(&hdr));
|
|
|
|
|
//ahb_dmc_cache_flush((uint32_t)dst, hdr._imgSize);
|
|
|
|
|
}
|
|
|
|
|
sbl_printf("decompressed fw image into RAM \r\n");
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief fw_image_decompress_to_flash(): decompress image to flash.
|
|
|
|
|
* @param fw_addr: firmware address.
|
|
|
|
|
* @param run_addr: run address.
|
|
|
|
|
* @return -1: failed; 0: succeed.
|
|
|
|
|
*/
|
|
|
|
|
int fw_image_decompress_to_flash(uint32_t fw_addr, uint32_t run_addr)
|
|
|
|
|
{
|
|
|
|
|
uint8_t *src = NULL;
|
|
|
|
|
uint8_t *dst = NULL;
|
|
|
|
|
int rc = 0;
|
|
|
|
|
imgHdr hdr = {0};
|
|
|
|
|
|
|
|
|
|
src = (uint8_t *)fw_addr;
|
|
|
|
|
dst = (uint8_t *)run_addr;
|
|
|
|
|
|
|
|
|
|
if (image_check(fw_addr, &hdr, 0) < 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*compatable with 1M image upgrade*/
|
|
|
|
|
if (iot_imghdr_get_imgType(&hdr) == imgFRW) {
|
|
|
|
|
if (image_copy(src, dst - HEADER_TOLTAL_SIZE, &hdr, 0) < 0) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
rc = fw_image_decompress(src+sizeof(imgHdr), dst, iot_imghdr_get_imgSize(&hdr));
|
|
|
|
|
if(rc != 0 ) {
|
|
|
|
|
sbl_printf("fw image decompressed ERROR! \r\n");
|
|
|
|
|
return -1;
|
|
|
|
|
} else {
|
|
|
|
|
uint32_t fw_crc = 0, crc = 0;
|
|
|
|
|
sbl_printf("fw image decompressed into flash \r\n");
|
|
|
|
|
fw_crc = iot_imghdr_get_fwCRC(&hdr);
|
|
|
|
|
crc = iot_getcrc32(dst, iot_imghdr_get_fwSize(&hdr));
|
|
|
|
|
if (crc != fw_crc) {
|
|
|
|
|
sbl_printf("decompress fw crc error\r\n");
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_load_next_firmware(): load custom app or plc app firmware.
|
|
|
|
|
* @param run_addr: pointer of run address.
|
|
|
|
|
* @param flash_size: flash size
|
|
|
|
|
* @param start_part: start part.
|
|
|
|
|
* @psram psram_eb: next firmware run in psram or not.
|
|
|
|
|
* @return 0: load firmware succeed, 1: load firmware failed.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t sbl_load_next_firmware(uint32_t *run_addr,
|
|
|
|
|
uint32_t flash_size, uint32_t start_part, uint32_t psram_eb)
|
|
|
|
|
{
|
|
|
|
|
uint32_t fw_addr = 0;
|
|
|
|
|
(void)psram_eb;
|
|
|
|
|
|
|
|
|
|
if (get_fw_addr_info(&fw_addr, run_addr, (uint8_t)flash_size, start_part) < 0) {
|
|
|
|
|
sbl_printf("No valid firmware found......\r\n");
|
|
|
|
|
while(1);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if RUN_IN_PSRAM
|
|
|
|
|
if(fw_image_decompress_to_psram(fw_addr, *run_addr) < 0) {
|
|
|
|
|
/* copy image failed */
|
|
|
|
|
sbl_printf("......\r\n");
|
|
|
|
|
while(1);
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
if (flash_size == FLASH_1M) {
|
|
|
|
|
/* 1m flash firmware is uncompressed and there is no run partition */
|
|
|
|
|
if (start_part) {
|
|
|
|
|
uint32_t offset1, offset2, size;
|
|
|
|
|
sbl_printf("re-mapping flash space\r\n");
|
|
|
|
|
iot_layout_get_part_offset(PART_NUM_FW1, &offset1);
|
|
|
|
|
iot_layout_get_part_offset(PART_NUM_FW2, &offset2);
|
|
|
|
|
iot_layout_get_part_size(PART_NUM_FW1, &size);
|
|
|
|
|
if (flash_addr_mapping(offset1, offset2, size) != 0) {
|
|
|
|
|
sbl_printf("re-mapping error\r\n");
|
|
|
|
|
while(1);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if ((os_mem_cmp(sbl_fw_uncp, "0", 1) == 0)) {
|
|
|
|
|
/* 2m and 4m flash firmware needs to be decompressed */
|
|
|
|
|
if(fw_image_decompress_to_flash(fw_addr, *run_addr) < 0) {
|
|
|
|
|
/* decompress image failed */
|
|
|
|
|
sbl_printf("......\r\n");
|
|
|
|
|
while(1);
|
|
|
|
|
} else{
|
|
|
|
|
/*decompress success*/
|
|
|
|
|
sbl_fw_uncp_success();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @brief sbl_jump_next_firmware(): jump to custom app or plc app firmware.
|
|
|
|
|
* @param run_addr: next firmware run address.
|
|
|
|
|
* @param mode: firmware run mode.
|
|
|
|
|
* @param print_eb: printf function enable or not.
|
|
|
|
|
* @param flash_size: flash size.
|
|
|
|
|
* @param psram_eb: next firmware run in psram or not.
|
|
|
|
|
* @return 0: jump to firmware succeed, 1: jump to firmware failed.
|
|
|
|
|
*/
|
|
|
|
|
uint32_t sbl_jump_next_firmware(uint32_t run_addr,
|
|
|
|
|
int mode, int print_eb, int flash_size, int psram_eb)
|
|
|
|
|
{
|
|
|
|
|
typedef void(*pgm_start_t)(int, int, int, int);
|
|
|
|
|
|
|
|
|
|
pgm_start_t pgm_start = (pgm_start_t)run_addr;
|
|
|
|
|
sbl_printf("\r\njump@0x%x\r\n", (int)pgm_start);
|
|
|
|
|
pgm_start(mode, print_eb, flash_size, psram_eb);
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2025-02-06 11:02:18 +08:00
|
|
|
|
// kl1会操作一下tms引脚,这个操作对kl2和kl3应该是无效的
|
|
|
|
|
void sbl_tms_interrupt_disable()
|
|
|
|
|
{
|
|
|
|
|
}
|