• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "app_main.h"
17 
18 #include <hi3861_platform.h>
19 #include <hi_mdm.h>
20 #include <hi_flash.h>
21 #include <hi_nv.h>
22 #include <hi_lowpower.h>
23 #include <hi_diag.h>
24 #include <hi_crash.h>
25 #include <hi_sal.h>
26 #include <hi_shell.h>
27 #if defined(CONFIG_AT_COMMAND) || defined(CONFIG_FACTORY_TEST_MODE)
28 #include <hi_at.h>
29 #endif
30 #include <hi_fs.h>
31 #include <hi_partition_table.h>
32 #include <hi_ver.h>
33 #include <hi_cpu.h>
34 #include <hi_crash.h>
35 #ifdef CONFIG_DMA_SUPPORT
36 #include <hi_dma.h>
37 #endif
38 #ifdef CONFIG_I2C_SUPPORT
39 #include <hi_i2c.h>
40 #endif
41 #ifdef CONFIG_I2S_SUPPORT
42 #include <hi_i2s.h>
43 #endif
44 #ifdef CONFIG_SPI_SUPPORT
45 #include <hi_spi.h>
46 #endif
47 #ifdef CONFIG_PWM_SUPPORT
48 #include <hi_pwm.h>
49 #endif
50 #ifdef CONFIG_SDIO_SUPPORT
51 #include <hi_sdio_slave.h>
52 #include <hi_watchdog.h>
53 #include <app_demo_sdio_slave.h>
54 #endif
55 
56 #ifndef CONFIG_FACTORY_TEST_MODE
57 #include "lwip/opt.h"
58 #include "lwip/ip_addr.h"
59 #include "lwip/netifapi.h"
60 #endif
61 
62 #include "app_demo_upg_verify.h"
63 #include "hi_wifi_api.h"
64 #ifdef CONFIG_HILINK
65 #include "hilink.h"
66 #endif
67 
68 #include "ohos_main.h"
69 
70 #define APP_DEMO_RELEASE_MEM_TASK_SIZE 0x200
71 /* 高优先级(不得小于3),尽快释放系统app_main栈内存 */
72 #define APP_DEMO_RELEASE_MEM_TASK_PRIO 0x3
73 
74 #define APP_INIT_EVENT_NUM  4
75 #define APP_INIT_VAP_NUM    2
76 #ifdef CONFIG_MESH_SUPPORT
77 #define APP_INIT_USR_NUM    6
78 #else
79 #define APP_INIT_USR_NUM    2
80 #endif
81 
82 #define PERIPHERAL_INIT_ERR_FLASH   (1 << 0)
83 #define PERIPHERAL_INIT_ERR_UART0   (1 << 1)
84 #define PERIPHERAL_INIT_ERR_UART1   (1 << 2)
85 #define PERIPHERAL_INIT_ERR_UART2   (1 << 3)
86 #define PERIPHERAL_INIT_ERR_IO      (1 << 4)
87 #define PERIPHERAL_INIT_ERR_CIPHER  (1 << 5)
88 #define PERIPHERAL_INIT_ERR_DMA     (1 << 6)
89 #define PERIPHERAL_INIT_ERR_I2C     (1 << 7)
90 #define PERIPHERAL_INIT_ERR_I2S     (1 << 8)
91 #define PERIPHERAL_INIT_ERR_SPI     (1 << 9)
92 #define PERIPHERAL_INIT_ERR_PWM     (1 << 10)
93 #define PERIPHERAL_INIT_ERR_SDIO    (1 << 11)
94 
95 #ifndef IO_CTRL_REG_BASE_ADDR
96 #define IO_CTRL_REG_BASE_ADDR 0x904
97 #endif
98 #define iocfg_reg_addr(_x) (HI_IOCFG_REG_BASE + IO_CTRL_REG_BASE_ADDR + (_x) * 4)
99 #define IOCFG_LOWPOWER_CFG_VAL 0xF8
100 
101 #ifdef CONFIG_SDIO_SUPPORT
102 #define APP_SDIO_INIT_TASK_SIZE 0x1000
103 #define APP_SDIO_INIT_TASK_PRIO 25
104 
sdio_init_task_body(hi_void * param)105 static hi_void *sdio_init_task_body(hi_void *param)
106 {
107     printf("start sdio init\r\n");
108     hi_unref_param(param);
109     /* 避免由于SDIO HOST长时间未配置触发看门狗异常,此处先关狗 */
110     hi_watchdog_disable();
111     hi_u32 ret = hi_sdio_init();
112     if (ret != HI_ERR_SUCCESS) {
113         printf("sdio driver init fail\r\n");
114     }
115     hi_watchdog_enable();
116     app_demo_sdio_callback_init();
117     printf("finish sdio init\r\n");
118     return HI_NULL;
119 }
120 
app_sdio_init(hi_void)121 hi_u32 app_sdio_init(hi_void)
122 {
123     /* Create a task to init sdio */
124     hi_u32 sdio_init_task_id = 0;
125     hi_task_attr attr = {0};
126     attr.stack_size = APP_SDIO_INIT_TASK_SIZE;
127     attr.task_prio = APP_SDIO_INIT_TASK_PRIO;
128     attr.task_name = (hi_char*)"sdio_init";
129     hi_u32 ret = hi_task_create(&sdio_init_task_id, &attr, sdio_init_task_body, HI_NULL);
130     if (ret != HI_ERR_SUCCESS) {
131         printf("Falied to create sdio init task!\n");
132     }
133     return ret;
134 }
135 #endif
136 
137 #define CLKEN_I2C0      14
138 #define CLKEN_I2C1      15
139 #define CLKEN_SPI0      5
140 #define CLKEN_SPI1      0
141 #define CLKEN_MONITOR   6
142 #define CLKEN_DMA_WBUS  1
143 #define CLKEN1_PWM5     10
144 #define CLKEN1_PWM_BUS  6
145 #define CLKEN1_PWM      5
146 #define CLKEN1_PWM4     4
147 #define CLKEN1_PWM3     3
148 #define CLKEN1_PWM2     2
149 #define CLKEN1_PWM1     1
150 #define CLKEN1_PWM0     0
151 #define CLKEN1_PWM_ALL  ((1 << (CLKEN1_PWM0)) | (1 << (CLKEN1_PWM1)) | (1 << (CLKEN1_PWM2)) | (1 << (CLKEN1_PWM3)) | \
152                         (1 << (CLKEN1_PWM4)) | (1 << (CLKEN1_PWM5)))
153 #define CLKEN2_I2S_BUS  11
154 #define CLKEN2_I2S      10
155 #define CLKEN_UART2     6
156 #define CLKEN_UART2_BUS 9
157 #define CLKEN_TIMER1    7
158 #define CLKEN_TIMER2    8
159 #define CLKEN_SDIO_WBUS 4
160 
peripheral_close_clken(hi_void)161 hi_void peripheral_close_clken(hi_void)
162 {
163     hi_u16 reg_val;
164     hi_reg_read16(CLDO_CTL_CLKEN_REG, reg_val);
165     reg_val &= ~((1 << CLKEN_I2C0) | (1 << CLKEN_I2C1));
166     reg_val &= ~((1 << CLKEN_SPI0) | (1 << CLKEN_SPI1));
167     reg_val &= ~((1 << CLKEN_DMA_WBUS) | (1 << CLKEN_MONITOR));
168     reg_val &= ~((1 << CLKEN_TIMER1) | (1 << CLKEN_TIMER2));
169     hi_reg_write16(CLDO_CTL_CLKEN_REG, reg_val); /* disable clken0 clk gate */
170 
171 #ifndef CONFIG_PWM_HOLD_AFTER_REBOOT
172     hi_reg_read16(CLDO_CTL_CLKEN1_REG, reg_val);
173     reg_val &= ~CLKEN1_PWM_ALL;
174     reg_val &= ~((1 << CLKEN1_PWM_BUS) | (1 << CLKEN1_PWM));
175     hi_reg_write16(CLDO_CTL_CLKEN1_REG, reg_val); /* disable clken1 clk gate */
176 #endif
177 
178     hi_reg_read16(CLDO_CTL_CLKEN2_REG, reg_val);
179     reg_val &= ~((1 << CLKEN2_I2S) | (1 << CLKEN2_I2S_BUS));
180     hi_reg_write16(CLDO_CTL_CLKEN2_REG, reg_val); /* disable clken2 clk gate */
181     hi_reg_read16(W_CTL_UART_MAC80M_CLKEN_REG, reg_val);
182 #ifdef CONFIG_SDIO_SUPPORT
183         reg_val &= ~((1 << CLKEN_UART2) | (1 << CLKEN_UART2_BUS));
184 #else
185         reg_val &= ~((1 << CLKEN_UART2) | (1 << CLKEN_UART2_BUS) | (1 << CLKEN_SDIO_WBUS));
186 #endif
187     hi_reg_write16(W_CTL_UART_MAC80M_CLKEN_REG, reg_val); /* disable uart_mac80m clk gate */
188     hi_reg_write16(PMU_CMU_CTL_CLK_960M_GT_REG, 0x1); /* disable 960m clk gate */
189 }
190 
191 static hi_uart_attribute g_at_uart_cfg  = {115200, 8, 1, 0, 0};
192 
193 hi_bool g_have_inited = HI_FALSE;
194 static app_iocfg_backup g_iocfg_backup = {0};
195 
peripheral_init(hi_void)196 hi_void peripheral_init(hi_void)
197 {
198     hi_u32 ret;
199     hi_u32 err_info = 0;
200     hi_cipher_set_clk_switch(HI_TRUE);
201     peripheral_close_clken();
202     hi_flash_deinit();
203     ret = hi_flash_init();
204     if (ret != HI_ERR_SUCCESS) {
205         err_info |= PERIPHERAL_INIT_ERR_FLASH;
206     }
207 
208     if (g_have_inited == HI_FALSE) {
209         ret = hi_uart_init(HI_UART_IDX_1, &g_at_uart_cfg, HI_NULL);
210         if (ret != HI_ERR_SUCCESS) {
211             err_info |= PERIPHERAL_INIT_ERR_UART1;
212         }
213     } else {
214         ret = hi_uart_lp_restore(HI_UART_IDX_1);
215         if (ret != HI_ERR_SUCCESS) {
216             err_info |= PERIPHERAL_INIT_ERR_UART1;
217         }
218         ret = hi_uart_lp_restore(HI_UART_IDX_0);
219         if (ret != HI_ERR_SUCCESS) {
220             err_info |= PERIPHERAL_INIT_ERR_UART0;
221         }
222         ret = hi_uart_lp_restore(HI_UART_IDX_2);
223         if (ret != HI_ERR_SUCCESS) {
224             err_info |= PERIPHERAL_INIT_ERR_UART2;
225         }
226     }
227     g_have_inited = HI_TRUE;
228 
229     app_io_init();
230 
231     ret = hi_cipher_init();
232     if (ret != HI_ERR_SUCCESS) {
233         err_info |= PERIPHERAL_INIT_ERR_CIPHER;
234     }
235 
236 #ifdef CONFIG_DMA_SUPPORT
237     /* 如果需要使用UART/SPI的DMA功能,或者使用I2S驱动等,需要初始化DMA */
238     /* if product use dma in uart or spi, or use I2S driver, or DMA memory transfer,
239        should init DMA Driver here. */
240     ret = hi_dma_init();
241     if (ret != HI_ERR_SUCCESS) {
242         err_info |= PERIPHERAL_INIT_ERR_DMA;
243     }
244 #endif
245 
246 #ifdef CONFIG_I2C_SUPPORT
247     ret = hi_i2c_deinit(HI_I2C_IDX_0); /* if wake_up from deep sleep, should deinit first */
248     ret |= hi_i2c_init(HI_I2C_IDX_0, 100000); /* baudrate: 100000 */
249     if (ret != HI_ERR_SUCCESS) {
250         err_info |= PERIPHERAL_INIT_ERR_I2C;
251     }
252 #endif
253 
254 #ifdef CONFIG_I2S_SUPPORT
255     ret = hi_i2s_deinit();  /* if wake_up from deep sleep, should deinit first */
256     hi_i2s_attribute i2s_cfg = {
257         .sample_rate = HI_I2S_SAMPLE_RATE_8K,
258         .resolution = HI_I2S_RESOLUTION_16BIT,
259     };
260     ret |= hi_i2s_init(&i2s_cfg);
261     if (ret != HI_ERR_SUCCESS) {
262         err_info |= PERIPHERAL_INIT_ERR_I2S;
263     }
264 #endif
265 
266 #ifdef CONFIG_SPI_SUPPORT
267     ret = hi_spi_deinit(HI_SPI_ID_0); /* if wake_up from deep sleep, should deinit first */
268     hi_spi_cfg_basic_info spi_cfg_basic_info;
269     spi_cfg_basic_info.cpha = 1;
270     spi_cfg_basic_info.cpol = 1;
271     spi_cfg_basic_info.data_width = HI_SPI_CFG_DATA_WIDTH_E_7BIT;
272     spi_cfg_basic_info.endian = 0;
273     spi_cfg_basic_info.fram_mode = 0;
274     spi_cfg_basic_info.freq = 2000000; /* set frequency 2000000 */
275     hi_spi_cfg_init_param spi_init_param = {0};
276     spi_init_param.is_slave = HI_FALSE;
277     ret |= hi_spi_init(HI_SPI_ID_0, spi_init_param, &spi_cfg_basic_info);
278     if (ret != HI_ERR_SUCCESS) {
279         err_info |= PERIPHERAL_INIT_ERR_SPI;
280     }
281 #endif
282 
283 #ifdef CONFIG_PWM_SUPPORT
284     ret = hi_pwm_init(HI_PWM_PORT_PWM1);
285     if (ret != HI_ERR_SUCCESS) {
286         err_info |= PERIPHERAL_INIT_ERR_PWM;
287     }
288 #endif
289 
290 #ifdef AT_DEBUG_CMD_SUPPORT
291     if (err_info != 0) {
292         hi_at_printf("peri_init:%x\r\n", err_info);
293     }
294 #endif
295 }
296 
peripheral_init_no_sleep(hi_void)297 hi_void peripheral_init_no_sleep(hi_void)
298 {
299     /* 示例:深睡唤醒不需要重新初始化的外设,可放置在此函数初始化 */
300 #ifdef CONFIG_SDIO_SUPPORT
301     hi_sdio_set_powerdown_when_deep_sleep(HI_FALSE);
302     hi_u32 ret = app_sdio_init();
303     if (ret != HI_ERR_SUCCESS) {
304         printf("sdio init failed\r\n");
305     }
306 #endif
307 }
308 
config_before_sleep(hi_void)309 hi_u32 config_before_sleep(hi_void)
310 {
311     /* 用户根据实际io设计配置,防止深睡阶段漏电流 */
312     if (hi_lpc_get_type() == HI_DEEP_SLEEP) {
313 #ifdef AT_DEBUG_CMD_SUPPORT
314         hi_at_printf("!");
315 #endif
316         /* 用户根据实际io使用情况设置:无上拉电阻、无下拉电阻、禁止输入信号使能等,防止漏电流,具体参考芯片手册 */
317         hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_6), g_iocfg_backup.gpio6_cfg);
318         hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_8), g_iocfg_backup.gpio8_cfg);
319         hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_10), g_iocfg_backup.gpio10_cfg);
320         hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_11), g_iocfg_backup.gpio11_cfg);
321         hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_12), g_iocfg_backup.gpio12_cfg);
322         hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_GPIO_13), g_iocfg_backup.gpio13_cfg);
323         hi_reg_read16(iocfg_reg_addr(HI_IO_NAME_SFC_CSN), g_iocfg_backup.sfc_csn_cfg);
324 
325         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_6), IOCFG_LOWPOWER_CFG_VAL);
326         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_8), IOCFG_LOWPOWER_CFG_VAL);
327         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_10), IOCFG_LOWPOWER_CFG_VAL);
328         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_11), IOCFG_LOWPOWER_CFG_VAL);
329         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_12), IOCFG_LOWPOWER_CFG_VAL);
330         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_13), IOCFG_LOWPOWER_CFG_VAL);
331         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_SFC_CSN), IOCFG_LOWPOWER_CFG_VAL);
332         hi_uart_lp_save(HI_UART_IDX_0);
333         hi_uart_lp_save(HI_UART_IDX_1);
334         hi_uart_lp_save(HI_UART_IDX_2);
335     }
336     return HI_ERR_SUCCESS;
337 }
338 
config_after_sleep(hi_void)339 hi_u32 config_after_sleep(hi_void)
340 {
341     /* 用户根据实际io设计恢复,防止深睡阶段漏电流 */
342     if (hi_lpc_get_type() == HI_DEEP_SLEEP) {
343         /* 用户根据实际io使用情况配置恢复 */
344         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_6), g_iocfg_backup.gpio6_cfg);
345         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_8), g_iocfg_backup.gpio8_cfg);
346         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_10), g_iocfg_backup.gpio10_cfg);
347         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_11), g_iocfg_backup.gpio11_cfg);
348         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_12), g_iocfg_backup.gpio12_cfg);
349         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_GPIO_13), g_iocfg_backup.gpio13_cfg);
350         hi_reg_write16(iocfg_reg_addr(HI_IO_NAME_SFC_CSN), g_iocfg_backup.sfc_csn_cfg);
351 #ifdef AT_DEBUG_CMD_SUPPORT
352         hi_at_printf("@\r\n");
353 #endif
354     }
355     return HI_ERR_SUCCESS;
356 }
357 
app_demo_task_second_body(hi_void * param)358 static hi_void *app_demo_task_second_body(hi_void *param)
359 {
360     /* 释放app_main栈内存使用 */
361     hi_unref_param(param);
362     return HI_NULL;
363 }
364 
app_demo_task_body(hi_void * param)365 static hi_void *app_demo_task_body(hi_void *param)
366 {
367     /* 释放app_main栈内存使用 */
368     hi_unref_param(param);
369 
370     hi_u32 task_id = 0;
371     hi_task_attr attr = {0};
372     attr.stack_size = APP_DEMO_RELEASE_MEM_TASK_SIZE;
373     attr.task_prio = APP_DEMO_RELEASE_MEM_TASK_PRIO;
374     attr.task_name = (hi_char*)"app_demo_second";
375     hi_u32 ret = hi_task_create(&task_id, &attr, app_demo_task_second_body, HI_NULL);
376     if (ret != HI_ERR_SUCCESS) {
377         printf("Falied to create app_demo_second task:0x%x\n", ret);
378     }
379     return HI_NULL;
380 }
381 
app_demo_task_release_mem(hi_void)382 hi_void app_demo_task_release_mem(hi_void)
383 {
384     /* 释放app_main栈内存使用 */
385     hi_u32 task_id = 0;
386     hi_task_attr attr = {0};
387     attr.stack_size = APP_DEMO_RELEASE_MEM_TASK_SIZE;
388     attr.task_prio = APP_DEMO_RELEASE_MEM_TASK_PRIO;
389     attr.task_name = (hi_char*)"app_demo";
390     hi_u32 ret = hi_task_create(&task_id, &attr, app_demo_task_body, HI_NULL);
391     if (ret != HI_ERR_SUCCESS) {
392         printf("Falied to create app_demo task:0x%x\n", ret);
393     }
394     return;
395 }
396 
397 
app_main(hi_void)398 hi_void app_main(hi_void)
399 {
400 #ifdef CONFIG_FACTORY_TEST_MODE
401         printf("factory test mode!\r\n");
402 #endif
403 
404     const hi_char* sdk_ver = hi_get_sdk_version();
405     printf("sdk ver:%s\r\n", sdk_ver);
406 
407     hi_flash_partition_table *ptable = HI_NULL;
408 
409     peripheral_init();
410     peripheral_init_no_sleep();
411 
412 #ifndef CONFIG_FACTORY_TEST_MODE
413     hi_lpc_register_wakeup_entry(peripheral_init);
414 #endif
415 
416     hi_u32 ret = hi_factory_nv_init(HI_FNV_DEFAULT_ADDR, HI_NV_DEFAULT_TOTAL_SIZE, HI_NV_DEFAULT_BLOCK_SIZE);
417     if (ret != HI_ERR_SUCCESS) {
418         printf("factory nv init fail\r\n");
419     }
420 
421     /* partion table should init after factory nv init. */
422     ret = hi_flash_partition_init();
423     if (ret != HI_ERR_SUCCESS) {
424         printf("flash partition table init fail:0x%x \r\n", ret);
425     }
426     ptable = hi_get_partition_table();
427 
428     ret = hi_nv_init(ptable->table[HI_FLASH_PARTITON_NORMAL_NV].addr, ptable->table[HI_FLASH_PARTITON_NORMAL_NV].size,
429         HI_NV_DEFAULT_BLOCK_SIZE);
430     if (ret != HI_ERR_SUCCESS) {
431         printf("nv init fail\r\n");
432     }
433 
434 #ifndef CONFIG_FACTORY_TEST_MODE
435     hi_upg_init();
436 #endif
437 
438     /* if not use file system, there is no need init it */
439     hi_fs_init();
440 
441     (hi_void)hi_event_init(APP_INIT_EVENT_NUM, HI_NULL);
442     hi_sal_init();
443     /* 此处设为TRUE后中断中看门狗复位会显示复位时PC值,但有复位不完全风险,量产版本请务必设为FALSE */
444     hi_syserr_watchdog_debug(HI_FALSE);
445     /* 默认记录宕机信息到FLASH,根据应用场景,可不记录,避免频繁异常宕机情况损耗FLASH寿命 */
446     hi_syserr_record_crash_info(HI_TRUE);
447 
448     hi_lpc_init();
449     hi_lpc_register_hw_handler(config_before_sleep, config_after_sleep);
450 
451 #if defined(CONFIG_AT_COMMAND) || defined(CONFIG_FACTORY_TEST_MODE)
452     ret = hi_at_init();
453     if (ret == HI_ERR_SUCCESS) {
454         hi_at_sys_cmd_register();
455     }
456 #endif
457 
458     /* 如果不需要使用Histudio查看WIFI驱动运行日志等,无需初始化diag */
459     /* if not use histudio for diagnostic, diag initialization is unnecessary */
460     /* Shell and Diag use the same uart port, only one of them can be selected */
461 #ifndef CONFIG_FACTORY_TEST_MODE
462 
463 #ifndef ENABLE_SHELL_DEBUG
464 #ifdef CONFIG_DIAG_SUPPORT
465     (hi_void)hi_diag_init();
466 #endif
467 #else
468     (hi_void)hi_shell_init();
469 #endif
470 
471     tcpip_init(NULL, NULL);
472 #endif
473 
474     ret = hi_wifi_init(APP_INIT_VAP_NUM, APP_INIT_USR_NUM);
475     if (ret != HISI_OK) {
476         printf("wifi init failed!\n");
477     } else {
478         printf("wifi init success!\n");
479     }
480     app_demo_task_release_mem(); /* 释放系统栈内存所使用任务 */
481 
482 #ifndef CONFIG_FACTORY_TEST_MODE
483     app_demo_upg_init();
484 #ifdef CONFIG_HILINK
485     ret = hilink_main();
486     if (ret != HISI_OK) {
487         printf("hilink init failed!\n");
488     } else {
489         printf("hilink init success!\n");
490     }
491 #endif
492 #endif
493     OHOS_Main();
494 }
495 
496