1 #include <stdio.h>
2 #include <string.h>
3 #include "aos/hal/flash.h"
4 #include "ali_dfu_port.h"
5 
6 /* 需要定义SPIFLAHS Sector 大小 */
7 #ifndef SPIF_SECTOR_SIZE
8 #define SPIF_SECTOR_SIZE 0x1000
9 #endif
10 
11 extern uint16_t util_crc16_ccitt(uint8_t const *p_data, uint32_t size, uint16_t const *p_crc);
12 extern void drv_reboot(void);
13 
14 #define LOG printf
15 
16 #define ADDR_GRAN_MASK (0xFFF)
17 #define ADDR_ALIGN_UP(a) (((a) + ADDR_GRAN_MASK) & ~ADDR_GRAN_MASK)
18 
19 static unsigned short image_crc16 = 0;
20 
21 /**
22  * @brief 镜像更新
23  *
24  * @param[in]  signature    暂时不使用
25  * @param[in]  offset       当前buf代表的内容,从镜像bin文件从offset位置开始,比如为100,表示当前buffer是bin文件的第100字节开始
26  * @param[in]  length       本次buffer的长度
27  * @param[in]  buf          本次写入的具体内容
28  *
29  * @return 0:success, otherwise is failed
30  */
ali_dfu_image_update(short signature,int offset,int length,int * buf)31 int ali_dfu_image_update(short signature, int offset, int length, int *buf)
32 {
33     int ret;
34     hal_logic_partition_t partition_info;
35     uint32_t wr_idx = offset;
36     uint8_t *wr_buf = (uint8_t *)buf;
37 
38     if (offset == 0)
39     {
40         image_crc16 = util_crc16_ccitt(wr_buf, length, NULL);
41     }
42     else
43     {
44         image_crc16 = util_crc16_ccitt(wr_buf, length, &image_crc16);
45     }
46 
47     ///get OTA temporary partition information
48     hal_flash_info_get(HAL_PARTITION_OTA_TEMP, &partition_info);
49 
50     if (partition_info.partition_length < (offset + length))
51     {
52         LOG("The write range is over OTA temporary!\r\n");
53         return -1;
54     }
55 
56     /* For bootloader upgrade, we will reserve two sectors, then save the image */
57     wr_idx += (SPIF_SECTOR_SIZE << 1);
58     ret = hal_flash_write(HAL_PARTITION_OTA_TEMP, &wr_idx, (void *)wr_buf, length);
59     if (ret < 0)
60     {
61         LOG("write flash error!!\r\n");
62         return -1;
63     }
64 
65     //LOG("write ok!\n");
66     return 0;
67 }
68 
69 /**
70  * @brief 写入flash之前和之后checksum计算
71  *
72  * @param[in]  image_id 暂时不使用
73  * @param[in]  crc16_output 计算出来的crc返回给调用者
74  *
75  * @return 1:success 0:failed
76  */
dfu_check_checksum(short image_id,unsigned short * crc16_output)77 unsigned char dfu_check_checksum(short image_id, unsigned short *crc16_output)
78 {
79     *crc16_output = image_crc16;
80     return 1;
81 }
82 
83 /**
84  * @brief 升级结束后重启
85  *
86  * @param[in]  -
87  * @return -
88  * @说明: 比如在此函数里面call 切换镜像分区的业务逻辑
89  */
dfu_reboot()90 void dfu_reboot()
91 {
92     drv_reboot();
93 }
94 
95 #ifdef CONFIG_GENIE_OTA_PINGPONG
genie_sal_ota_get_current_image_id(void)96 uint8_t genie_sal_ota_get_current_image_id(void)
97 {
98     return 0;
99 }
100 
genie_sal_ota_change_image_id(uint8_t target_id)101 uint8_t genie_sal_ota_change_image_id(uint8_t target_id)
102 {
103     return 0;
104 }
105 #endif
106 
erase_dfu_flash(void)107 int erase_dfu_flash(void)
108 {
109     int ret;
110     hal_logic_partition_t partition_info;
111     uint32_t offset = (SPIF_SECTOR_SIZE << 1);
112     uint32_t length = 0;
113     uint8_t cmp_buf[32] = {0xFF};
114     uint8_t wr_buf[32] = {0};
115 
116     ///get OTA temporary partition information
117     hal_flash_info_get(HAL_PARTITION_OTA_TEMP, &partition_info);
118 
119     length = partition_info.partition_length - offset;
120 
121     memset(cmp_buf, 0xFF, sizeof(cmp_buf));
122     ret = hal_flash_read(HAL_PARTITION_OTA_TEMP, &offset, (void *)wr_buf, sizeof(wr_buf));
123     if (ret < 0)
124     {
125         LOG("read flash error!!\r\n");
126         return -1;
127     }
128     if (memcmp(wr_buf, cmp_buf, sizeof(wr_buf)) == 0)
129     {
130         return 0;
131     }
132 
133     LOG("OTA dirty\n");
134 
135     offset = (SPIF_SECTOR_SIZE << 1);
136 
137     /* For bootloader upgrade, we will reserve two sectors, then save the image */
138     ret = hal_flash_erase(HAL_PARTITION_OTA_TEMP, offset, length);
139     if (ret < 0)
140     {
141         LOG("Erase flash error!!\r\n");
142         return -1;
143     }
144 
145     return 0;
146 }
147 
ali_dfu_get_ota_partition_max_size(void)148 uint32_t ali_dfu_get_ota_partition_max_size(void)
149 {
150     uint32_t reserve_size = (SPIF_SECTOR_SIZE << 1);
151     hal_logic_partition_t partition_info;
152 
153     hal_flash_info_get(HAL_PARTITION_OTA_TEMP, &partition_info);
154 
155     if (partition_info.partition_length > reserve_size)
156     {
157         return partition_info.partition_length - reserve_size;
158     }
159 
160     return 0;
161 }
162