blob: 8248c5d6dd4cc34573f12203a9d8b160513cb01a [file] [log] [blame]
#include <string.h>
#include <time.h>
#include <signal.h>
#include "aboot-tiny.h"
#include "jacana_firmware.h"
#include "jacana_pvt.h"
#include "jacana_callback.h"
#include "jacana_serialport.h"
#include "jacana_clock.h"
#include "jacana_mem.h"
#include "jacana_log.h"
#include "jacana_usleep.h"
#include "jacana_download.h"
#define GNSS_MODULE_FW_DOWNLOAD_TIMER_VALUE 5
static timer_t gnss_module_fw_download_timer_id;
/*---------------------------------------------------------------------------*/
int jacana_aboot_tiny_force_stop(void)
{
jacana_aboot_tiny_set_result(ABOOT_TINY_ERROR_FORCE_STOP);
return aboot_tiny_stop();
}
/*---------------------------------------------------------------------------*/
/* Safety Timer For FW Downloading...*/
static int gnss_module_fw_download_timer_start(void)
{
int rc = 0;
struct itimerspec ts;
memset (&ts, 0x00, sizeof (struct itimerspec));
ts.it_value.tv_sec = GNSS_MODULE_FW_DOWNLOAD_TIMER_VALUE;
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = GNSS_MODULE_FW_DOWNLOAD_TIMER_VALUE;
ts.it_interval.tv_nsec = 0;
rc = timer_settime(gnss_module_fw_download_timer_id, 0, &ts, NULL);
jacana_log_printf("gnss download timer start.");
return rc;
}
static int gnss_module_fw_download_timer_stop(void)
{
int rc = 0;
struct itimerspec ts;
memset (&ts, 0x00, sizeof (struct itimerspec));
ts.it_value.tv_sec = 0;
ts.it_value.tv_nsec = 0;
ts.it_interval.tv_sec = 0;
ts.it_interval.tv_nsec = 0;
rc = timer_settime(gnss_module_fw_download_timer_id, 0, &ts, NULL);
jacana_log_printf("gnss download timer stop.");
return rc;
}
static void gps_state_fw_download(__attribute__( (unused)) union sigval sv)
{
if(aboot_tiny_is_running())
{
jacana_aboot_tiny_force_stop();
}
jacana_log_printf("gnss download timer timeout.");
}
static int gnss_module_fw_download_timer_init(void)
{
int rc = 0;
struct sigevent sigev;
memset (&sigev, 0, sizeof (struct sigevent));
sigev.sigev_value.sival_ptr = &gnss_module_fw_download_timer_id;
sigev.sigev_notify = SIGEV_THREAD;
sigev.sigev_notify_attributes = NULL;
sigev.sigev_notify_function = gps_state_fw_download;
rc = timer_create(CLOCK_REALTIME, &sigev, &gnss_module_fw_download_timer_id);
jacana_log_printf("gnss download timer init.");
return rc;
}
/*---------------------------------------------------------------------------*/
int
jacana_aboot_tiny_download(const char *dev, int baud)
{
/* Should be called at very beginning */
aboot_tiny_init(jacana_aboot_tiny_callback);
/* WDT Timer is created here. */
gnss_module_fw_download_timer_init();
/* Set initial result as success */
jacana_aboot_tiny_set_result(ABOOT_TINY_ERROR_SUCCESS);
/* Log printf */
aboot_tiny_log_printf = jacana_log_printf;
/* Memory alloc/free */
aboot_tiny_mem_alloc = jacana_mem_alloc;
aboot_tiny_mem_free = jacana_mem_free;
aboot_tiny_usleep = jacana_delay_usleep;
/* Jacana clock init */
jacana_clock_init();
aboot_tiny_clock_get = jacana_clock_get;
/* System platform init */
aboot_tiny_platform_init();
/* Jacana uart init */
if(jacana_serialport_init(dev, baud, aboot_tiny_uart_rx_callback) < 0) {
aboot_tiny_log_printf("error: open serial port failed\n");
return -1;
}
aboot_tiny_uart_send = jacana_serialport_write;
/* Get progress fixup size */
void *priv = jacana_pvt_raw_open();
if(!priv) {
aboot_tiny_log_printf("error: open pvt partition failed\n");
return -1;
}
size_t pvt_size = jacana_pvt_raw_get_total_size(priv);
size_t progress_fixup = ((pvt_size + SPARSE_BLOCK_SZ - 1)
& ~(SPARSE_BLOCK_SZ - 1)) * 2;
jacana_pvt_raw_close(priv);
/* Jacana firmware interface init */
firmware_handle_t firmware;
pvt_info_t pvt_info;
firmware.pvt_info = &pvt_info;
priv = jacana_firmware_raw_open();
if(!priv) {
aboot_tiny_log_printf("error: open jacana firmware partition failed\n");
return -1;
}
if(jacana_firmware_open(&firmware, priv) < 0) {
jacana_firmware_raw_close(priv);
aboot_tiny_log_printf("error: open jacana firmware failed\n");
return -1;
}
aboot_tiny_firmware_read_line = jacana_firmware_read_line;
aboot_tiny_firmware_read_data = jacana_firmware_read_data;
gnss_module_fw_download_timer_start();
/* Start download engine */
if(aboot_tiny_start(&firmware, progress_fixup, true) < 0) {
jacana_firmware_raw_close(priv);
jacana_firmware_close(&firmware);
aboot_tiny_log_printf("error: start aboot engine failed\n");
return -1;
}
/* customize timeout parameter in second */
aboot_tiny_set_link_lost_timeout(3);
aboot_tiny_set_cmd_response_timeout(2);
/* Enter main event loops */
aboot_tiny_main_loop();
/* Close serialport device */
jacana_serialport_exit();
gnss_module_fw_download_timer_stop();
/**
* firmware already closed when switch to pvt download,
* so we need close pvt here
*/
priv = firmware.priv;
jacana_pvt_close(&firmware);
jacana_pvt_raw_close(priv);
int rc = (int)jacana_aboot_tiny_get_result();
if(rc) {
aboot_tiny_log_printf("Jacana download failed with error code %d.\n", rc);
}
return -rc;
}
/*---------------------------------------------------------------------------*/