update spiffs to v0.3.0
This commit is contained in:
parent
560ad8e029
commit
ba836cf5de
75
README.md
75
README.md
|
@ -1,5 +1,5 @@
|
||||||
# **NodeMCU** #
|
# **NodeMCU** #
|
||||||
version 0.9.5
|
version 0.9.6
|
||||||
|
|
||||||
[![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
[![Join the chat at https://gitter.im/nodemcu/nodemcu-firmware](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/nodemcu/nodemcu-firmware?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||||
[![Build Status](https://travis-ci.org/nodemcu/nodemcu-firmware.svg)](https://travis-ci.org/nodemcu/nodemcu-firmware) [![Download](https://img.shields.io/badge/download-~400k-orange.svg)](https://github.com/nodemcu/nodemcu-firmware/releases/latest)
|
[![Build Status](https://travis-ci.org/nodemcu/nodemcu-firmware.svg)](https://travis-ci.org/nodemcu/nodemcu-firmware) [![Download](https://img.shields.io/badge/download-~400k-orange.svg)](https://github.com/nodemcu/nodemcu-firmware/releases/latest)
|
||||||
|
@ -36,6 +36,39 @@ Tencent QQ group: 309957875<br />
|
||||||
- cross compiler (done)
|
- cross compiler (done)
|
||||||
|
|
||||||
# Change log
|
# Change log
|
||||||
|
2015-04-06<br />
|
||||||
|
bump version to 0.9.6. not follow sdk version any more.<br />
|
||||||
|
fix mqtt module bugs. please see examples [mqtt](https://github.com/nodemcu/nodemcu-firmware/tree/master/lua_examples/mqtt).<br />
|
||||||
|
fix dht lib.<br />
|
||||||
|
update spiffs to V0.3.0.<br />
|
||||||
|
enhancement for wifi.ap submodule.<br />
|
||||||
|
wifi.sta.config (wifi_station_config):
|
||||||
|
- range checking password length (8~64)
|
||||||
|
|
||||||
|
wifi.ap.config (wifi_ap_config):
|
||||||
|
- range checking ssid length (1~32)
|
||||||
|
- range checking pwd length (8~64)
|
||||||
|
- new params:
|
||||||
|
- auth: wifi.OPEN, wifi.WPA_PSK, wifi.WPA2_PSK, wifi.WPA_WPA2_PSK
|
||||||
|
- default WITH pwd: wifi.WPA_WPA2_PSK
|
||||||
|
- default WITHOUT pwd: wifi.OPEN
|
||||||
|
- channel: 1~13 (default: 6)
|
||||||
|
- hidden: 0/1 (default: 0)
|
||||||
|
- max: 1~4 (default: 4)
|
||||||
|
- beacon: 100~60000ms (default: 100)
|
||||||
|
|
||||||
|
wifi.ap.getclient (wifi_ap_listclient):
|
||||||
|
- returns table(mac,ip) of all connected clients
|
||||||
|
|
||||||
|
wifi.ap.dhcp:
|
||||||
|
- new submodule
|
||||||
|
- config (wifi_ap_dhcp_config), returns start/end ips
|
||||||
|
- params:
|
||||||
|
- start (e.g., "192.168.1.100")
|
||||||
|
- end ip calculated from wifi.ap.config.max
|
||||||
|
- start (wifi_ap_dhcp_start), returns boolean
|
||||||
|
- stop (wifi_ap_dhcp_stop), returns boolean
|
||||||
|
|
||||||
2015-03-31<br />
|
2015-03-31<br />
|
||||||
polish mqtt module, add queue for mqtt module.<br />
|
polish mqtt module, add queue for mqtt module.<br />
|
||||||
add reconnect option to mqtt.connect api, :connect( host, port, secure, auto_reconnect, function(client) )<br />
|
add reconnect option to mqtt.connect api, :connect( host, port, secure, auto_reconnect, function(client) )<br />
|
||||||
|
@ -209,44 +242,8 @@ baudrate:9600
|
||||||
end)
|
end)
|
||||||
```
|
```
|
||||||
|
|
||||||
####Connect to MQTT Broker
|
#### MQTT examples
|
||||||
|
please see [mqtt examples](https://github.com/nodemcu/nodemcu-firmware/tree/master/lua_examples/mqtt)
|
||||||
```lua
|
|
||||||
-- init mqtt client with keepalive timer 120sec
|
|
||||||
m = mqtt.Client("clientid", 120, "user", "password")
|
|
||||||
|
|
||||||
-- setup Last Will and Testament (optional)
|
|
||||||
-- Broker will publish a message with qos = 0, retain = 0, data = "offline"
|
|
||||||
-- to topic "/lwt" if client don't send keepalive packet
|
|
||||||
m:lwt("/lwt", "offline", 0, 0)
|
|
||||||
|
|
||||||
m:on("connect", function(con) print ("connected") end)
|
|
||||||
m:on("offline", function(con) print ("offline") end)
|
|
||||||
|
|
||||||
-- on publish message receive event
|
|
||||||
m:on("message", function(conn, topic, data)
|
|
||||||
print(topic .. ":" )
|
|
||||||
if data ~= nil then
|
|
||||||
print(data)
|
|
||||||
end
|
|
||||||
end)
|
|
||||||
|
|
||||||
-- m:connect( host, port, secure, auto_reconnect, function(client) )
|
|
||||||
-- for secure: m:connect("192.168.11.118", 1880, 1, 0)
|
|
||||||
-- for auto-reconnect: m:connect("192.168.11.118", 1880, 0, 1)
|
|
||||||
m:connect("192.168.11.118", 1880, 0, 0, function(conn) print("connected") end)
|
|
||||||
|
|
||||||
-- subscribe topic with qos = 0
|
|
||||||
m:subscribe("/topic",0, function(conn) print("subscribe success") end)
|
|
||||||
-- or subscribe multiple topic (topic/0, qos = 0; topic/1, qos = 1; topic2 , qos = 2)
|
|
||||||
-- m:subscribe({["topic/0"]=0,["topic/1"]=1,topic2=2}, function(conn) print("subscribe success") end)
|
|
||||||
-- publish a message with data = hello, QoS = 0, retain = 0
|
|
||||||
m:publish("/topic","hello",0,0, function(conn) print("sent") end)
|
|
||||||
|
|
||||||
m:close(); -- if auto-reconnect == 1, will disable auto-reconnect and then disconnect from host.
|
|
||||||
-- you can call m:connect again
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
#### UDP client and server
|
#### UDP client and server
|
||||||
```lua
|
```lua
|
||||||
|
|
|
@ -3,10 +3,10 @@
|
||||||
|
|
||||||
#define NODE_VERSION_MAJOR 0U
|
#define NODE_VERSION_MAJOR 0U
|
||||||
#define NODE_VERSION_MINOR 9U
|
#define NODE_VERSION_MINOR 9U
|
||||||
#define NODE_VERSION_REVISION 5U
|
#define NODE_VERSION_REVISION 6U
|
||||||
#define NODE_VERSION_INTERNAL 0U
|
#define NODE_VERSION_INTERNAL 0U
|
||||||
|
|
||||||
#define NODE_VERSION "NodeMCU 0.9.5"
|
#define NODE_VERSION "NodeMCU 0.9.6"
|
||||||
#define BUILD_DATE "build 20150405"
|
#define BUILD_DATE "build 20150406"
|
||||||
|
|
||||||
#endif /* __USER_VERSION_H__ */
|
#endif /* __USER_VERSION_H__ */
|
||||||
|
|
|
@ -78,17 +78,21 @@ void myspiffs_unmount() {
|
||||||
int myspiffs_format( void )
|
int myspiffs_format( void )
|
||||||
{
|
{
|
||||||
SPIFFS_unmount(&fs);
|
SPIFFS_unmount(&fs);
|
||||||
u32_t sect_first, sect_last;
|
// u32_t sect_first, sect_last;
|
||||||
sect_first = ( u32_t )platform_flash_get_first_free_block_address( NULL );
|
// sect_first = ( u32_t )platform_flash_get_first_free_block_address( NULL );
|
||||||
sect_first += 0x3000;
|
// sect_first += 0x3000;
|
||||||
sect_first &= 0xFFFFC000; // align to 4 sector.
|
// sect_first &= 0xFFFFC000; // align to 4 sector.
|
||||||
sect_first = platform_flash_get_sector_of_address(sect_first);
|
// sect_first = platform_flash_get_sector_of_address(sect_first);
|
||||||
sect_last = INTERNAL_FLASH_SIZE + INTERNAL_FLASH_START_ADDRESS - 4;
|
// sect_last = INTERNAL_FLASH_SIZE + INTERNAL_FLASH_START_ADDRESS - 4;
|
||||||
sect_last = platform_flash_get_sector_of_address(sect_last);
|
// sect_last = platform_flash_get_sector_of_address(sect_last);
|
||||||
NODE_DBG("sect_first: %x, sect_last: %x\n", sect_first, sect_last);
|
// NODE_DBG("sect_first: %x, sect_last: %x\n", sect_first, sect_last);
|
||||||
while( sect_first <= sect_last )
|
// while( sect_first <= sect_last )
|
||||||
if( platform_flash_erase_sector( sect_first ++ ) == PLATFORM_ERR )
|
// if( platform_flash_erase_sector( sect_first ++ ) == PLATFORM_ERR )
|
||||||
|
// return 0;
|
||||||
|
int32_t res = SPIFFS_format(&fs);
|
||||||
|
if (res != SPIFFS_OK) {
|
||||||
return 0;
|
return 0;
|
||||||
|
}
|
||||||
myspiffs_mount();
|
myspiffs_mount();
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,13 @@ extern "C" {
|
||||||
#define SPIFFS_ERR_NOT_WRITABLE -10021
|
#define SPIFFS_ERR_NOT_WRITABLE -10021
|
||||||
#define SPIFFS_ERR_NOT_READABLE -10022
|
#define SPIFFS_ERR_NOT_READABLE -10022
|
||||||
#define SPIFFS_ERR_CONFLICTING_NAME -10023
|
#define SPIFFS_ERR_CONFLICTING_NAME -10023
|
||||||
|
#define SPIFFS_ERR_NOT_CONFIGURED -10024
|
||||||
|
|
||||||
|
#define SPIFFS_ERR_NOT_A_FS -10025
|
||||||
|
#define SPIFFS_ERR_MOUNTED -10026
|
||||||
|
#define SPIFFS_ERR_ERASE_FAIL -10027
|
||||||
|
#define SPIFFS_ERR_MAGIC_NOT_POSSIBLE -10028
|
||||||
|
|
||||||
|
|
||||||
#define SPIFFS_ERR_INTERNAL -10050
|
#define SPIFFS_ERR_INTERNAL -10050
|
||||||
|
|
||||||
|
@ -215,6 +222,11 @@ typedef struct {
|
||||||
|
|
||||||
// check callback function
|
// check callback function
|
||||||
spiffs_check_callback check_cb_f;
|
spiffs_check_callback check_cb_f;
|
||||||
|
|
||||||
|
// mounted flag
|
||||||
|
u8_t mounted;
|
||||||
|
// config magic
|
||||||
|
u32_t config_magic;
|
||||||
} spiffs;
|
} spiffs;
|
||||||
|
|
||||||
/* spiffs file status struct */
|
/* spiffs file status struct */
|
||||||
|
@ -242,7 +254,10 @@ typedef struct {
|
||||||
// functions
|
// functions
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the file system dynamic parameters and mounts the filesystem
|
* Initializes the file system dynamic parameters and mounts the filesystem.
|
||||||
|
* If SPIFFS_USE_MAGIC is enabled the mounting may fail with SPIFFS_ERR_NOT_A_FS
|
||||||
|
* if the flash does not contain a recognizable file system.
|
||||||
|
* In this case, SPIFFS_format must be called prior to remounting.
|
||||||
* @param fs the file system struct
|
* @param fs the file system struct
|
||||||
* @param config the physical and logical configuration of the file system
|
* @param config the physical and logical configuration of the file system
|
||||||
* @param work a memory work buffer comprising 2*config->log_page_size
|
* @param work a memory work buffer comprising 2*config->log_page_size
|
||||||
|
@ -441,6 +456,24 @@ s32_t SPIFFS_check(spiffs *fs);
|
||||||
*/
|
*/
|
||||||
s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used);
|
s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Formats the entire file system. All data will be lost.
|
||||||
|
* The filesystem must not be mounted when calling this.
|
||||||
|
*
|
||||||
|
* NB: formatting is awkward. Due to backwards compatibility, SPIFFS_mount
|
||||||
|
* MUST be called prior to formatting in order to configure the filesystem.
|
||||||
|
* If SPIFFS_mount succeeds, SPIFFS_unmount must be called before calling
|
||||||
|
* SPIFFS_format.
|
||||||
|
* If SPIFFS_mount fails, SPIFFS_format can be called directly without calling
|
||||||
|
* SPIFFS_unmount first.
|
||||||
|
*/
|
||||||
|
s32_t SPIFFS_format(spiffs *fs);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns nonzero if spiffs is mounted, or zero if unmounted.
|
||||||
|
*/
|
||||||
|
u8_t SPIFFS_mounted(spiffs *fs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if EOF reached.
|
* Check if EOF reached.
|
||||||
* @param fs the file system struct
|
* @param fs the file system struct
|
||||||
|
|
|
@ -119,14 +119,22 @@ typedef uint8_t u8_t;
|
||||||
#define SPIFFS_COPY_BUFFER_STACK (64)
|
#define SPIFFS_COPY_BUFFER_STACK (64)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Enable this to have an identifiable spiffs filesystem. This will look for
|
||||||
|
// a magic in all sectors to determine if this is a valid spiffs system or
|
||||||
|
// not on mount point. If not, SPIFFS_format must be called prior to mounting
|
||||||
|
// again.
|
||||||
|
#ifndef SPIFFS_USE_MAGIC
|
||||||
|
#define SPIFFS_USE_MAGIC (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level
|
// SPIFFS_LOCK and SPIFFS_UNLOCK protects spiffs from reentrancy on api level
|
||||||
// These should be defined on a multithreaded system
|
// These should be defined on a multithreaded system
|
||||||
|
|
||||||
// define this to entering a mutex if you're running on a multithreaded system
|
// define this to enter a mutex if you're running on a multithreaded system
|
||||||
#ifndef SPIFFS_LOCK
|
#ifndef SPIFFS_LOCK
|
||||||
#define SPIFFS_LOCK(fs)
|
#define SPIFFS_LOCK(fs)
|
||||||
#endif
|
#endif
|
||||||
// define this to exiting a mutex if you're running on a multithreaded system
|
// define this to exit a mutex if you're running on a multithreaded system
|
||||||
#ifndef SPIFFS_UNLOCK
|
#ifndef SPIFFS_UNLOCK
|
||||||
#define SPIFFS_UNLOCK(fs)
|
#define SPIFFS_UNLOCK(fs)
|
||||||
#endif
|
#endif
|
||||||
|
@ -159,7 +167,12 @@ typedef uint8_t u8_t;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set SPFIFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function
|
// Enable this if your target needs aligned data for index tables
|
||||||
|
#ifndef SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
|
||||||
|
#define SPIFFS_ALIGNED_OBJECT_INDEX_TABLES 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Set SPIFFS_TEST_VISUALISATION to non-zero to enable SPIFFS_vis function
|
||||||
// in the api. This function will visualize all filesystem using given printf
|
// in the api. This function will visualize all filesystem using given printf
|
||||||
// function.
|
// function.
|
||||||
#ifndef SPIFFS_TEST_VISUALISATION
|
#ifndef SPIFFS_TEST_VISUALISATION
|
||||||
|
|
|
@ -8,31 +8,11 @@ static s32_t spiffs_gc_erase_block(
|
||||||
spiffs *fs,
|
spiffs *fs,
|
||||||
spiffs_block_ix bix) {
|
spiffs_block_ix bix) {
|
||||||
s32_t res;
|
s32_t res;
|
||||||
u32_t addr = SPIFFS_BLOCK_TO_PADDR(fs, bix);
|
|
||||||
s32_t size = SPIFFS_CFG_LOG_BLOCK_SZ(fs);
|
|
||||||
|
|
||||||
SPIFFS_GC_DBG("gc: erase block %i\n", bix);
|
SPIFFS_GC_DBG("gc: erase block %i\n", bix);
|
||||||
|
res = spiffs_erase_block(fs, bix);
|
||||||
// here we ignore res, just try erasing the block
|
|
||||||
while (size > 0) {
|
|
||||||
SPIFFS_GC_DBG("gc: erase %08x:%08x\n", addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs));
|
|
||||||
(void)fs->cfg.hal_erase_f(addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs));
|
|
||||||
addr += SPIFFS_CFG_PHYS_ERASE_SZ(fs);
|
|
||||||
size -= SPIFFS_CFG_PHYS_ERASE_SZ(fs);
|
|
||||||
}
|
|
||||||
fs->free_blocks++;
|
|
||||||
|
|
||||||
// register erase count for this block
|
|
||||||
res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0,
|
|
||||||
SPIFFS_ERASE_COUNT_PADDR(fs, bix),
|
|
||||||
sizeof(spiffs_obj_id), (u8_t *)&fs->max_erase_count);
|
|
||||||
SPIFFS_CHECK_RES(res);
|
SPIFFS_CHECK_RES(res);
|
||||||
|
|
||||||
fs->max_erase_count++;
|
|
||||||
if (fs->max_erase_count == SPIFFS_OBJ_ID_IX_FLAG) {
|
|
||||||
fs->max_erase_count = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if SPIFFS_CACHE
|
#if SPIFFS_CACHE
|
||||||
{
|
{
|
||||||
u32_t i;
|
u32_t i;
|
||||||
|
|
|
@ -21,6 +21,36 @@ u32_t SPIFFS_buffer_bytes_for_cache(spiffs *fs, u32_t num_pages) {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
u8_t SPIFFS_mounted(spiffs *fs) {
|
||||||
|
return SPIFFS_CHECK_MOUNT(fs);
|
||||||
|
}
|
||||||
|
|
||||||
|
s32_t SPIFFS_format(spiffs *fs) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
|
if (SPIFFS_CHECK_MOUNT(fs)) {
|
||||||
|
fs->err_code = SPIFFS_ERR_MOUNTED;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
s32_t res;
|
||||||
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
spiffs_block_ix bix = 0;
|
||||||
|
while (bix < fs->block_count) {
|
||||||
|
fs->max_erase_count = 0;
|
||||||
|
res = spiffs_erase_block(fs, bix);
|
||||||
|
if (res != SPIFFS_OK) {
|
||||||
|
res = SPIFFS_ERR_ERASE_FAIL;
|
||||||
|
}
|
||||||
|
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
|
||||||
|
bix++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPIFFS_UNLOCK(fs);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
|
s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
|
||||||
u8_t *fd_space, u32_t fd_space_size,
|
u8_t *fd_space, u32_t fd_space_size,
|
||||||
void *cache, u32_t cache_size,
|
void *cache, u32_t cache_size,
|
||||||
|
@ -65,7 +95,16 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
|
||||||
spiffs_cache_init(fs);
|
spiffs_cache_init(fs);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s32_t res = spiffs_obj_lu_scan(fs);
|
s32_t res;
|
||||||
|
|
||||||
|
#if SPIFFS_USE_MAGIC
|
||||||
|
res = SPIFFS_CHECK_MAGIC_POSSIBLE(fs) ? SPIFFS_OK : SPIFFS_ERR_MAGIC_NOT_POSSIBLE;
|
||||||
|
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fs->config_magic = SPIFFS_CONFIG_MAGIC;
|
||||||
|
|
||||||
|
res = spiffs_obj_lu_scan(fs);
|
||||||
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
|
SPIFFS_API_CHECK_RES_UNLOCK(fs, res);
|
||||||
|
|
||||||
SPIFFS_DBG("page index byte len: %i\n", SPIFFS_CFG_LOG_PAGE_SZ(fs));
|
SPIFFS_DBG("page index byte len: %i\n", SPIFFS_CFG_LOG_PAGE_SZ(fs));
|
||||||
|
@ -79,13 +118,15 @@ s32_t SPIFFS_mount(spiffs *fs, spiffs_config *config, u8_t *work,
|
||||||
|
|
||||||
fs->check_cb_f = check_cb_f;
|
fs->check_cb_f = check_cb_f;
|
||||||
|
|
||||||
|
fs->mounted = 1;
|
||||||
|
|
||||||
SPIFFS_UNLOCK(fs);
|
SPIFFS_UNLOCK(fs);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIFFS_unmount(spiffs *fs) {
|
void SPIFFS_unmount(spiffs *fs) {
|
||||||
if (!SPIFFS_CHECK_MOUNT(fs)) return;
|
if (!SPIFFS_CHECK_CFG(fs) || !SPIFFS_CHECK_MOUNT(fs)) return;
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
u32_t i;
|
u32_t i;
|
||||||
spiffs_fd *fds = (spiffs_fd *)fs->fd_space;
|
spiffs_fd *fds = (spiffs_fd *)fs->fd_space;
|
||||||
|
@ -98,7 +139,8 @@ void SPIFFS_unmount(spiffs *fs) {
|
||||||
spiffs_fd_return(fs, cur_fd->file_nbr);
|
spiffs_fd_return(fs, cur_fd->file_nbr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fs->block_count = 0;
|
fs->mounted = 0;
|
||||||
|
|
||||||
SPIFFS_UNLOCK(fs);
|
SPIFFS_UNLOCK(fs);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,6 +154,7 @@ void SPIFFS_clearerr(spiffs *fs) {
|
||||||
|
|
||||||
s32_t SPIFFS_creat(spiffs *fs, char *path, spiffs_mode mode) {
|
s32_t SPIFFS_creat(spiffs *fs, char *path, spiffs_mode mode) {
|
||||||
(void)mode;
|
(void)mode;
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
spiffs_obj_id obj_id;
|
spiffs_obj_id obj_id;
|
||||||
|
@ -127,6 +170,7 @@ s32_t SPIFFS_creat(spiffs *fs, char *path, spiffs_mode mode) {
|
||||||
|
|
||||||
spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode mode) {
|
spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode mode) {
|
||||||
(void)mode;
|
(void)mode;
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -185,6 +229,7 @@ spiffs_file SPIFFS_open(spiffs *fs, char *path, spiffs_flags flags, spiffs_mode
|
||||||
}
|
}
|
||||||
|
|
||||||
spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) {
|
spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_flags flags, spiffs_mode mode) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -214,6 +259,7 @@ spiffs_file SPIFFS_open_by_dirent(spiffs *fs, struct spiffs_dirent *e, spiffs_fl
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
|
s32_t SPIFFS_read(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -282,6 +328,7 @@ static s32_t spiffs_hydro_write(spiffs *fs, spiffs_fd *fd, void *buf, u32_t offs
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
|
s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -400,6 +447,7 @@ s32_t SPIFFS_write(spiffs *fs, spiffs_file fh, void *buf, u32_t len) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
|
s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -444,6 +492,7 @@ s32_t SPIFFS_lseek(spiffs *fs, spiffs_file fh, s32_t offs, int whence) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_remove(spiffs *fs, char *path) {
|
s32_t SPIFFS_remove(spiffs *fs, char *path) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -477,6 +526,7 @@ s32_t SPIFFS_remove(spiffs *fs, char *path) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) {
|
s32_t SPIFFS_fremove(spiffs *fs, spiffs_file fh) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -525,6 +575,7 @@ static s32_t spiffs_stat_pix(spiffs *fs, spiffs_page_ix pix, spiffs_file fh, spi
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_stat(spiffs *fs, char *path, spiffs_stat *s) {
|
s32_t SPIFFS_stat(spiffs *fs, char *path, spiffs_stat *s) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -542,6 +593,7 @@ s32_t SPIFFS_stat(spiffs *fs, char *path, spiffs_stat *s) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) {
|
s32_t SPIFFS_fstat(spiffs *fs, spiffs_file fh, spiffs_stat *s) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -595,6 +647,7 @@ static s32_t spiffs_fflush_cache(spiffs *fs, spiffs_file fh) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) {
|
s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
s32_t res = SPIFFS_OK;
|
s32_t res = SPIFFS_OK;
|
||||||
#if SPIFFS_CACHE_WR
|
#if SPIFFS_CACHE_WR
|
||||||
|
@ -608,6 +661,11 @@ s32_t SPIFFS_fflush(spiffs *fs, spiffs_file fh) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void SPIFFS_close(spiffs *fs, spiffs_file fh) {
|
void SPIFFS_close(spiffs *fs, spiffs_file fh) {
|
||||||
|
if (!SPIFFS_CHECK_CFG((fs))) {
|
||||||
|
(fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SPIFFS_CHECK_MOUNT(fs)) {
|
if (!SPIFFS_CHECK_MOUNT(fs)) {
|
||||||
fs->err_code = SPIFFS_ERR_NOT_MOUNTED;
|
fs->err_code = SPIFFS_ERR_NOT_MOUNTED;
|
||||||
return;
|
return;
|
||||||
|
@ -623,6 +681,7 @@ void SPIFFS_close(spiffs *fs, spiffs_file fh) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) {
|
s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) {
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -664,10 +723,17 @@ s32_t SPIFFS_rename(spiffs *fs, char *old, char *new) {
|
||||||
|
|
||||||
spiffs_DIR *SPIFFS_opendir(spiffs *fs, char *name, spiffs_DIR *d) {
|
spiffs_DIR *SPIFFS_opendir(spiffs *fs, char *name, spiffs_DIR *d) {
|
||||||
(void)name;
|
(void)name;
|
||||||
|
|
||||||
|
if (!SPIFFS_CHECK_CFG((fs))) {
|
||||||
|
(fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!SPIFFS_CHECK_MOUNT(fs)) {
|
if (!SPIFFS_CHECK_MOUNT(fs)) {
|
||||||
fs->err_code = SPIFFS_ERR_NOT_MOUNTED;
|
fs->err_code = SPIFFS_ERR_NOT_MOUNTED;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->fs = fs;
|
d->fs = fs;
|
||||||
d->block = 0;
|
d->block = 0;
|
||||||
d->entry = 0;
|
d->entry = 0;
|
||||||
|
@ -743,12 +809,14 @@ struct spiffs_dirent *SPIFFS_readdir(spiffs_DIR *d, struct spiffs_dirent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_closedir(spiffs_DIR *d) {
|
s32_t SPIFFS_closedir(spiffs_DIR *d) {
|
||||||
|
SPIFFS_API_CHECK_CFG(d->fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(d->fs);
|
SPIFFS_API_CHECK_MOUNT(d->fs);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
s32_t SPIFFS_check(spiffs *fs) {
|
s32_t SPIFFS_check(spiffs *fs) {
|
||||||
s32_t res;
|
s32_t res;
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -766,6 +834,7 @@ s32_t SPIFFS_check(spiffs *fs) {
|
||||||
|
|
||||||
s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) {
|
s32_t SPIFFS_info(spiffs *fs, u32_t *total, u32_t *used) {
|
||||||
s32_t res = SPIFFS_OK;
|
s32_t res = SPIFFS_OK;
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
@ -847,6 +916,7 @@ s32_t SPIFFS_size(spiffs *fs, spiffs_file fh) {
|
||||||
#if SPIFFS_TEST_VISUALISATION
|
#if SPIFFS_TEST_VISUALISATION
|
||||||
s32_t SPIFFS_vis(spiffs *fs) {
|
s32_t SPIFFS_vis(spiffs *fs) {
|
||||||
s32_t res = SPIFFS_OK;
|
s32_t res = SPIFFS_OK;
|
||||||
|
SPIFFS_API_CHECK_CFG(fs);
|
||||||
SPIFFS_API_CHECK_MOUNT(fs);
|
SPIFFS_API_CHECK_MOUNT(fs);
|
||||||
SPIFFS_LOCK(fs);
|
SPIFFS_LOCK(fs);
|
||||||
|
|
||||||
|
|
|
@ -213,6 +213,45 @@ s32_t spiffs_obj_lu_find_entry_visitor(
|
||||||
return SPIFFS_VIS_END;
|
return SPIFFS_VIS_END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
s32_t spiffs_erase_block(
|
||||||
|
spiffs *fs,
|
||||||
|
spiffs_block_ix bix) {
|
||||||
|
s32_t res;
|
||||||
|
u32_t addr = SPIFFS_BLOCK_TO_PADDR(fs, bix);
|
||||||
|
s32_t size = SPIFFS_CFG_LOG_BLOCK_SZ(fs);
|
||||||
|
|
||||||
|
// here we ignore res, just try erasing the block
|
||||||
|
while (size > 0) {
|
||||||
|
SPIFFS_DBG("erase %08x:%08x\n", addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs));
|
||||||
|
(void)fs->cfg.hal_erase_f(addr, SPIFFS_CFG_PHYS_ERASE_SZ(fs));
|
||||||
|
addr += SPIFFS_CFG_PHYS_ERASE_SZ(fs);
|
||||||
|
size -= SPIFFS_CFG_PHYS_ERASE_SZ(fs);
|
||||||
|
}
|
||||||
|
fs->free_blocks++;
|
||||||
|
|
||||||
|
// register erase count for this block
|
||||||
|
res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0,
|
||||||
|
SPIFFS_ERASE_COUNT_PADDR(fs, bix),
|
||||||
|
sizeof(spiffs_obj_id), (u8_t *)&fs->max_erase_count);
|
||||||
|
SPIFFS_CHECK_RES(res);
|
||||||
|
|
||||||
|
#if SPIFFS_USE_MAGIC
|
||||||
|
// finally, write magic
|
||||||
|
spiffs_obj_id magic = SPIFFS_MAGIC(fs);
|
||||||
|
res = _spiffs_wr(fs, SPIFFS_OP_C_WRTHRU | SPIFFS_OP_T_OBJ_LU2, 0,
|
||||||
|
SPIFFS_MAGIC_PADDR(fs, bix),
|
||||||
|
sizeof(spiffs_obj_id), (u8_t *)&magic);
|
||||||
|
SPIFFS_CHECK_RES(res);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
fs->max_erase_count++;
|
||||||
|
if (fs->max_erase_count == SPIFFS_OBJ_ID_IX_FLAG) {
|
||||||
|
fs->max_erase_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static s32_t spiffs_obj_lu_scan_v(
|
static s32_t spiffs_obj_lu_scan_v(
|
||||||
spiffs *fs,
|
spiffs *fs,
|
||||||
|
@ -238,40 +277,44 @@ static s32_t spiffs_obj_lu_scan_v(
|
||||||
return SPIFFS_VIS_COUNTINUE;
|
return SPIFFS_VIS_COUNTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Scans thru all obj lu and counts free, deleted and used pages
|
// Scans thru all obj lu and counts free, deleted and used pages
|
||||||
// Find the maximum block erase count
|
// Find the maximum block erase count
|
||||||
|
// Checks magic if enabled
|
||||||
s32_t spiffs_obj_lu_scan(
|
s32_t spiffs_obj_lu_scan(
|
||||||
spiffs *fs) {
|
spiffs *fs) {
|
||||||
s32_t res;
|
s32_t res;
|
||||||
spiffs_block_ix bix;
|
spiffs_block_ix bix;
|
||||||
int entry;
|
int entry;
|
||||||
|
#if SPIFFS_USE_MAGIC
|
||||||
|
spiffs_block_ix unerased_bix = (spiffs_block_ix)-1;
|
||||||
|
#endif
|
||||||
|
|
||||||
fs->free_blocks = 0;
|
// find out erase count
|
||||||
fs->stats_p_allocated = 0;
|
// if enabled, check magic
|
||||||
fs->stats_p_deleted = 0;
|
|
||||||
|
|
||||||
res = spiffs_obj_lu_find_entry_visitor(fs,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
spiffs_obj_lu_scan_v,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
&bix,
|
|
||||||
&entry);
|
|
||||||
|
|
||||||
if (res == SPIFFS_VIS_END) {
|
|
||||||
res = SPIFFS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
SPIFFS_CHECK_RES(res);
|
|
||||||
|
|
||||||
bix = 0;
|
bix = 0;
|
||||||
spiffs_obj_id erase_count_final;
|
spiffs_obj_id erase_count_final;
|
||||||
spiffs_obj_id erase_count_min = SPIFFS_OBJ_ID_FREE;
|
spiffs_obj_id erase_count_min = SPIFFS_OBJ_ID_FREE;
|
||||||
spiffs_obj_id erase_count_max = 0;
|
spiffs_obj_id erase_count_max = 0;
|
||||||
while (bix < fs->block_count) {
|
while (bix < fs->block_count) {
|
||||||
|
#if SPIFFS_USE_MAGIC
|
||||||
|
spiffs_obj_id magic;
|
||||||
|
res = _spiffs_rd(fs,
|
||||||
|
SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ,
|
||||||
|
0, SPIFFS_MAGIC_PADDR(fs, bix) ,
|
||||||
|
sizeof(spiffs_obj_id), (u8_t *)&magic);
|
||||||
|
|
||||||
|
SPIFFS_CHECK_RES(res);
|
||||||
|
if (magic != SPIFFS_MAGIC(fs)) {
|
||||||
|
if (unerased_bix == (spiffs_block_ix)-1) {
|
||||||
|
// allow one unerased block as it might be powered down during an erase
|
||||||
|
unerased_bix = bix;
|
||||||
|
} else {
|
||||||
|
// more than one unerased block, bail out
|
||||||
|
SPIFFS_CHECK_RES(SPIFFS_ERR_NOT_A_FS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
spiffs_obj_id erase_count;
|
spiffs_obj_id erase_count;
|
||||||
res = _spiffs_rd(fs,
|
res = _spiffs_rd(fs,
|
||||||
SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ,
|
SPIFFS_OP_T_OBJ_LU2 | SPIFFS_OP_C_READ,
|
||||||
|
@ -297,6 +340,38 @@ s32_t spiffs_obj_lu_scan(
|
||||||
|
|
||||||
fs->max_erase_count = erase_count_final;
|
fs->max_erase_count = erase_count_final;
|
||||||
|
|
||||||
|
#if SPIFFS_USE_MAGIC
|
||||||
|
if (unerased_bix != (spiffs_block_ix)-1) {
|
||||||
|
// found one unerased block, remedy
|
||||||
|
SPIFFS_DBG("mount: erase block %i\n", bix);
|
||||||
|
res = spiffs_erase_block(fs, unerased_bix);
|
||||||
|
SPIFFS_CHECK_RES(res);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// count blocks
|
||||||
|
|
||||||
|
fs->free_blocks = 0;
|
||||||
|
fs->stats_p_allocated = 0;
|
||||||
|
fs->stats_p_deleted = 0;
|
||||||
|
|
||||||
|
res = spiffs_obj_lu_find_entry_visitor(fs,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
spiffs_obj_lu_scan_v,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
&bix,
|
||||||
|
&entry);
|
||||||
|
|
||||||
|
if (res == SPIFFS_VIS_END) {
|
||||||
|
res = SPIFFS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
SPIFFS_CHECK_RES(res);
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,10 @@
|
||||||
#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
|
#define SPIFFS_OBJ_ID_DELETED ((spiffs_obj_id)0)
|
||||||
#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1)
|
#define SPIFFS_OBJ_ID_FREE ((spiffs_obj_id)-1)
|
||||||
|
|
||||||
|
#define SPIFFS_MAGIC(fs) ((spiffs_obj_id)(0x20140529 ^ SPIFFS_CFG_LOG_PAGE_SZ(fs)))
|
||||||
|
|
||||||
|
#define SPIFFS_CONFIG_MAGIC (0x20090315)
|
||||||
|
|
||||||
#if SPIFFS_SINGLETON == 0
|
#if SPIFFS_SINGLETON == 0
|
||||||
#define SPIFFS_CFG_LOG_PAGE_SZ(fs) \
|
#define SPIFFS_CFG_LOG_PAGE_SZ(fs) \
|
||||||
((fs)->cfg.log_page_size)
|
((fs)->cfg.log_page_size)
|
||||||
|
@ -189,9 +193,18 @@
|
||||||
// returns data size in a data page
|
// returns data size in a data page
|
||||||
#define SPIFFS_DATA_PAGE_SIZE(fs) \
|
#define SPIFFS_DATA_PAGE_SIZE(fs) \
|
||||||
( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) )
|
( SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_page_header) )
|
||||||
// returns physical address for block's erase count
|
// returns physical address for block's erase count,
|
||||||
|
// always in the physical last entry of the last object lookup page
|
||||||
#define SPIFFS_ERASE_COUNT_PADDR(fs, bix) \
|
#define SPIFFS_ERASE_COUNT_PADDR(fs, bix) \
|
||||||
( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id) )
|
( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id) )
|
||||||
|
// returns physical address for block's magic,
|
||||||
|
// always in the physical second last entry of the last object lookup page
|
||||||
|
#define SPIFFS_MAGIC_PADDR(fs, bix) \
|
||||||
|
( SPIFFS_BLOCK_TO_PADDR(fs, bix) + SPIFFS_OBJ_LOOKUP_PAGES(fs) * SPIFFS_CFG_LOG_PAGE_SZ(fs) - sizeof(spiffs_obj_id)*2 )
|
||||||
|
// checks if there is any room for magic in the object luts
|
||||||
|
#define SPIFFS_CHECK_MAGIC_POSSIBLE(fs) \
|
||||||
|
( (SPIFFS_OBJ_LOOKUP_MAX_ENTRIES(fs) % (SPIFFS_CFG_LOG_PAGE_SZ(fs)/sizeof(spiffs_obj_id))) * sizeof(spiffs_obj_id) \
|
||||||
|
<= (SPIFFS_CFG_LOG_PAGE_SZ(fs)-sizeof(spiffs_obj_id)*2) )
|
||||||
|
|
||||||
// define helpers object
|
// define helpers object
|
||||||
|
|
||||||
|
@ -238,7 +251,10 @@
|
||||||
|
|
||||||
|
|
||||||
#define SPIFFS_CHECK_MOUNT(fs) \
|
#define SPIFFS_CHECK_MOUNT(fs) \
|
||||||
((fs)->block_count > 0)
|
((fs)->mounted != 0)
|
||||||
|
|
||||||
|
#define SPIFFS_CHECK_CFG(fs) \
|
||||||
|
((fs)->config_magic == SPIFFS_CONFIG_MAGIC)
|
||||||
|
|
||||||
#define SPIFFS_CHECK_RES(res) \
|
#define SPIFFS_CHECK_RES(res) \
|
||||||
do { \
|
do { \
|
||||||
|
@ -251,6 +267,12 @@
|
||||||
return -1; \
|
return -1; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define SPIFFS_API_CHECK_CFG(fs) \
|
||||||
|
if (!SPIFFS_CHECK_CFG((fs))) { \
|
||||||
|
(fs)->err_code = SPIFFS_ERR_NOT_CONFIGURED; \
|
||||||
|
return -1; \
|
||||||
|
}
|
||||||
|
|
||||||
#define SPIFFS_API_CHECK_RES(fs, res) \
|
#define SPIFFS_API_CHECK_RES(fs, res) \
|
||||||
if ((res) < SPIFFS_OK) { \
|
if ((res) < SPIFFS_OK) { \
|
||||||
(fs)->err_code = (res); \
|
(fs)->err_code = (res); \
|
||||||
|
@ -381,6 +403,8 @@ typedef struct {
|
||||||
// object structs
|
// object structs
|
||||||
|
|
||||||
// page header, part of each page except object lookup pages
|
// page header, part of each page except object lookup pages
|
||||||
|
// NB: this is always aligned when the data page is an object index,
|
||||||
|
// as in this case struct spiffs_page_object_ix is used
|
||||||
typedef struct __attribute(( packed )) {
|
typedef struct __attribute(( packed )) {
|
||||||
// object id
|
// object id
|
||||||
spiffs_obj_id obj_id;
|
spiffs_obj_id obj_id;
|
||||||
|
@ -391,11 +415,15 @@ typedef struct __attribute(( packed )) {
|
||||||
} spiffs_page_header;
|
} spiffs_page_header;
|
||||||
|
|
||||||
// object index header page header
|
// object index header page header
|
||||||
typedef struct __attribute(( packed )) {
|
typedef struct __attribute(( packed ))
|
||||||
|
#if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
|
||||||
|
__attribute(( aligned(sizeof(spiffs_page_ix)) ))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
// common page header
|
// common page header
|
||||||
spiffs_page_header p_hdr;
|
spiffs_page_header p_hdr;
|
||||||
// alignment
|
// alignment
|
||||||
u8_t _align[4 - ((sizeof(spiffs_page_header)+sizeof(spiffs_obj_type)+SPIFFS_OBJ_NAME_LEN)&3)==0 ? 4 : ((sizeof(spiffs_page_header)+sizeof(spiffs_obj_type)+SPIFFS_OBJ_NAME_LEN)&3)];
|
u8_t _align[4 - (sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3)];
|
||||||
// size of object
|
// size of object
|
||||||
u32_t size;
|
u32_t size;
|
||||||
// type of object
|
// type of object
|
||||||
|
@ -478,6 +506,10 @@ s32_t spiffs_obj_lu_find_entry_visitor(
|
||||||
spiffs_block_ix *block_ix,
|
spiffs_block_ix *block_ix,
|
||||||
int *lu_entry);
|
int *lu_entry);
|
||||||
|
|
||||||
|
s32_t spiffs_erase_block(
|
||||||
|
spiffs *fs,
|
||||||
|
spiffs_block_ix bix);
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
|
|
||||||
s32_t spiffs_obj_lu_scan(
|
s32_t spiffs_obj_lu_scan(
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
// spiffs file system offset in emulated spi flash
|
// spiffs file system offset in emulated spi flash
|
||||||
#define SPIFFS_PHYS_ADDR (4*1024*1024)
|
#define SPIFFS_PHYS_ADDR (4*1024*1024)
|
||||||
|
|
||||||
|
// test using filesystem magic
|
||||||
|
//#define SPIFFS_USE_MAGIC 1
|
||||||
|
|
||||||
#define SECTOR_SIZE 65536
|
#define SECTOR_SIZE 65536
|
||||||
#define LOG_BLOCK (SECTOR_SIZE*2)
|
#define LOG_BLOCK (SECTOR_SIZE*2)
|
||||||
#define LOG_PAGE (SECTOR_SIZE/256)
|
#define LOG_PAGE (SECTOR_SIZE/256)
|
||||||
|
|
|
@ -157,4 +157,19 @@ TEST(nodemcu_full_fs_2) {
|
||||||
|
|
||||||
} TEST_END(nodemcu_full_fs_2)
|
} TEST_END(nodemcu_full_fs_2)
|
||||||
|
|
||||||
|
TEST(magic_test) {
|
||||||
|
// one obj lu page, not full
|
||||||
|
fs_reset_specific(0, 4096*16, 4096, 4096*1, 128);
|
||||||
|
TEST_CHECK(SPIFFS_CHECK_MAGIC_POSSIBLE(FS));
|
||||||
|
// one obj lu page, full
|
||||||
|
fs_reset_specific(0, 4096*16, 4096, 4096*2, 128);
|
||||||
|
TEST_CHECK(!SPIFFS_CHECK_MAGIC_POSSIBLE(FS));
|
||||||
|
// two obj lu pages, not full
|
||||||
|
fs_reset_specific(0, 4096*16, 4096, 4096*4, 128);
|
||||||
|
TEST_CHECK(SPIFFS_CHECK_MAGIC_POSSIBLE(FS));
|
||||||
|
|
||||||
|
return TEST_RES_OK;
|
||||||
|
|
||||||
|
} TEST_END(magic_test)
|
||||||
|
|
||||||
SUITE_END(bug_tests)
|
SUITE_END(bug_tests)
|
||||||
|
|
|
@ -318,6 +318,7 @@ void fs_reset_specific(u32_t phys_addr, u32_t phys_size,
|
||||||
u32_t log_block_size, u32_t log_page_size) {
|
u32_t log_block_size, u32_t log_page_size) {
|
||||||
memset(area, 0xcc, sizeof(area));
|
memset(area, 0xcc, sizeof(area));
|
||||||
memset(&area[phys_addr], 0xff, phys_size);
|
memset(&area[phys_addr], 0xff, phys_size);
|
||||||
|
memset(&__fs, 0, sizeof(__fs));
|
||||||
|
|
||||||
spiffs_config c;
|
spiffs_config c;
|
||||||
c.hal_erase_f = _erase;
|
c.hal_erase_f = _erase;
|
||||||
|
@ -332,7 +333,20 @@ void fs_reset_specific(u32_t phys_addr, u32_t phys_size,
|
||||||
memset(erases,0,sizeof(erases));
|
memset(erases,0,sizeof(erases));
|
||||||
memset(_cache,0,sizeof(_cache));
|
memset(_cache,0,sizeof(_cache));
|
||||||
|
|
||||||
SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f);
|
s32_t res = SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f);
|
||||||
|
#if SPIFFS_USE_MAGIC
|
||||||
|
if (res == SPIFFS_OK) {
|
||||||
|
SPIFFS_unmount(&__fs);
|
||||||
|
}
|
||||||
|
res = SPIFFS_format(&__fs);
|
||||||
|
if (res != SPIFFS_OK) {
|
||||||
|
printf("format failed, %i\n", SPIFFS_errno(&__fs));
|
||||||
|
}
|
||||||
|
res = SPIFFS_mount(&__fs, &c, _work, _fds, sizeof(_fds), _cache, sizeof(_cache), spiffs_check_cb_f);
|
||||||
|
if (res != SPIFFS_OK) {
|
||||||
|
printf("mount failed, %i\n", SPIFFS_errno(&__fs));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
clear_flash_ops_log();
|
clear_flash_ops_log();
|
||||||
log_flash_ops = 1;
|
log_flash_ops = 1;
|
||||||
|
@ -574,6 +588,8 @@ void _teardown() {
|
||||||
printf(" cache hits : %i (sum %i)\n", (FS)->cache_hits, chits_tot);
|
printf(" cache hits : %i (sum %i)\n", (FS)->cache_hits, chits_tot);
|
||||||
printf(" cache misses : %i (sum %i)\n", (FS)->cache_misses, cmiss_tot);
|
printf(" cache misses : %i (sum %i)\n", (FS)->cache_misses, cmiss_tot);
|
||||||
printf(" cache utiliz : %f\n", ((float)chits_tot/(float)(chits_tot + cmiss_tot)));
|
printf(" cache utiliz : %f\n", ((float)chits_tot/(float)(chits_tot + cmiss_tot)));
|
||||||
|
chits_tot = 0;
|
||||||
|
cmiss_tot = 0;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
dump_flash_access_stats();
|
dump_flash_access_stats();
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
####Connect to MQTT Broker
|
||||||
|
|
||||||
|
```lua
|
||||||
|
-- init mqtt client with keepalive timer 120sec
|
||||||
|
m = mqtt.Client("clientid", 120, "user", "password")
|
||||||
|
|
||||||
|
-- setup Last Will and Testament (optional)
|
||||||
|
-- Broker will publish a message with qos = 0, retain = 0, data = "offline"
|
||||||
|
-- to topic "/lwt" if client don't send keepalive packet
|
||||||
|
m:lwt("/lwt", "offline", 0, 0)
|
||||||
|
|
||||||
|
m:on("connect", function(con) print ("connected") end)
|
||||||
|
m:on("offline", function(con) print ("offline") end)
|
||||||
|
|
||||||
|
-- on publish message receive event
|
||||||
|
m:on("message", function(conn, topic, data)
|
||||||
|
print(topic .. ":" )
|
||||||
|
if data ~= nil then
|
||||||
|
print(data)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
-- m:connect( host, port, secure, auto_reconnect, function(client) )
|
||||||
|
-- for secure: m:connect("192.168.11.118", 1880, 1, 0)
|
||||||
|
-- for auto-reconnect: m:connect("192.168.11.118", 1880, 0, 1)
|
||||||
|
m:connect("192.168.11.118", 1880, 0, 0, function(conn) print("connected") end)
|
||||||
|
|
||||||
|
-- subscribe topic with qos = 0
|
||||||
|
m:subscribe("/topic",0, function(conn) print("subscribe success") end)
|
||||||
|
-- or subscribe multiple topic (topic/0, qos = 0; topic/1, qos = 1; topic2 , qos = 2)
|
||||||
|
-- m:subscribe({["topic/0"]=0,["topic/1"]=1,topic2=2}, function(conn) print("subscribe success") end)
|
||||||
|
-- publish a message with data = hello, QoS = 0, retain = 0
|
||||||
|
m:publish("/topic","hello",0,0, function(conn) print("sent") end)
|
||||||
|
|
||||||
|
m:close(); -- if auto-reconnect == 1, will disable auto-reconnect and then disconnect from host.
|
||||||
|
-- you can call m:connect again
|
||||||
|
|
||||||
|
```
|
Loading…
Reference in New Issue