Commit 46ea2aa4 authored by TerryE's avatar TerryE
Browse files

Make the wifi.smart functions options and remove wofs and upgrade

AFAIK no one uses the wifi.startsmart() and wifi.stopsmart().  Removing
them frees up an extra 20-25K of Flash to use as filesystem.  So I have
added a new config define WIFI_SMART_ENABLE which is enabled by default
so the default functionality is the same, but if this is commented out
then this code is omitted.

I have also removed wofs and upgrade from this build as we no longer
support these.
parent ef5eed30
......@@ -25,7 +25,6 @@ SUBDIRS= \
user \
driver \
json \
upgrade \
platform \
libc \
lua \
......@@ -36,7 +35,6 @@ SUBDIRS= \
u8glib \
ucglib \
smart \
wofs \
modules \
spiffs \
cjson \
......@@ -72,7 +70,6 @@ COMPONENTS_eagle.app.v6 = \
user/libuser.a \
driver/libdriver.a \
json/libjson.a \
upgrade/libupgrade.a \
platform/libplatform.a \
task/libtask.a \
libc/liblibc.a \
......@@ -83,7 +80,6 @@ COMPONENTS_eagle.app.v6 = \
u8glib/u8glib.a \
ucglib/ucglib.a \
smart/smart.a \
wofs/wofs.a \
spiffs/spiffs.a \
cjson/libcjson.a \
crypto/libcrypto.a \
......
......@@ -57,9 +57,7 @@
//#define MD2_ENABLE
#define SHA2_ENABLE
// #define BUILD_WOFS 1
#define BUILD_SPIFFS 1
#define SPIFFS_CACHE 1
// #define LUA_NUMBER_INTEGRAL
......@@ -94,6 +92,8 @@
//#define WIFI_STA_HOSTNAME "NodeMCU"
//#define WIFI_STA_HOSTNAME_APPEND_MAC
#define WIFI_SMART_ENABLE
#define STRBUF_DEFAULT_INCREMENT 32
#endif /* __USER_CONFIG_H__ */
......@@ -38,7 +38,6 @@ endif
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../wofs
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
......@@ -40,7 +40,6 @@ STD_CFLAGS=-std=gnu11 -Wimplicit
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../wofs
INCLUDES += -I ../spiffs
INCLUDES += -I ../libc
INCLUDES += -I ../modules
......
......@@ -47,7 +47,6 @@ INCLUDES += -I ../u8glib
INCLUDES += -I ../ucglib
INCLUDES += -I ../lua
INCLUDES += -I ../platform
INCLUDES += -I ../wofs
INCLUDES += -I ../spiffs
INCLUDES += -I ../smart
INCLUDES += -I ../cjson
......
......@@ -61,22 +61,7 @@ static int file_format( lua_State* L )
return 0;
}
#if defined(BUILD_WOFS)
// Lua: list()
static int file_list( lua_State* L )
{
uint32_t start = 0;
size_t act_len = 0;
char fsname[ FS_NAME_MAX_LENGTH + 1 ];
lua_newtable( L );
while( FS_FILE_OK == wofs_next(&start, fsname, FS_NAME_MAX_LENGTH, &act_len) ){
lua_pushinteger(L, act_len);
lua_setfield( L, -2, fsname );
}
return 1;
}
#elif defined(BUILD_SPIFFS)
#if defined(BUILD_SPIFFS)
extern spiffs fs;
......@@ -324,13 +309,13 @@ static const LUA_REG_TYPE file_map[] = {
{ LSTRKEY( "read" ), LFUNCVAL( file_read ) },
{ LSTRKEY( "readline" ), LFUNCVAL( file_readline ) },
{ LSTRKEY( "format" ), LFUNCVAL( file_format ) },
#if defined(BUILD_SPIFFS) && !defined(BUILD_WOFS)
#if defined(BUILD_SPIFFS)
{ LSTRKEY( "remove" ), LFUNCVAL( file_remove ) },
{ LSTRKEY( "seek" ), LFUNCVAL( file_seek ) },
{ LSTRKEY( "flush" ), LFUNCVAL( file_flush ) },
{ LSTRKEY( "rename" ), LFUNCVAL( file_rename ) },
{ LSTRKEY( "fsinfo" ), LFUNCVAL( file_fsinfo ) },
{ LSTRKEY( "fscfg" ), LFUNCVAL( file_fscfg ) },
{ LSTRKEY( "fscfg" ), LFUNCVAL( file_fscfg ) },
{ LSTRKEY( "exists" ), LFUNCVAL( file_exists ) },
#endif
{ LNILKEY, LNILVAL }
......
......@@ -19,7 +19,6 @@
#include "lrodefs.h"
#include "c_types.h"
#include "romfs.h"
#include "c_string.h"
#include "driver/uart.h"
#include "user_interface.h"
......
......@@ -10,10 +10,14 @@
#include "c_types.h"
#include "user_interface.h"
#ifdef WIFI_SMART_ENABLE
#include "smart.h"
#include "smartconfig.h"
static int wifi_smart_succeed = LUA_NOREF;
#endif
static uint8 getap_output_format=0;
//wifi.sleep variables
......@@ -27,6 +31,7 @@ static os_timer_t wifi_sta_status_timer;
static uint8 prev_wifi_status=0;
#ifdef WIFI_SMART_ENABLE
#if defined( NODE_SMART_OLDSTYLE )
#else
static lua_State* smart_L = NULL;
......@@ -75,6 +80,7 @@ static void wifi_smart_succeed_cb(sc_status status, void *pdata){
#endif // defined( NODE_SMART_OLDSTYLE )
}
#endif // WIFI_SMART_ENABLE
static int wifi_scan_succeed = LUA_NOREF;
static lua_State* gL = NULL;
......@@ -142,6 +148,7 @@ static void wifi_scan_done(void *arg, STATUS status)
}
}
#ifdef WIFI_SMART_ENABLE
// Lua: smart(channel, function succeed_cb)
// Lua: smart(type, function succeed_cb)
static int wifi_start_smart( lua_State* L )
......@@ -224,6 +231,7 @@ static int wifi_exit_smart( lua_State* L )
wifi_smart_succeed = LUA_NOREF;
return 0;
}
#endif // WIFI_SMART_ENABLE
// Lua: realmode = setmode(mode)
static int wifi_setmode( lua_State* L )
......@@ -1441,8 +1449,10 @@ static const LUA_REG_TYPE wifi_map[] = {
{ LSTRKEY( "setphymode" ), LFUNCVAL( wifi_setphymode ) },
{ LSTRKEY( "getphymode" ), LFUNCVAL( wifi_getphymode ) },
{ LSTRKEY( "sleep" ), LFUNCVAL( wifi_sleep ) },
#ifdef WIFI_SMART_ENABLE
{ LSTRKEY( "startsmart" ), LFUNCVAL( wifi_start_smart ) },
{ LSTRKEY( "stopsmart" ), LFUNCVAL( wifi_exit_smart ) },
#endif
{ LSTRKEY( "sleeptype" ), LFUNCVAL( wifi_sleeptype ) },
{ LSTRKEY( "sta" ), LROVAL( wifi_station_map ) },
......
......@@ -40,7 +40,6 @@ STD_CFLAGS=-std=gnu11 -Wimplicit
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../wofs
INCLUDES += -I ../spiffs
INCLUDES += -I ../libc
INCLUDES += -I ../lua
......
......@@ -41,12 +41,6 @@
#define SYS_PARAM_SEC_NUM 4
#define SYS_PARAM_SEC_START (FLASH_SEC_NUM - SYS_PARAM_SEC_NUM)
// #define WOFS_SEC_START 0x80
// #define WOFS_SEC_START 0x60
// #define WOFS_SEC_END (SYS_PARAM_SEC_START)
// #define WOFS_SEC_NUM (WOFS_SEC_END - WOFS_SEC_START)
// #define WOFS_SEC_NUM 0xc
#define INTERNAL_FLASH_SECTOR_SIZE SPI_FLASH_SEC_SIZE
// #define INTERNAL_FLASH_SECTOR_ARRAY { 0x4000, 0x4000, 0x4000, 0x4000, 0x10000, 0x20000, 0x20000, 0x20000, 0x20000, 0x20000 }
#define INTERNAL_FLASH_WRITE_UNIT_SIZE 4
......
#include "flash_fs.h"
#include "c_string.h"
#if defined( BUILD_WOFS )
#include "romfs.h"
#elif defined( BUILD_SPIFFS )
#include "spiffs.h"
#endif
int fs_mode2flag(const char *mode){
if(c_strlen(mode)==1){
......
......@@ -4,38 +4,7 @@
#include "user_config.h"
#if defined( BUILD_WOFS )
#include "romfs.h"
#define FS_OPEN_OK 0
#define FS_RDONLY O_RDONLY
#define FS_WRONLY O_WRONLY
#define FS_RDWR O_RDWR
#define FS_APPEND O_APPEND
#define FS_TRUNC O_TRUNC
#define FS_CREAT O_CREAT
#define FS_EXCL O_EXCL
#define FS_SEEK_SET SEEK_SET
#define FS_SEEK_CUR SEEK_CUR
#define FS_SEEK_END SEEK_END
#define fs_open wofs_open
#define fs_close wofs_close
#define fs_write wofs_write
#define fs_read wofs_read
#define fs_seek wofs_lseek
#define fs_eof wofs_eof
#define fs_getc wofs_getc
#define fs_ungetc wofs_ungetc
#define fs_format wofs_format
#define fs_next wofs_next
#define FS_NAME_MAX_LENGTH MAX_FNAME_LENGTH
#elif defined( BUILD_SPIFFS )
#if defined( BUILD_SPIFFS )
#include "spiffs.h"
......
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = libupgrade.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../../include/ets
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
#include "ets_sys.h"
#include "osapi.h"
#include "os_type.h"
#include "lwip/err.h"
#include "lwip/ip_addr.h"
#include "lwip/mem.h"
#include "lwip/app/espconn.h"
#include "upgrade.h"
#include "upgrade_lib.c"
#define UPGRADE_DEBUG
#ifdef UPGRADE_DEBUG
#define UPGRADE_DBG os_printf
#else
#define UPGRADE_DBG
#endif
LOCAL struct espconn *upgrade_conn;
LOCAL uint8 *pbuf;
LOCAL os_timer_t upgrade_10s;
LOCAL os_timer_t upgrade_timer;
LOCAL uint32 totallength = 0;
LOCAL uint32 sumlength = 0;
/******************************************************************************
* FunctionName : upgrade_disconcb
* Description : The connection has been disconnected successfully.
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
upgrade_disconcb(void *arg)
{
struct espconn *pespconn = arg;
if (pespconn == NULL) {
return;
}
os_free(pespconn->proto.tcp);
pespconn->proto.tcp = NULL;
os_free(pespconn);
pespconn = NULL;
upgrade_conn = NULL;
}
/******************************************************************************
* FunctionName : upgrade_datasent
* Description : Data has been sent successfully,This means that more data can
* be sent.
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
upgrade_datasent(void *arg)
{
struct espconn *pespconn = arg;
if (pespconn ->state == ESPCONN_CONNECT) {
}
}
/******************************************************************************
* FunctionName : upgrade_deinit
* Description : disconnect the connection with the host
* Parameters : bin -- server number
* Returns : none
*******************************************************************************/
void ICACHE_FLASH_ATTR
LOCAL upgrade_deinit(void)
{
if (system_upgrade_flag_check() != UPGRADE_FLAG_START) {
system_upgrade_deinit();
}
}
/******************************************************************************
* FunctionName : upgrade_10s_cb
* Description : Processing the client when connected with host time out
* Parameters : pespconn -- A point to the host
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR upgrade_10s_cb(struct espconn *pespconn)
{
if (pespconn == NULL) {
return;
}
system_upgrade_deinit();
os_free(pespconn->proto.tcp);
pespconn->proto.tcp = NULL;
os_free(pespconn);
pespconn = NULL;
upgrade_conn = NULL;
}
/******************************************************************************
* FunctionName : user_upgrade_check
* Description : Processing the received data from the server
* Parameters : arg -- Additional argument to pass to the callback function
* pusrdata -- The received data (or NULL when the connection has been closed!)
* length -- The length of received data
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
upgrade_check(struct upgrade_server_info *server)
{
UPGRADE_DBG("upgrade_check\n");
if (system_upgrade_flag_check() != UPGRADE_FLAG_FINISH) {
totallength = 0;
sumlength = 0;
os_timer_disarm(&upgrade_timer);
system_upgrade_flag_set(UPGRADE_FLAG_IDLE);
upgrade_deinit();
server->upgrade_flag = false;
if (server->check_cb != NULL) {
server->check_cb(server);
}
} else {
os_timer_disarm(&upgrade_timer);
upgrade_deinit();
server->upgrade_flag = true;
if (server->check_cb != NULL) {
server->check_cb(server);
}
}
#ifdef UPGRADE_SSL_ENABLE
espconn_secure_disconnect(upgrade_conn);
#else
espconn_disconnect(upgrade_conn);
#endif
}
/******************************************************************************
* FunctionName : upgrade_download
* Description : Processing the upgrade data from the host
* Parameters : bin -- server number
* pusrdata -- The upgrade data (or NULL when the connection has been closed!)
* length -- The length of upgrade data
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
upgrade_download(void *arg, char *pusrdata, unsigned short length)
{
char *ptr = NULL;
char *ptmp2 = NULL;
char lengthbuffer[32];
if (totallength == 0 && (ptr = (char *)os_strstr(pusrdata, "\r\n\r\n")) != NULL &&
(ptr = (char *)os_strstr(pusrdata, "Content-Length")) != NULL) {
ptr = (char *)os_strstr(pusrdata, "\r\n\r\n");
length -= ptr - pusrdata;
length -= 4;
totallength += length;
UPGRADE_DBG("upgrade file download start.\n");
system_upgrade(ptr + 4, length);
ptr = (char *)os_strstr(pusrdata, "Content-Length: ");
if (ptr != NULL) {
ptr += 16;
ptmp2 = (char *)os_strstr(ptr, "\r\n");
if (ptmp2 != NULL) {
os_memset(lengthbuffer, 0, sizeof(lengthbuffer));
os_memcpy(lengthbuffer, ptr, ptmp2 - ptr);
sumlength = atoi(lengthbuffer);
} else {
UPGRADE_DBG("sumlength failed\n");
}
} else {
UPGRADE_DBG("Content-Length: failed\n");
}
} else {
totallength += length;
os_printf("totallen = %d\n",totallength);
system_upgrade(pusrdata, length);
}
if (totallength == sumlength) {
UPGRADE_DBG("upgrade file download finished.\n");
system_upgrade_flag_set(UPGRADE_FLAG_FINISH);
totallength = 0;
sumlength = 0;
upgrade_check(upgrade_conn->reverse);
os_timer_disarm(&upgrade_10s);
os_timer_setfn(&upgrade_10s, (os_timer_func_t *)upgrade_deinit, NULL);
os_timer_arm(&upgrade_10s, 10, 0);
} else {
if (upgrade_conn->state != ESPCONN_READ) {
totallength = 0;
sumlength = 0;
os_timer_disarm(&upgrade_10s);
os_timer_setfn(&upgrade_10s, (os_timer_func_t *)upgrade_check, upgrade_conn->reverse);
os_timer_arm(&upgrade_10s, 10, 0);
}
}
}
/******************************************************************************
* FunctionName : upgrade_connect
* Description : client connected with a host successfully
* Parameters : arg -- Additional argument to pass to the callback function
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
upgrade_connect_cb(void *arg)
{
struct espconn *pespconn = arg;
UPGRADE_DBG("upgrade_connect_cb\n");
os_timer_disarm(&upgrade_10s);
espconn_regist_disconcb(pespconn, upgrade_disconcb);
espconn_regist_sentcb(pespconn, upgrade_datasent);
if (pbuf != NULL) {
UPGRADE_DBG("%s\n", pbuf);
#ifdef UPGRADE_SSL_ENABLE
espconn_secure_sent(pespconn, pbuf, os_strlen(pbuf));
#else
espconn_sent(pespconn, pbuf, os_strlen(pbuf));
#endif
}
}
/******************************************************************************
* FunctionName : upgrade_connection
* Description : connect with a server
* Parameters : bin -- server number
* url -- the url whitch upgrade files saved
* Returns : none
*******************************************************************************/
LOCAL void ICACHE_FLASH_ATTR
upgrade_connect(struct upgrade_server_info *server)
{
UPGRADE_DBG("upgrade_connect\n");
pbuf = server->url;
espconn_regist_connectcb(upgrade_conn, upgrade_connect_cb);
espconn_regist_recvcb(upgrade_conn, upgrade_download);
system_upgrade_init();
system_upgrade_flag_set(UPGRADE_FLAG_START);
#ifdef UPGRADE_SSL_ENABLE
espconn_secure_connect(upgrade_conn);
#else
espconn_connect(upgrade_conn);
#endif
os_timer_disarm(&upgrade_10s);
os_timer_setfn(&upgrade_10s, (os_timer_func_t *)upgrade_10s_cb, upgrade_conn);
os_timer_arm(&upgrade_10s, 10000, 0);
}
/******************************************************************************
* FunctionName : user_upgrade_init
* Description : parameter initialize as a client
* Parameters : server -- A point to a server parmer which connected
* Returns : none
*******************************************************************************/
bool ICACHE_FLASH_ATTR
#ifdef UPGRADE_SSL_ENABLE
system_upgrade_start_ssl(struct upgrade_server_info *server)
#else
system_upgrade_start(struct upgrade_server_info *server)
#endif
{
if (system_upgrade_flag_check() == UPGRADE_FLAG_START) {
return false;
}
if (server == NULL) {
UPGRADE_DBG("server is NULL\n");
return false;
}
if (upgrade_conn == NULL) {
upgrade_conn = (struct espconn *)os_zalloc(sizeof(struct espconn));
}
if (upgrade_conn != NULL) {
upgrade_conn->proto.tcp = NULL;
upgrade_conn->type = ESPCONN_TCP;
upgrade_conn->state = ESPCONN_NONE;
upgrade_conn->reverse = server;
if (upgrade_conn->proto.tcp == NULL) {
upgrade_conn->proto.tcp = (esp_tcp *)os_zalloc(sizeof(esp_tcp));
}
if (upgrade_conn->proto.tcp != NULL) {
upgrade_conn->proto.tcp->local_port = espconn_port();
upgrade_conn->proto.tcp->remote_port = server->port;
os_memcpy(upgrade_conn->proto.tcp->remote_ip, server->ip, 4);
UPGRADE_DBG("%s\n", __func__);
upgrade_connect(server);
if (server->check_cb != NULL) {
os_timer_disarm(&upgrade_timer);
os_timer_setfn(&upgrade_timer, (os_timer_func_t *)upgrade_check, server);
os_timer_arm(&upgrade_timer, server->check_times, 0);
}
}
}
return true;
}
#include "ets_sys.h"
#include "spi_flash.h"
//#include "net80211/ieee80211_var.h"
#include "lwip/mem.h"
#include "upgrade.h"
struct upgrade_param {
uint32 fw_bin_addr;
uint8 fw_bin_sec;
uint8 fw_bin_sec_num;
uint8 fw_bin_sec_earse;
uint8 extra;
uint8 save[4];
uint8 *buffer;
};
LOCAL struct upgrade_param *upgrade;
extern SpiFlashChip *flashchip;
/******************************************************************************
* FunctionName : system_upgrade_internal
* Description : a
* Parameters :
* Returns :
*******************************************************************************/
LOCAL bool ICACHE_FLASH_ATTR
system_upgrade_internal(struct upgrade_param *upgrade, uint8 *data, uint16 len)
{
bool ret = false;
if(data == NULL || len == 0)
{
return true;
}
upgrade->buffer = (uint8 *)os_zalloc(len + upgrade->extra);
os_memcpy(upgrade->buffer, upgrade->save, upgrade->extra);
os_memcpy(upgrade->buffer + upgrade->extra, data, len);
len += upgrade->extra;
upgrade->extra = len & 0x03;
len -= upgrade->extra;
os_memcpy(upgrade->save, upgrade->buffer + len, upgrade->extra);
do {
if (upgrade->fw_bin_addr + len >= (upgrade->fw_bin_sec + upgrade->fw_bin_sec_num) * SPI_FLASH_SEC_SIZE) {
break;
}
if (len > SPI_FLASH_SEC_SIZE) {
} else {
// os_printf("%x %x\n",upgrade->fw_bin_sec_earse,upgrade->fw_bin_addr);
/* earse sector, just earse when first enter this zone */
if (upgrade->fw_bin_sec_earse != (upgrade->fw_bin_addr + len) >> 12) {
upgrade->fw_bin_sec_earse = (upgrade->fw_bin_addr + len) >> 12;
spi_flash_erase_sector(upgrade->fw_bin_sec_earse);
// os_printf("%x\n",upgrade->fw_bin_sec_earse);
}
}
if (spi_flash_write(upgrade->fw_bin_addr, (uint32 *)upgrade->buffer, len) != SPI_FLASH_RESULT_OK) {
break;
}
ret = true;
upgrade->fw_bin_addr += len;
} while (0);
os_free(upgrade->buffer);
upgrade->buffer = NULL;
return ret;
}
/******************************************************************************
* FunctionName : system_upgrade
* Description : a
* Parameters :
* Returns :
*******************************************************************************/
bool ICACHE_FLASH_ATTR
system_upgrade(uint8 *data, uint16 len)
{
bool ret;
ret = system_upgrade_internal(upgrade, data, len);
return ret;
}
/******************************************************************************
* FunctionName : system_upgrade_init
* Description : a
* Parameters :
* Returns :
*******************************************************************************/
void ICACHE_FLASH_ATTR
system_upgrade_init(void)
{
uint32 user_bin2_start;
uint8 flash_buf[4];
uint8 high_half;
spi_flash_read(0, (uint32 *)flash_buf, 4);
high_half = (flash_buf[3] & 0xF0) >> 4;
if (upgrade == NULL) {
upgrade = (struct upgrade_param *)os_zalloc(sizeof(struct upgrade_param));
}
system_upgrade_flag_set(UPGRADE_FLAG_IDLE);
if (high_half == 2 || high_half == 3 || high_half == 4) {
user_bin2_start = 129; // 128 + 1
upgrade->fw_bin_sec_num = 123; // 128 - 1 - 4
} else {
user_bin2_start = 65; // 64 + 1
upgrade->fw_bin_sec_num = 59; // 64 - 1 - 4
}
upgrade->fw_bin_sec = (system_upgrade_userbin_check() == USER_BIN1) ? user_bin2_start : 1;
upgrade->fw_bin_addr = upgrade->fw_bin_sec * SPI_FLASH_SEC_SIZE;
}
/******************************************************************************
* FunctionName : system_upgrade_deinit
* Description : a
* Parameters :
* Returns :
*******************************************************************************/
void ICACHE_FLASH_ATTR
system_upgrade_deinit(void)
{
os_free(upgrade);
upgrade = NULL;
}
......@@ -43,7 +43,6 @@ INCLUDES += -I ../../include/ets
INCLUDES += -I ../libc
INCLUDES += -I ../platform
INCLUDES += -I ../lua
INCLUDES += -I ../wofs
INCLUDES += -I ../spiffs
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
......
#############################################################
# Required variables for each makefile
# Discard this section from all parent makefiles
# Expected variables (with automatic defaults):
# CSRCS (all "C" files in the dir)
# SUBDIRS (all subdirs with a Makefile)
# GEN_LIBS - list of libs to be generated ()
# GEN_IMAGES - list of images to be generated ()
# COMPONENTS_xxx - a list of libs/objs in the form
# subdir/lib to be extracted and rolled up into
# a generated lib/image xxx.a ()
#
ifndef PDIR
GEN_LIBS = wofs.a
endif
#############################################################
# Configuration i.e. compile options etc.
# Target specific stuff (defines etc.) goes in here!
# Generally values applying to a tree are captured in the
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
#DEFINES +=
#############################################################
# Recursion Magic - Don't touch this!!
#
# Each subtree potentially has an include directory
# corresponding to the common APIs applicable to modules
# rooted at that subtree. Accordingly, the INCLUDE PATH
# of a module can only contain the include directories up
# its parent path, and not its siblings
#
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../libc
INCLUDES += -I ../platform
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
// Generated by mkfs.lua
// DO NOT MODIFY
#ifndef __ROMFILES_H__
#define __ROMFILES_H__
const unsigned char romfiles_fs[] =
{
0xFF
};
#endif
// Filesystem implementation
#include "romfs.h"
#include "c_string.h"
// #include "c_errno.h"
#include "romfiles.h"
#include "c_stdio.h"
// #include "c_stdlib.h"
#include "c_fcntl.h"
#include "platform.h"
#if defined( BUILD_ROMFS ) || defined( BUILD_WOFS )
#define TOTAL_MAX_FDS 8
// DO NOT CHANGE THE ROMFS ALIGNMENT.
// UNLESS YOU _LIKE_ TO WATCH THE WORLD BURN.
#define ROMFS_ALIGN 4
#define fsmin( x , y ) ( ( x ) < ( y ) ? ( x ) : ( y ) )
static FD fd_table[ TOTAL_MAX_FDS ];
static int romfs_num_fd;
#define WOFS_END_MARKER_CHAR 0xFF
#define WOFS_DEL_FIELD_SIZE ( ROMFS_ALIGN )
#define WOFS_FILE_DELETED 0xAA
// Length of the 'file size' field for both ROMFS/WOFS
#define ROMFS_SIZE_LEN 4
static int romfs_find_empty_fd(void)
{
int i;
for( i = 0; i < TOTAL_MAX_FDS; i ++ )
if( fd_table[ i ].baseaddr == 0xFFFFFFFF &&
fd_table[ i ].offset == 0xFFFFFFFF &&
fd_table[ i ].size == 0xFFFFFFFF )
return i;
return -1;
}
static void romfs_close_fd( int fd )
{
if(fd<0 || fd>=TOTAL_MAX_FDS)
return;
c_memset( fd_table + fd, 0xFF, sizeof( FD ) );
fd_table[ fd ].flags = 0;
}
// Helper function: read a byte from the FS
static uint8_t romfsh_read8( uint32_t addr, const FSDATA *pfs )
{
uint8_t temp;
if( pfs->flags & ROMFS_FS_FLAG_DIRECT )
return pfs->pbase[ addr ];
pfs->readf( &temp, addr, 1, pfs );
return temp;
}
// Helper function: return 1 if PFS reffers to a WOFS, 0 otherwise
static int romfsh_is_wofs( const FSDATA* pfs )
{
return ( pfs->flags & ROMFS_FS_FLAG_WO ) != 0;
}
// Find the next file, returning FS_FILE_OK or FS_FILE_NOT_FOUND if there no file left.
static uint8_t romfs_next_file( uint32_t *start, char* fname, size_t len, size_t *act_len, FSDATA *pfs )
{
uint32_t i, j, n;
uint32_t fsize;
int is_deleted;
// Look for the file
i = *start;
*act_len = 0;
if( (i >= INTERNAL_FLASH_SIZE) || (romfsh_read8( i, pfs ) == WOFS_END_MARKER_CHAR )) // end of file system
{
*start = (i >= INTERNAL_FLASH_SIZE)?(INTERNAL_FLASH_SIZE-1):i;
return FS_FILE_NOT_FOUND;
}
// Read file name
len = len>MAX_FNAME_LENGTH?MAX_FNAME_LENGTH:len;
for( j = 0; j < len; j ++ )
{
fname[ j ] = romfsh_read8( i + j, pfs );
if( fname[ j ] == 0 )
break;
}
n = j; // save the file name length to n
// ' i + j' now points at the '0' byte
j = i + j + 1;
// Round to a multiple of ROMFS_ALIGN
j = ( j + ROMFS_ALIGN - 1 ) & ~( ROMFS_ALIGN - 1 );
// WOFS has an additional WOFS_DEL_FIELD_SIZE bytes before the size as an indication for "file deleted"
if( romfsh_is_wofs( pfs ) )
{
is_deleted = romfsh_read8( j, pfs ) == WOFS_FILE_DELETED;
j += WOFS_DEL_FIELD_SIZE;
}
else
is_deleted = 0;
// And read the size
fsize = romfsh_read8( j, pfs ) + ( romfsh_read8( j + 1, pfs ) << 8 );
fsize += ( romfsh_read8( j + 2, pfs ) << 16 ) + ( romfsh_read8( j + 3, pfs ) << 24 );
j += ROMFS_SIZE_LEN;
if( !is_deleted )
{
// Found the valid file
*act_len = n;
}
// Move to next file
i = j + fsize;
// On WOFS, all file names must begin at a multiple of ROMFS_ALIGN
if( romfsh_is_wofs( pfs ) )
i = ( i + ROMFS_ALIGN - 1 ) & ~( ROMFS_ALIGN - 1 );
*start = i; // modify the start address
return FS_FILE_OK;
}
// Open the given file, returning one of FS_FILE_NOT_FOUND, FS_FILE_ALREADY_OPENED
// or FS_FILE_OK
static uint8_t romfs_open_file( const char* fname, FD* pfd, FSDATA *pfs, uint32_t *plast, uint32_t *pnameaddr )
{
uint32_t i, j, n;
char fsname[ MAX_FNAME_LENGTH + 1 ];
uint32_t fsize;
int is_deleted;
// Look for the file
i = 0;
while( 1 )
{
if( i >= INTERNAL_FLASH_SIZE ){
*plast = INTERNAL_FLASH_SIZE - 1; // point to last one
return FS_FILE_NOT_FOUND;
}
if( romfsh_read8( i, pfs ) == WOFS_END_MARKER_CHAR )
{
*plast = i;
return FS_FILE_NOT_FOUND;
}
// Read file name
n = i;
for( j = 0; j < MAX_FNAME_LENGTH; j ++ )
{
fsname[ j ] = romfsh_read8( i + j, pfs );
if( fsname[ j ] == 0 )
break;
}
// ' i + j' now points at the '0' byte
j = i + j + 1;
// Round to a multiple of ROMFS_ALIGN
j = ( j + ROMFS_ALIGN - 1 ) & ~( ROMFS_ALIGN - 1 );
// WOFS has an additional WOFS_DEL_FIELD_SIZE bytes before the size as an indication for "file deleted"
if( romfsh_is_wofs( pfs ) )
{
is_deleted = romfsh_read8( j, pfs ) == WOFS_FILE_DELETED;
j += WOFS_DEL_FIELD_SIZE;
}
else
is_deleted = 0;
// And read the size
fsize = romfsh_read8( j, pfs ) + ( romfsh_read8( j + 1, pfs ) << 8 );
fsize += ( romfsh_read8( j + 2, pfs ) << 16 ) + ( romfsh_read8( j + 3, pfs ) << 24 );
j += ROMFS_SIZE_LEN;
if( !c_strncasecmp( fname, fsname, MAX_FNAME_LENGTH ) && !is_deleted )
{
// Found the file
pfd->baseaddr = j;
pfd->offset = 0;
pfd->size = fsize;
if( pnameaddr )
*pnameaddr = n;
return FS_FILE_OK;
}
// Move to next file
i = j + fsize;
// On WOFS, all file names must begin at a multiple of ROMFS_ALIGN
if( romfsh_is_wofs( pfs ) )
i = ( i + ROMFS_ALIGN - 1 ) & ~( ROMFS_ALIGN - 1 );
}
*plast = 0;
return FS_FILE_NOT_FOUND;
}
static int romfs_open( const char *path, int flags, int mode, void *pdata )
{
FD tempfs;
int i;
FSDATA *pfsdata = ( FSDATA* )pdata;
int must_create = 0;
int exists;
uint8_t lflags = ROMFS_FILE_FLAG_READ;
uint32_t firstfree, nameaddr;
if( romfs_num_fd == TOTAL_MAX_FDS )
{
return -1;
}
// Does the file exist?
exists = romfs_open_file( path, &tempfs, pfsdata, &firstfree, &nameaddr ) == FS_FILE_OK;
// Now interpret "flags" to set file flags and to check if we should create the file
if( flags & O_CREAT )
{
// If O_CREAT is specified with O_EXCL and the file already exists, return with error
if( ( flags & O_EXCL ) && exists )
{
return -1;
}
// Otherwise create the file if it does not exist
must_create = !exists;
}
if( ( flags & O_TRUNC ) && ( flags & ( O_WRONLY | O_RDWR ) ) && exists )
{
// The file exists, but it must be truncated
// In the case of WOFS, this effectively means "create a new file"
must_create = 1;
}
// ROMFS can't create files
if( must_create && ( ( pfsdata->flags & ROMFS_FS_FLAG_WO ) == 0 ) )
{
return -1;
}
// Decode access mode
if( flags & O_WRONLY )
lflags = ROMFS_FILE_FLAG_WRITE;
else if( flags & O_RDWR )
lflags = ROMFS_FILE_FLAG_READ | ROMFS_FILE_FLAG_WRITE;
if( flags & O_APPEND )
lflags |= ROMFS_FILE_FLAG_APPEND;
// If a write access is requested when the file must NOT be created, this
// is an error
if( ( lflags & ( ROMFS_FILE_FLAG_WRITE | ROMFS_FILE_FLAG_APPEND ) ) && !must_create )
{
return -1;
}
if( ( lflags & ( ROMFS_FILE_FLAG_WRITE | ROMFS_FILE_FLAG_APPEND ) ) && romfs_fs_is_flag_set( pfsdata, ROMFS_FS_FLAG_WRITING ) )
{
// At most one file can be opened in write mode at any given time on WOFS
return -1;
}
// Do we need to create the file ?
if( must_create )
{
if( exists )
{
// Invalidate the file first by changing WOFS_DEL_FIELD_SIZE bytes before
// the file length to WOFS_FILE_DELETED
uint8_t tempb[] = { WOFS_FILE_DELETED, 0xFF, 0xFF, 0xFF };
pfsdata->writef( tempb, tempfs.baseaddr - ROMFS_SIZE_LEN - WOFS_DEL_FIELD_SIZE, WOFS_DEL_FIELD_SIZE, pfsdata );
}
// Find the last available position by asking romfs_open_file to look for a file
// with an invalid name
romfs_open_file( "\1", &tempfs, pfsdata, &firstfree, NULL );
// Is there enough space on the FS for another file?
if( pfsdata->max_size - firstfree + 1 < c_strlen( path ) + 1 + WOFS_MIN_NEEDED_SIZE + WOFS_DEL_FIELD_SIZE )
{
return -1;
}
// Make sure we can get a file descriptor before writing
if( ( i = romfs_find_empty_fd() ) < 0 )
{
return -1;
}
// Write the name of the file
pfsdata->writef( path, firstfree, c_strlen( path ) + 1, pfsdata );
firstfree += c_strlen( path ) + 1; // skip over the name
// Align to a multiple of ROMFS_ALIGN
firstfree = ( firstfree + ROMFS_ALIGN - 1 ) & ~( ROMFS_ALIGN - 1 );
firstfree += ROMFS_SIZE_LEN + WOFS_DEL_FIELD_SIZE; // skip over the size and the deleted flags area
tempfs.baseaddr = firstfree;
tempfs.offset = tempfs.size = 0;
// Set the "writing" flag on the FS to indicate that there is a file opened in write mode
romfs_fs_set_flag( pfsdata, ROMFS_FS_FLAG_WRITING );
}
else // File must exist (and was found in the previous 'romfs_open_file' call)
{
if( !exists )
{
return -1;
}
if( ( i = romfs_find_empty_fd() ) < 0 )
{
return -1;
}
}
// Copy the descriptor information
tempfs.flags = lflags;
c_memcpy( fd_table + i, &tempfs, sizeof( FD ) );
romfs_num_fd ++;
return i;
}
static int romfs_close( int fd, void *pdata )
{
if(fd<0 || fd>=TOTAL_MAX_FDS)
return 0;
FD* pfd = fd_table + fd;
FSDATA *pfsdata = ( FSDATA* )pdata;
uint8_t temp[ ROMFS_SIZE_LEN ];
if( pfd->flags & ( ROMFS_FILE_FLAG_WRITE | ROMFS_FILE_FLAG_APPEND ) )
{
// Write back the size
temp[ 0 ] = pfd->size & 0xFF;
temp[ 1 ] = ( pfd->size >> 8 ) & 0xFF;
temp[ 2 ] = ( pfd->size >> 16 ) & 0xFF;
temp[ 3 ] = ( pfd->size >> 24 ) & 0xFF;
pfsdata->writef( temp, pfd->baseaddr - ROMFS_SIZE_LEN, ROMFS_SIZE_LEN, pfsdata );
// Clear the "writing" flag on the FS instance to allow other files to be opened
// in write mode
romfs_fs_clear_flag( pfsdata, ROMFS_FS_FLAG_WRITING );
}
romfs_close_fd( fd );
romfs_num_fd --;
return 0;
}
static _ssize_t romfs_write( int fd, const void* ptr, size_t len, void *pdata )
{
if(fd<0 || fd>=TOTAL_MAX_FDS)
return -1;
if(len == 0)
return 0;
FD* pfd = fd_table + fd;
FSDATA *pfsdata = ( FSDATA* )pdata;
if( ( pfd->flags & ( ROMFS_FILE_FLAG_WRITE | ROMFS_FILE_FLAG_APPEND ) ) == 0 )
{
return -1;
}
// Append mode: set the file pointer to the end
if( pfd->flags & ROMFS_FILE_FLAG_APPEND )
pfd->offset = pfd->size;
// Only write at the end of the file!
if( pfd->offset != pfd->size )
return 0;
// Check if we have enough space left on the device. Always keep 1 byte for the final 0xFF
// and ROMFS_ALIGN - 1 bytes for aligning the contents of the file data in the worst case
// scenario (so ROMFS_ALIGN bytes in total)
if( pfd->baseaddr + pfd->size + len > pfsdata->max_size - ROMFS_ALIGN )
len = pfsdata->max_size - ( pfd->baseaddr + pfd->size ) - ROMFS_ALIGN;
pfsdata->writef( ptr, pfd->offset + pfd->baseaddr, len, pfsdata );
pfd->offset += len;
pfd->size += len;
return len;
}
static _ssize_t romfs_read( int fd, void* ptr, size_t len, void *pdata )
{
if(fd<0 || fd>=TOTAL_MAX_FDS)
return -1;
if(len == 0)
return 0;
FD* pfd = fd_table + fd;
long actlen = fsmin( len, pfd->size - pfd->offset );
FSDATA *pfsdata = ( FSDATA* )pdata;
if( ( pfd->flags & ROMFS_FILE_FLAG_READ ) == 0 )
{
return -1;
}
if( pfsdata->flags & ROMFS_FS_FLAG_DIRECT )
c_memcpy( ptr, pfsdata->pbase + pfd->offset + pfd->baseaddr, actlen );
else
actlen = pfsdata->readf( ptr, pfd->offset + pfd->baseaddr, actlen, pfsdata );
pfd->offset += actlen;
return actlen;
}
// lseek
static int romfs_lseek( int fd, int off, int whence, void *pdata )
{
if(fd<0 || fd>=TOTAL_MAX_FDS)
return -1;
FD* pfd = fd_table + fd;
uint32_t newpos = 0;
switch( whence )
{
case SEEK_SET:
newpos = off;
break;
case SEEK_CUR:
newpos = pfd->offset + off;
break;
case SEEK_END:
newpos = pfd->size + off;
break;
default:
return -1;
}
if( newpos > pfd->size )
return -1;
pfd->offset = newpos;
return newpos;
}
// ****************************************************************************
// WOFS functions and instance descriptor for real hardware
#if defined( BUILD_WOFS )
static uint32_t sim_wofs_write( const void *from, uint32_t toaddr, uint32_t size, const void *pdata )
{
const FSDATA *pfsdata = ( const FSDATA* )pdata;
if(toaddr>=INTERNAL_FLASH_SIZE)
{
NODE_ERR("ERROR in flash op: wrong addr.\n");
return 0;
}
toaddr += ( uint32_t )pfsdata->pbase;
return platform_flash_write( from, toaddr, size );
}
static uint32_t sim_wofs_read( void *to, uint32_t fromaddr, uint32_t size, const void *pdata )
{
const FSDATA *pfsdata = ( const FSDATA* )pdata;
if(fromaddr>=INTERNAL_FLASH_SIZE)
{
NODE_ERR("ERROR in flash op: wrong addr.\n");
return 0;
}
fromaddr += ( uint32_t )pfsdata->pbase;
return platform_flash_read( to, fromaddr, size );
}
// This must NOT be a const!
static FSDATA wofs_fsdata =
{
NULL,
ROMFS_FS_FLAG_WO,
sim_wofs_read,
sim_wofs_write,
0
};
// WOFS formatting function
// Returns 1 if OK, 0 for error
int wofs_format( void )
{
uint32_t sect_first, sect_last;
FD tempfd;
platform_flash_get_first_free_block_address( &sect_first );
// Get the first free address in WOFS. We use this address to compute the last block that we need to
// erase, instead of simply erasing everything from sect_first to the last Flash page.
romfs_open_file( "\1", &tempfd, &wofs_fsdata, &sect_last, NULL );
sect_last = platform_flash_get_sector_of_address( sect_last + ( uint32_t )wofs_fsdata.pbase );
while( sect_first <= sect_last )
if( platform_flash_erase_sector( sect_first ++ ) == PLATFORM_ERR )
return 0;
return 1;
}
int wofs_open(const char *_name, int flags){
return romfs_open( _name, flags, 0, &wofs_fsdata );
}
int wofs_close( int fd ){
return romfs_close( fd, &wofs_fsdata );
}
size_t wofs_write( int fd, const void* ptr, size_t len ){
return romfs_write( fd, ptr, len, &wofs_fsdata );
}
size_t wofs_read( int fd, void* ptr, size_t len){
return romfs_read( fd, ptr, len, &wofs_fsdata );
}
int wofs_lseek( int fd, int off, int whence ){
return romfs_lseek( fd, off, whence, &wofs_fsdata );
}
int wofs_eof( int fd ){
if(fd<0 || fd>=TOTAL_MAX_FDS)
return -1;
FD* pfd = fd_table + fd;
// NODE_DBG("off:%d, sz:%d\n",pfd->offset, pfd->size);
return pfd->offset == pfd->size;
}
int wofs_getc( int fd ){
char c = EOF;
if(!wofs_eof(fd)){
romfs_read( fd, &c, 1, &wofs_fsdata );
}
// NODE_DBG("c: %d\n", c);
return (int)c;
}
int wofs_ungetc( int c, int fd ){
return romfs_lseek( fd, -1, SEEK_CUR, &wofs_fsdata );
}
// Find the next file, returning FS_FILE_OK or FS_FILE_NOT_FOUND if there no file left.
uint8_t wofs_next( uint32_t *start, char* fname, size_t len, size_t *act_len ){
return romfs_next_file( start, fname, len, act_len, &wofs_fsdata );
}
#endif // #ifdef BUILD_WOFS
// Initialize both ROMFS and WOFS as needed
int romfs_init( void )
{
unsigned i;
for( i = 0; i < TOTAL_MAX_FDS; i ++ )
{
c_memset( fd_table + i, 0xFF, sizeof( FD ) );
fd_table[ i ].flags = 0;
}
#if defined( BUILD_WOFS )
// Get the start address and size of WOFS and register it
wofs_fsdata.pbase = ( uint8_t* )platform_flash_get_first_free_block_address( NULL );
wofs_fsdata.max_size = INTERNAL_FLASH_SIZE - ( ( uint32_t )wofs_fsdata.pbase );
NODE_DBG("wofs.pbase:%x,max:%x\n",wofs_fsdata.pbase,wofs_fsdata.max_size);
#endif // ifdef BUILD_WOFS
return 0;
}
#else // #if defined( BUILD_ROMFS ) || defined( BUILD_WOFS )
int romfs_init( void )
{
}
#endif // #if defined( BUILD_ROMFS ) || defined( BUILD_WOFS )
int test_romfs()
{
int fd;
int i, size;
fd = wofs_open("init.lua",O_RDONLY);
NODE_DBG("open file fd:%d\n", fd);
char r[128];
NODE_DBG("read from file:\n");
c_memset(r,0,128);
size = wofs_read(fd,r,128);
r[size]=0;
NODE_DBG(r);
NODE_DBG("\n");
wofs_close(fd);
fd = wofs_open("testm.lua",O_RDONLY);
NODE_DBG("open file fd:%d\n", fd);
NODE_DBG("read from file:\n");
c_memset(r,0,128);
size = wofs_read(fd,r,128);
r[size]=0;
NODE_DBG(r);
NODE_DBG("\n");
wofs_close(fd);
return 0;
}
// Read-only ROM filesystem
#ifndef __ROMFS_H__
#define __ROMFS_H__
#include "c_types.h"
#include "c_fcntl.h"
/*******************************************************************************
The Read-Only "filesystem" resides in a contiguous zone of memory, with the
following structure (repeated for each file):
Filename: ASCIIZ, max length is DM_MAX_FNAME_LENGTH, first byte is 0xFF if last file
File size: (4 bytes), aligned to ROMFS_ALIGN bytes
File data: (file size bytes)
The WOFS (Write Once File System) uses much of the ROMFS functions, thuss it is
also implemented in romfs.c. It resides in a contiguous zone of memory, with a
structure that is quite similar with ROMFS' structure (repeated for each file):
Filename: ASCIIZ, max length is DM_MAX_FNAME_LENGTH, first byte is 0xFF if last file.
WOFS filenames always begin at an address which is a multiple of ROMFS_ALIGN.
File deleted flag: (WOFS_DEL_FIELD_SIZE bytes), aligned to ROMFS_ALIGN bytes
File size: (4 bytes), aligned to ROMFS_ALIGN bytes
File data: (file size bytes)
*******************************************************************************/
// GLOBAL maximum file length (on ALL supported filesystem)
#define MAX_FNAME_LENGTH 30
enum
{
FS_FILE_NOT_FOUND,
FS_FILE_OK
};
// ROMFS/WOFS functions
typedef uint32_t ( *p_fs_read )( void *to, uint32_t fromaddr, uint32_t size, const void *pdata );
typedef uint32_t ( *p_fs_write )( const void *from, uint32_t toaddr, uint32_t size, const void *pdata );
// File flags
#define ROMFS_FILE_FLAG_READ 0x01
#define ROMFS_FILE_FLAG_WRITE 0x02
#define ROMFS_FILE_FLAG_APPEND 0x04
// A small "FILE" structure
typedef struct
{
uint32_t baseaddr;
uint32_t offset;
uint32_t size;
uint8_t flags;
} FD;
// WOFS constants
// The miminum size we need in order to create another file
// This size will be added to the size of the filename when creating a new file
// to ensure that there's enough space left on the device
// This comes from the size of the file length field (4) + the maximum number of
// bytes needed to align this field (3) + a single 0xFF byte which marks the end
// of the filesystem (1) + the maximum number of bytes needed to align the contents
// of a file (3)
#define WOFS_MIN_NEEDED_SIZE 11
// Filesystem flags
#define ROMFS_FS_FLAG_DIRECT 0x01 // direct mode (the file is mapped in a memory area directly accesible by the CPU)
#define ROMFS_FS_FLAG_WO 0x02 // this FS is actually a WO (Write-Once) FS
#define ROMFS_FS_FLAG_WRITING 0x04 // for WO only: there is already a file opened in write mode
// File system descriptor
typedef struct
{
uint8_t *pbase; // pointer to FS base in memory (only for ROMFS_FS_FLAG_DIRECT)
uint8_t flags; // flags (see above)
p_fs_read readf; // pointer to read function (for non-direct mode FS)
p_fs_write writef; // pointer to write function (only for ROMFS_FS_FLAG_WO)
uint32_t max_size; // maximum size of the FS (in bytes)
} FSDATA;
#define romfs_fs_set_flag( p, f ) p->flags |= ( f )
#define romfs_fs_clear_flag( p, f ) p->flags &= ( uint8_t )~( f )
#define romfs_fs_is_flag_set( p, f ) ( ( p->flags & ( f ) ) != 0 )
#if defined( BUILD_WOFS )
int wofs_format( void );
int wofs_open(const char *name, int flags);
int wofs_close( int fd );
size_t wofs_write( int fd, const void* ptr, size_t len );
size_t wofs_read( int fd, void* ptr, size_t len);
int wofs_lseek( int fd, int off, int whence );
int wofs_eof( int fd );
int wofs_getc( int fd );
int wofs_ungetc( int c, int fd );
uint8_t wofs_next( uint32_t *start, char* fname, size_t len, size_t *act_len ); // for list file name
#endif
// FS functions
int romfs_init( void );
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment