Unverified Commit 310faf7f authored by Terry Ellison's avatar Terry Ellison Committed by GitHub
Browse files

Merge pull request #2886 from nodemcu/dev

Next master drop
parents 68c425c0 a08e74d9
#include "spiffs.h"
bool myspiffs_mount();
void myspiffs_unmount();
int myspiffs_open(const char *name, int flags);
int myspiffs_close( int fd );
size_t myspiffs_write( int fd, const void* ptr, size_t len );
size_t myspiffs_read( int fd, void* ptr, size_t len);
int myspiffs_lseek( int fd, int off, int whence );
int myspiffs_eof( int fd );
int myspiffs_tell( int fd );
int myspiffs_getc( int fd );
int myspiffs_ungetc( int c, int fd );
int myspiffs_flush( int fd );
int myspiffs_error( int fd );
void myspiffs_clearerr( int fd );
int myspiffs_check( void );
int myspiffs_rename( const char *old, const char *newname );
size_t myspiffs_size( int fd );
int myspiffs_format (void);
......@@ -2,11 +2,10 @@
#define _NODEMCU_SPIFFS_H
#ifndef NODEMCU_SPIFFS_NO_INCLUDE
#include "c_stdint.h"
#include "c_stddef.h"
#include "c_stdio.h"
#include <stdint.h>
#include <stddef.h>
#include <stdio.h>
#include "user_interface.h"
typedef uint32_t intptr_t;
#endif
// Turn off stats
......
#include "c_stdio.h"
#include <stdio.h>
#include "platform.h"
#include "spiffs.h"
/*
* With the intoduction of a unified FatFS and SPIFFS support (#1397), the SPIFFS
* interface is now abstracted through a uses a single SPIFFS entry point
* myspiffs_realm() which returns a vfs_fs_fns object (as does myfatfs_realm()).
* All other functions and data are static.
*
* Non-OS SDK V3.0 introduces a flash partition table (PT) and SPIFFS has now been
* updated to support this:
* - SPIFFS limits search to the specifed SPIFFS0 address and size.
* - Any headroom / offset from other partitions is reflected in the PT allocations.
* - Unforced mounts will attempt to mount any valid SPIFSS found in this range
* (NodeMCU uses the SPIFFS_USE_MAGIC setting to make existing FS discoverable).
* - Subject to the following, no offset or FS search is done. The FS is assumed
* to be at the first valid location at the start of the partition.
*/
#include "spiffs_nucleus.h"
spiffs fs;
static spiffs fs;
#define LOG_PAGE_SIZE 256
#define LOG_BLOCK_SIZE (INTERNAL_FLASH_SECTOR_SIZE * 2)
#define LOG_BLOCK_SIZE_SMALL_FS (INTERNAL_FLASH_SECTOR_SIZE)
#define MIN_BLOCKS_FS 4
#define MASK_1MB (0x100000-1)
#define ALIGN (0x2000)
static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
static u8_t spiffs_fds[sizeof(spiffs_fd) * SPIFFS_MAX_OPEN_FILES];
......@@ -27,12 +44,18 @@ static s32_t my_spiffs_write(u32_t addr, u32_t size, u8_t *src) {
return SPIFFS_OK;
}
static int erase_cnt = -1; // If set to >=0 then erasing gives a ... feedback
static s32_t my_spiffs_erase(u32_t addr, u32_t size) {
u32_t sect_first = platform_flash_get_sector_of_address(addr);
u32_t sect_last = sect_first;
while( sect_first <= sect_last )
if( platform_flash_erase_sector( sect_first ++ ) == PLATFORM_ERR )
while( sect_first <= sect_last ) {
if (erase_cnt >= 0 && (erase_cnt++ & 0xF) == 0) {
dbg_printf(".");
}
if( platform_flash_erase_sector( sect_first ++ ) == PLATFORM_ERR ) {
return SPIFFS_ERR_INTERNAL;
}
}
return SPIFFS_OK;
}
......@@ -42,131 +65,64 @@ void myspiffs_check_callback(spiffs_check_type type, spiffs_check_report report,
}
/*******************
The W25Q32BV array is organized into 16,384 programmable pages of 256-bytes each. Up to 256 bytes can be programmed at a time. 
Pages can be erased in groups of 16 (4KB sector erase), groups of 128 (32KB block erase), groups of 256 (64KB block erase) or 
the entire chip (chip erase). The W25Q32BV has 1,024 erasable sectors and 64 erasable blocks respectively. 
The small 4KB sectors allow for greater flexibility in applications that require data and parameter storage. 
********************/
* Note that the W25Q32BV array is organized into 16,384 programmable pages of 256-bytes 
* each. Up to 256 bytes can be programmed at a time. Pages can be erased in groups of 
* 16 (4KB sector erase), groups of 128 (32KB block erase), groups of 256 (64KB block 
* erase) or the entire chip (chip erase). The W25Q32BV has 1,024 erasable sectors and 
* 64 erasable blocks respectively. The small 4KB sectors allow for greater flexibility 
* in applications that require data and parameter storage. 
*
* Returns TRUE if FS was found.
*/
static bool myspiffs_set_cfg(spiffs_config *cfg, bool force_create) {
uint32 pt_start, pt_size, pt_end;
static bool myspiffs_set_location(spiffs_config *cfg, int align, int offset, int block_size) {
#ifdef SPIFFS_FIXED_LOCATION
cfg->phys_addr = (SPIFFS_FIXED_LOCATION + block_size - 1) & ~(block_size-1);
#else
cfg->phys_addr = ( u32_t )platform_flash_get_first_free_block_address( NULL ) + offset;
cfg->phys_addr = (cfg->phys_addr + align - 1) & ~(align - 1);
#endif
#ifdef SPIFFS_SIZE_1M_BOUNDARY
cfg->phys_size = ((0x100000 - (SYS_PARAM_SEC_NUM * INTERNAL_FLASH_SECTOR_SIZE) - ( ( u32_t )cfg->phys_addr )) & ~(block_size - 1)) & 0xfffff;
#else
cfg->phys_size = (INTERNAL_FLASH_SIZE - ( ( u32_t )cfg->phys_addr )) & ~(block_size - 1);
#endif
if ((int) cfg->phys_size < 0) {
pt_size = platform_flash_get_partition (NODEMCU_SPIFFS0_PARTITION, &pt_start);
if (pt_size == 0) {
return FALSE;
}
cfg->log_block_size = block_size;
return (cfg->phys_size / block_size) >= MIN_BLOCKS_FS;
}
/*
* Returns TRUE if FS was found
* align must be a power of two
*/
static bool myspiffs_set_cfg_block(spiffs_config *cfg, int align, int offset, int block_size, bool force_create) {
cfg->phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE; // according to datasheet
cfg->log_page_size = LOG_PAGE_SIZE; // as we said
pt_end = pt_start + pt_size;
cfg->hal_read_f = my_spiffs_read;
cfg->hal_write_f = my_spiffs_write;
cfg->hal_erase_f = my_spiffs_erase;
if (!myspiffs_set_location(cfg, align, offset, block_size)) {
cfg->phys_erase_block = INTERNAL_FLASH_SECTOR_SIZE;
cfg->log_page_size = LOG_PAGE_SIZE;
cfg->phys_addr = (pt_start + ALIGN - 1) & ~(ALIGN - 1);
cfg->phys_size = (pt_end & ~(ALIGN - 1)) - cfg->phys_addr;
if (cfg->phys_size < MIN_BLOCKS_FS * LOG_BLOCK_SIZE_SMALL_FS) {
return FALSE;
} else if (cfg->phys_size < MIN_BLOCKS_FS * LOG_BLOCK_SIZE_SMALL_FS) {
cfg->log_block_size = LOG_BLOCK_SIZE_SMALL_FS;
} else {
cfg->log_block_size = LOG_BLOCK_SIZE;
}
NODE_DBG("fs.start:%x,max:%x\n",cfg->phys_addr,cfg->phys_size);
#ifdef SPIFFS_USE_MAGIC_LENGTH
if (force_create) {
return TRUE;
}
int size = SPIFFS_probe_fs(cfg);
if (size > 0 && size < cfg->phys_size) {
NODE_DBG("Overriding size:%x\n",size);
cfg->phys_size = size;
}
if (size > 0) {
return TRUE;
}
return FALSE;
#else
return TRUE;
#endif
}
static bool myspiffs_set_cfg(spiffs_config *cfg, int align, int offset, bool force_create) {
if (force_create) {
return myspiffs_set_cfg_block(cfg, align, offset, LOG_BLOCK_SIZE , TRUE) ||
myspiffs_set_cfg_block(cfg, align, offset, LOG_BLOCK_SIZE_SMALL_FS, TRUE);
}
return myspiffs_set_cfg_block(cfg, align, offset, LOG_BLOCK_SIZE_SMALL_FS, FALSE) ||
myspiffs_set_cfg_block(cfg, align, offset, LOG_BLOCK_SIZE , FALSE);
}
static bool myspiffs_find_cfg(spiffs_config *cfg, bool force_create) {
int i;
if (!force_create) {
#ifdef SPIFFS_FIXED_LOCATION
if (myspiffs_set_cfg(cfg, 0, 0, FALSE)) {
return TRUE;
}
#else
if (INTERNAL_FLASH_SIZE >= 700000) {
for (i = 0; i < 8; i++) {
if (myspiffs_set_cfg(cfg, 0x10000, 0x10000 * i, FALSE)) {
return TRUE;
}
}
}
int size = SPIFFS_probe_fs(cfg);
for (i = 0; i < 8; i++) {
if (myspiffs_set_cfg(cfg, LOG_BLOCK_SIZE, LOG_BLOCK_SIZE * i, FALSE)) {
return TRUE;
}
if (size > 0 && size < cfg->phys_size) {
NODE_DBG("Overriding size:%x\n",size);
cfg->phys_size = size;
}
#endif
}
// No existing file system -- set up for a format
if (INTERNAL_FLASH_SIZE >= 700000) {
myspiffs_set_cfg(cfg, 0x10000, 0x10000, TRUE);
#ifndef SPIFFS_MAX_FILESYSTEM_SIZE
if (cfg->phys_size < 400000) {
// Don't waste so much in alignment
myspiffs_set_cfg(cfg, LOG_BLOCK_SIZE, LOG_BLOCK_SIZE * 4, TRUE);
if (size <= 0) {
return FALSE;
}
#endif
} else {
myspiffs_set_cfg(cfg, LOG_BLOCK_SIZE, 0, TRUE);
}
#ifdef SPIFFS_MAX_FILESYSTEM_SIZE
if (cfg->phys_size > SPIFFS_MAX_FILESYSTEM_SIZE) {
cfg->phys_size = (SPIFFS_MAX_FILESYSTEM_SIZE) & ~(cfg->log_block_size - 1);
}
#endif
return FALSE;
NODE_DBG("myspiffs set cfg block: %x %x %x %x %x %x\n", pt_start, pt_end,
cfg->phys_size, cfg->phys_addr, cfg->phys_size, cfg->log_block_size);
return TRUE;
}
static bool myspiffs_mount_internal(bool force_mount) {
static bool myspiffs_mount(bool force_mount) {
spiffs_config cfg;
if (!myspiffs_find_cfg(&cfg, force_mount) && !force_mount) {
if (!myspiffs_set_cfg(&cfg, force_mount) && !force_mount) {
return FALSE;
}
......@@ -189,10 +145,6 @@ static bool myspiffs_mount_internal(bool force_mount) {
return res == SPIFFS_OK;
}
bool myspiffs_mount() {
return myspiffs_mount_internal(FALSE);
}
void myspiffs_unmount() {
SPIFFS_unmount(&fs);
}
......@@ -202,42 +154,23 @@ void myspiffs_unmount() {
int myspiffs_format( void )
{
SPIFFS_unmount(&fs);
myspiffs_mount_internal(TRUE);
myspiffs_mount(TRUE);
SPIFFS_unmount(&fs);
NODE_DBG("Formatting: size 0x%x, addr 0x%x\n", fs.cfg.phys_size, fs.cfg.phys_addr);
erase_cnt = 0;
int status = SPIFFS_format(&fs);
erase_cnt = -1;
if (SPIFFS_format(&fs) < 0) {
return 0;
}
return myspiffs_mount();
return status < 0 ? 0 : myspiffs_mount(FALSE);
}
#if 0
void test_spiffs() {
char buf[12];
// Surely, I've mounted spiffs before entering here
spiffs_file fd = SPIFFS_open(&fs, "my_file", SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_RDWR, 0);
if (SPIFFS_write(&fs, fd, (u8_t *)"Hello world", 12) < 0) NODE_DBG("errno %i\n", SPIFFS_errno(&fs));
SPIFFS_close(&fs, fd);
fd = SPIFFS_open(&fs, "my_file", SPIFFS_RDWR, 0);
if (SPIFFS_read(&fs, fd, (u8_t *)buf, 12) < 0) NODE_DBG("errno %i\n", SPIFFS_errno(&fs));
SPIFFS_close(&fs, fd);
NODE_DBG("--> %s <--\n", buf);
}
#endif
// ***************************************************************************
// vfs API
// ***************************************************************************
#include <c_stdlib.h>
#include <stdlib.h>
#include "vfs_int.h"
#define MY_LDRV_ID "FLASH"
......@@ -348,7 +281,7 @@ static sint32_t myspiffs_vfs_closedir( const struct vfs_dir *dd ) {
sint32_t res = SPIFFS_closedir( d );
// free descriptor memory
c_free( (void *)dd );
free( (void *)dd );
}
static sint32_t myspiffs_vfs_readdir( const struct vfs_dir *dd, struct vfs_stat *buf ) {
......@@ -356,11 +289,11 @@ static sint32_t myspiffs_vfs_readdir( const struct vfs_dir *dd, struct vfs_stat
struct spiffs_dirent dirent;
if (SPIFFS_readdir( d, &dirent )) {
c_memset( buf, 0, sizeof( struct vfs_stat ) );
memset( buf, 0, sizeof( struct vfs_stat ) );
// copy entries to item
// fill in supported stat entries
c_strncpy( buf->name, dirent.name, FS_OBJ_NAME_LEN+1 );
strncpy( buf->name, dirent.name, FS_OBJ_NAME_LEN+1 );
buf->name[FS_OBJ_NAME_LEN] = '\0';
buf->size = dirent.size;
return VFS_RES_OK;
......@@ -383,7 +316,7 @@ static sint32_t myspiffs_vfs_close( const struct vfs_file *fd ) {
sint32_t res = SPIFFS_close( &fs, fh );
// free descriptor memory
c_free( (void *)fd );
free( (void *)fd );
return res;
}
......@@ -459,21 +392,21 @@ static sint32_t myspiffs_vfs_ferrno( const struct vfs_file *fd ) {
static int fs_mode2flag(const char *mode){
if(c_strlen(mode)==1){
if(c_strcmp(mode,"w")==0)
if(strlen(mode)==1){
if(strcmp(mode,"w")==0)
return SPIFFS_WRONLY|SPIFFS_CREAT|SPIFFS_TRUNC;
else if(c_strcmp(mode, "r")==0)
else if(strcmp(mode, "r")==0)
return SPIFFS_RDONLY;
else if(c_strcmp(mode, "a")==0)
else if(strcmp(mode, "a")==0)
return SPIFFS_WRONLY|SPIFFS_CREAT|SPIFFS_APPEND;
else
return SPIFFS_RDONLY;
} else if (c_strlen(mode)==2){
if(c_strcmp(mode,"r+")==0)
} else if (strlen(mode)==2){
if(strcmp(mode,"r+")==0)
return SPIFFS_RDWR;
else if(c_strcmp(mode, "w+")==0)
else if(strcmp(mode, "w+")==0)
return SPIFFS_RDWR|SPIFFS_CREAT|SPIFFS_TRUNC;
else if(c_strcmp(mode, "a+")==0)
else if(strcmp(mode, "a+")==0)
return SPIFFS_RDWR|SPIFFS_CREAT|SPIFFS_APPEND;
else
return SPIFFS_RDONLY;
......@@ -489,13 +422,13 @@ static vfs_file *myspiffs_vfs_open( const char *name, const char *mode ) {
struct myvfs_file *fd;
int flags = fs_mode2flag( mode );
if (fd = (struct myvfs_file *)c_malloc( sizeof( struct myvfs_file ) )) {
if (fd = (struct myvfs_file *)malloc( sizeof( struct myvfs_file ) )) {
if (0 < (fd->fh = SPIFFS_open( &fs, name, flags, 0 ))) {
fd->vfs_file.fs_type = VFS_FS_SPIFFS;
fd->vfs_file.fns = &myspiffs_file_fns;
return (vfs_file *)fd;
} else {
c_free( fd );
free( fd );
}
}
......@@ -505,13 +438,13 @@ static vfs_file *myspiffs_vfs_open( const char *name, const char *mode ) {
static vfs_dir *myspiffs_vfs_opendir( const char *name ){
struct myvfs_dir *dd;
if (dd = (struct myvfs_dir *)c_malloc( sizeof( struct myvfs_dir ) )) {
if (dd = (struct myvfs_dir *)malloc( sizeof( struct myvfs_dir ) )) {
if (SPIFFS_opendir( &fs, name, &(dd->d) )) {
dd->vfs_dir.fs_type = VFS_FS_SPIFFS;
dd->vfs_dir.fns = &myspiffs_dd_fns;
return (vfs_dir *)dd;
} else {
c_free( dd );
free( dd );
}
}
......@@ -522,10 +455,10 @@ static sint32_t myspiffs_vfs_stat( const char *name, struct vfs_stat *buf ) {
spiffs_stat stat;
if (0 <= SPIFFS_stat( &fs, name, &stat )) {
c_memset( buf, 0, sizeof( struct vfs_stat ) );
memset( buf, 0, sizeof( struct vfs_stat ) );
// fill in supported stat entries
c_strncpy( buf->name, stat.name, FS_OBJ_NAME_LEN+1 );
strncpy( buf->name, stat.name, FS_OBJ_NAME_LEN+1 );
buf->name[FS_OBJ_NAME_LEN] = '\0';
buf->size = stat.size;
......@@ -555,7 +488,7 @@ static sint32_t myspiffs_vfs_fscfg( uint32_t *phys_addr, uint32_t *phys_size ) {
static vfs_vol *myspiffs_vfs_mount( const char *name, int num ) {
// volume descriptor not supported, just return TRUE / FALSE
return myspiffs_mount() ? (vfs_vol *)1 : NULL;
return myspiffs_mount(FALSE) ? (vfs_vol *)1 : NULL;
}
static sint32_t myspiffs_vfs_format( void ) {
......@@ -574,12 +507,12 @@ static void myspiffs_vfs_clearerr( void ) {
// ---------------------------------------------------------------------------
// VFS interface functions
//
vfs_fs_fns *myspiffs_realm( const char *inname, char **outname, int set_current_drive ) {
if (inname[0] == '/') {
size_t idstr_len = c_strlen( MY_LDRV_ID );
// logical drive is specified, check if it's our id
if (0 == c_strncmp( &(inname[1]), MY_LDRV_ID, idstr_len )) {
*outname = (char *)&(inname[1 + idstr_len]);
if (0 == strncmp(inname + 1, MY_LDRV_ID, sizeof(MY_LDRV_ID)-1)) {
*outname = (char *)(inname + sizeof(MY_LDRV_ID));
if (*outname[0] == '/') {
// skip leading /
(*outname)++;
......
......@@ -165,7 +165,7 @@
// Lower value generates more read/writes. No meaning having it bigger
// than logical page size.
#ifndef SPIFFS_COPY_BUFFER_STACK
#define SPIFFS_COPY_BUFFER_STACK (64)
#define SPIFFS_COPY_BUFFER_STACK (256)
#endif
// Enable this to have an identifiable spiffs filesystem. This will look for
......
......@@ -476,6 +476,9 @@ typedef struct {
// object structs
#ifdef _MSC_VER
#pragma pack ( push, 1 )
#endif
// page header, part of each page except object lookup pages
// NB: this is always aligned when the data page is an object index,
......@@ -492,8 +495,13 @@ typedef struct SPIFFS_PACKED {
// object index header page header
typedef struct SPIFFS_PACKED
#if SPIFFS_ALIGNED_OBJECT_INDEX_TABLES
#ifdef _MSC_VER
//Note: the following needs to track the sizeof(spiffs_page_ix), which is defined in spiffs_config.h
__declspec( align( 2 ) )
#else
__attribute(( aligned(sizeof(spiffs_page_ix)) ))
#endif
#endif
{
// common page header
spiffs_page_header p_hdr;
......@@ -517,6 +525,10 @@ typedef struct SPIFFS_PACKED {
u8_t _align[4 - ((sizeof(spiffs_page_header)&3)==0 ? 4 : (sizeof(spiffs_page_header)&3))];
} spiffs_page_object_ix;
#ifdef _MSC_VER
#pragma pack ( pop )
#endif
// callback func for object lookup visitor
typedef s32_t (*spiffs_visitor_f)(spiffs *fs, spiffs_obj_id id, spiffs_block_ix bix, int ix_entry,
const void *user_const_p, void *user_var_p);
......
......@@ -38,9 +38,6 @@ STD_CFLAGS= -std=gnu11 -Wimplicit -Wno-undef -include config_ext.h
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../libc
INCLUDES += -I ../platform
INCLUDES += -I .
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
......@@ -7,10 +7,10 @@
* http://www.sqlite.org/src/doc/trunk/src/test_vfs.c
**/
#include <c_stdio.h>
#include <c_stdlib.h>
#include <c_string.h>
#include <c_types.h>
#include <stdio.h>
#include <stddef.h>
#include <string.h>
#include <stdint.h>
#include <osapi.h>
#include <vfs.h>
#include <time.h>
......
......@@ -2795,7 +2795,7 @@ SQLITE_API void sqlite3_free_table(char **result);
** table and column names into a constructed SQL statement.
**
** ^(The "%z" formatting option works like "%s" but with the
** addition that after the c_string has been read and copied into
** addition that after the string has been read and copied into
** the result, [sqlite3_free()] is called on the input string.)^
*/
SQLITE_API char *sqlite3_mprintf(const char*,...);
......@@ -11017,7 +11017,7 @@ struct fts5_api {
** Include standard header files as necessary
*/
#ifdef HAVE_STDINT_H
#include <c_stdint.h>
#include <stdint.h>
#endif
#ifdef HAVE_INTTYPES_H
#include <inttypes.h>
......@@ -11608,9 +11608,9 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*);
 
/************** End of parse.h ***********************************************/
/************** Continuing where we left off in sqliteInt.h ******************/
#include <c_stdio.h>
#include <c_stdlib.h>
#include <c_string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <stddef.h>
 
......@@ -12585,7 +12585,7 @@ SQLITE_PRIVATE int sqlite3SchemaMutexHeld(sqlite3*,int,Schema*);
*/
#ifndef SQLITE_VDBE_H
#define SQLITE_VDBE_H
/* #include <c_stdio.h> */
/* #include <stdio.h> */
 
/*
** A single VDBE is an opaque structure named "Vdbe". Only routines
......@@ -18868,7 +18868,7 @@ SQLITE_API int sqlite3_db_status(
** Richmond, Virginia (USA)
*/
/* #include "sqliteInt.h" */
/* #include <c_stdlib.h> */
/* #include <stdlib.h> */
/* #include <assert.h> */
#include <time.h>
 
......@@ -20978,7 +20978,7 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){
# define backtrace(A,B) 1
# define backtrace_symbols_fd(A,B,C)
#endif
/* #include <c_stdio.h> */
/* #include <stdio.h> */
 
/*
** Each memory allocation looks like this:
......@@ -29771,7 +29771,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){
/*
** standard include files.
*/
#include <sys/c_types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
......@@ -78053,7 +78053,7 @@ static int findNextHostParameter(const char *zSql, int *pnToken){
** obtained from sqlite3DbMalloc(). If sqlite3.nVdbeExec is 1, then the
** string contains a copy of zRawSql but with host parameters expanded to
** their current bindings. Or, if sqlite3.nVdbeExec is greater than 1,
** then the returned c_string holds a copy of zRawSql with "-- " prepended
** then the returned string holds a copy of zRawSql with "-- " prepended
** to each line of text.
**
** If the SQLITE_TRACE_SIZE_LIMIT macro is defined to an integer, then
......@@ -89198,8 +89198,8 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){
** an SQL statement.
*/
/* #include "sqliteInt.h" */
/* #include <c_stdlib.h> */
/* #include <c_string.h> */
/* #include <stdlib.h> */
/* #include <string.h> */
 
 
/*
......@@ -105553,7 +105553,7 @@ SQLITE_PRIVATE void sqlite3ResolvePartIdxLabel(Parse *pParse, int iLabel){
** time functions, are implemented separately.)
*/
/* #include "sqliteInt.h" */
/* #include <c_stdlib.h> */
/* #include <stdlib.h> */
/* #include <assert.h> */
/* #include "vdbeInt.h" */
 
......@@ -108885,7 +108885,7 @@ SQLITE_PRIVATE void sqlite3OpenTable(
 
/*
** Return a pointer to the column affinity string associated with index
** pIdx. A column affinity c_string has one character for each column in
** pIdx. A column affinity string has one character for each column in
** the table, according to the affinity of the column:
**
** Character Column affinity
......@@ -108951,7 +108951,7 @@ SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(sqlite3 *db, Index *pIdx){
** then just set the P4 operand of the previous opcode (which should be
** an OP_MakeRecord) to the affinity string.
**
** A column affinity c_string has one character per column:
** A column affinity string has one character per column:
**
** Character Column affinity
** ------------------------------
......@@ -135437,7 +135437,7 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){
** The following is the concatenation of all %include directives from the
** input grammar file:
*/
/* #include <c_stdio.h> */
/* #include <stdio.h> */
/************ Begin %include sections from the grammar ************************/
 
/* #include "sqliteInt.h" */
......@@ -136309,7 +136309,7 @@ struct yyParser {
typedef struct yyParser yyParser;
 
#ifndef NDEBUG
/* #include <c_stdio.h> */
/* #include <stdio.h> */
static FILE *yyTraceFILE = 0;
static char *yyTracePrompt = 0;
#endif /* NDEBUG */
......@@ -138629,7 +138629,7 @@ SQLITE_PRIVATE void sqlite3Parser(
** parser for analysis.
*/
/* #include "sqliteInt.h" */
/* #include <c_stdlib.h> */
/* #include <stdlib.h> */
 
/* Character classes for tokenizing
**
......@@ -145471,10 +145471,10 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeIsdiacritic(int);
#endif
 
/* #include <assert.h> */
/* #include <c_stdlib.h> */
/* #include <stdlib.h> */
/* #include <stddef.h> */
/* #include <c_stdio.h> */
/* #include <c_string.h> */
/* #include <stdio.h> */
/* #include <string.h> */
/* #include <stdarg.h> */
 
/* #include "fts3.h" */
......@@ -151141,7 +151141,7 @@ SQLITE_API int sqlite3_fts3_init(
/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
 
/* #include <c_string.h> */
/* #include <string.h> */
/* #include <assert.h> */
 
typedef struct Fts3auxTable Fts3auxTable;
......@@ -151758,7 +151758,7 @@ SQLITE_API int sqlite3_fts3_enable_parentheses = 0;
*/
#define SQLITE_FTS3_DEFAULT_NEAR_PARAM 10
 
/* #include <c_string.h> */
/* #include <string.h> */
/* #include <assert.h> */
 
/*
......@@ -152786,7 +152786,7 @@ SQLITE_PRIVATE void sqlite3Fts3ExprFree(Fts3Expr *pDel){
 
#ifdef SQLITE_TEST
 
/* #include <c_stdio.h> */
/* #include <stdio.h> */
 
/*
** Function to query the hash-table of tokenizers (see README.tokenizers).
......@@ -153019,8 +153019,8 @@ SQLITE_PRIVATE int sqlite3Fts3ExprInitTestInterface(sqlite3* db){
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
 
/* #include <assert.h> */
/* #include <c_stdlib.h> */
/* #include <c_string.h> */
/* #include <stdlib.h> */
/* #include <string.h> */
 
/* #include "fts3_hash.h" */
 
......@@ -153404,9 +153404,9 @@ SQLITE_PRIVATE void *sqlite3Fts3HashInsert(
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
 
/* #include <assert.h> */
/* #include <c_stdlib.h> */
/* #include <c_stdio.h> */
/* #include <c_string.h> */
/* #include <stdlib.h> */
/* #include <stdio.h> */
/* #include <string.h> */
 
/* #include "fts3_tokenizer.h" */
 
......@@ -154070,7 +154070,7 @@ SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
 
/* #include <assert.h> */
/* #include <c_string.h> */
/* #include <string.h> */
 
/*
** Return true if the two-argument version of fts3_tokenizer()
......@@ -154272,7 +154272,7 @@ SQLITE_PRIVATE int sqlite3Fts3InitTokenizer(
#else
# include "tcl.h"
#endif
/* #include <c_string.h> */
/* #include <string.h> */
 
/*
** Implementation of a special SQL scalar function for testing tokenizers
......@@ -154588,9 +154588,9 @@ SQLITE_PRIVATE int sqlite3Fts3InitHashTable(
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
 
/* #include <assert.h> */
/* #include <c_stdlib.h> */
/* #include <c_stdio.h> */
/* #include <c_string.h> */
/* #include <stdlib.h> */
/* #include <stdio.h> */
/* #include <string.h> */
 
/* #include "fts3_tokenizer.h" */
 
......@@ -154840,7 +154840,7 @@ SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(
/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
 
/* #include <c_string.h> */
/* #include <string.h> */
/* #include <assert.h> */
 
typedef struct Fts3tokTable Fts3tokTable;
......@@ -155276,9 +155276,9 @@ SQLITE_PRIVATE int sqlite3Fts3InitTok(sqlite3 *db, Fts3Hash *pHash){
/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
 
/* #include <c_string.h> */
/* #include <string.h> */
/* #include <assert.h> */
/* #include <c_stdlib.h> */
/* #include <stdlib.h> */
 
 
#define FTS_MAX_APPENDABLE_HEIGHT 16
......@@ -160954,7 +160954,7 @@ SQLITE_PRIVATE int sqlite3Fts3Optimize(Fts3Table *p){
/* #include "fts3Int.h" */
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
 
/* #include <c_string.h> */
/* #include <string.h> */
/* #include <assert.h> */
 
/*
......@@ -162124,7 +162124,7 @@ static int fts3MatchinfoLcs(Fts3Cursor *pCsr, MatchInfo *pInfo){
** be returned by the matchinfo() function. Argument zArg contains the
** format string passed as the second argument to matchinfo (or the
** default value "pcx" if no second argument was specified). The format
** c_string has already been validated and the pInfo->aMatchinfo[] array
** string has already been validated and the pInfo->aMatchinfo[] array
** is guaranteed to be large enough for the output.
**
** If bGlobal is true, then populate all fields of the matchinfo() output.
......@@ -162668,9 +162668,9 @@ SQLITE_PRIVATE void sqlite3Fts3Matchinfo(
#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3)
 
/* #include <assert.h> */
/* #include <c_stdlib.h> */
/* #include <c_stdio.h> */
/* #include <c_string.h> */
/* #include <stdlib.h> */
/* #include <stdio.h> */
/* #include <string.h> */
 
/* #include "fts3_tokenizer.h" */
 
......@@ -163473,9 +163473,9 @@ SQLITE_PRIVATE int sqlite3FtsUnicodeFold(int c, int bRemoveDiacritic){
/* #include "sqlite3.h" */
#endif
 
/* #include <c_string.h> */
/* #include <string.h> */
/* #include <assert.h> */
/* #include <c_stdio.h> */
/* #include <stdio.h> */
 
#ifndef SQLITE_AMALGAMATION
#include "sqlite3rtree.h"
......@@ -168105,8 +168105,8 @@ SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(
*/
 
/* #include <assert.h> */
/* #include <c_string.h> */
/* #include <c_stdio.h> */
/* #include <string.h> */
/* #include <stdio.h> */
 
/* #include "sqlite3.h" */
 
......@@ -174118,7 +174118,7 @@ SQLITE_PRIVATE int sqlite3DbstatRegister(sqlite3 *db){ return SQLITE_OK; }
#if defined(SQLITE_ENABLE_SESSION) && defined(SQLITE_ENABLE_PREUPDATE_HOOK)
/* #include "sqlite3session.h" */
/* #include <assert.h> */
/* #include <c_string.h> */
/* #include <string.h> */
 
#ifndef SQLITE_AMALGAMATION
/* # include "sqliteInt.h" */
......@@ -178800,8 +178800,8 @@ SQLITE_API int sqlite3changeset_concat_strm(
#endif
SQLITE_EXTENSION_INIT1
/* #include <assert.h> */
/* #include <c_string.h> */
/* #include <c_stdlib.h> */
/* #include <string.h> */
/* #include <stdlib.h> */
/* #include <stdarg.h> */
 
/* Mark a function parameter as unused, to suppress nuisance compiler
......@@ -181812,7 +181812,7 @@ struct fts5_api {
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
 
/* #include <c_string.h> */
/* #include <string.h> */
/* #include <assert.h> */
 
#ifndef SQLITE_AMALGAMATION
......@@ -182624,7 +182624,7 @@ static int sqlite3Fts5UnicodeFold(int c, int bRemoveDiacritic);
** The following is the concatenation of all %include directives from the
** input grammar file:
*/
/* #include <c_stdio.h> */
/* #include <stdio.h> */
/************ Begin %include sections from the grammar ************************/
 
/* #include "fts5Int.h" */
......@@ -182929,7 +182929,7 @@ struct fts5yyParser {
typedef struct fts5yyParser fts5yyParser;
 
#ifndef NDEBUG
/* #include <c_stdio.h> */
/* #include <stdio.h> */
static FILE *fts5yyTraceFILE = 0;
static char *fts5yyTracePrompt = 0;
#endif /* NDEBUG */
......@@ -185988,7 +185988,7 @@ static void *sqlite3Fts5ParserAlloc(void *(*mallocProc)(u64));
static void sqlite3Fts5ParserFree(void*, void (*freeProc)(void*));
static void sqlite3Fts5Parser(void*, int, Fts5Token, Fts5Parse*);
#ifndef NDEBUG
/* #include <c_stdio.h> */
/* #include <stdio.h> */
static void sqlite3Fts5ParserTrace(FILE*, char*);
#endif
 
......@@ -36,9 +36,6 @@ endif
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../libc
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
......@@ -3,7 +3,7 @@
*/
#include "task/task.h"
#include "mem.h"
#include "c_stdio.h"
#include <stdio.h>
#define TASK_HANDLE_MONIKER 0x68680000
#define TASK_HANDLE_MASK 0xFFF80000
......
......@@ -38,13 +38,6 @@ STD_CFLAGS=-std=gnu11 -Wimplicit
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ./include
INCLUDES += -I ../include
INCLUDES += -I ../../include
INCLUDES += -I ../libc
INCLUDES += -I ../platform
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
......@@ -33,7 +33,7 @@
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**************************************************************************/
#include "c_types.h"
#include <stdint.h>
#ifndef _TSL2561_H_
#define _TSL2561_H_
......
......@@ -24,7 +24,7 @@ STD_CFLAGS=-std=gnu11 -Wimplicit
# makefile at its root level - these are then overridden
# for a subtree within the makefile rooted therein
#
DEFINES += -DU8X8_USE_PINS -DU8G2_USE_LARGE_FONTS
DEFINES += -DU8X8_USE_PINS -DU8G2_USE_LARGE_FONTS -DU8X8_WITH_USER_PTR
#############################################################
# Recursion Magic - Don't touch this!!
......@@ -40,11 +40,7 @@ DEFINES += -DU8X8_USE_PINS -DU8G2_USE_LARGE_FONTS
CSRCS := $(wildcard u8g2/src/clib/*.c *.c)
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I u8g2/src/clib
INCLUDES += -I ../libc
INCLUDES += -I ../lua
INCLUDES += -I ../platform
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
Subproject commit d4da8254220adf39db44faa52a0842967095d230
Subproject commit 2ee84c8f14adaa8fd1ebfe091c4de348c5474b18
......@@ -6,7 +6,7 @@
#include "u8x8_nodemcu_hal.h"
#include "c_stdlib.h"
#include <stdlib.h>
static const u8x8_display_info_t u8x8_fbrle_display_info =
......@@ -104,7 +104,7 @@ static uint8_t u8x8_d_fbrle(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
uint8_t *buf = ((u8x8_tile_t *)arg_ptr)->tile_ptr;
struct fbrle_line *fbrle_line;
if (!(fbrle_line = (struct fbrle_line *)c_malloc( fbrle_line_size ))) {
if (!(fbrle_line = (struct fbrle_line *)malloc( fbrle_line_size ))) {
break;
}
......@@ -147,7 +147,7 @@ static uint8_t u8x8_d_fbrle(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *ar
}
}
c_free( fbrle_line );
free( fbrle_line );
}
break;
......
......@@ -40,10 +40,7 @@ DEFINES += -DUSE_PIN_LIST
CSRCS := $(wildcard ucg/src/clib/*.c *.c)
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ucg/src/clib
INCLUDES += -I ./
INCLUDES += -I ../libc
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
......@@ -38,12 +38,6 @@ DEFINES += -DESP_INIT_DATA_DEFAULT="\"$(SDK_DIR)/bin/esp_init_data_default_v05.b
# Required for each makefile to inherit from the parent
#
INCLUDES := $(INCLUDES) -I $(PDIR)include
INCLUDES += -I ./
INCLUDES += -I ../../include/ets
INCLUDES += -I ../libc
INCLUDES += -I ../platform
INCLUDES += -I ../lua
INCLUDES += -I ../spiffs
PDIR := ../$(PDIR)
sinclude $(PDIR)Makefile
......
......@@ -39,9 +39,10 @@
// overflows. The downside is that it does not implement a wide range
// of formatting characters.
#include <c_stdlib.h>
#include <c_types.h>
#include <c_stdarg.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <stddef.h>
#include "driver/uart.h"
static void kprintn (void (*)(const char), uint32_t, int, int, char);
......
/*
* Copyright 2015 Dius Computing Pty Ltd. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the
* distribution.
* - Neither the name of the copyright holders nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* @author Johny Mattsson <jmattsson@dius.com.au>
*/
#include "user_exceptions.h"
static exception_handler_fn load_store_handler;
void load_non_32_wide_handler (struct exception_frame *ef, uint32_t cause)
{
uint32_t val, insn;
(void)cause; /* If this is not EXCCAUSE_LOAD_STORE_ERROR you're doing it wrong! */
asm (
/*
* Move the aligned content of the exception addr to val
*/
"rsr a6, EXCVADDR;" /* read out the faulting address */
"movi a5, ~3;" /* prepare a mask for the EPC */
"and a5, a5, a6;" /* apply mask for 32bit aligned base */
"l32i a5, a5, 0;" /* load aligned value */
"ssa8l a6;" /* set up shift register for value */
"srl %[val], a5;" /* shift left to align value */
/* we are done with a6 = EXCVADDR */
/*
* Move the aligned instruction to insn
*/
"movi a5, ~3;" /* prepare a mask for the insn */
"and a6, a5, %[epc];" /* apply mask for 32bit aligned base */
"l32i a5, a6, 0;" /* load part 1 */
"l32i a6, a6, 4;" /* load part 2 */
"ssa8l %[epc];" /* set up shift register for src op */
"src %[op], a6, a5;" /* right shift to get faulting instruction */
:[val]"=r"(val), [op]"=r"(insn)
:[epc]"r"(ef->epc)
:"a5", "a6"
);
/* These instructions have the format 0xADSBII where AB = opcode and D = dest reg */
uint32_t regno = (insn>>4)&0x0f; /* pick out nibble D*/
uint32_t opcode = (uint8_t) (((insn>>12)<<4)|(insn&0xf)); /* and nibbles AB */
#define L8UI 0x02u
#define L16UI 0x12u
#define L16SI 0x92u
if (opcode == L8UI) { /* L8UI */
val = (uint8_t) val;
} else {
val = (uint16_t) val; /* assume L16SI or L16UI */
if (opcode == L16SI) {
val = (unsigned)((int)((sint16_t)val)); /* force signed 16->32 bit */
} else if (opcode != L16UI) {
/*
* Anything other than L8UI, L16SI or L16UI then chain to the next handler
* if set (typically a remote GDB break). Otherwise execute the default action
* which is to trigger a system break and hang if the break doesn't get handled
*/
if (load_store_handler) {
load_store_handler(NULL, 0 /* ef , cause */);
return;
} else {
asm ("break 1, 1");
while (1) {}
}
}
}
ef->a_reg[regno ? regno-1: regno] = val; /* carry out the load */
ef->epc += 3; /* resume at following instruction */
}
/**
* The SDK's user_main function installs a debugging handler regardless
* of whether there's a proper handler installed for EXCCAUSE_LOAD_STORE_ERROR,
* which of course breaks everything if we allow that to go through. As such,
* we use the linker to wrap that call and stop the SDK from shooting itself in
* its proverbial foot. We do save the EXCCAUSE_LOAD_STORE_ERROR handler so that
* we can chain to it above.
*/
exception_handler_fn TEXT_SECTION_ATTR
__wrap__xtos_set_exception_handler (uint32_t cause, exception_handler_fn fn)
{
if (cause != EXCCAUSE_LOAD_STORE_ERROR)
__real__xtos_set_exception_handler (cause, fn);
else
load_store_handler = fn;
}
......@@ -10,13 +10,12 @@
*******************************************************************************/
#include "lua.h"
#include "platform.h"
#include "c_string.h"
#include "c_stdlib.h"
#include "c_stdio.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "vfs.h"
#include "flash_api.h"
#include "user_interface.h"
#include "user_exceptions.h"
#include "user_modules.h"
#include "ets_sys.h"
......@@ -24,6 +23,7 @@
#include "task/task.h"
#include "mem.h"
#include "espconn.h"
#include "sections.h"
#ifdef LUA_USE_MODULES_RTCTIME
#include "rtc/rtctime.h"
......@@ -33,77 +33,246 @@ static task_handle_t input_sig;
static uint8 input_sig_flag = 0;
/* Contents of esp_init_data_default.bin */
extern const uint32_t init_data[];
extern const uint32_t init_data_end[];
extern const uint32_t init_data[], init_data_end[];
#define INIT_DATA_SIZE ((init_data_end - init_data)*sizeof(uint32_t))
__asm__(
/* Place in .text for same reason as user_start_trampoline */
".section \".rodata.dram\"\n"
".align 4\n"
"init_data:\n"
".incbin \"" ESP_INIT_DATA_DEFAULT "\"\n"
"init_data: .incbin \"" ESP_INIT_DATA_DEFAULT "\"\n"
"init_data_end:\n"
".previous\n"
);
/* Note: the trampoline *must* be explicitly put into the .text segment, since
* by the time it is invoked the irom has not yet been mapped. This naturally
* also goes for anything the trampoline itself calls.
extern const char _irom0_text_start[], _irom0_text_end[], _flash_used_end[];
#define IROM0_SIZE (_irom0_text_end - _irom0_text_start)
#define PRE_INIT_TEXT_ATTR __attribute__((section(".p3.pre_init")))
#define IROM_PTABLE_ATTR __attribute__((section(".irom0.ptable")))
#define USED_ATTR __attribute__((used))
#define PARTITION(n) (SYSTEM_PARTITION_CUSTOMER_BEGIN + n)
#define SIZE_256K 0x00040000
#define SIZE_1024K 0x00100000
#define PT_CHUNK 0x00002000
#define PT_ALIGN(n) ((n + (PT_CHUNK-1)) & (~((PT_CHUNK-1))))
#define FLASH_BASE_ADDR ((char *) 0x40200000)
#define NODEMCU_PARTITION_EAGLEROM PLATFORM_PARTITION(NODEMCU_EAGLEROM_PARTITION)
#define NODEMCU_PARTITION_IROM0TEXT PLATFORM_PARTITION(NODEMCU_IROM0TEXT_PARTITION)
#define NODEMCU_PARTITION_LFS PLATFORM_PARTITION(NODEMCU_LFS0_PARTITION)
#define NODEMCU_PARTITION_SPIFFS PLATFORM_PARTITION(NODEMCU_SPIFFS0_PARTITION)
#define MAX_PARTITIONS 20
#define WORDSIZE sizeof(uint32_t)
#define PTABLE_SIZE 7 /** THIS MUST BE MATCHED TO NO OF PT ENTRIES BELOW **/
struct defaultpt {
platform_rcr_t hdr;
partition_item_t pt[PTABLE_SIZE+1]; // the +! is for the endmarker
};
#define PT_LEN (NUM_PARTITIONS*sizeof(partition_item_t))
/*
* See app/platform/platform.h for how the platform reboot config records are used
* and these records are allocated. The first record is a default partition table
* and this is statically declared in compilation below.
*/
void TEXT_SECTION_ATTR user_start_trampoline (void)
{
__real__xtos_set_exception_handler (
EXCCAUSE_LOAD_STORE_ERROR, load_non_32_wide_handler);
static const struct defaultpt rompt IROM_PTABLE_ATTR USED_ATTR = {
.hdr = {.len = sizeof(struct defaultpt)/WORDSIZE - 1,
.id = PLATFORM_RCR_PT},
.pt = {
{ NODEMCU_PARTITION_EAGLEROM, 0x00000, 0x0B000},
{ SYSTEM_PARTITION_RF_CAL, 0x0B000, 0x1000},
{ SYSTEM_PARTITION_PHY_DATA, 0x0C000, 0x1000},
{ SYSTEM_PARTITION_SYSTEM_PARAMETER, 0x0D000, 0x3000},
{ NODEMCU_PARTITION_IROM0TEXT, 0x10000, 0x0000},
{ NODEMCU_PARTITION_LFS, 0x0, LUA_FLASH_STORE},
{ NODEMCU_PARTITION_SPIFFS, 0x0, SPIFFS_MAX_FILESYSTEM_SIZE},
{0,(uint32_t) &_irom0_text_end,0}
}
};
//TODO: map the TLS server and client certs into NODEMCU_TLSCERT_PARTITION
static uint32_t first_time_setup(partition_item_t *pt, uint32_t n, uint32_t flash_size);
static void phy_data_setup (partition_item_t *pt, uint32_t n);
extern void _ResetHandler(void);
/*
* The non-OS SDK prolog has been fundamentally revised in V3. See SDK EN document
* Partition Table.md for further discussion. This version of user_main.c is a
* complete rework aligned to V3, with the redundant pre-V3 features removed.
*
* SDK V3 significantly reduces the RAM footprint required by the SDK and introduces
* the use of a partition table (PT) to control flash allocation. The NodeMCU uses
* this PT for overall allocation of its flash resources. The non_OS SDK calls the
* user_pre_init() entry to do all of this startup configuration. Note that this
* runs with Icache enabled -- that is the IROM0 partition is already mapped to the
* address space at 0x40210000 and so that most SDK services are available, such
* as system_get_flash_size_map() which returns the valid flash size (including the
* 8Mb and 16Mb variants).
*
* The first 4K page of IROM0 (flash offset 0x10000) is used to maintain a set of
* Resource Communication Records (RCR) for inter-boot configuration using a NAND
* write-once algo (see app/platform/platform.h). One of the current records is the
* SDK3.0 PT. This build statically compiles in an initial version at the start of
* the PT, with a {0, _irom0_text_end,0} marker as the last record and some fields
* also that need to be recomputed at runtime. This version is either replaced
* by first boot processing after provisioning, or by a node.setpartitiontable()
* API call. These replacement PTs are complete and can be passed directly for use
* by the non-OS SDK.
*
* Note that we have released a host PC-base python tool, nodemcu-partition.py, to
* configure the PT, etc during provisioning.
*/
void user_pre_init(void) {
#ifdef LUA_USE_MODULES_RTCTIME
// Note: Keep this as close to call_user_start() as possible, since it
// is where the cpu clock actually gets bumped to 80MHz.
rtctime_early_startup ();
rtctime_early_startup ();
#endif
partition_item_t *rcr_pt = NULL, *pt;
enum flash_size_map fs_size_code = system_get_flash_size_map();
// Flash size lookup is SIZE_256K*2^N where N is as follows (see SDK/user_interface.h)
/* 0 1 2 3 4 5 6 7 8 9 */
/* ½M ¼M 1M 2M 4M 2M 4M 4M 8M 16M */
static char flash_size_scaler[] = "\001\000\002\003\004\003\004\004\005\006";
uint32_t flash_size = SIZE_256K << flash_size_scaler[fs_size_code];
uint32_t i = platform_rcr_read(PLATFORM_RCR_PT, (void **) &rcr_pt);
uint32_t n = i / sizeof(partition_item_t);
if (flash_size < SIZE_1024K) {
os_printf("Flash size (%u) too small to support NodeMCU\n", flash_size);
return;
} else {
os_printf("system SPI FI size:%u, Flash size: %u\n", fs_size_code, flash_size );
}
/* Re-implementation of default init data deployment. The SDK does not
* appear to be laying down its own version of init data anymore, so
* we have to do it again. To see whether we need to, we read out
* the flash size and do a test for esp_init_data based on that size.
* If it's missing, we need to initialize it *right now* before the SDK
* starts up and gets stuck at "rf_cal[0] !=0x05,is 0xFF".
* If the size byte is wrong, then we'll end up fixing up the init data
* again on the next boot, after we've corrected the size byte.
* Only remaining issue is lack of spare code bytes in iram, so this
* is deliberately quite terse and not as readable as one might like.
*/
SPIFlashInfo sfi;
// enable operations on >4MB flash chip
extern SpiFlashChip * flashchip;
uint32 orig_chip_size = flashchip->chip_size;
flashchip->chip_size = FLASH_SIZE_16MBYTE;
SPIRead (0, (uint32_t *)(&sfi), sizeof (sfi)); // Cache read not enabled yet, safe to use
// handle all size entries
switch (sfi.size) {
case 0: sfi.size = 1; break; // SIZE_4MBIT
case 1: sfi.size = 0; break; // SIZE_2MBIT
case 5: sfi.size = 3; break; // SIZE_16MBIT_8M_8M
case 6: // fall-through
case 7: sfi.size = 4; break; // SIZE_32MBIT_8M_8M, SIZE_32MBIT_16M_16M
case 8: sfi.size = 5; break; // SIZE_64MBIT
case 9: sfi.size = 6; break; // SIZE_128MBIT
default: break;
}
uint32_t flash_end_addr = (256 * 1024) << sfi.size;
uint32_t init_data_hdr = 0xffffffff;
uint32_t init_data_addr = flash_end_addr - 4 * SPI_FLASH_SEC_SIZE;
SPIRead (init_data_addr, &init_data_hdr, sizeof (init_data_hdr));
if (init_data_hdr == 0xffffffff)
{
SPIEraseSector (init_data_addr);
SPIWrite (init_data_addr, init_data, 4 * (init_data_end - init_data));
}
pt = os_malloc_iram(i); // We will work on and register a copy of the PT in iRAM
// Return if anything is amiss; The SDK will halt if the PT hasn't been registered
if ( !rcr_pt || !pt || n * sizeof(partition_item_t) != i) {
return;
}
os_memcpy(pt, rcr_pt, i);
if (pt[n-1].type == 0) {
// If the last PT entry is a {0,XX,0} end marker, then we need first time setup
n = first_time_setup(pt, n-1, flash_size); // return n because setup might shrink the PT
}
if (platform_rcr_read(PLATFORM_RCR_PHY_DATA, NULL)!=0) {
phy_data_setup(pt, n);
}
// Now register the partition and return
// for (i=0;i<n;i++) os_printf("P%d: %3d %06x %06x\n", i, pt[i].type, pt[i].addr, pt[i].size);
if( fs_size_code > 1 && system_partition_table_regist(pt, n, fs_size_code)) {
return;
}
os_printf("Invalid system partition table\n");
while (1) {};
}
/*
* If the PLATFORM_RCR_PT record doesn't exist then the PHY_DATA partition might
* not have been initialised. This must be set to the proper default init data
* otherwise the SDK will halt on the "rf_cal[0] !=0x05,is 0xFF" error.
*/
static void phy_data_setup (partition_item_t *pt, uint32_t n) {
uint8_t header[sizeof(uint32_t)] = {0};
int i;
for (i = 0; i < n; i++) {
if (pt[i].type == SYSTEM_PARTITION_PHY_DATA) {
uint32_t addr = pt[i].addr;
platform_s_flash_read(header, addr, sizeof(header));
if (header[0] != 0x05) {
uint32_t sector = pt[i].addr/INTERNAL_FLASH_SECTOR_SIZE;
if (platform_flash_erase_sector(sector) == PLATFORM_OK) {
os_printf("Writing Init Data to 0x%08x\n",addr);
platform_s_flash_write(init_data, addr, INIT_DATA_SIZE);
}
}
// flag setup complete so we don't retry this every boot
platform_rcr_write(PLATFORM_RCR_PHY_DATA, &addr, 0);
return;
}
}
// If the PHY_DATA doesn't exist or the write fails then the
// SDK will raise the rf_cal error anyway, so just return.
}
/*
* First time setup does the one-off PT calculations and checks. If these are OK,
* then writes back a new RCR for the updated PT and triggers a reboot. It returns
* on failure.
*/
static uint32_t first_time_setup(partition_item_t *pt, uint32_t n, uint32_t flash_size) {
int i, j, last = 0, newn = n;
/*
* Scan down the PT adjusting and 0 entries to sensible defaults. Also delete any
* zero-sized partitions (as the SDK barfs on these).
*/
for (i = 0, j = 0; i < n; i ++) {
partition_item_t *p = pt + i;
switch (p->type) {
case NODEMCU_PARTITION_IROM0TEXT:
// If the IROM0 partition size is 0 then compute from the IROM0_SIZE. Note
// that the size in the end-marker is used by the nodemcu-partition.py
// script and not here.
if (p->size == 0) {
p->size = PT_ALIGN(IROM0_SIZE);
}
break;
case NODEMCU_PARTITION_LFS:
// Properly align the LFS partition size and make it consecutive to
// the previous partition.
p->size = PT_ALIGN(p->size);
if (p->addr == 0)
p->addr = last;
break;
case NODEMCU_PARTITION_SPIFFS:
if (p->size == ~0x0 && p->addr == 0) {
// This allocate all the remaining flash to SPIFFS
p->addr = last;
p->size = flash_size - last;
} else if (p->size == ~0x0) {
p->size = flash_size - p->addr;
} else if (p->addr == 0) {
// if the is addr not specified then start SPIFFS at 1Mb
// boundary if the size will fit otherwise make it consecutive
// to the previous partition.
p->addr = (p->size <= flash_size - 0x100000) ? 0x100000 : last;
}
}
if (p->size == 0) {
// Delete 0-sized partitions as the SDK barfs on these
newn--;
} else {
// Do consistency tests on the partition
if (p->addr & (INTERNAL_FLASH_SECTOR_SIZE - 1) ||
p->size & (INTERNAL_FLASH_SECTOR_SIZE - 1) ||
p->addr < last ||
p->addr + p->size > flash_size) {
os_printf("Partition %u invalid alignment\n", i);
while(1) {/*system_soft_wdt_feed ();*/}
}
if (j < i) // shift the partition down if we have any deleted slots
pt[j] = *p;
//os_printf("Partition %d: %04x %06x %06x\n", j, p->type, p->addr, p->size);
j++;
last = p->addr + p->size;
}
}
// revert temporary setting
flashchip->chip_size = orig_chip_size;
platform_rcr_write(PLATFORM_RCR_PT, pt, newn*sizeof(partition_item_t));
ets_delay_us(5000);
_ResetHandler(); // Trigger reset; the new PT will be loaded on reboot
}
call_user_start ();
uint32 ICACHE_RAM_ATTR user_iram_memory_is_enabled(void) {
return FALSE; // NodeMCU runs like a dog if iRAM is enabled
}
// +================== New task interface ==================+
......@@ -138,33 +307,6 @@ void nodemcu_init(void) {
NODE_DBG("Can not init platform for modules.\n");
return;
}
uint32_t size_detected = flash_detect_size_byte();
uint32_t size_from_rom = flash_rom_get_size_byte();
if( size_detected != size_from_rom ) {
NODE_ERR("Self adjust flash size. 0x%x (ROM) -> 0x%x (Detected)\n",
size_from_rom, size_detected);
// Fit hardware real flash size.
flash_rom_set_size_byte(size_detected);
system_restart ();
// Don't post the start_lua task, we're about to reboot...
return;
}
#ifdef BUILD_SPIFFS
if (!vfs_mount("/FLASH", 0)) {
// Failed to mount -- try reformat
dbg_printf("Formatting file system. Please wait...\n");
if (!vfs_format()) {
NODE_ERR( "\n*** ERROR ***: unable to format. FS might be compromised.\n" );
NODE_ERR( "It is advised to re-flash the NodeMCU image.\n" );
}
// Note that fs_format leaves the file system mounted
}
// test_spiffs();
#endif
// endpoint_setup();
if (!task_post_low(task_get_id(start_lua),'s'))
NODE_ERR("Failed to post the start_lua task!\n");
}
......@@ -179,59 +321,6 @@ void user_rf_pre_init(void)
}
#endif
/******************************************************************************
* FunctionName : user_rf_cal_sector_set
* Description : SDK just reversed 4 sectors, used for rf init data and paramters.
* We add this function to force users to set rf cal sector, since
* we don't know which sector is free in user's application.
* sector map for last several sectors : ABCCC
* A : rf cal
* B : rf init data
* C : sdk parameters
* Parameters : none
* Returns : rf cal sector
*******************************************************************************/
uint32
user_rf_cal_sector_set(void)
{
enum flash_size_map size_map = system_get_flash_size_map();
uint32 rf_cal_sec = 0;
switch (size_map) {
case FLASH_SIZE_4M_MAP_256_256:
rf_cal_sec = 128 - 5;
break;
case FLASH_SIZE_8M_MAP_512_512:
rf_cal_sec = 256 - 5;
break;
case FLASH_SIZE_16M_MAP_512_512:
case FLASH_SIZE_16M_MAP_1024_1024:
rf_cal_sec = 512 - 5;
break;
case FLASH_SIZE_32M_MAP_512_512:
case FLASH_SIZE_32M_MAP_1024_1024:
case FLASH_SIZE_32M_MAP_2048_2048:
rf_cal_sec = 1024 - 5;
break;
case FLASH_SIZE_64M_MAP_1024_1024:
rf_cal_sec = 2048 - 5;
break;
case FLASH_SIZE_128M_MAP_1024_1024:
rf_cal_sec = 4096 - 5;
break;
default:
rf_cal_sec = 0;
break;
}
return rf_cal_sec;
}
/******************************************************************************
* FunctionName : user_init
......@@ -241,6 +330,7 @@ user_rf_cal_sector_set(void)
*******************************************************************************/
void user_init(void)
{
#ifdef LUA_USE_MODULES_RTCTIME
rtctime_late_startup ();
#endif
......@@ -255,3 +345,18 @@ void user_init(void)
#endif
system_init_done_cb(nodemcu_init);
}
#if 0
/*
* The SDK now establishes exception handlers for EXCCAUSE errors: ILLEGAL,
* INSTR_ERROR, LOAD_STORE_ERROR, PRIVILEGED, UNALIGNED, LOAD_PROHIBITED,
* STORE_PROHIBITED. These handlers are established in SDK/app_main.c.
* LOAD_STORE_ERROR is handled by SDK/user_exceptions.o:load_non_32_wide_handler()
* which is a fork of our version. The remaining are handled by a static function
* at SDK:app+main.c:offset 0x0348. This wrappoer is only needed for debugging.
*/
void __real__xtos_set_exception_handler (uint32_t cause, exception_handler_fn fn);
void __wrap__xtos_set_exception_handler (uint32_t cause, exception_handler_fn fn) {
os_printf("Exception handler %x %x\n", cause, fn);
__real__xtos_set_exception_handler (cause, fn);
}
#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