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
/* /*
* Copyright 2015 Dius Computing Pty Ltd. All rights reserved. * Copyright 2015 Dius Computing Pty Ltd. All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
* are met: * are met:
* *
* - Redistributions of source code must retain the above copyright * - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. * notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright * - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the * documentation and/or other materials provided with the
* distribution. * distribution.
* - Neither the name of the copyright holders nor the names of * - Neither the name of the copyright holders nor the names of
* its contributors may be used to endorse or promote products derived * its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission. * from this software without specific prior written permission.
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE. * OF THE POSSIBILITY OF SUCH DAMAGE.
* *
* @author Johny Mattsson <jmattsson@dius.com.au> * @author Johny Mattsson <jmattsson@dius.com.au>
*/ */
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #ifdef _MSC_VER
#include <fcntl.h> #include "getopt.h" /* local copy from MingW project */
#include <getopt.h> #include <io.h>
#include <sys/mman.h> #define STDIN_FILENO 0
#include <errno.h> #define STDOUT_FILENO 1
#include "spiffs.h" #define STDERR_FILENO 2
#define NO_CPU_ESP8266_INCLUDE typedef ptrdiff_t off_t;
#include "../platform/cpu_esp8266.h" #else
#include <unistd.h>
static spiffs fs; #include <getopt.h>
static uint8_t *flash; #include <sys/mman.h>
#endif
static int retcode = 0; #include <fcntl.h>
#include <errno.h>
#define LOG_PAGE_SIZE 256 #include "spiffs.h"
#define NO_CPU_ESP8266_INCLUDE
// If the caclulated size is this or less, then use smaller blocks #include "../platform/cpu_esp8266.h"
// (1 page) rather than the normal 2 pages. This gives a little bit
// more flexibility for the file system, at the expense of a bit of static spiffs fs;
// efficiency static uint8_t *flash;
#define SMALL_FILESYSTEM (128 * 1024)
static int retcode = 0;
static int delete_on_die = 0;
static const char *delete_list[10]; #define LOG_PAGE_SIZE 256
static int delete_list_index = 0;
// If the caclulated size is this or less, then use smaller blocks
static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2]; // (1 page) rather than the normal 2 pages. This gives a little bit
static u8_t spiffs_fds[32*4]; // more flexibility for the file system, at the expense of a bit of
// efficiency
static s32_t flash_read (u32_t addr, u32_t size, u8_t *dst) { #define SMALL_FILESYSTEM (128 * 1024)
memcpy (dst, flash + addr, size);
return SPIFFS_OK; static int delete_on_die = 0;
} static const char *delete_list[10];
static int delete_list_index = 0;
static s32_t flash_write (u32_t addr, u32_t size, u8_t *src) {
memcpy (flash + addr, src, size); static u8_t spiffs_work_buf[LOG_PAGE_SIZE*2];
return SPIFFS_OK; static u8_t spiffs_fds[32*4];
}
static s32_t flash_read (u32_t addr, u32_t size, u8_t *dst) {
static s32_t flash_erase (u32_t addr, u32_t size) { memcpy (dst, flash + addr, size);
memset (flash + addr, 0xff, size); return SPIFFS_OK;
return SPIFFS_OK; }
}
static s32_t flash_write (u32_t addr, u32_t size, u8_t *src) {
memcpy (flash + addr, src, size);
static void die (const char *what) return SPIFFS_OK;
{ }
if (errno == 0) {
fprintf(stderr, "%s: fatal error\n", what); static s32_t flash_erase (u32_t addr, u32_t size) {
} else { memset (flash + addr, 0xff, size);
perror (what); return SPIFFS_OK;
} }
if (delete_on_die) {
const char **p = delete_list;
while (*p) { static void die (const char *what)
unlink(*p); {
p++; if (errno == 0) {
} fprintf(stderr, "%s: fatal error\n", what);
} } else {
exit (1); perror (what);
} }
if (delete_on_die) {
const char **p = delete_list;
static void list (void) while (*p) {
{ unlink(*p);
spiffs_DIR dir; p++;
if (!SPIFFS_opendir (&fs, "/", &dir)) }
die ("spiffs_opendir"); }
struct spiffs_dirent de; exit (1);
while (SPIFFS_readdir (&dir, &de)) }
{
static const char types[] = "?fdhs"; // file, dir, hardlink, softlink
char name[sizeof(de.name)+1] = { 0 }; static void list (void)
memcpy (name, de.name, sizeof(de.name)); {
printf("%c %6u %s\n", types[de.type], de.size, name); spiffs_DIR dir;
} if (!SPIFFS_opendir (&fs, "/", &dir))
SPIFFS_closedir (&dir); die ("spiffs_opendir");
} struct spiffs_dirent de;
while (SPIFFS_readdir (&dir, &de))
{
static void cat (char *fname) static const char types[] = "?fdhs"; // file, dir, hardlink, softlink
{ char name[sizeof(de.name)+1] = { 0 };
spiffs_file fh = SPIFFS_open (&fs, fname, SPIFFS_RDONLY, 0); memcpy (name, de.name, sizeof(de.name));
char buff[512]; printf("%c %6u %s\n", types[de.type], de.size, name);
s32_t n; }
while ((n = SPIFFS_read (&fs, fh, buff, sizeof (buff))) > 0) SPIFFS_closedir (&dir);
write (STDOUT_FILENO, buff, n); }
SPIFFS_close (&fs, fh);
}
static void cat (char *fname)
{
static void import (char *src, char *dst) spiffs_file fh = SPIFFS_open (&fs, fname, SPIFFS_RDONLY, 0);
{ char buff[512];
int fd = open (src, O_RDONLY); s32_t n;
if (fd < 0) while ((n = SPIFFS_read (&fs, fh, buff, sizeof (buff))) > 0)
die (src); write (STDOUT_FILENO, buff, n);
SPIFFS_close (&fs, fh);
spiffs_file fh = SPIFFS_open (&fs, dst, SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_WRONLY, 0); }
if (fh < 0)
die ("spiffs_open");
static void import (char *src, char *dst)
char buff[16384]; {
s32_t n; int fd = open (src, O_RDONLY);
while ((n = read (fd, buff, sizeof (buff))) > 0) if (fd < 0)
if (SPIFFS_write (&fs, fh, buff, n) < 0) die (src);
die ("spiffs_write");
spiffs_file fh = SPIFFS_open (&fs, dst, SPIFFS_CREAT | SPIFFS_TRUNC | SPIFFS_WRONLY, 0);
if (SPIFFS_close (&fs, fh) < 0) if (fh < 0)
die("spiffs_close"); die ("spiffs_open");
close (fd);
} char buff[16384];
s32_t n;
while ((n = read (fd, buff, sizeof (buff))) > 0)
static void export (char *src, char *dst) if (SPIFFS_write (&fs, fh, buff, n) < 0)
{ die ("spiffs_write");
spiffs_file fh = SPIFFS_open (&fs, src, SPIFFS_RDONLY, 0);
if (fh < 0) if (SPIFFS_close (&fs, fh) < 0)
die ("spiffs_open"); die("spiffs_close");
close (fd);
int fd = open (dst, O_CREAT | O_TRUNC | O_WRONLY, 0664); }
if (fd < 0)
die (dst);
static void export (char *src, char *dst)
char buff[512]; {
s32_t n; spiffs_file fh = SPIFFS_open (&fs, src, SPIFFS_RDONLY, 0);
while ((n = SPIFFS_read (&fs, fh, buff, sizeof (buff))) > 0) if (fh < 0)
if (write (fd, buff, n) < 0) die ("spiffs_open");
die ("write");
int fd = open (dst, O_CREAT | O_TRUNC | O_WRONLY, 0664);
SPIFFS_close (&fs, fh); if (fd < 0)
close (fd); die (dst);
}
char buff[512];
s32_t n;
char *trim (char *in) while ((n = SPIFFS_read (&fs, fh, buff, sizeof (buff))) > 0)
{ if (write (fd, buff, n) < 0)
if (!in) die ("write");
return "";
SPIFFS_close (&fs, fh);
char *out = 0; close (fd);
while (*in) }
{
if (!out && !isspace (*in))
out = in; char *trim (char *in)
++in; {
} if (!in)
if (!out) return "";
return "";
while (--in > out && isspace (*in)) char *out = 0;
; while (*in)
in[1] = 0; {
return out; if (!out && !isspace (*in))
} out = in;
++in;
}
void syntax (void) if (!out)
{ return "";
fprintf (stderr, while (--in > out && isspace (*in))
"Syntax: spiffsimg -f <filename> [-d] [-o <locationfilename>] [-c size] [-S flashsize] [-U usedsize] [-l | -i | -r <scriptname> ]\n\n" ;
); in[1] = 0;
exit (1); return out;
} }
static size_t getsize(const char *s)
{ void syntax (void)
char *end = 0; {
size_t val = strtoul(s, &end, 0); fprintf (stderr,
"Syntax: spiffsimg -f <filename> [-d] [-o <locationfilename>] [-c size] [-S flashsize] [-U usedsize] [-l | -i | -r <scriptname> ]\n\n"
if (end) { );
int factor; exit (1);
if (*end == 'k' || *end == 'K') { }
factor = 1 << 10;
end++; static size_t getsize(const char *s)
} else if (*end == 'm' || *end == 'M') { {
factor = 1 << 20; char *end = 0;
end++; size_t val = strtoul(s, &end, 0);
} else {
factor = 1; if (end) {
} int factor;
// Capital B is bytes if (*end == 'k' || *end == 'K') {
if (*end == 'B') { factor = 1 << 10;
factor = factor << 3; end++;
} } else if (*end == 'm' || *end == 'M') {
// we want bytes factor = 1 << 20;
val = (val * factor) / 8; end++;
} } else {
factor = 1;
return val; }
} // Capital B is bytes
if (*end == 'B') {
int main (int argc, char *argv[]) factor = factor << 3;
{ }
if (argc == 1) // we want bytes
syntax (); val = (val * factor) / 8;
}
int opt;
const char *fname = 0; return val;
bool create = false; }
enum { CMD_NONE, CMD_LIST, CMD_INTERACTIVE, CMD_SCRIPT } command = CMD_NONE;
int sz = 0; int main (int argc, char *argv[])
const char *script_name = 0; {
const char *resolved = 0; if (argc == 1)
int flashsize = 0; syntax ();
int used = 0;
while ((opt = getopt (argc, argv, "do:f:c:lir:S:U:")) != -1) int opt;
{ const char *fname = 0;
switch (opt) bool create = false;
{ enum { CMD_NONE, CMD_LIST, CMD_INTERACTIVE, CMD_SCRIPT } command = CMD_NONE;
case 'f': fname = optarg; break; int sz = 0;
case 'o': resolved = optarg; break; const char *script_name = 0;
case 'c': create = true; sz = strtol(optarg, 0, 0); break; const char *resolved = 0;
case 'S': create = true; flashsize = getsize(optarg); break; int flashsize = 0;
case 'U': create = true; used = strtol(optarg, 0, 0); break; int used = 0;
case 'd': delete_on_die = 1; break; while ((opt = getopt (argc, argv, "do:f:c:lir:S:U:")) != -1)
case 'l': command = CMD_LIST; break; {
case 'i': command = CMD_INTERACTIVE; break; switch (opt)
case 'r': command = CMD_SCRIPT; script_name = optarg; break; {
default: die ("unknown option"); case 'f': fname = optarg; break;
} case 'o': resolved = optarg; break;
} case 'c': create = true; sz = strtol(optarg, 0, 0); break;
case 'S': create = true; flashsize = getsize(optarg); break;
if (!fname) { case 'U': create = true; used = strtol(optarg, 0, 0); break;
die("Need a filename"); case 'd': delete_on_die = 1; break;
} case 'l': command = CMD_LIST; break;
case 'i': command = CMD_INTERACTIVE; break;
int fd; case 'r': command = CMD_SCRIPT; script_name = optarg; break;
default: die ("unknown option");
if (create) }
{ }
if (!sz) {
if (!flashsize || !used) { if (!fname) {
die("Missing flashSize or Used"); die("Need a filename");
} }
sz = flashsize - used - SYS_PARAM_SEC_NUM * 4096; // This leaves space for the parameter area
if (sz < 0x4000) { #ifdef _MSC_VER
die("Not enough space"); _set_fmode( _O_BINARY ); //change default open mode to binary rather than text
} #endif
if (sz > SMALL_FILESYSTEM) { int fd;
used = (used + 0xffff) & ~0xffff;
} else { if (create)
used = (used + 0x1fff) & ~0x1fff; {
} if (!sz) {
sz = flashsize - used - SYS_PARAM_SEC_NUM * 4096; if (!flashsize || !used) {
} die("Missing flashSize or Used");
sz &= ~(0x1fff); }
sz = flashsize - used - SYS_PARAM_SEC_NUM * 4096; // This leaves space for the parameter area
if (used == 0) { if (sz < 0x4000) {
if (strchr(fname, '%')) { die("Not enough space");
die("Unable to calculate where to put the flash image, and % present in filename"); }
} if (sz > SMALL_FILESYSTEM) {
} used = (used + 0xffff) & ~0xffff;
} else {
char fnamebuff[1024]; used = (used + 0x1fff) & ~0x1fff;
}
sprintf(fnamebuff, fname, used); sz = flashsize - used - SYS_PARAM_SEC_NUM * 4096;
}
delete_list[delete_list_index++] = strdup(fnamebuff);; sz &= ~(0x1fff);
fd = open (fnamebuff, (create ? (O_CREAT | O_TRUNC) : 0) | O_RDWR, 0664);
if (fd == -1) if (used == 0) {
die ("open"); if (strchr(fname, '%')) {
die("Unable to calculate where to put the flash image, and % present in filename");
if (resolved) { }
delete_list[delete_list_index++] = resolved; }
FILE *f = fopen(resolved, "w");
fprintf(f, "0x%x", used); char fnamebuff[1024];
fclose(f);
} sprintf(fnamebuff, fname, used);
if (lseek (fd, sz -1, SEEK_SET) == -1) delete_list[delete_list_index++] = strdup(fnamebuff);;
die ("lseek"); fd = open (fnamebuff, (create ? (O_CREAT | O_TRUNC) : 0) | O_RDWR, 0664);
if (write (fd, "", 1) != 1) if (fd == -1)
die ("write"); die ("open");
}
else { if (resolved) {
fd = open (fname, O_RDWR, 0664); delete_list[delete_list_index++] = resolved;
if (fd == -1) FILE *f = fopen(resolved, "w");
die ("open"); fprintf(f, "0x%x", used);
fclose(f);
if (!sz) }
{
off_t offs = lseek (fd, 0, SEEK_END); if (lseek (fd, sz -1, SEEK_SET) == -1)
if (offs == -1) die ("lseek");
die ("lseek"); if (write (fd, "", 1) != 1)
sz = offs; die ("write");
} }
} else {
fd = open (fname, O_RDWR, 0664);
if (sz & (0x1000 -1)) if (fd == -1)
die ("file size not multiple of erase block size"); die ("open");
flash = mmap (0, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (!sz)
if (!flash) {
die ("mmap"); off_t offs = lseek (fd, 0, SEEK_END);
if (offs == -1)
if (create) die ("lseek");
memset (flash, 0xff, sz); sz = offs;
}
spiffs_config cfg; }
cfg.phys_size = sz;
cfg.phys_addr = 0; if (sz & (0x1000 -1))
cfg.phys_erase_block = 0x1000; die ("file size not multiple of erase block size");
cfg.log_block_size = 0x1000 * (sz > SMALL_FILESYSTEM ? 2 : 1);
cfg.log_page_size = LOG_PAGE_SIZE; #ifdef _MSC_VER
cfg.hal_read_f = flash_read; //We don't have a mmap(), so we simply allocate a file buffer we write out
cfg.hal_write_f = flash_write; //at the end of the program. This also means that we need to let the program
cfg.hal_erase_f = flash_erase; //end normally (i.e. not via Ctrl-C) or else that final write will not happen.
if (cfg.phys_size < 4 * cfg.log_block_size) { //If you are in interactive mode, there is not a command for 'exit', however
die("disk not large enough for four blocks"); //EOF may be used to end the interactive loop by pressing Ctrl-Z, return.
} flash = (uint8_t*)malloc( sz );
if ( lseek( fd, 0, SEEK_SET ) == -1 )
if (SPIFFS_mount (&fs, &cfg, die( "lseek" );
spiffs_work_buf, if ( read( fd, flash, sz ) != sz )
spiffs_fds, die( "write" );
sizeof(spiffs_fds), #else
malloc(65536), 65536, 0) != 0) { flash = mmap( 0, sz, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
if (create) { #endif
if (SPIFFS_format(&fs) != 0) { if (!flash)
die("spiffs_format"); die ("mmap");
}
if (SPIFFS_mount (&fs, &cfg, if (create)
spiffs_work_buf, memset (flash, 0xff, sz);
spiffs_fds,
sizeof(spiffs_fds), spiffs_config cfg;
malloc(65536), 65536, 0) != 0) { cfg.phys_size = sz;
die ("spiffs_mount"); cfg.phys_addr = 0;
} cfg.phys_erase_block = 0x1000;
if (command == CMD_INTERACTIVE) { cfg.log_block_size = 0x1000 * (sz > SMALL_FILESYSTEM ? 2 : 1);
printf("Created filesystem -- size 0x%x, block_size=%d\n", cfg.phys_size, cfg.log_block_size); cfg.log_page_size = LOG_PAGE_SIZE;
} cfg.hal_read_f = flash_read;
} else { cfg.hal_write_f = flash_write;
die ("spiffs_mount"); cfg.hal_erase_f = flash_erase;
} if (cfg.phys_size < 4 * cfg.log_block_size) {
} die("disk not large enough for four blocks");
}
if (command == CMD_NONE)
; // maybe just wanted to create an empty image? if (SPIFFS_mount (&fs, &cfg,
else if (command == CMD_LIST) spiffs_work_buf,
list (); spiffs_fds,
else sizeof(spiffs_fds),
{ malloc(65536), 65536, 0) != 0) {
FILE *in = (command == CMD_INTERACTIVE) ? stdin : fopen (script_name, "r"); if (create) {
if (!in) if (SPIFFS_format(&fs) != 0) {
die ("fopen"); die("spiffs_format");
char buff[128] = { 0 }; }
if (in == stdin) if (SPIFFS_mount (&fs, &cfg,
printf("> "); spiffs_work_buf,
while (fgets (buff, sizeof (buff) -1, in)) spiffs_fds,
{ sizeof(spiffs_fds),
char *line = trim (buff); malloc(65536), 65536, 0) != 0) {
if (!line[0] || line[0] == '#') die ("spiffs_mount");
continue; }
if (strcmp (line, "ls") == 0) if (command == CMD_INTERACTIVE) {
list (); printf("Created filesystem -- size 0x%x, block_size=%d\n", cfg.phys_size, cfg.log_block_size);
else if (strncmp (line, "import ", 7) == 0) }
{ } else {
char *src = 0, *dst = 0; die ("spiffs_mount");
if (sscanf (line +7, " %ms %ms", &src, &dst) != 2) }
{ }
fprintf (stderr, "SYNTAX ERROR: %s\n", line);
retcode = 1; if (command == CMD_NONE)
} ; // maybe just wanted to create an empty image?
else else if (command == CMD_LIST)
import (src, dst); list ();
free (src); else
free (dst); {
} FILE *in = (command == CMD_INTERACTIVE) ? stdin : fopen (script_name, "r");
else if (strncmp (line, "export ", 7) == 0) if (!in)
{ die ("fopen");
char *src = 0, *dst = 0; char buff[128] = { 0 };
if (sscanf (line + 7, " %ms %ms", &src, &dst) != 2) if (in == stdin)
{ printf("> ");
fprintf (stderr, "SYNTAX ERROR: %s\n", line); while (fgets (buff, sizeof (buff) -1, in))
retcode = 1; {
} char *line = trim (buff);
else if (!line[0] || line[0] == '#')
export (src, dst); continue;
free (src); if (strcmp (line, "ls") == 0)
free (dst); list ();
} else if (strncmp (line, "import ", 7) == 0)
else if (strncmp (line, "rm ", 3) == 0) {
{ char *src = 0, *dst = 0;
if (SPIFFS_remove (&fs, trim (line + 3)) < 0) #ifdef _MSC_VER
{ src = (char*)malloc(260 + 1); //MAX_PATH
fprintf (stderr, "FAILED: %s\n", line); dst = (char*)malloc( 260 + 1 );
retcode = 1; if (sscanf (line +7, " %260s %260s", src, dst) != 2)
} #else
} if (sscanf (line +7, " %ms %ms", &src, &dst) != 2)
else if (strncmp (line, "cat ", 4) == 0) #endif
cat (trim (line + 4)); {
else if (strncmp (line, "info", 4) == 0) fprintf (stderr, "SYNTAX ERROR: %s\n", line);
{ retcode = 1;
u32_t total, used; }
if (SPIFFS_info (&fs, &total, &used) < 0) else
{ import (src, dst);
fprintf (stderr, "FAILED: %s\n", line); free (src);
retcode = 1; free (dst);
} }
else else if (strncmp (line, "export ", 7) == 0)
printf ("Total: %u, Used: %u\n", total, used); {
} char *src = 0, *dst = 0;
else #ifdef _MSC_VER
{ src = (char*)malloc( 260 + 1 ); //MAX_PATH
printf ("SYNTAX ERROR: %s\n", line); dst = (char*)malloc( 260 + 1 );
retcode = 1; if ( sscanf( line + 7, " %260s %260s", src, dst ) != 2 )
} #else
if (sscanf (line + 7, " %ms %ms", &src, &dst) != 2)
if (in == stdin) #endif
printf ("> "); {
} fprintf (stderr, "SYNTAX ERROR: %s\n", line);
if (in == stdin) retcode = 1;
printf ("\n"); }
} else
export (src, dst);
SPIFFS_unmount (&fs); free (src);
munmap (flash, sz); free (dst);
close (fd); }
return retcode; else if (strncmp (line, "rm ", 3) == 0)
} {
if (SPIFFS_remove (&fs, trim (line + 3)) < 0)
{
fprintf (stderr, "FAILED: %s\n", line);
retcode = 1;
}
}
else if (strncmp (line, "cat ", 4) == 0)
cat (trim (line + 4));
else if (strncmp (line, "info", 4) == 0)
{
u32_t total, used;
if (SPIFFS_info (&fs, &total, &used) < 0)
{
fprintf (stderr, "FAILED: %s\n", line);
retcode = 1;
}
else
printf ("Total: %u, Used: %u\n", total, used);
}
else
{
printf ("SYNTAX ERROR: %s\n", line);
retcode = 1;
}
if (in == stdin)
printf ("> ");
}
if (in == stdin)
printf ("\n");
}
SPIFFS_unmount (&fs);
#ifdef _MSC_VER
if ( lseek( fd, 0, SEEK_SET ) == -1 )
die( "lseek" );
if ( write( fd, flash, sz ) != sz )
die( "write" );
free( flash );
#else
munmap (flash, sz);
#endif
close (fd);
return retcode;
}
...@@ -10,7 +10,7 @@ typedef uint16_t u16_t; ...@@ -10,7 +10,7 @@ typedef uint16_t u16_t;
typedef int8_t s8_t; typedef int8_t s8_t;
typedef uint8_t u8_t; typedef uint8_t u8_t;
#ifndef __CYGWIN__ #if !defined(__CYGWIN__) && !defined(_MSC_VER)
typedef long long ptrdiff_t; typedef long long ptrdiff_t;
#define offsetof(type, member) __builtin_offsetof (type, member) #define offsetof(type, member) __builtin_offsetof (type, member)
#endif #endif
#!/bin/sh
set -e
echo "Running ci build for linux"
(
cd "$TRAVIS_BUILD_DIR" || exit
export BUILD_DATE=$(date +%Y%m%d)
# build integer firmware
make EXTRA_CCFLAGS="-DLUA_NUMBER_INTEGRAL -DBUILD_DATE='\"'$BUILD_DATE'\"'"
cd bin/ || exit
file_name_integer="nodemcu_integer_${TRAVIS_TAG}.bin"
srec_cat -output ${file_name_integer} -binary 0x00000.bin -binary -fill 0xff 0x00000 0x10000 0x10000.bin -binary -offset 0x10000
cd ../ || exit
# build float firmware
make clean
make EXTRA_CCFLAGS="-DBUILD_DATE='\"'$BUILD_DATE'\"'" all
cd bin/ || exit
file_name_float="nodemcu_float_${TRAVIS_TAG}.bin"
srec_cat -output ${file_name_float} -binary 0x00000.bin -binary -fill 0xff 0x00000 0x10000 0x10000.bin -binary -offset 0x10000
)
#!/bin/sh
set -e
echo "Running ci build for windows msbuild (supports only hosttools)"
(
cd "$TRAVIS_BUILD_DIR"/msvc || exit
export PATH=$MSBUILD_PATH:$PATH
msbuild.exe hosttools.sln
)
#!/bin/bash
# Downloads and installs a self-contained Lua and LuaRocks.
# Supports Linux, macOS and MSYS2.
# Copyright (c) 2015-2019 Pierre Chapuis, MIT Licensed.
# Latest stable version available at: https://loadk.com/localua.sh
# Maintained at: https://github.com/oploadk/localua
DEFAULT_LUA_V="5.3.5"
DEFAULT_LR_V="3.0.4"
usage () {
>&2 echo -e "USAGE: $0 output-dir [lua-version] [luarocks-version]\n"
>&2 echo -n "The first optional argument is the Lua version, "
>&2 echo -n "the second one is the LuaRocks version. "
>&2 echo -e "Defaults are Lua $DEFAULT_LUA_V and LuaRocks $DEFAULT_LR_V.\n"
>&2 echo -n "You can set a custom build directory with environment "
>&2 echo -e "variable LOCALUA_BUILD_DIRECTORY (not useful in general).\n"
>&2 echo -e "You can set a custom makefile target with LOCALUA_TARGET.\n"
>&2 echo -e "You can disable LUA_COMPAT by setting LOCALUA_NO_COMPAT.\n"
>&2 echo -e "You can skip luarocks by setting LOCALUA_NO_LUAROCKS."
exit 1
}
# Set output directory, Lua version and LuaRocks version
ODIR="$1"
[ -z "$ODIR" ] && usage
LUA_V="$2"
[ -z "$LUA_V" ] && LUA_V="$DEFAULT_LUA_V"
LUA_SHORTV="$(echo $LUA_V | cut -c 1-3)"
LR_V="$3"
[ -z "$LR_V" ] && LR_V="$DEFAULT_LR_V"
# Set build directory
BDIR="$LOCALUA_BUILD_DIRECTORY"
[ -z "$BDIR" ] && BDIR="$(mktemp -d /tmp/localua-XXXXXX)"
# Create output directory and get absolute path
mkdir -p "$ODIR"
>/dev/null pushd "$ODIR"
ODIR="$(pwd)"
>/dev/null popd
# Download, unpack and build Lua and LuaRocks
if [ -z "$LOCALUA_TARGET" ]; then
case "$(uname)" in
Linux)
LOCALUA_TARGET="linux";;
Darwin)
LOCALUA_TARGET="macosx";;
MSYS*)
LOCALUA_TARGET="msys";;
*)
LOCALUA_TARGET="posix";;
esac
fi
pushd "$BDIR"
wget "http://www.lua.org/ftp/lua-${LUA_V}.tar.gz"
tar xf "lua-${LUA_V}.tar.gz"
pushd "lua-${LUA_V}"
sed 's#"/usr/local/"#"'"$ODIR"'/"#' "src/luaconf.h" > "$BDIR/t"
mv "$BDIR/t" "src/luaconf.h"
if [ ! -z "$LOCALUA_NO_COMPAT" ]; then
sed 's#-DLUA_COMPAT_5_2##' "src/Makefile" > "$BDIR/t"
sed 's#-DLUA_COMPAT_ALL##' "$BDIR/t" > "src/Makefile"
fi
if [ "$LOCALUA_TARGET" = "msys" ]; then
>> "src/Makefile" echo
>> "src/Makefile" echo 'msys:' >> "src/Makefile"
>> "src/Makefile" echo -ne "\t"
>> "src/Makefile" echo '$(MAKE) "LUA_A=lua53.dll" "LUA_T=lua.exe" \'
>> "src/Makefile" echo -ne "\t"
>> "src/Makefile" echo '"AR=$(CC) -shared -Wl,--out-implib,liblua.dll.a -o" "RANLIB=strip --strip-unneeded" \'
>> "src/Makefile" echo -ne "\t"
>> "src/Makefile" echo '"SYSCFLAGS=-DLUA_BUILD_AS_DLL -DLUA_USE_POSIX -DLUA_USE_DLOPEN" "SYSLIBS=" "SYSLDFLAGS=-s" lua.exe'
>> "src/Makefile" echo -ne "\t"
>> "src/Makefile" echo '$(MAKE) "LUAC_T=luac.exe" luac.exe'
make -C src "$LOCALUA_TARGET" || exit 1
make \
TO_BIN="lua.exe luac.exe lua53.dll" \
TO_LIB="liblua.a liblua.dll.a" \
INSTALL_TOP="$ODIR" install || exit 1
else
make "$LOCALUA_TARGET" || exit 1
make INSTALL_TOP="$ODIR" install || exit 1
fi
popd
if [ -z "$LOCALUA_NO_LUAROCKS" ]; then
wget "http://luarocks.org/releases/luarocks-${LR_V}.tar.gz"
tar xf "luarocks-${LR_V}.tar.gz"
pushd "luarocks-${LR_V}"
./configure --with-lua="$ODIR" --prefix="$ODIR" \
--lua-version="$LUA_SHORTV" \
--sysconfdir="$ODIR/luarocks" --force-config
make bootstrap
popd
fi
popd
# Cleanup
rm -rf "$BDIR"
...@@ -29,8 +29,4 @@ cd "$TRAVIS_BUILD_DIR"/ld || exit ...@@ -29,8 +29,4 @@ cd "$TRAVIS_BUILD_DIR"/ld || exit
cd "$TRAVIS_BUILD_DIR" || exit cd "$TRAVIS_BUILD_DIR" || exit
make clean make clean
make make
LUA_FILES=`find lua_modules lua_examples -iname "*.lua"`
echo checking $LUA_FILES
./luac.cross -p $LUA_FILES
) )
#!/bin/bash
set -e
echo "Installing Lua 5.3, LuaRocks and Luacheck"
(
cd "$TRAVIS_BUILD_DIR" || exit
bash tools/travis/localua.sh cache/localua || exit
cache/localua/bin/luarocks install luacheck || exit
)
(
echo "Static analysys of:"
find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 echo
)
(find lua_modules lua_examples -iname "*.lua" -print0 | xargs -0 cache/localua/bin/luacheck --config tools/luacheck_config.lua) || exit
#!/usr/bin/env bash
USER_MODULES_H=app/include/user_modules.h
COMMIT_ID="$(git rev-parse HEAD)"
BRANCH="$(git rev-parse --abbrev-ref HEAD | sed -E 's/[\/\\]+/_/g')"
RELEASE="$(git describe --tags --long | sed -E 's/(.*)-(.*)-.*/\1 +\2/g' | sed 's/ +0$//')"
RELEASE_DTS=$(TZ=UTC git show --quiet --date=format-local:"%Y%m%d%H%M" --format="%cd" HEAD)
BUILD_DATE="$(date "+%Y-%m-%d %H:%M")"
MODULES=$(awk '/^[ \t]*#define LUA_USE_MODULES/{modules=modules sep tolower(substr($2,17));sep=","}END{if(length(modules)==0)modules="-";print modules}' $USER_MODULES_H | tr -d '\r')
# create temp buildinfo
TEMPFILE=/tmp/buildinfo.h
cat > $TEMPFILE << EndOfMessage
#ifndef __BUILDINFO_H__
#define __BUILDINFO_H__
#include "user_config.h"
#define BUILDINFO_STR_HELPER(x) #x
#define BUILDINFO_TO_STR(x) BUILDINFO_STR_HELPER(x)
#ifdef LUA_FLASH_STORE
#define BUILDINFO_LFS LUA_FLASH_STORE
#else
#define BUILDINFO_LFS 0
#endif
#ifdef CLIENT_SSL_ENABLE
#define BUILDINFO_SSL true
#define BUILDINFO_SSL_STR "true"
#else
#define BUILDINFO_SSL false
#define BUILDINFO_SSL_STR "false"
#endif
#ifdef LUA_NUMBER_INTEGRAL
#define BUILDINFO_BUILD_TYPE "integer"
#else
#define BUILDINFO_BUILD_TYPE "float"
#endif
#define USER_PROLOG "$USER_PROLOG"
#define BUILDINFO_BRANCH "$BRANCH"
#define BUILDINFO_COMMIT_ID "$COMMIT_ID"
#define BUILDINFO_RELEASE "$RELEASE"
#define BUILDINFO_RELEASE_DTS "$RELEASE_DTS"
#define BUILDINFO_MODULES "$MODULES"
#define BUILDINFO_BUILD_DATE "$BUILD_DATE"
#define NODE_VERSION_LONG \\
USER_PROLOG "\n" \\
"\tbranch: " BUILDINFO_BRANCH "\n" \\
"\tcommit: " BUILDINFO_COMMIT_ID "\n" \\
"\trelease: " BUILDINFO_RELEASE "\n" \\
"\trelease DTS: " BUILDINFO_RELEASE_DTS "\n" \\
"\tSSL: " BUILDINFO_SSL_STR "\n" \\
"\tbuild type: " BUILDINFO_BUILD_TYPE "\n" \\
"\tLFS: " BUILDINFO_TO_STR(BUILDINFO_LFS) "\n" \\
"\tmodules: " BUILDINFO_MODULES "\n"
EndOfMessage
echo "#endif /* __BUILDINFO_H__ */" >> $TEMPFILE
diff -q $TEMPFILE app/include/buildinfo.h || cp $TEMPFILE app/include/buildinfo.h
rm $TEMPFILE
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