Files
banban/ql-application/threadx/interface/fota/example_fota.c

435 lines
12 KiB
C

/*================================================================
Copyright (c) 2021, Quectel Wireless Solutions Co., Ltd. All rights reserved.
Quectel Wireless Solutions Proprietary and Confidential.
=================================================================*/
#include <stdio.h>
#include "ql_rtos.h"
#include "ql_application.h"
#include "ql_fota.h"
#include "ql_power.h"
#include "ql_fs.h"
#include "ql_uart.h"
#include "ql_spi_nor.h"
#include "ql_spi.h"
#define fota_exam_log(fmt, ...) printf("[FOTA_EXAM][%s, %d] " fmt "\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)
/* 蜉溯�螳? ********************************************************/
#define QUEC_IN_OR_EXT_FLASH_TEST //讓。扈��驛ィflash蜥悟、匁撃flash蜷梧慮謾ッ謖{ta豬玖ッ�
#ifndef QUEC_IN_OR_EXT_FLASH_TEST
// #define QUEC_EXTERNAL_NORFLASH_TEST // 螟匁撃NOR
// #define QUEC_EXTERNAL_NANDFLASH_TEST // 螟匁撃NAND
// #define QL_SECFOTA_ENABLE // 螳牙�fota菴ソ閭ス
#else
#define QUEC_EXTERNAL_NANDFLASH_TEST // 螟匁撃NAND
#endif
/* **************************************************************/
#ifdef QUEC_EXTERNAL_NANDFLASH_TEST
#define NAND_DEV_NAME "/spinand"
#define NAND_FOTA_PACK_PATH NAND_DEV_NAME "/fotafile.bin"
#endif
#ifdef QL_SECFOTA_ENABLE
void ql_secfota_callback(int err_code)
{
fota_exam_log("ql_secfota_callback ret = %d", err_code);
}
#endif
#ifdef QUEC_EXTERNAL_NANDFLASH_TEST
static int cust_yaffs_mount(void)
{
int ret = 0;
ql_spi_nand_init(QL_SPI_NAND_DEV0, QL_SPI_NAND_PIN_33_36, QL_SPI_NAND_CLOCK_26M);
// 邇ー蝨ィnand譛我ク、螂玲磁蜿」�御ク€荳ェ譏ッql nand�御ク€荳ェ譏ッql yaffs
// ql nand譏ッ遘サ霑懷ー∬」�噪謗・蜿」�瑚ー�畑莉サ諢乗磁蜿」閾ェ蜉ィ謖りスス�瑚ョソ髣ョ譌カ荳埼怙隕∝クヲ隶セ螟��?+譁�サカ蜷搾シ碁サ倩ョ、隶セ螟�錐譏ッ"spinand"
// ql yaffs譏ッ蜴溽函yaffs謗・蜿」蟆∬」�€梧擂�碁怙隕∵焔蜉ィ謖りスス�瑚ョソ髣ョ蠢�。サ蟶ヲ隶セ螟�錐�瑚ョセ螟�錐閾ェ螳壻ケ?
// 螯よ棡菴�諠ウ豺キ逕ィ�碁ぅ荵域撃霓ス譌カ譌�髴€謇句勘謖りスス�碁怙隕∬ァヲ蜿台ク€谺。閾ェ蜉ィ謖りスス�御ク比スソ逕ィql_yaffs隶ソ髣ョ譁�サカ譌カ�悟ソ�。サ蟶ヲ鮟倩ョ、隶セ螟�錐"spinand"
#define QL_USE_QL_NAND_API 0
#if QL_USE_QL_NAND_API
ret = ql_nand_fope("mount_temp.txt", "w+");
if (ret)
{
printf("ql_nand_fope error\n");
return -1;
}
ql_nand_fclose(ret);
return 0;
#else
ret = ql_yaffs_start_up();
if (ret)
{
printf("ql_yaffs_start_up error, ret = %d\r\n", ret);
return -1;
}
struct ql_yaffs_dev dev = {NAND_DEV_NAME, 0, 2048};
ql_yaffs_create_dev(&dev);
ret = ql_yaffs_mount(NAND_DEV_NAME);
if (ret)
{
printf("ql_yaffs_mount error ret = %d, Try to format\r\n", ret);
ql_yaffs_format(NAND_DEV_NAME, 1, 1, 0);
ret = ql_yaffs_mount(NAND_DEV_NAME);
if (ret)
{
printf("ql_yaffs_mount error, ret = %d\r\n", ret);
return -1;
}
}
#endif
return 0;
}
#endif
// minifota 蜊募桁蜊�コァ萓狗ィ�
void ql_mergefile_minifota_test(void)
{
#define MG_MINIFOTA_PROFILE_IDX 1
#define MG_MINIFOTA_URL_TYPE QL_FOTA_DWNLD_MOD_HTTP
#define MG_MINIFOTA_PACK_RUL "http://112.31.84.164:8302/yang/old_new.bin"
fota_exam_log("========== ql_mergefile_minifota_test ==========");
int ret = ql_fota_mergefile_mini_system(MG_MINIFOTA_PROFILE_IDX,
MG_MINIFOTA_URL_TYPE,
MG_MINIFOTA_PACK_RUL,
NULL, NULL, NULL);
if (ret != 0)
{
fota_exam_log("ql_fota_mergefile_mini_system error, ret = %d", ret);
}
}
// minifota 蜿悟桁蜊�コァ萓狗ィ�
void ql_double_minifota_test(void)
{
#define DOUBLE_MINIFOTA_PROFILE_IDX 1
#define DOUBLE_MINIFOTA_URL_TYPE QL_FOTA_DWNLD_MOD_HTTP
#define DOUBLE_MINIFOTA_PACK_1_URL "http://112.31.84.164:8302/yang/old_new.bin"
#define DOUBLE_MINIFOTA_PACK_2_URL "http://112.31.84.164:8302/yang/old_new.bin"
fota_exam_log("========== ql_double_minifota_test ==========");
#ifdef QL_SECFOTA_ENABLE
ql_secfota_config(1, ql_secfota_callback);
#endif
int ret = ql_fota_mini_system(DOUBLE_MINIFOTA_PROFILE_IDX,
DOUBLE_MINIFOTA_URL_TYPE,
DOUBLE_MINIFOTA_PACK_1_URL,
DOUBLE_MINIFOTA_PACK_2_URL,
NULL, NULL);
if (ret != 0)
{
fota_exam_log("ql_fota_mini_system error, ret = %d", ret);
}
}
void ql_fota_self_adapt_test(void)
{
#define SELF_ADAPT_PROFILE_IDX 0
#define SELF_ADAPT_PACK_URL "http://112.31.84.164:8302/yang/old_new.bin"
int ret = 0;
fota_exam_log("========== !!!!!!!!!!!!!!!!!!!!99999999999 ==========");
ret = ql_fota_start(SELF_ADAPT_PROFILE_IDX, SELF_ADAPT_PACK_URL);
if(ret != 0){
fota_exam_log("========== fota test end ==========");
}
}
void ql_full_app_test(void)
{
#define FULL_APP_PACK_URL "http://112.31.84.164:8300/august/app.bin"
int ret = 0;
//fota_exam_log("========== full fota test success !!!!!!!!!!!!!!!!!!!! ==========");
fota_exam_log("full fota test star");
ret = ql_fullfota_app_start(FULL_APP_PACK_URL);
if(ret != 0){
fota_exam_log("==========full fota test end ==========");
}
}
static ql_flag_t fota_uart_flag;
#define QL_FOTA_UART_READ 0x1
void quec_fota_uart_callback(QL_UART_PORT_NUMBER_E port, void *para)
{
static char read_flag = 1;
if (read_flag)
{
read_flag = 0;
ql_rtos_flag_release(fota_uart_flag, QL_FOTA_UART_READ, QL_FLAG_OR);
}
}
static void quec_fota_uart_test(void * argv)
{
int ret = -1, event = 0;
int write_bytes = 0;
unsigned char data[] = "hello, this is file fota test!!!, please Transfer dfota.bin\n";
unsigned char read_buf[4096] = {0};
ql_uart_config_t dcb;
int count = 0, res = 0, file_len = 0;
QFILE *fp = NULL;
qlFotaImgProcCtxPtr ctx = NULL;
int file_size = 0;
#if defined(QUEC_EXTERNAL_NORFLASH_TEST)
unsigned char *id;
int port_index = EXTERNAL_NORFLASH_PORT33_36;
int clk = _APBC_SSP_FNCLKSEL_1_625MHZ_;
printf("[FS] ========== exflash init \r\n");
ql_spi_nor_init(port_index, clk);
id = ql_spi_nor_read_id(port_index);
printf("[NORFLASH]=====norflash ID:0x%02x 0x%02x 0x%02x\r\n", id[0], id[1], id[2]);
ret = qextfs_init('C', "external_fs", 1, port_index, 0, 0x100000);
printf("[FS] ========== exfs init : %d \r\n", ret);
ql_fota_set_package_path("C:/FotaFile.bin");
ql_remove("C:/FotaFile.bin");
#elif defined(QUEC_EXTERNAL_NANDFLASH_TEST)
ret = cust_yaffs_mount();
if(ret)
{
printf("cust_yaffs_mount fail\r\n");
return;
}
printf("cust_yaffs_mount success\r\n");
char fota_pkg_dir[40] = {0};
sprintf(fota_pkg_dir, "%s%s", QL_FOTA_IN_NAND_TAG, NAND_FOTA_PACK_PATH); //nand tag
ql_fota_set_package_path(fota_pkg_dir);
#endif
ret = ql_uart_open(QL_MAIN_UART_PORT, QL_UART_BAUD_115200, QL_FC_HW);
if (ret)
{
printf("open uart[%d] failed! \n", QL_MAIN_UART_PORT);
return;
}
ql_rtos_flag_create(&fota_uart_flag);
/*****************************************/
ql_uart_get_dcbconfig(QL_MAIN_UART_PORT, &dcb);
printf("[%s][%d]baudrate:%d, data_bit:%d, stop_bit:%d, parity_bit:%d, flow_ctrl:%d \r\n", __func__, __LINE__, dcb.baudrate, dcb.data_bit, dcb.stop_bit, dcb.parity_bit, dcb.flow_ctrl);
dcb.baudrate = QL_UART_BAUD_115200;
ql_uart_set_dcbconfig(QL_MAIN_UART_PORT, &dcb);
/*****************************************/
ql_uart_register_cb(QL_MAIN_UART_PORT, quec_fota_uart_callback); // use callback to read uart data
ql_uart_write(QL_MAIN_UART_PORT, data, sizeof(data));
ql_rtos_flag_wait(fota_uart_flag, QL_FOTA_UART_READ, QL_FLAG_OR, &event, QL_WAIT_FOREVER);
#ifdef QL_SECFOTA_ENABLE
ql_secfota_config(1, ql_secfota_callback);
#endif
ctx = ql_fota_init();
if (!ctx)
{
printf("*** fota init fail ***");
return;
}
count = 0;
while ((ret >= 0) && (count < 60))
{
ret = ql_uart_read(QL_MAIN_UART_PORT, read_buf, sizeof(read_buf));
if (ret <= 0)
{
count++;
ql_rtos_task_sleep_ms(5);
continue;
}
else
{
count = 0;
file_len += ret;
res = ql_fota_image_write(ctx, (void *)read_buf, ret);
if (res < 0)
{
printf("ql_fwrite error:%d \n", res);
}
}
}
if (count >= 60)
{
printf("Transfer end:%d ,file_len:%d\n", ret, file_len);
}
ql_uart_close(QL_MAIN_UART_PORT);
ret = ql_fota_image_flush(ctx);
if (ret)
{
printf("*** fota image flush fail ***");
return;
}
printf("ql_fota_image_flush end\n");
ret = ql_fota_image_verify(ctx);
if (ret)
{
printf("*** fota image verify fail ***");
return;
}
printf("ql_fota_image_verify success! \n");
#ifdef QUEC_EXTERNAL_NANDFLASH_TEST
ql_yaffs_sync(NAND_DEV_NAME);
#endif
printf("ready to power reset!!\n");
ql_power_reset();
}
#ifdef QUEC_IN_OR_EXT_FLASH_TEST
static unsigned char use_nandflash_ota_flag = 0;
void quec_usbcdc_fota_callback(QL_UART_PORT_NUMBER_E port, void *para)
{
int read_len = 0;
char r_data[1024] = {0};
read_len = ql_uart_read(port, r_data, sizeof(r_data));
printf("uart[%d] callback read data, data:%s, read_len:%d \n", port, r_data, read_len);
if(strcmp(r_data,"use_in") == 0){
printf("use quec inside flash for full fota app\r\n");
ql_fota_fixed_internal_flash_upgrade(TRUE);
ql_fota_set_package_path("U:/FotaFile.bin");
use_nandflash_ota_flag = 0;
}else if(strcmp(r_data,"use_ext") == 0){
printf("use quec outside flash for full fota\r\n");
ql_fota_fixed_internal_flash_upgrade(FALSE);
ql_fota_set_package_path("QOTANAD@/spinand/fotafile.bin");
use_nandflash_ota_flag = 1;
}
}
static void quec_fota_uart_double_test(void * argv)
{
int ret = -1, event = 0;
int write_bytes = 0;
unsigned char data[] = "hello, this is file fota test!!!, please Transfer dfota.bin\n";
unsigned char read_buf[4096] = {0};
ql_uart_config_t dcb;
int count = 0, res = 0, file_len = 0;
QFILE *fp = NULL;
qlFotaImgProcCtxPtr ctx = NULL;
int file_size = 0;
ret = cust_yaffs_mount();
if(ret)
{
printf("cust_yaffs_mount fail\r\n");
return;
}
printf("cust_yaffs_mount success\r\n");
ql_uart_open(QL_USB_CDC_PORT, QL_UART_BAUD_115200, QL_FC_NONE);
ql_uart_register_cb(QL_USB_CDC_PORT, quec_usbcdc_fota_callback); //use callback to read uart data
ret = ql_uart_open(QL_MAIN_UART_PORT, QL_UART_BAUD_115200, QL_FC_HW);
if (ret)
{
printf("open uart[%d] failed! \n", QL_MAIN_UART_PORT);
return;
}
ql_rtos_flag_create(&fota_uart_flag);
/*****************************************/
ql_uart_get_dcbconfig(QL_MAIN_UART_PORT, &dcb);
printf("[%s][%d]baudrate:%d, data_bit:%d, stop_bit:%d, parity_bit:%d, flow_ctrl:%d \r\n", __func__, __LINE__, dcb.baudrate, dcb.data_bit, dcb.stop_bit, dcb.parity_bit, dcb.flow_ctrl);
dcb.baudrate = QL_UART_BAUD_115200;
ql_uart_set_dcbconfig(QL_MAIN_UART_PORT, &dcb);
/*****************************************/
ql_uart_register_cb(QL_MAIN_UART_PORT, quec_fota_uart_callback); // use callback to read uart data
ql_uart_write(QL_MAIN_UART_PORT, data, sizeof(data));
ql_rtos_flag_wait(fota_uart_flag, QL_FOTA_UART_READ, QL_FLAG_OR, &event, QL_WAIT_FOREVER);
ctx = ql_fota_init();
if (!ctx)
{
printf("*** fota init fail ***");
return;
}
count = 0;
while ((ret >= 0) && (count < 400))
{
ret = ql_uart_read(QL_MAIN_UART_PORT, read_buf, sizeof(read_buf));
if (ret <= 0)
{
count++;
ql_rtos_task_sleep_ms(5);
continue;
}
else
{
count = 0;
file_len += ret;
res = ql_fota_image_write(ctx, (void *)read_buf, ret);
if (res < 0)
{
printf("ql_fwrite error:%d \n", res);
}
}
}
if (count >= 400)
{
printf("Transfer end:%d ,file_len:%d\n", ret, file_len);
}
ql_uart_close(QL_MAIN_UART_PORT);
ret = ql_fota_image_flush(ctx);
if (ret)
{
printf("*** fota image flush fail ***");
return;
}
printf("ql_fota_image_flush end\n");
ret = ql_fota_image_verify(ctx);
if (ret)
{
printf("*** fota image verify fail ***");
return;
}
printf("ql_fota_image_verify success! \n");
if(use_nandflash_ota_flag)
ql_yaffs_sync("/spinand");
printf("ready to power reset!!\n");
ql_power_reset();
}
application_init(quec_fota_uart_double_test, "quec_fota_uart_double_test", 50, 10);//荳イ蜿」FBF蜊�コァ,蜿掲lash
#endif
// application_init(ql_mergefile_minifota_test, "ql_mergefile_minifota_test", 10, 2); //蜊募桁蜊�コァ
// application_init(ql_double_minifota_test, "quec_fota_test", 6, 10); //蜿悟桁蜊�コァ
// application_init(ql_fota_self_adapt_test, "ql_fota_self_adapt_test", 10, 2); //閾ェ騾ょコ泌桁蜊募桁MINI蜥熊ULL蜊�コァ
// application_init(ql_full_app_test, "ql_full_app_test", 2, 10); //蜈ィ驥丞合郤ァ
// application_init(quec_fota_uart_test, "quec_fota_uart_test", 50, 10); //荳イ蜿」FBF蜊�コァ