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.
This commit is contained in:
TerryE 2016-02-26 16:37:06 +00:00
parent ef5eed307c
commit 46ea2aa42e
20 changed files with 16 additions and 1303 deletions

View File

@ -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 \

View File

@ -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__ */

View File

@ -38,7 +38,6 @@ endif
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../wofs
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile

View File

@ -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

View File

@ -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

View File

@ -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,7 +309,7 @@ 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 ) },

View File

@ -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"

View File

@ -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 ) },

View File

@ -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

View File

@ -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

View File

@ -1,11 +1,7 @@
#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){

View File

@ -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"

View File

@ -1,47 +0,0 @@
#############################################################
# 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

View File

@ -1,317 +0,0 @@
#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;
}

View File

@ -1,145 +0,0 @@
#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;
}

View File

@ -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

View File

@ -1,44 +0,0 @@
#############################################################
# 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

View File

@ -1,12 +0,0 @@
// Generated by mkfs.lua
// DO NOT MODIFY
#ifndef __ROMFILES_H__
#define __ROMFILES_H__
const unsigned char romfiles_fs[] =
{
0xFF
};
#endif

View File

@ -1,565 +0,0 @@
// 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;
}

View File

@ -1,101 +0,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