blob: 74cd150b8285660bae526247815048e7a0749bd4 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <mtd/mtd-user.h>
#include <errno.h>
#include <dlfcn.h>
#include "mbtk_log.h"
#define FLASH_DEVICE "/dev/mtd32"
#define BACKUP_DEVICE "/dev/mtd33"
/**
* @brief 从指定的flash页面读取数据
* @param block_id 块ID(从1开始)
* @param data 存储读取数据的缓冲区
* @param len 存储读取数据长度的指针
* @return GSW_HAL_SUCCESS 或 GSW_HAL_FAIL
*/
int mbtk_oem_read_data_ext(unsigned int block_id, void *data, unsigned int *len)
{
int fd;
struct mtd_info_user mtd_info;
off_t offset;
ssize_t bytes_read;
unsigned int max_block_id;
// 输入参数验证
if (!data || !len)
{
LOGE("invalid :data or len is NULL\n");
return -2;
}
// 打开flash设备
fd = open(FLASH_DEVICE, O_RDONLY);
if (fd == -1)
{
LOGE("open flash device error %s\n", strerror(errno));
return -1;
}
// 获取MTD设备信息
if (ioctl(fd, MEMGETINFO, &mtd_info) < 0)
{
LOGE("Get MTD info erro:%s\n", strerror(errno));
close(fd);
return -1;
}
// 计算最大块ID
max_block_id = mtd_info.size / mtd_info.erasesize;
// 验证block_id
if (block_id < 1 || block_id > max_block_id)
{
LOGE("invalid block_id: %u (max: %u)\n", block_id, max_block_id);
close(fd);
return -2;
}
// 计算偏移量(block_id从1开始)
offset = (block_id - 1) * mtd_info.erasesize;
// 定位到块位置
if (lseek(fd, offset, SEEK_SET) == -1)
{
LOGE("lseek block error:%s\n", strerror(errno));
close(fd);
return -1;
}
// 读取块
bytes_read = read(fd, data, mtd_info.erasesize);
if (bytes_read != mtd_info.erasesize)
{
LOGE("Read block fail:%s\n", strerror(errno));
close(fd);
return -1;
}
*len = bytes_read;
close(fd);
return 0;
}
/**
* @brief 向指定的flash页面写入数据并进行备份
* @param block_id 块ID(从1开始)
* @param data 要写入的数据
* @param len 要写入的数据长度
* @return GSW_HAL_SUCCESS 或 GSW_HAL_FAIL
*/
int mbtk_oem_write_data_ext(unsigned int block_id, void *data, unsigned int len)
{
int fd_main;
int fd_backup;
struct mtd_info_user mtd_info;
off_t offset_main;
off_t offset_backup;
ssize_t bytes_written;
unsigned int max_block_id;
struct erase_info_user erase_info;
// 输入参数验证
if (!data)
{
printf("invalid data is NULL\n");
return -2;
}
// 首先打开主设备以获取MTD信息
fd_main = open(FLASH_DEVICE, O_RDWR);
if (fd_main == -1)
{
printf("open flash error %s\n", strerror(errno));
return -1;
}
// 获取MTD设备信息
if (ioctl(fd_main, MEMGETINFO, &mtd_info) < 0)
{
printf("get mtd block info error %s\n", strerror(errno));
close(fd_main);
return -1;
}
// 计算最大块ID
max_block_id = mtd_info.size / mtd_info.erasesize;
// 验证block_id和len
if (block_id < 1 || block_id > max_block_id)
{
LOGE("invalid block_id: %u (max:%u)\n", block_id, max_block_id);
close(fd_main);
return -2;
}
if (len > mtd_info.erasesize)
{
LOGE("invalid len: %u (max: %u)\n", len, mtd_info.erasesize);
close(fd_main);
return -2;
}
// 打开备份设备
fd_backup = open(BACKUP_DEVICE, O_RDWR);
if (fd_backup == -1)
{
LOGE("open bak device fail %s\n", strerror(errno));
close(fd_main);
return -1;
}
// 计算偏移量
offset_main = (block_id - 1) * mtd_info.erasesize;
offset_backup = (block_id - 1) * mtd_info.erasesize;
// 准备erase_info结构体
erase_info.start = offset_main; // 设置主设备的起始位置
erase_info.length = mtd_info.erasesize; // 设置擦除长度
// 首先写入备份
if (ioctl(fd_backup, MEMERASE, &erase_info) < 0)
{
LOGE("MEMERASE backup block faile:%s\n", strerror(errno));
close(fd_main);
close(fd_backup);
return -1;
}
if (lseek(fd_backup, offset_backup, SEEK_SET) == -1)
{
LOGE("lseek backup device failed %s\n", strerror(errno));
close(fd_main);
close(fd_backup);
return -1;
}
bytes_written = write(fd_backup, data, len);
if (bytes_written != len)
{
LOGE("write to backup flahs failed %s\n", strerror(errno));
close(fd_main);
close(fd_backup);
return -1;
}
erase_info.start = offset_main;
erase_info.length = mtd_info.erasesize;
// 然后写入主flash
if (ioctl(fd_main, MEMERASE, &erase_info) < 0)
{
LOGE("MEMERASE main flash failed %s\n", strerror(errno));
close(fd_main);
close(fd_backup);
return -1;
}
if (lseek(fd_main, offset_main, SEEK_SET) == -1)
{
LOGE("lseek main flash failed %s\n", strerror(errno));
close(fd_main);
close(fd_backup);
return -1;
}
bytes_written = write(fd_main, data, len);
if (bytes_written != len)
{
LOGE(" write to main flash failed %s\n", strerror(errno));
close(fd_main);
close(fd_backup);
return -1;
}
// 确保数据已写入flash
fsync(fd_main);
fsync(fd_backup);
close(fd_main);
close(fd_backup);
return 0;
}