pull/39/head
Benjamin Runnels 9 years ago
parent 7b722c4314
commit 31d308416b
  1. 5
      .gitignore
  2. 21
      Makefile
  3. 22
      esp-link.sln
  4. 66
      espfs/espfs.c
  5. 4
      espfs/espfs.h
  6. 90
      espfs/mkespfsimage/main.c
  7. 48
      espfs/mkespfsimage/mman-win32/Makefile
  8. 11
      espfs/mkespfsimage/mman-win32/config.mak
  9. 157
      espfs/mkespfsimage/mman-win32/configure
  10. 180
      espfs/mkespfsimage/mman-win32/mman.c
  11. 55
      espfs/mkespfsimage/mman-win32/mman.h
  12. 235
      espfs/mkespfsimage/mman-win32/test.c
  13. 7
      espmake.cmd
  14. 5
      include/esp8266.h
  15. 10
      include/espmissingincludes.h
  16. 2
      user/config.c

5
.gitignore vendored

@ -10,7 +10,8 @@ html_compressed/
esp-link.tgz
tve-patch/
yui
.localhistory/
espfs/mkespfsimage/mman-win32/mman.o
espfs/mkespfsimage/mman-win32/libmman.a
esp-link.opensdf
esp-link.sdf
espfs/mkespfsimage/mman-win32/libmman.a
.localhistory/

@ -23,6 +23,7 @@ SDK_BASE ?= $(abspath ../esp_iot_sdk_v1.3.0)
# Esptool.py path and port, only used for 1-time serial flashing
# Typically you'll use https://github.com/themadinventor/esptool
# Windows users use the com port i.e: ESPPORT ?= com3
ESPTOOL ?= $(abspath ../esp-open-sdk/esptool/esptool.py)
ESPPORT ?= /dev/ttyUSB0
ESPBAUD ?= 460800
@ -108,7 +109,6 @@ CHANGE_TO_STA ?= yes
# This could speed up the downloading of these files, but might break compatibility with older
# web browsers not supporting gzip encoding because Accept-Encoding is simply ignored.
# Enable this option if you have large static files to serve (for e.g. JQuery, Twitter bootstrap)
# By default only js, css and html files are compressed using heatshrink.
# If you have text based static files with different extensions what you want to serve compressed
# then you will need to add the extension to the following places:
# - Add the extension to this Makefile at the webpages.espfs target to the find command
@ -127,10 +127,6 @@ GZIP_COMPRESSION ?= yes
COMPRESS_W_YUI ?= yes
YUI-COMPRESSOR ?= yuicompressor-2.4.8.jar
# If USE_HEATSHRINK is set to "yes" then the espfs files will be compressed with Heatshrink and
# decompressed on the fly while reading the file.
# Because the decompression is done in the esp8266, it does not require any support in the browser.
USE_HEATSHRINK ?= no
# -------------- End of config options -------------
@ -147,7 +143,7 @@ APPGEN_TOOL ?= gen_appbin.py
# which modules (subdirectories) of the project to include in compiling
MODULES = espfs httpd user serial cmd
EXTRA_INCDIR = include . # lib/heatshrink/
EXTRA_INCDIR = include .
# libraries used in this project, mainly provided by the SDK
LIBS = c gcc hal phy pp net80211 wpa main lwip
@ -216,10 +212,6 @@ ifeq ("$(GZIP_COMPRESSION)","yes")
CFLAGS += -DGZIP_COMPRESSION
endif
ifeq ("$(USE_HEATSHRINK)","yes")
CFLAGS += -DESPFS_HEATSHRINK
endif
ifeq ("$(CHANGE_TO_STA)","yes")
CFLAGS += -DCHANGE_TO_STA
endif
@ -289,6 +281,9 @@ $(BUILD_DIR):
wiflash: all
./wiflash $(ESP_HOSTNAME) $(FW_BASE)/user1.bin $(FW_BASE)/user2.bin
baseflash: all
$(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) write_flash 0x01000 $(FW_BASE)/user1.bin
flash: all
$(Q) $(ESPTOOL) --port $(ESPPORT) --baud $(ESPBAUD) -fs $(ET_FS) -ff $(ET_FF) write_flash \
0x00000 "$(SDK_BASE)/bin/boot_v1.4(b1).bin" 0x01000 $(FW_BASE)/user1.bin \
@ -296,7 +291,11 @@ flash: all
yui/$(YUI-COMPRESSOR):
$(Q) mkdir -p yui
ifeq ($(OS),Windows_NT)
cd yui; wget --no-check-certificate https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI-COMPRESSOR) -O $(YUI-COMPRESSOR)
else
cd yui; wget https://github.com/yui/yuicompressor/releases/download/v2.4.8/$(YUI-COMPRESSOR)
endif
ifeq ("$(COMPRESS_W_YUI)","yes")
$(BUILD_BASE)/espfs_img.o: yui/$(YUI-COMPRESSOR)
@ -348,7 +347,7 @@ build/eagle.esphttpd2.v6.ld: $(SDK_LDDIR)/eagle.app.v6.new.1024.app2.ld
endif
espfs/mkespfsimage/mkespfsimage: espfs/mkespfsimage/
$(Q) $(MAKE) -C espfs/mkespfsimage USE_HEATSHRINK="$(USE_HEATSHRINK)" GZIP_COMPRESSION="$(GZIP_COMPRESSION)"
$(Q) $(MAKE) -C espfs/mkespfsimage GZIP_COMPRESSION="$(GZIP_COMPRESSION)"
release: all
$(Q) rm -rf release; mkdir -p release/esp-link

@ -0,0 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "esp-link", "esp-link.vcxproj", "{A92F0CAA-F89B-4F78-AD2A-A042429BD87F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Release|ARM = Release|ARM
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{A92F0CAA-F89B-4F78-AD2A-A042429BD87F}.Debug|ARM.ActiveCfg = Debug|ARM
{A92F0CAA-F89B-4F78-AD2A-A042429BD87F}.Debug|ARM.Build.0 = Debug|ARM
{A92F0CAA-F89B-4F78-AD2A-A042429BD87F}.Release|ARM.ActiveCfg = Release|ARM
{A92F0CAA-F89B-4F78-AD2A-A042429BD87F}.Release|ARM.Build.0 = Release|ARM
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

@ -40,11 +40,6 @@ It's written for use with httpd, but doesn't need to be used as such.
#include "espfsformat.h"
#include "espfs.h"
#ifdef ESPFS_HEATSHRINK
#include "heatshrink_config_custom.h"
#include "heatshrink_decoder.h"
#endif
static char* espFsData = NULL;
struct EspFsFile {
@ -167,18 +162,6 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(char *fileName) {
r->posDecomp=0;
if (h.compression==COMPRESS_NONE) {
r->decompData=NULL;
#ifdef ESPFS_HEATSHRINK
} else if (h.compression==COMPRESS_HEATSHRINK) {
//File is compressed with Heatshrink.
char parm;
heatshrink_decoder *dec;
//Decoder params are stored in 1st byte.
memcpyAligned(&parm, r->posComp, 1);
r->posComp++;
//os_printf("Heatshrink compressed file; decode parms = %x\n", parm);
dec=heatshrink_decoder_alloc(16, (parm>>4)&0xf, parm&0xf);
r->decompData=dec;
#endif
} else {
os_printf("Invalid compression: %d\n", h.compression);
return NULL;
@ -209,48 +192,6 @@ int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) {
fh->posComp+=len;
// os_printf("Done reading %d bytes, pos=%x\n", len, fh->posComp);
return len;
#ifdef ESPFS_HEATSHRINK
} else if (fh->decompressor==COMPRESS_HEATSHRINK) {
int decoded=0;
size_t elen, rlen;
char ebuff[16];
heatshrink_decoder *dec=(heatshrink_decoder *)fh->decompData;
// os_printf("Alloc %p\n", dec);
if (fh->posDecomp == fdlen) {
return 0;
}
// We must ensure that whole file is decompressed and written to output buffer.
// This means even when there is no input data (elen==0) try to poll decoder until
// posDecomp equals decompressed file length
while(decoded<len) {
//Feed data into the decompressor
//ToDo: Check ret val of heatshrink fns for errors
elen=flen-(fh->posComp - fh->posStart);
if (elen>0) {
memcpyAligned(ebuff, fh->posComp, 16);
heatshrink_decoder_sink(dec, (uint8_t *)ebuff, (elen>16)?16:elen, &rlen);
fh->posComp+=rlen;
}
//Grab decompressed data and put into buff
heatshrink_decoder_poll(dec, (uint8_t *)buff, len-decoded, &rlen);
fh->posDecomp+=rlen;
buff+=rlen;
decoded+=rlen;
// os_printf("Elen %d rlen %d d %d pd %ld fdl %d\n",elen,rlen,decoded, fh->posDecomp, fdlen);
if (elen == 0) {
if (fh->posDecomp == fdlen) {
// os_printf("Decoder finish\n");
heatshrink_decoder_finish(dec);
}
return decoded;
}
}
return len;
#endif
}
return 0;
}
@ -258,13 +199,6 @@ int ICACHE_FLASH_ATTR espFsRead(EspFsFile *fh, char *buff, int len) {
//Close the file.
void ICACHE_FLASH_ATTR espFsClose(EspFsFile *fh) {
if (fh==NULL) return;
#ifdef ESPFS_HEATSHRINK
if (fh->decompressor==COMPRESS_HEATSHRINK) {
heatshrink_decoder *dec=(heatshrink_decoder *)fh->decompData;
heatshrink_decoder_free(dec);
// os_printf("Freed %p\n", dec);
}
#endif
//os_printf("Freed %p\n", fh);
os_free(fh);
}

@ -1,10 +1,6 @@
#ifndef ESPFS_H
#define ESPFS_H
// This define is done in Makefile. If you do not use default Makefile, uncomment
// to be able to use Heatshrink-compressed espfs images.
//#define ESPFS_HEATSHRINK
typedef enum {
ESPFS_INIT_RESULT_OK,
ESPFS_INIT_RESULT_NO_IMAGE,

@ -5,27 +5,29 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <arpa/inet.h>
#include <string.h>
#include "espfs.h"
#include "espfsformat.h"
//Heatshrink
#ifdef ESPFS_HEATSHRINK
#include "heatshrink_common.h"
#include "heatshrink_config.h"
#include "heatshrink_encoder.h"
#ifdef __MINGW32__
#include "mman-win32/mman.h"
#else
#include <sys/mman.h>
#endif
#ifdef __WIN32__
#include <winsock2.h>
#else
#include <arpa/inet.h>
#endif
#include "espfsformat.h"
//Gzip
#ifdef ESPFS_GZIP
// If compiler complains about missing header, try running "sudo apt-get install zlib1g-dev"
// If compiler complains about missing header, try running "sudo apt-get install zlib1g-dev"
// to install missing package.
#include <zlib.h>
#endif
//Routines to convert host format to the endianness used in the xtensa
short htoxs(short in) {
char r[2];
@ -43,53 +45,6 @@ int htoxl(int in) {
return *((int *)r);
}
#ifdef ESPFS_HEATSHRINK
size_t compressHeatshrink(char *in, int insize, char *out, int outsize, int level) {
char *inp=in;
char *outp=out;
size_t len;
int ws[]={5, 6, 8, 11, 13};
int ls[]={3, 3, 4, 4, 4};
HSE_poll_res pres;
HSE_sink_res sres;
size_t r;
if (level==-1) level=8;
level=(level-1)/2; //level is now 0, 1, 2, 3, 4
heatshrink_encoder *enc=heatshrink_encoder_alloc(ws[level], ls[level]);
if (enc==NULL) {
perror("allocating mem for heatshrink");
exit(1);
}
//Save encoder parms as first byte
*outp=(ws[level]<<4)|ls[level];
outp++; outsize--;
r=1;
do {
if (insize>0) {
sres=heatshrink_encoder_sink(enc, inp, insize, &len);
if (sres!=HSER_SINK_OK) break;
inp+=len; insize-=len;
if (insize==0) heatshrink_encoder_finish(enc);
}
do {
pres=heatshrink_encoder_poll(enc, outp, outsize, &len);
if (pres!=HSER_POLL_MORE && pres!=HSER_POLL_EMPTY) break;
outp+=len; outsize-=len;
r+=len;
} while (pres==HSER_POLL_MORE);
} while (insize!=0);
if (insize!=0) {
fprintf(stderr, "Heatshrink: Bug? insize is still %d. sres=%d pres=%d\n", insize, sres, pres);
exit(1);
}
heatshrink_encoder_free(enc);
return r;
}
#endif
#ifdef ESPFS_GZIP
size_t compressGzip(char *in, int insize, char *out, int outsize, int level) {
z_stream stream;
@ -202,11 +157,6 @@ int handleFile(int f, char *name, int compression, int level, char **compName, o
if (compression==COMPRESS_NONE) {
csize=size;
cdat=fdat;
#ifdef ESPFS_HEATSHRINK
} else if (compression==COMPRESS_HEATSHRINK) {
cdat=malloc(size*2);
csize=compressHeatshrink(fdat, size, cdat, size*2, level);
#endif
} else {
fprintf(stderr, "Unknown compression - %d\n", compression);
exit(1);
@ -245,9 +195,7 @@ int handleFile(int f, char *name, int compression, int level, char **compName, o
munmap(fdat, size);
if (compName != NULL) {
if (h.compression==COMPRESS_HEATSHRINK) {
*compName = "heatshrink";
} else if (h.compression==COMPRESS_NONE) {
if (h.compression==COMPRESS_NONE) {
if (h.flags & FLAG_GZIP) {
*compName = "gzip";
} else {
@ -284,11 +232,7 @@ int main(int argc, char **argv) {
int compType; //default compression type - heatshrink
int compLvl=-1;
#ifdef ESPFS_HEATSHRINK
compType = COMPRESS_HEATSHRINK;
#else
compType = COMPRESS_NONE;
#endif
for (x=1; x<argc; x++) {
if (strcmp(argv[x], "-c")==0 && argc>=x-2) {
@ -322,11 +266,7 @@ int main(int argc, char **argv) {
#endif
fprintf(stderr, "> out.espfs\n");
fprintf(stderr, "Compressors:\n");
#ifdef ESPFS_HEATSHRINK
fprintf(stderr, "0 - None\n1 - Heatshrink(default)\n");
#else
fprintf(stderr, "0 - None(default)\n");
#endif
fprintf(stderr, "\nCompression level: 1 is worst but low RAM usage, higher is better compression \nbut uses more ram on decompression. -1 = compressors default.\n");
#ifdef ESPFS_GZIP
fprintf(stderr, "\nGzipped extensions: list of comma separated, case sensitive file extensions \nthat will be gzipped. Defaults to 'html,css,js'\n");
@ -334,6 +274,10 @@ int main(int argc, char **argv) {
exit(0);
}
#ifdef __WIN32__
setmode(fileno(stdout), _O_BINARY);
#endif
while(fgets(fileName, sizeof(fileName), stdin)) {
//Kill off '\n' at the end
fileName[strlen(fileName)-1]=0;

@ -0,0 +1,48 @@
#
# mman-win32 (mingw32) Makefile
#
include config.mak
ifeq ($(BUILD_STATIC),yes)
TARGETS+=libmman.a
INSTALL+=static-install
endif
ifeq ($(BUILD_MSVC),yes)
SHFLAGS+=-Wl,--output-def,libmman.def
INSTALL+=lib-install
endif
all: $(TARGETS)
mman.o: mman.c mman.h
$(CC) -o mman.o -c mman.c -Wall -O3 -fomit-frame-pointer
libmman.a: mman.o
$(AR) cru libmman.a mman.o
$(RANLIB) libmman.a
static-install:
mkdir -p $(DESTDIR)$(libdir)
cp libmman.a $(DESTDIR)$(libdir)
mkdir -p $(DESTDIR)$(incdir)
cp mman.h $(DESTDIR)$(incdir)
lib-install:
mkdir -p $(DESTDIR)$(libdir)
cp libmman.lib $(DESTDIR)$(libdir)
install: $(INSTALL)
test.exe: test.c mman.c mman.h
$(CC) -o test.exe test.c -L. -lmman
test: $(TARGETS) test.exe
test.exe
clean::
rm -f mman.o libmman.a libmman.def libmman.lib test.exe *.dat
distclean: clean
rm -f config.mak
.PHONY: clean distclean install test

@ -0,0 +1,11 @@
# Automatically generated by configure
PREFIX=/mingw
libdir=/mingw/lib
incdir=/mingw/include/sys
AR=ar
CC=gcc
RANLIB=ranlib
STRIP=strip
BUILD_STATIC=yes
BUILD_MSVC=
LIBCMD=echo ignoring lib

@ -0,0 +1,157 @@
#!/bin/sh
# mmap-win32 configure script
#
# Parts copied from FFmpeg's configure
#
set_all(){
value=$1
shift
for var in $*; do
eval $var=$value
done
}
enable(){
set_all yes $*
}
disable(){
set_all no $*
}
enabled(){
eval test "x\$$1" = "xyes"
}
disabled(){
eval test "x\$$1" = "xno"
}
show_help(){
echo "Usage: configure [options]"
echo "Options: [defaults in brackets after descriptions]"
echo "All \"enable\" options have \"disable\" counterparts"
echo
echo " --help print this message"
echo " --prefix=PREFIX install in PREFIX [$PREFIX]"
echo " --libdir=DIR install libs in DIR [$PREFIX/lib]"
echo " --incdir=DIR install includes in DIR [$PREFIX/include]"
echo " --enable-static build static libraries [yes]"
echo " --enable-msvc create msvc-compatible import lib [auto]"
echo
echo " --cc=CC use C compiler CC [$cc_default]"
echo " --cross-prefix=PREFIX use PREFIX for compilation tools [$cross_prefix]"
exit 1
}
die_unknown(){
echo "Unknown option \"$1\"."
echo "See $0 --help for available options."
exit 1
}
PREFIX="/mingw"
libdir="${PREFIX}/lib"
incdir="${PREFIX}/include/sys"
ar="ar"
cc_default="gcc"
ranlib="ranlib"
strip="strip"
DEFAULT="msvc
"
DEFAULT_YES="static
stripping
"
CMDLINE_SELECT="$DEFAULT
$DEFAULT_NO
$DEFAULT_YES
"
enable $DEFAULT_YES
disable $DEFAULT_NO
for opt do
optval="${opt#*=}"
case "$opt" in
--help)
show_help
;;
--prefix=*)
PREFIX="$optval"
;;
--libdir=*)
libdir="$optval"
;;
--incdir=*)
incdir="$optval"
;;
--cc=*)
cc="$optval"
;;
--cross-prefix=*)
cross_prefix="$optval"
;;
--enable-?*|--disable-?*)
eval `echo "$opt" | sed 's/--/action=/;s/-/ option=/;s/-/_/g'`
echo "$CMDLINE_SELECT" | grep -q "^ *$option\$" || die_unknown $opt
$action $option
;;
*)
die_unknown $opt
;;
esac
done
ar="${cross_prefix}${ar}"
cc_default="${cross_prefix}${cc_default}"
ranlib="${cross_prefix}${ranlib}"
strip="${cross_prefix}${strip}"
if ! test -z $cc; then
cc_default="${cc}"
fi
cc="${cc_default}"
disabled static && {
echo "At least one library type must be set.";
exit 1;
}
if enabled msvc; then
lib /? > /dev/null 2>&1 /dev/null || {
echo "MSVC's lib command not found."
echo "Make sure MSVC is installed and its bin folder is in your \$PATH."
exit 1
}
fi
if ! enabled stripping; then
strip="echo ignoring strip"
fi
enabled msvc && libcmd="lib" || libcmd="echo ignoring lib"
echo "# Automatically generated by configure" > config.mak
echo "PREFIX=$PREFIX" >> config.mak
echo "libdir=$libdir" >> config.mak
echo "incdir=$incdir" >> config.mak
echo "AR=$ar" >> config.mak
echo "CC=$cc" >> config.mak
echo "RANLIB=$ranlib" >> config.mak
echo "STRIP=$strip" >> config.mak
echo "BUILD_STATIC=$static" >> config.mak
echo "BUILD_MSVC=$msvc" >> config.mak
echo "LIBCMD=$libcmd" >> config.mak
echo "prefix: $PREFIX"
echo "libdir: $libdir"
echo "incdir: $incdir"
echo "ar: $ar"
echo "cc: $cc"
echo "ranlib: $ranlib"
echo "strip: $strip"
echo "static: $static"

@ -0,0 +1,180 @@
#include <windows.h>
#include <errno.h>
#include <io.h>
#include "mman.h"
#ifndef FILE_MAP_EXECUTE
#define FILE_MAP_EXECUTE 0x0020
#endif /* FILE_MAP_EXECUTE */
static int __map_mman_error(const DWORD err, const int deferr)
{
if (err == 0)
return 0;
//TODO: implement
return err;
}
static DWORD __map_mmap_prot_page(const int prot)
{
DWORD protect = 0;
if (prot == PROT_NONE)
return protect;
if ((prot & PROT_EXEC) != 0)
{
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
}
else
{
protect = ((prot & PROT_WRITE) != 0) ?
PAGE_READWRITE : PAGE_READONLY;
}
return protect;
}
static DWORD __map_mmap_prot_file(const int prot)
{
DWORD desiredAccess = 0;
if (prot == PROT_NONE)
return desiredAccess;
if ((prot & PROT_READ) != 0)
desiredAccess |= FILE_MAP_READ;
if ((prot & PROT_WRITE) != 0)
desiredAccess |= FILE_MAP_WRITE;
if ((prot & PROT_EXEC) != 0)
desiredAccess |= FILE_MAP_EXECUTE;
return desiredAccess;
}
void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
{
HANDLE fm, h;
void * map = MAP_FAILED;
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4293)
#endif
const DWORD dwFileOffsetLow = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)off : (DWORD)(off & 0xFFFFFFFFL);
const DWORD dwFileOffsetHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((off >> 32) & 0xFFFFFFFFL);
const DWORD protect = __map_mmap_prot_page(prot);
const DWORD desiredAccess = __map_mmap_prot_file(prot);
const off_t maxSize = off + (off_t)len;
const DWORD dwMaxSizeLow = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)maxSize : (DWORD)(maxSize & 0xFFFFFFFFL);
const DWORD dwMaxSizeHigh = (sizeof(off_t) <= sizeof(DWORD)) ?
(DWORD)0 : (DWORD)((maxSize >> 32) & 0xFFFFFFFFL);
#ifdef _MSC_VER
#pragma warning(pop)
#endif
errno = 0;
if (len == 0
/* Unsupported flag combinations */
|| (flags & MAP_FIXED) != 0
/* Usupported protection combinations */
|| prot == PROT_EXEC)
{
errno = EINVAL;
return MAP_FAILED;
}
h = ((flags & MAP_ANONYMOUS) == 0) ?
(HANDLE)_get_osfhandle(fildes) : INVALID_HANDLE_VALUE;
if ((flags & MAP_ANONYMOUS) == 0 && h == INVALID_HANDLE_VALUE)
{
errno = EBADF;
return MAP_FAILED;
}
fm = CreateFileMapping(h, NULL, protect, dwMaxSizeHigh, dwMaxSizeLow, NULL);
if (fm == NULL)
{
errno = __map_mman_error(GetLastError(), EPERM);
return MAP_FAILED;
}
map = MapViewOfFile(fm, desiredAccess, dwFileOffsetHigh, dwFileOffsetLow, len);
CloseHandle(fm);
if (map == NULL)
{
errno = __map_mman_error(GetLastError(), EPERM);
return MAP_FAILED;
}
return map;
}
int munmap(void *addr, size_t len)
{
if (UnmapViewOfFile(addr))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int mprotect(void *addr, size_t len, int prot)
{
DWORD newProtect = __map_mmap_prot_page(prot);
DWORD oldProtect = 0;
if (VirtualProtect(addr, len, newProtect, &oldProtect))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int msync(void *addr, size_t len, int flags)
{
if (FlushViewOfFile(addr, len))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int mlock(const void *addr, size_t len)
{
if (VirtualLock((LPVOID)addr, len))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}
int munlock(const void *addr, size_t len)
{
if (VirtualUnlock((LPVOID)addr, len))
return 0;
errno = __map_mman_error(GetLastError(), EPERM);
return -1;
}

@ -0,0 +1,55 @@
/*
* sys/mman.h
* mman-win32
*/
#ifndef _SYS_MMAN_H_
#define _SYS_MMAN_H_
#ifndef _WIN32_WINNT // Allow use of features specific to Windows XP or later.
#define _WIN32_WINNT 0x0501 // Change this to the appropriate value to target other versions of Windows.
#endif
/* All the headers include this file. */
#ifndef _MSC_VER
#include <_mingw.h>
#endif
#include <sys/types.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PROT_NONE 0
#define PROT_READ 1
#define PROT_WRITE 2
#define PROT_EXEC 4
#define MAP_FILE 0
#define MAP_SHARED 1
#define MAP_PRIVATE 2
#define MAP_TYPE 0xf
#define MAP_FIXED 0x10
#define MAP_ANONYMOUS 0x20
#define MAP_ANON MAP_ANONYMOUS
#define MAP_FAILED ((void *)-1)
/* Flags for msync. */
#define MS_ASYNC 1
#define MS_SYNC 2
#define MS_INVALIDATE 4
void* mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off);
int munmap(void *addr, size_t len);
int mprotect(void *addr, size_t len, int prot);
int msync(void *addr, size_t len, int flags);
int mlock(const void *addr, size_t len);
int munlock(const void *addr, size_t len);
#ifdef __cplusplus
};
#endif
#endif /* _SYS_MMAN_H_ */

@ -0,0 +1,235 @@
#include "mman.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#ifndef NULL
#define NULL (void*)0
#endif
const char* map_file_name = "map_file.dat";
int test_anon_map_readwrite()
{
void* map = mmap(NULL, 1024, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map == MAP_FAILED)
{
printf("mmap (MAP_ANONYMOUS, PROT_READ | PROT_WRITE) returned unexpected error: %d\n", errno);
return -1;
}
*((unsigned char*)map) = 1;
int result = munmap(map, 1024);
if (result != 0)
printf("munmap (MAP_ANONYMOUS, PROT_READ | PROT_WRITE) returned unexpected error: %d\n", errno);
return result;
}
int test_anon_map_readonly()
{
void* map = mmap(NULL, 1024, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map == MAP_FAILED)
{
printf("mmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
return -1;
}
*((unsigned char*)map) = 1;
int result = munmap(map, 1024);
if (result != 0)
printf("munmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
return result;
}
int test_anon_map_writeonly()
{
void* map = mmap(NULL, 1024, PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map == MAP_FAILED)
{
printf("mmap (MAP_ANONYMOUS, PROT_WRITE) returned unexpected error: %d\n", errno);
return -1;
}
*((unsigned char*)map) = 1;
int result = munmap(map, 1024);
if (result != 0)
printf("munmap (MAP_ANONYMOUS, PROT_WRITE) returned unexpected error: %d\n", errno);
return result;
}
int test_anon_map_readonly_nowrite()
{
void* map = mmap(NULL, 1024, PROT_READ,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (map == MAP_FAILED)
{
printf("mmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
return -1;
}
if (*((unsigned char*)map) != 0)
printf("test_anon_map_readonly_nowrite (MAP_ANONYMOUS, PROT_READ) returned unexpected value: %d\n",
(int)*((unsigned char*)map));
int result = munmap(map, 1024);
if (result != 0)
printf("munmap (MAP_ANONYMOUS, PROT_READ) returned unexpected error: %d\n", errno);
return result;
}
int test_file_map_readwrite()
{
mode_t mode = S_IRUSR | S_IWUSR;
int o = open(map_file_name, O_TRUNC | O_BINARY | O_RDWR | O_CREAT, mode);
void* map = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_PRIVATE, o, 0);
if (map == MAP_FAILED)
{
printf("mmap returned unexpected error: %d\n", errno);
return -1;
}
*((unsigned char*)map) = 1;
int result = munmap(map, 1024);
if (result != 0)
printf("munmap returned unexpected error: %d\n", errno);
close(o);
/*TODO: get file info and content and compare it with the sources conditions */
unlink(map_file_name);
return result;
}
int test_file_map_mlock_munlock()
{
const size_t map_size = 1024;
int result = 0;
mode_t mode = S_IRUSR | S_IWUSR;
int o = open(map_file_name, O_TRUNC | O_BINARY | O_RDWR | O_CREAT, mode);
if (o == -1)
{
printf("unable to create file %s: %d\n", map_file_name, errno);
return -1;
}
void* map = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, o, 0);
if (map == MAP_FAILED)
{
printf("mmap returned unexpected error: %d\n", errno);
result = -1;
goto done_close;
}
if (mlock(map, map_size) != 0)
{
printf("mlock returned unexpected error: %d\n", errno);
result = -1;
goto done_munmap;
}
*((unsigned char*)map) = 1;
if (munlock(map, map_size) != 0)
{
printf("munlock returned unexpected error: %d\n", errno);
result = -1;
}
done_munmap:
result = munmap(map, map_size);
if (result != 0)
printf("munmap returned unexpected error: %d\n", errno);
done_close:
close(o);
unlink(map_file_name);
done:
return result;
}
int test_file_map_msync()
{
const size_t map_size = 1024;
int result = 0;
mode_t mode = S_IRUSR | S_IWUSR;
int o = open(map_file_name, O_TRUNC | O_BINARY | O_RDWR | O_CREAT, mode);
if (o == -1)
{
printf("unable to create file %s: %d\n", map_file_name, errno);
return -1;
}
void* map = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, o, 0);
if (map == MAP_FAILED)
{
printf("mmap returned unexpected error: %d\n", errno);
result = -1;
goto done_close;
}
*((unsigned char*)map) = 1;
if (msync(map, map_size, MS_SYNC) != 0)
{
printf("msync returned unexpected error: %d\n", errno);
result = -1;
}
result = munmap(map, map_size);
if (result != 0)
printf("munmap returned unexpected error: %d\n", errno);
done_close:
close(o);
unlink(map_file_name);
done:
return result;
}
#define EXEC_TEST(name) \
if (name() != 0) { result = -1; printf( #name ": fail\n"); } \
else { printf(#name ": pass\n"); }
int main()
{
int result = 0;
EXEC_TEST(test_anon_map_readwrite);
//NOTE: this test must cause an access violation exception
//EXEC_TEST(test_anon_map_readonly);
EXEC_TEST(test_anon_map_readonly_nowrite);
EXEC_TEST(test_anon_map_writeonly);
EXEC_TEST(test_file_map_readwrite);
EXEC_TEST(test_file_map_mlock_munlock);
EXEC_TEST(test_file_map_msync);
//TODO: EXEC_TEST(test_file_map_mprotect);
return result;
}

@ -0,0 +1,7 @@
@echo off
REM remove automatic created obj folder
rd obj /S /Q >nul 2>&1
PATH=%PATH%;C:\Espressif\xtensa-lx106-elf\bin;C:\MinGW\bin;C:\MinGW\msys\1.0\bin;C:\espressif\git-bin;C:\espressif\java-bin;C:\Python27
make -f Makefile %1 %2 %3 %4 %5

@ -13,7 +13,10 @@
#include <mem.h>
#include <osapi.h>
#include <upgrade.h>
#include <user_interface.h>
#include "espmissingincludes.h"
#include "uart_hw.h"
#ifdef __WIN32__
#include <_mingw.h>
#endif

@ -1,9 +1,8 @@
#ifndef ESPMISSINGINCLUDES_H
#define ESPMISSINGINCLUDES_H
#include <stdint.h>
#include <c_types.h>
#include <ets_sys.h>
#include <user_interface.h>
#include <eagle_soc.h>
//Missing function prototypes in include folders. Gcc will warn on these if we don't define 'em anywhere.
//MOST OF THESE ARE GUESSED! but they seem to work and shut up the compiler.
@ -54,6 +53,11 @@ int rand(void);
void ets_bzero(void *s, size_t n);
void ets_delay_us(int ms);
// Shortcuts for memory functions
#define os_malloc pvPortMalloc
#define os_free vPortFree
#define os_zalloc pvPortZalloc
// disappeared in SDK 1.1.0:
#define os_timer_done ets_timer_done
#define os_timer_handler_isr ets_timer_handler_isr

@ -17,7 +17,7 @@ FlashConfig flashDefault = {
"esp-link\0 ", // hostname
0, 0x00ffffff, 0, // static ip, netmask, gateway
0, // log mode
0, // swap_uart (don't by default)
0, // swap uart (don't by default)
1, 0, // tcp_enable, rssi_enable
"\0", // api_key
};

Loading…
Cancel
Save