blob: 8248c5d6dd4cc34573f12203a9d8b160513cb01a [file] [log] [blame]
b.liuced8dd02024-06-28 13:28:29 +08001#include <string.h>
2#include <time.h>
3#include <signal.h>
4#include "aboot-tiny.h"
5#include "jacana_firmware.h"
6#include "jacana_pvt.h"
7#include "jacana_callback.h"
8#include "jacana_serialport.h"
9#include "jacana_clock.h"
10#include "jacana_mem.h"
11#include "jacana_log.h"
12#include "jacana_usleep.h"
13#include "jacana_download.h"
14
15#define GNSS_MODULE_FW_DOWNLOAD_TIMER_VALUE 5
16static timer_t gnss_module_fw_download_timer_id;
17
18/*---------------------------------------------------------------------------*/
19int jacana_aboot_tiny_force_stop(void)
20{
21 jacana_aboot_tiny_set_result(ABOOT_TINY_ERROR_FORCE_STOP);
22 return aboot_tiny_stop();
23}
24/*---------------------------------------------------------------------------*/
25
26/* Safety Timer For FW Downloading...*/
27static int gnss_module_fw_download_timer_start(void)
28{
29 int rc = 0;
30 struct itimerspec ts;
31
32 memset (&ts, 0x00, sizeof (struct itimerspec));
33 ts.it_value.tv_sec = GNSS_MODULE_FW_DOWNLOAD_TIMER_VALUE;
34 ts.it_value.tv_nsec = 0;
35 ts.it_interval.tv_sec = GNSS_MODULE_FW_DOWNLOAD_TIMER_VALUE;
36 ts.it_interval.tv_nsec = 0;
37 rc = timer_settime(gnss_module_fw_download_timer_id, 0, &ts, NULL);
38 jacana_log_printf("gnss download timer start.");
39 return rc;
40}
41
42
43static int gnss_module_fw_download_timer_stop(void)
44{
45 int rc = 0;
46 struct itimerspec ts;
47
48 memset (&ts, 0x00, sizeof (struct itimerspec));
49 ts.it_value.tv_sec = 0;
50 ts.it_value.tv_nsec = 0;
51 ts.it_interval.tv_sec = 0;
52 ts.it_interval.tv_nsec = 0;
53 rc = timer_settime(gnss_module_fw_download_timer_id, 0, &ts, NULL);
54 jacana_log_printf("gnss download timer stop.");
55 return rc;
56}
57
58
59static void gps_state_fw_download(__attribute__( (unused)) union sigval sv)
60{
61 if(aboot_tiny_is_running())
62 {
63 jacana_aboot_tiny_force_stop();
64 }
65
66 jacana_log_printf("gnss download timer timeout.");
67}
68
69static int gnss_module_fw_download_timer_init(void)
70{
71 int rc = 0;
72 struct sigevent sigev;
73
74 memset (&sigev, 0, sizeof (struct sigevent));
75 sigev.sigev_value.sival_ptr = &gnss_module_fw_download_timer_id;
76 sigev.sigev_notify = SIGEV_THREAD;
77 sigev.sigev_notify_attributes = NULL;
78 sigev.sigev_notify_function = gps_state_fw_download;
79 rc = timer_create(CLOCK_REALTIME, &sigev, &gnss_module_fw_download_timer_id);
80 jacana_log_printf("gnss download timer init.");
81 return rc;
82}
83
84/*---------------------------------------------------------------------------*/
85int
86jacana_aboot_tiny_download(const char *dev, int baud)
87{
88 /* Should be called at very beginning */
89 aboot_tiny_init(jacana_aboot_tiny_callback);
90
91 /* WDT Timer is created here. */
92 gnss_module_fw_download_timer_init();
93
94 /* Set initial result as success */
95 jacana_aboot_tiny_set_result(ABOOT_TINY_ERROR_SUCCESS);
96
97 /* Log printf */
98 aboot_tiny_log_printf = jacana_log_printf;
99
100 /* Memory alloc/free */
101 aboot_tiny_mem_alloc = jacana_mem_alloc;
102 aboot_tiny_mem_free = jacana_mem_free;
103 aboot_tiny_usleep = jacana_delay_usleep;
104
105 /* Jacana clock init */
106 jacana_clock_init();
107 aboot_tiny_clock_get = jacana_clock_get;
108
109 /* System platform init */
110 aboot_tiny_platform_init();
111
112 /* Jacana uart init */
113 if(jacana_serialport_init(dev, baud, aboot_tiny_uart_rx_callback) < 0) {
114 aboot_tiny_log_printf("error: open serial port failed\n");
115 return -1;
116 }
117 aboot_tiny_uart_send = jacana_serialport_write;
118
119 /* Get progress fixup size */
120 void *priv = jacana_pvt_raw_open();
121 if(!priv) {
122 aboot_tiny_log_printf("error: open pvt partition failed\n");
123 return -1;
124 }
125 size_t pvt_size = jacana_pvt_raw_get_total_size(priv);
126 size_t progress_fixup = ((pvt_size + SPARSE_BLOCK_SZ - 1)
127 & ~(SPARSE_BLOCK_SZ - 1)) * 2;
128 jacana_pvt_raw_close(priv);
129
130 /* Jacana firmware interface init */
131 firmware_handle_t firmware;
132 pvt_info_t pvt_info;
133 firmware.pvt_info = &pvt_info;
134 priv = jacana_firmware_raw_open();
135 if(!priv) {
136 aboot_tiny_log_printf("error: open jacana firmware partition failed\n");
137 return -1;
138 }
139 if(jacana_firmware_open(&firmware, priv) < 0) {
140 jacana_firmware_raw_close(priv);
141 aboot_tiny_log_printf("error: open jacana firmware failed\n");
142 return -1;
143 }
144 aboot_tiny_firmware_read_line = jacana_firmware_read_line;
145 aboot_tiny_firmware_read_data = jacana_firmware_read_data;
146
147 gnss_module_fw_download_timer_start();
148 /* Start download engine */
149 if(aboot_tiny_start(&firmware, progress_fixup, true) < 0) {
150 jacana_firmware_raw_close(priv);
151 jacana_firmware_close(&firmware);
152 aboot_tiny_log_printf("error: start aboot engine failed\n");
153 return -1;
154 }
155
156 /* customize timeout parameter in second */
157 aboot_tiny_set_link_lost_timeout(3);
158 aboot_tiny_set_cmd_response_timeout(2);
159
160 /* Enter main event loops */
161 aboot_tiny_main_loop();
162
163 /* Close serialport device */
164 jacana_serialport_exit();
165
166 gnss_module_fw_download_timer_stop();
167 /**
168 * firmware already closed when switch to pvt download,
169 * so we need close pvt here
170 */
171 priv = firmware.priv;
172 jacana_pvt_close(&firmware);
173 jacana_pvt_raw_close(priv);
174
175 int rc = (int)jacana_aboot_tiny_get_result();
176 if(rc) {
177 aboot_tiny_log_printf("Jacana download failed with error code %d.\n", rc);
178 }
179
180 return -rc;
181}
182/*---------------------------------------------------------------------------*/