| #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; | 
 | } | 
 | /*---------------------------------------------------------------------------*/ |