blob: 74cd150b8285660bae526247815048e7a0749bd4 [file] [log] [blame]
hj.shaoa2da3dc2025-05-29 19:31:08 -07001#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4#include <fcntl.h>
5#include <unistd.h>
6#include <sys/ioctl.h>
7#include <mtd/mtd-user.h>
8#include <errno.h>
9#include <dlfcn.h>
10#include "mbtk_log.h"
11
12
13
14
15#define FLASH_DEVICE "/dev/mtd32"
16#define BACKUP_DEVICE "/dev/mtd33"
17
18
19/**
20 * @brief 从指定的flash页面读取数据
21 * @param block_id 块ID(从1开始)
22 * @param data 存储读取数据的缓冲区
23 * @param len 存储读取数据长度的指针
24 * @return GSW_HAL_SUCCESS 或 GSW_HAL_FAIL
25 */
26int mbtk_oem_read_data_ext(unsigned int block_id, void *data, unsigned int *len)
27{
28 int fd;
29 struct mtd_info_user mtd_info;
30 off_t offset;
31 ssize_t bytes_read;
32 unsigned int max_block_id;
33 // 输入参数验证
34 if (!data || !len)
35 {
36 LOGE("invalid :data or len is NULL\n");
37 return -2;
38 }
39
40 // 打开flash设备
41 fd = open(FLASH_DEVICE, O_RDONLY);
42 if (fd == -1)
43 {
44 LOGE("open flash device error %s\n", strerror(errno));
45 return -1;
46 }
47
48 // 获取MTD设备信息
49 if (ioctl(fd, MEMGETINFO, &mtd_info) < 0)
50 {
51 LOGE("Get MTD info erro:%s\n", strerror(errno));
52 close(fd);
53 return -1;
54 }
55
56 // 计算最大块ID
57 max_block_id = mtd_info.size / mtd_info.erasesize;
58
59 // 验证block_id
60 if (block_id < 1 || block_id > max_block_id)
61 {
62 LOGE("invalid block_id: %u (max: %u)\n", block_id, max_block_id);
63 close(fd);
64 return -2;
65 }
66
67 // 计算偏移量(block_id从1开始)
68 offset = (block_id - 1) * mtd_info.erasesize;
69
70 // 定位到块位置
71 if (lseek(fd, offset, SEEK_SET) == -1)
72 {
73 LOGE("lseek block error:%s\n", strerror(errno));
74 close(fd);
75 return -1;
76 }
77
78 // 读取块
79 bytes_read = read(fd, data, mtd_info.erasesize);
80 if (bytes_read != mtd_info.erasesize)
81 {
82 LOGE("Read block fail:%s\n", strerror(errno));
83 close(fd);
84 return -1;
85 }
86
87 *len = bytes_read;
88 close(fd);
89 return 0;
90}
91
92/**
93 * @brief 向指定的flash页面写入数据并进行备份
94 * @param block_id 块ID(从1开始)
95 * @param data 要写入的数据
96 * @param len 要写入的数据长度
97 * @return GSW_HAL_SUCCESS 或 GSW_HAL_FAIL
98 */
99int mbtk_oem_write_data_ext(unsigned int block_id, void *data, unsigned int len)
100{
101 int fd_main;
102 int fd_backup;
103 struct mtd_info_user mtd_info;
104 off_t offset_main;
105 off_t offset_backup;
106 ssize_t bytes_written;
107 unsigned int max_block_id;
108 struct erase_info_user erase_info;
109 // 输入参数验证
110 if (!data)
111 {
112 printf("invalid data is NULL\n");
113 return -2;
114 }
115
116 // 首先打开主设备以获取MTD信息
117 fd_main = open(FLASH_DEVICE, O_RDWR);
118 if (fd_main == -1)
119 {
120 printf("open flash error %s\n", strerror(errno));
121 return -1;
122 }
123
124 // 获取MTD设备信息
125 if (ioctl(fd_main, MEMGETINFO, &mtd_info) < 0)
126 {
127 printf("get mtd block info error %s\n", strerror(errno));
128 close(fd_main);
129 return -1;
130 }
131
132 // 计算最大块ID
133 max_block_id = mtd_info.size / mtd_info.erasesize;
134
135 // 验证block_id和len
136 if (block_id < 1 || block_id > max_block_id)
137 {
138 LOGE("invalid block_id: %u (max:%u)\n", block_id, max_block_id);
139 close(fd_main);
140 return -2;
141 }
142
143 if (len > mtd_info.erasesize)
144 {
145 LOGE("invalid len: %u (max: %u)\n", len, mtd_info.erasesize);
146 close(fd_main);
147 return -2;
148 }
149
150 // 打开备份设备
151 fd_backup = open(BACKUP_DEVICE, O_RDWR);
152 if (fd_backup == -1)
153 {
154 LOGE("open bak device fail %s\n", strerror(errno));
155 close(fd_main);
156 return -1;
157 }
158
159 // 计算偏移量
160 offset_main = (block_id - 1) * mtd_info.erasesize;
161 offset_backup = (block_id - 1) * mtd_info.erasesize;
162
163 // 准备erase_info结构体
164 erase_info.start = offset_main; // 设置主设备的起始位置
165 erase_info.length = mtd_info.erasesize; // 设置擦除长度
166
167 // 首先写入备份
168 if (ioctl(fd_backup, MEMERASE, &erase_info) < 0)
169 {
170 LOGE("MEMERASE backup block faile:%s\n", strerror(errno));
171 close(fd_main);
172 close(fd_backup);
173 return -1;
174 }
175
176 if (lseek(fd_backup, offset_backup, SEEK_SET) == -1)
177 {
178 LOGE("lseek backup device failed %s\n", strerror(errno));
179 close(fd_main);
180 close(fd_backup);
181 return -1;
182 }
183
184 bytes_written = write(fd_backup, data, len);
185 if (bytes_written != len)
186 {
187 LOGE("write to backup flahs failed %s\n", strerror(errno));
188 close(fd_main);
189 close(fd_backup);
190 return -1;
191 }
192
193 erase_info.start = offset_main;
194 erase_info.length = mtd_info.erasesize;
195
196 // 然后写入主flash
197 if (ioctl(fd_main, MEMERASE, &erase_info) < 0)
198 {
199 LOGE("MEMERASE main flash failed %s\n", strerror(errno));
200 close(fd_main);
201 close(fd_backup);
202 return -1;
203 }
204
205 if (lseek(fd_main, offset_main, SEEK_SET) == -1)
206 {
207 LOGE("lseek main flash failed %s\n", strerror(errno));
208 close(fd_main);
209 close(fd_backup);
210 return -1;
211 }
212
213 bytes_written = write(fd_main, data, len);
214 if (bytes_written != len)
215 {
216 LOGE(" write to main flash failed %s\n", strerror(errno));
217 close(fd_main);
218 close(fd_backup);
219 return -1;
220 }
221
222 // 确保数据已写入flash
223 fsync(fd_main);
224 fsync(fd_backup);
225
226 close(fd_main);
227 close(fd_backup);
228 return 0;
229}
230