initial commit
This commit is contained in:
8
hal/hal_flash/config.mk
Executable file
8
hal/hal_flash/config.mk
Executable file
@@ -0,0 +1,8 @@
|
||||
HEADERS += $(HAL_DIR)/hal_flash/*.h
|
||||
SRCDIRS += $(HAL_DIR)/hal_flash
|
||||
|
||||
ifdef MOD_FLASH
|
||||
SRCDIRS += += $(HAL_DIR)/hal_flash/$(MOD_FLASH)
|
||||
else
|
||||
$(warning warning you sure no hal_flash?)
|
||||
endif
|
||||
4
hal/hal_flash/hal_interface_flash.c
Executable file
4
hal/hal_flash/hal_interface_flash.c
Executable file
@@ -0,0 +1,4 @@
|
||||
#include "hal_interface_flash.h"
|
||||
#define TAG "TAG_FLASH"
|
||||
|
||||
|
||||
38
hal/hal_flash/hal_interface_flash.h
Executable file
38
hal/hal_flash/hal_interface_flash.h
Executable file
@@ -0,0 +1,38 @@
|
||||
#ifndef __HAL_FLASH_H__
|
||||
#define __HAL_FLASH_H__
|
||||
#include "hal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 数据类型定义
|
||||
//
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
/*flash init interface define,should be implement if needed*/
|
||||
uint32_t hal_flash_init();
|
||||
|
||||
/*flash deinit interface define,should be implement if needed*/
|
||||
uint32_t hal_flash_deinit();
|
||||
|
||||
// path can be file, return size has been writed
|
||||
uint32_t hal_flash_write(const int8_t *path, int8_t *data, uint32_t size);
|
||||
|
||||
// path can be file, return size has been read
|
||||
uint32_t hal_flash_read(const int8_t *path, int8_t *data, uint32_t size);
|
||||
|
||||
uint32_t hal_flash_format(const int8_t *path);
|
||||
|
||||
uint32_t hal_flash_test();
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __HAL_FLASH_H__ */
|
||||
66
hal/hal_flash/linux/linux_storate.c
Executable file
66
hal/hal_flash/linux/linux_storate.c
Executable file
@@ -0,0 +1,66 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
#include "hal.h"
|
||||
#include "ratelimit.h"
|
||||
#include "hal_interface_flash.h"
|
||||
|
||||
#define TAG "TAG_FLASH"
|
||||
#include "hlog.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*flash init interface define,should be implement if needed*/
|
||||
uint32_t hal_flash_init(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*flash deinit interface define,should be implement if needed*/
|
||||
uint32_t hal_flash_deinit(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t hal_flash_read(const int8_t *path, int8_t *data, uint32_t max_size){
|
||||
FILE *file = fopen ( path, "r" );
|
||||
if ( file ) {
|
||||
uint32_t readed = fread( data, 1, max_size, file );
|
||||
fclose(file);
|
||||
return readed;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t hal_flash_write(const int8_t *path, int8_t *data, uint32_t size){
|
||||
FILE *file = fopen ( path, "w" );
|
||||
if ( file ) {
|
||||
uint32_t writed = fwrite( data, 1, size, file );
|
||||
CHECK_SAME(writed, size);
|
||||
fclose(file);
|
||||
return writed;
|
||||
}
|
||||
CHECK_NULL(path, file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t hal_flash_test(){
|
||||
char path[MAX_PATH];
|
||||
char buf[MAX_PATH];
|
||||
sprintf(path, "%s/%s_test.txt", (char *)get_current_dir_name(), get_filename(__FILE__));
|
||||
hal_flash_write(path, "1234560", 6);
|
||||
uint32_t size = hal_flash_read(path, buf, sizeof(buf));
|
||||
hlogd("read:%u, str:%s", size, buf );
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
350
hal/hal_flash/linux_nor/linux_nor_flash.c
Executable file
350
hal/hal_flash/linux_nor/linux_nor_flash.c
Executable file
@@ -0,0 +1,350 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <mtd/mtd-user.h>
|
||||
#include "hal.h"
|
||||
#include "ratelimit.h"
|
||||
#include "hal_interface_flash.h"
|
||||
|
||||
#define TAG "TAG_FLASH"
|
||||
#include "hlog.h"
|
||||
|
||||
|
||||
#define FLASH_MTD_PARTITION_HEAD_SIZE 32
|
||||
#define FLASH_MTD_BUFFER_SIZE (16*1024) //16K
|
||||
#define FLASH_MTD_SECTOR_SIZE (64*1024)
|
||||
|
||||
#define min(x,y) ({ typeof(x) _x = (x); typeof(y) _y = (y); (void) (&_x == &_y); _x < _y ? _x : _y; })
|
||||
|
||||
static int flash_mtd_open(const char *name, int flags)
|
||||
{
|
||||
FILE *fp;
|
||||
char dev[64] = { 0 };
|
||||
int i,ret;
|
||||
|
||||
if ((fp = fopen("/proc/mtd", "r")))
|
||||
{
|
||||
while (fgets(dev,sizeof(dev),fp))
|
||||
{
|
||||
if (sscanf(dev,"mtd%d:",&i) && strstr(dev, name))
|
||||
{
|
||||
snprintf(dev, sizeof(dev), "/dev/mtd/%d", i);
|
||||
if ((ret = open(dev, flags)) < 0)
|
||||
{
|
||||
snprintf(dev, sizeof(dev), "/dev/mtd%d", i);
|
||||
ret = open(dev, flags);
|
||||
}
|
||||
fclose(fp);
|
||||
ratelimit2(1, 1, hlogd("find mtd%d name %s,ret:%d",i,name,ret));
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*flash init interface define,should be implement if needed*/
|
||||
uint32_t hal_flash_init(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*flash deinit interface define,should be implement if needed*/
|
||||
uint32_t hal_flash_deinit(){
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t hal_flash_read(const int8_t *path, int8_t *data, uint32_t size){
|
||||
struct mtd_info_user info = {0};
|
||||
int fd = -1, ret = -1;
|
||||
fd = flash_mtd_open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
{
|
||||
hloge("Could not open mtd device:%s for read.",path);
|
||||
goto END;
|
||||
}
|
||||
|
||||
if (ioctl(fd, MEMGETINFO, &info))
|
||||
{
|
||||
hloge("Could not get mtd device info");
|
||||
goto END;
|
||||
}
|
||||
|
||||
if (size > info.size)
|
||||
{
|
||||
hloge("Too many bytes - %d > %d bytes\n",size,info.erasesize);
|
||||
goto END;
|
||||
}
|
||||
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
ret = read(fd, data, size);
|
||||
if (ret != size)
|
||||
{
|
||||
hloge("Reading from mtd failed\n");
|
||||
goto END;
|
||||
}
|
||||
END:
|
||||
if (fd != -1 ){
|
||||
close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t hal_flash_write(const int8_t *path, int8_t *data, uint32_t size){
|
||||
int fd = -1, ret = -1;
|
||||
struct mtd_info_user info;
|
||||
struct erase_info_user erase;
|
||||
uint32_t isEraseAll = true;
|
||||
char *buffer = (char *)calloc(1, FLASH_MTD_BUFFER_SIZE);
|
||||
|
||||
fd = flash_mtd_open(path, O_RDWR | O_SYNC);
|
||||
if (fd < 0)
|
||||
{
|
||||
hloge("Could not open mtd device:%s for write.", path);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ioctl(fd, MEMGETINFO, &info))
|
||||
{
|
||||
hloge("Could not get mtd device info.");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (info.size != FLASH_MTD_SECTOR_SIZE)
|
||||
{
|
||||
hloge("only support mtd with one sector!!!");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (size > FLASH_MTD_SECTOR_SIZE)
|
||||
{
|
||||
hloge("too much data!!!");
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!isEraseAll)
|
||||
{
|
||||
lseek(fd,0,SEEK_SET);
|
||||
ret = read(fd,buffer,FLASH_MTD_SECTOR_SIZE);
|
||||
if (ret < 0)
|
||||
{
|
||||
hloge("read sector fail!!!");
|
||||
goto err;
|
||||
}
|
||||
memcpy(buffer, data, size);
|
||||
}
|
||||
|
||||
erase.start = 0;
|
||||
erase.length = info.size;
|
||||
hlogd("start to erase MTD.");
|
||||
if (ioctl (fd,MEMERASE,&erase) < 0)
|
||||
{
|
||||
hloge("failed to erase MTD.");
|
||||
goto err;
|
||||
}
|
||||
hlogd("erase MTD complete.");
|
||||
|
||||
if (!isEraseAll)
|
||||
{
|
||||
lseek(fd,0,SEEK_SET);
|
||||
ret = write(fd,buffer,FLASH_MTD_SECTOR_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
ret = write(fd, data, size);
|
||||
}
|
||||
if (ret < 0)
|
||||
{
|
||||
hloge("write sector fail,ret = %d!!!",ret);
|
||||
}
|
||||
err:
|
||||
if (fd!=-1){
|
||||
close(fd);
|
||||
}
|
||||
hv_free(buffer);
|
||||
hloge("----------------------------> nv write end!\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t flash_mtd_erase_partition(const char* to_partition)
|
||||
{
|
||||
int fd,ret = 0;
|
||||
struct mtd_info_user info;
|
||||
struct erase_info_user erase;
|
||||
|
||||
hlogd("flash_mtd_erase_partition.");
|
||||
fd = flash_mtd_open(to_partition, O_RDWR | O_SYNC);
|
||||
if (fd < 0)
|
||||
{
|
||||
hloge("Could not open mtd device:%s for write.",to_partition);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ioctl(fd, MEMGETINFO, &info))
|
||||
{
|
||||
hloge("Could not get mtd device info.");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
hlogd("mtd size = 0x%x",info.size);
|
||||
erase.start = 0;
|
||||
erase.length = info.size;
|
||||
if (ioctl (fd,MEMERASE,&erase) < 0)
|
||||
{
|
||||
hloge("failed to erase MTD.");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
hlogd("erase ok.");
|
||||
|
||||
exit:
|
||||
if (fd)
|
||||
{
|
||||
close(fd);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
uint32_t flash_mtd_write_partition(const char* to_partition, const char* from_file)
|
||||
{
|
||||
int to_partition_mtd = 0;
|
||||
int from_file_fd = 0;
|
||||
int ret = 0;
|
||||
struct mtd_info_user mtd_info;
|
||||
struct stat filestat;
|
||||
char *buffer = (char *)calloc(1, FLASH_MTD_BUFFER_SIZE);
|
||||
int readed = 0;
|
||||
int writed = 0;
|
||||
int dataSize = 0;
|
||||
int progressPercentage = 0;
|
||||
|
||||
hlogd("flash_mtd_write_partition.");
|
||||
to_partition_mtd = flash_mtd_open(to_partition,O_RDWR | O_SYNC);
|
||||
if (to_partition_mtd < 0)
|
||||
{
|
||||
hloge("Could not open mtd device:%s for write.",to_partition);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (ioctl(to_partition_mtd, MEMGETINFO, &mtd_info))
|
||||
{
|
||||
hloge("Could not get mtd device info.");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
from_file_fd = open(from_file,O_RDWR | O_SYNC);
|
||||
if (from_file_fd < 0)
|
||||
{
|
||||
hloge("failed to open %s.",from_file);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (fstat (from_file_fd,&filestat) < 0)
|
||||
{
|
||||
hloge("failed to get file status.");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
hlogd("mtd size = 0x%x, file size = 0x%x", (uint32_t)mtd_info.size, (uint32_t)filestat.st_size);
|
||||
if (mtd_info.size < filestat.st_size)
|
||||
{
|
||||
hloge("file size is too big!!!");
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
lseek(from_file_fd,FLASH_MTD_PARTITION_HEAD_SIZE,SEEK_SET);
|
||||
lseek(to_partition_mtd,FLASH_MTD_PARTITION_HEAD_SIZE,SEEK_SET);
|
||||
while(1)
|
||||
{
|
||||
readed = read(from_file_fd,buffer,FLASH_MTD_BUFFER_SIZE);
|
||||
if (readed)
|
||||
{
|
||||
writed = write(to_partition_mtd,buffer,readed);
|
||||
if (writed != readed)
|
||||
{
|
||||
hloge("write flash failed!writed = 0x%x,readed=0x%x", writed, readed);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataSize += writed;
|
||||
if ((dataSize*10)/filestat.st_size != progressPercentage)
|
||||
{
|
||||
progressPercentage = (dataSize*10)/filestat.st_size;
|
||||
hlogd("write flash progress %d%%.",progressPercentage*10);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
lseek(from_file_fd,0,SEEK_SET);
|
||||
lseek(to_partition_mtd,0,SEEK_SET);
|
||||
readed = read(from_file_fd,buffer,FLASH_MTD_PARTITION_HEAD_SIZE);
|
||||
if (FLASH_MTD_PARTITION_HEAD_SIZE == readed)
|
||||
{
|
||||
writed = write(to_partition_mtd,buffer,readed);
|
||||
if (writed != readed)
|
||||
{
|
||||
hloge("write flash failed!writed = 0x%x,readed=0x%x",writed,readed);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
dataSize += writed;
|
||||
hlogd("write flash progress %u.", (uint32_t)((dataSize*100)/filestat.st_size));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hloge("write flash failed!writed = 0x%x,readed=0x%x", writed, readed);
|
||||
ret = -1;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
hlogd("write flash complete!!");
|
||||
|
||||
exit:
|
||||
if (to_partition_mtd)
|
||||
{
|
||||
close(to_partition_mtd);
|
||||
}
|
||||
if (from_file_fd)
|
||||
{
|
||||
close(from_file_fd);
|
||||
}
|
||||
hv_free(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user