mirror of
https://github.com/SuperBFG7/ympd
synced 2024-12-27 19:30:27 +00:00
Upgrade to mongoose-6.11
This commit is contained in:
parent
1ec430513f
commit
25fa58aa8c
1
src/mongoose
Symbolic link
1
src/mongoose
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
mongoose-6.11/
|
9
src/mongoose-6.11/.mbedignore
Normal file
9
src/mongoose-6.11/.mbedignore
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
binary/
|
||||||
|
deps/
|
||||||
|
docker/
|
||||||
|
docs/
|
||||||
|
examples/
|
||||||
|
platforms/
|
||||||
|
src/
|
||||||
|
test/
|
||||||
|
multilingual/
|
8
src/mongoose-6.11/CONTRIBUTING.md
Normal file
8
src/mongoose-6.11/CONTRIBUTING.md
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
People who have agreed to the
|
||||||
|
[Cesanta CLA](https://docs.cesanta.com/contributors_la.shtml)
|
||||||
|
can make contributions. Note that the CLA isn't a copyright
|
||||||
|
_assigment_ but rather a copyright _license_.
|
||||||
|
You retain the copyright on your contributions.
|
||||||
|
|
||||||
|
We follow the Google C/C++ style guide: https://google.github.io/styleguide/cppguide.html
|
||||||
|
We'd appreciate if your contribution follows the same style guide.
|
16
src/mongoose-6.11/LICENSE
Normal file
16
src/mongoose-6.11/LICENSE
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
Copyright (c) 2004-2013 Sergey Lyubka <valenok@gmail.com>
|
||||||
|
Copyright (c) 2013-2016 Cesanta Software Limited
|
||||||
|
All rights reserved
|
||||||
|
|
||||||
|
This software is dual-licensed: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License version 2 as
|
||||||
|
published by the Free Software Foundation. For the terms of this
|
||||||
|
license, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
You are free to use this software under the terms of the GNU General
|
||||||
|
Public License, but WITHOUT ANY WARRANTY; without even the implied
|
||||||
|
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
See the GNU General Public License for more details.
|
||||||
|
|
||||||
|
Alternatively, you can license this software under a commercial
|
||||||
|
license, as set out in <https://www.cesanta.com/license>.
|
68
src/mongoose-6.11/README.md
Normal file
68
src/mongoose-6.11/README.md
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
# Mongoose - Embedded Web Server / Embedded Networking Library
|
||||||
|
|
||||||
|
![](https://img.shields.io/badge/license-GPL_2-green.svg "License")
|
||||||
|
|
||||||
|
Mongoose is ideal for embedded environments. It has been designed
|
||||||
|
for connecting devices and bringing them online. On the market since 2004,
|
||||||
|
used by vast number of open source and
|
||||||
|
commercial products - it even runs on the International Space station!
|
||||||
|
Mongoose makes embedded network programming fast, robust, and easy.
|
||||||
|
|
||||||
|
- [Download Mongoose Source Code here](https://www.cesanta.com/download.html)
|
||||||
|
|
||||||
|
Looking for a complete IoT firmware solution?
|
||||||
|
|
||||||
|
Check out [Mongoose OS](https://mongoose-os.com) - open source embedded operating system for low-power connected microcontrollers. Secure, designed for Internet of Things, complete environment for prototyping, development and managing.
|
||||||
|
|
||||||
|
# Support
|
||||||
|
- [Study mongoose example code](https://github.com/cesanta/mongoose/tree/master/examples)
|
||||||
|
- [Read User Guide and API reference](https://cesanta.com/docs/overview/intro.html)
|
||||||
|
- [Support Forum - ask your technical questions here](https://forum.mongoose-os.com/categories/mongoose)
|
||||||
|
- [Commercial licensing and support available](https://www.cesanta.com/licensing.html)
|
||||||
|
- [Check our latest releases](https://github.com/cesanta/mongoose/releases)
|
||||||
|
|
||||||
|
# Features
|
||||||
|
|
||||||
|
* Cross-platform: works on Linux/UNIX, MacOS, QNX, eCos, Windows, Android,
|
||||||
|
iPhone, FreeRTOS (TI CC3200, ESP8266), etc
|
||||||
|
* Supported hardware platforms: TI CC3200, TI MSP432, NRF52, STM32, PIC32, ESP8266, ESP32 and more
|
||||||
|
* Builtin protocols:
|
||||||
|
- plain TCP, plain UDP, SSL/TLS (over TCP, one-way or two-way)
|
||||||
|
- HTTP client, HTTP server
|
||||||
|
- WebSocket client, WebSocket server
|
||||||
|
- MQTT client, MQTT broker
|
||||||
|
- CoAP client, CoAP server
|
||||||
|
- DNS client, DNS server, async DNS resolver
|
||||||
|
* Single-threaded, asynchronous, non-blocking core with simple event-based API
|
||||||
|
* Native support for [PicoTCP embedded TCP/IP stack](http://www.picotcp.com),
|
||||||
|
[LWIP embedded TCP/IP stack](https://en.wikipedia.org/wiki/LwIP)
|
||||||
|
* Tiny static and run-time footprint
|
||||||
|
* Source code is both ISO C and ISO C++ compliant
|
||||||
|
* Very easy to integrate: just copy
|
||||||
|
[mongoose.c](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.c) and
|
||||||
|
[mongoose.h](https://raw.githubusercontent.com/cesanta/mongoose/master/mongoose.h)
|
||||||
|
files to your build tree
|
||||||
|
|
||||||
|
# Licensing
|
||||||
|
|
||||||
|
Mongoose is released under Commercial and [GNU GPL v.2](http://www.gnu.org/licenses/old-licenses/gpl-2.0.html) open source licenses.
|
||||||
|
|
||||||
|
Commercial Projects: [Contact us for commercial license.](https://www.cesanta.com/contact.html)
|
||||||
|
|
||||||
|
# Dashboard Example
|
||||||
|
|
||||||
|
Mongoose is often used to implement device dashboards and real-time
|
||||||
|
data exchange over Websocket. Here is a dashboard example that illustrates
|
||||||
|
the functionality:
|
||||||
|
|
||||||
|
![](http://www.cesanta.com/images/dashboard.png)
|
||||||
|
|
||||||
|
[Developing a new product? Contact us today to discuss how Mongoose can help.](https://www.cesanta.com/contact.html)
|
||||||
|
|
||||||
|
# Contributions
|
||||||
|
|
||||||
|
To submit contributions, sign [Cesanta CLA](https://cesanta.com/cla.html)
|
||||||
|
and send GitHub pull request. You retain the copyright on your contributions.
|
||||||
|
|
||||||
|
# Looking for a pre-compiled Mongoose web server Windows or Mac binary?
|
||||||
|
- [Download pre-compiled Mongoose web server binary.](https://www.cesanta.com/binary.html)
|
8
src/mongoose-6.11/jni/Android.mk
Normal file
8
src/mongoose-6.11/jni/Android.mk
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
LOCAL_PATH := $(call my-dir)/..
|
||||||
|
include $(CLEAR_VARS)
|
||||||
|
|
||||||
|
LOCAL_CFLAGS := -std=c99 -O2 -W -Wall -pthread -pipe $(COPT)
|
||||||
|
LOCAL_MODULE := mongoose
|
||||||
|
LOCAL_SRC_FILES := examples/simplest_web_server/simplest_web_server.c mongoose.c
|
||||||
|
|
||||||
|
include $(BUILD_EXECUTABLE)
|
16132
src/mongoose-6.11/mongoose.c
Normal file
16132
src/mongoose-6.11/mongoose.c
Normal file
File diff suppressed because it is too large
Load Diff
6222
src/mongoose-6.11/mongoose.h
Normal file
6222
src/mongoose-6.11/mongoose.h
Normal file
File diff suppressed because it is too large
Load Diff
1
src/mongoose-6.11/src/CPPLINT.cfg
Normal file
1
src/mongoose-6.11/src/CPPLINT.cfg
Normal file
@ -0,0 +1 @@
|
|||||||
|
exclude_files=sha1\.c
|
105
src/mongoose-6.11/src/common/cs_dbg.c
Normal file
105
src/mongoose-6.11/src/common/cs_dbg.c
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/cs_dbg.h"
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "common/cs_time.h"
|
||||||
|
#include "common/str_util.h"
|
||||||
|
|
||||||
|
enum cs_log_level cs_log_threshold WEAK =
|
||||||
|
#if CS_ENABLE_DEBUG
|
||||||
|
LL_VERBOSE_DEBUG;
|
||||||
|
#else
|
||||||
|
LL_ERROR;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static char *s_filter_pattern = NULL;
|
||||||
|
static size_t s_filter_pattern_len;
|
||||||
|
|
||||||
|
void cs_log_set_filter(const char *pattern) WEAK;
|
||||||
|
|
||||||
|
#if CS_ENABLE_STDIO
|
||||||
|
|
||||||
|
FILE *cs_log_file WEAK = NULL;
|
||||||
|
|
||||||
|
#if CS_LOG_ENABLE_TS_DIFF
|
||||||
|
double cs_log_ts WEAK;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum cs_log_level cs_log_cur_msg_level WEAK = LL_NONE;
|
||||||
|
|
||||||
|
void cs_log_set_filter(const char *pattern) {
|
||||||
|
free(s_filter_pattern);
|
||||||
|
if (pattern != NULL) {
|
||||||
|
s_filter_pattern = strdup(pattern);
|
||||||
|
s_filter_pattern_len = strlen(pattern);
|
||||||
|
} else {
|
||||||
|
s_filter_pattern = NULL;
|
||||||
|
s_filter_pattern_len = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int cs_log_print_prefix(enum cs_log_level, const char *, const char *) WEAK;
|
||||||
|
int cs_log_print_prefix(enum cs_log_level level, const char *func,
|
||||||
|
const char *filename) {
|
||||||
|
char prefix[21];
|
||||||
|
|
||||||
|
if (level > cs_log_threshold) return 0;
|
||||||
|
if (s_filter_pattern != NULL &&
|
||||||
|
mg_match_prefix(s_filter_pattern, s_filter_pattern_len, func) == 0 &&
|
||||||
|
mg_match_prefix(s_filter_pattern, s_filter_pattern_len, filename) == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strncpy(prefix, func, 20);
|
||||||
|
prefix[20] = '\0';
|
||||||
|
if (cs_log_file == NULL) cs_log_file = stderr;
|
||||||
|
cs_log_cur_msg_level = level;
|
||||||
|
fprintf(cs_log_file, "%-20s ", prefix);
|
||||||
|
#if CS_LOG_ENABLE_TS_DIFF
|
||||||
|
{
|
||||||
|
double now = cs_time();
|
||||||
|
fprintf(cs_log_file, "%7u ", (unsigned int) ((now - cs_log_ts) * 1000000));
|
||||||
|
cs_log_ts = now;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cs_log_printf(const char *fmt, ...) WEAK;
|
||||||
|
void cs_log_printf(const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
va_start(ap, fmt);
|
||||||
|
vfprintf(cs_log_file, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
fputc('\n', cs_log_file);
|
||||||
|
fflush(cs_log_file);
|
||||||
|
cs_log_cur_msg_level = LL_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cs_log_set_file(FILE *file) WEAK;
|
||||||
|
void cs_log_set_file(FILE *file) {
|
||||||
|
cs_log_file = file;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void cs_log_set_filter(const char *pattern) {
|
||||||
|
(void) pattern;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CS_ENABLE_STDIO */
|
||||||
|
|
||||||
|
void cs_log_set_level(enum cs_log_level level) WEAK;
|
||||||
|
void cs_log_set_level(enum cs_log_level level) {
|
||||||
|
cs_log_threshold = level;
|
||||||
|
#if CS_LOG_ENABLE_TS_DIFF && CS_ENABLE_STDIO
|
||||||
|
cs_log_ts = cs_time();
|
||||||
|
#endif
|
||||||
|
}
|
149
src/mongoose-6.11/src/common/cs_dbg.h
Normal file
149
src/mongoose-6.11/src/common/cs_dbg.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_CS_DBG_H_
|
||||||
|
#define CS_COMMON_CS_DBG_H_
|
||||||
|
|
||||||
|
#include "common/platform.h"
|
||||||
|
|
||||||
|
#if CS_ENABLE_STDIO
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CS_ENABLE_DEBUG
|
||||||
|
#define CS_ENABLE_DEBUG 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CS_LOG_ENABLE_TS_DIFF
|
||||||
|
#define CS_LOG_ENABLE_TS_DIFF 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Log level; `LL_INFO` is the default. Use `cs_log_set_level()` to change it.
|
||||||
|
*/
|
||||||
|
enum cs_log_level {
|
||||||
|
LL_NONE = -1,
|
||||||
|
LL_ERROR = 0,
|
||||||
|
LL_WARN = 1,
|
||||||
|
LL_INFO = 2,
|
||||||
|
LL_DEBUG = 3,
|
||||||
|
LL_VERBOSE_DEBUG = 4,
|
||||||
|
|
||||||
|
_LL_MIN = -2,
|
||||||
|
_LL_MAX = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set max log level to print; messages with the level above the given one will
|
||||||
|
* not be printed.
|
||||||
|
*/
|
||||||
|
void cs_log_set_level(enum cs_log_level level);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set log filter. NULL (a default) logs everything.
|
||||||
|
* Otherwise, function name and file name will be tested against the given
|
||||||
|
* pattern, and only matching messages will be printed.
|
||||||
|
*
|
||||||
|
* For the pattern syntax, refer to `mg_match_prefix()` in `str_util.h`.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* ```c
|
||||||
|
* void foo(void) {
|
||||||
|
* LOG(LL_INFO, ("hello from foo"));
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* void bar(void) {
|
||||||
|
* LOG(LL_INFO, ("hello from bar"));
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* void test(void) {
|
||||||
|
* cs_log_set_filter(NULL);
|
||||||
|
* foo();
|
||||||
|
* bar();
|
||||||
|
*
|
||||||
|
* cs_log_set_filter("f*");
|
||||||
|
* foo();
|
||||||
|
* bar(); // Will NOT print anything
|
||||||
|
*
|
||||||
|
* cs_log_set_filter("bar");
|
||||||
|
* foo(); // Will NOT print anything
|
||||||
|
* bar();
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
void cs_log_set_filter(const char *pattern);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper function which prints message prefix with the given `level`, function
|
||||||
|
* name `func` and `filename`. If message should be printed (accordingly to the
|
||||||
|
* current log level and filter), prints the prefix and returns 1, otherwise
|
||||||
|
* returns 0.
|
||||||
|
*
|
||||||
|
* Clients should typically just use `LOG()` macro.
|
||||||
|
*/
|
||||||
|
int cs_log_print_prefix(enum cs_log_level level, const char *func,
|
||||||
|
const char *filename);
|
||||||
|
|
||||||
|
extern enum cs_log_level cs_log_threshold;
|
||||||
|
|
||||||
|
#if CS_ENABLE_STDIO
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Set file to write logs into. If `NULL`, logs go to `stderr`.
|
||||||
|
*/
|
||||||
|
void cs_log_set_file(FILE *file);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Prints log to the current log file, appends "\n" in the end and flushes the
|
||||||
|
* stream.
|
||||||
|
*/
|
||||||
|
void cs_log_printf(const char *fmt, ...)
|
||||||
|
#ifdef __GNUC__
|
||||||
|
__attribute__((format(printf, 1, 2)))
|
||||||
|
#endif
|
||||||
|
;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Format and print message `x` with the given level `l`. Example:
|
||||||
|
*
|
||||||
|
* ```c
|
||||||
|
* LOG(LL_INFO, ("my info message: %d", 123));
|
||||||
|
* LOG(LL_DEBUG, ("my debug message: %d", 123));
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
#define LOG(l, x) \
|
||||||
|
do { \
|
||||||
|
if (cs_log_print_prefix(l, __func__, __FILE__)) cs_log_printf x; \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#ifndef CS_NDEBUG
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Shortcut for `LOG(LL_VERBOSE_DEBUG, (...))`
|
||||||
|
*/
|
||||||
|
#define DBG(x) LOG(LL_VERBOSE_DEBUG, x)
|
||||||
|
|
||||||
|
#else /* NDEBUG */
|
||||||
|
|
||||||
|
#define DBG(x)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#else /* CS_ENABLE_STDIO */
|
||||||
|
|
||||||
|
#define LOG(l, x)
|
||||||
|
#define DBG(x)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_CS_DBG_H_ */
|
211
src/mongoose-6.11/src/common/cs_md5.c
Normal file
211
src/mongoose-6.11/src/common/cs_md5.c
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
/*
|
||||||
|
* This code implements the MD5 message-digest algorithm.
|
||||||
|
* The algorithm is due to Ron Rivest. This code was
|
||||||
|
* written by Colin Plumb in 1993, no copyright is claimed.
|
||||||
|
* This code is in the public domain; do with it what you wish.
|
||||||
|
*
|
||||||
|
* Equivalent code is available from RSA Data Security, Inc.
|
||||||
|
* This code has been tested against that, and is equivalent,
|
||||||
|
* except that you don't need to include two pages of legalese
|
||||||
|
* with every copy.
|
||||||
|
*
|
||||||
|
* To compute the message digest of a chunk of bytes, declare an
|
||||||
|
* MD5Context structure, pass it to MD5Init, call MD5Update as
|
||||||
|
* needed on buffers full of bytes, and then call MD5Final, which
|
||||||
|
* will fill a supplied 16-byte array with the digest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/cs_md5.h"
|
||||||
|
#include "common/str_util.h"
|
||||||
|
|
||||||
|
#if !defined(EXCLUDE_COMMON)
|
||||||
|
#if !CS_DISABLE_MD5
|
||||||
|
|
||||||
|
#include "common/cs_endian.h"
|
||||||
|
|
||||||
|
static void byteReverse(unsigned char *buf, unsigned longs) {
|
||||||
|
/* Forrest: MD5 expect LITTLE_ENDIAN, swap if BIG_ENDIAN */
|
||||||
|
#if BYTE_ORDER == BIG_ENDIAN
|
||||||
|
do {
|
||||||
|
uint32_t t = (uint32_t)((unsigned) buf[3] << 8 | buf[2]) << 16 |
|
||||||
|
((unsigned) buf[1] << 8 | buf[0]);
|
||||||
|
*(uint32_t *) buf = t;
|
||||||
|
buf += 4;
|
||||||
|
} while (--longs);
|
||||||
|
#else
|
||||||
|
(void) buf;
|
||||||
|
(void) longs;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
#define F1(x, y, z) (z ^ (x & (y ^ z)))
|
||||||
|
#define F2(x, y, z) F1(z, x, y)
|
||||||
|
#define F3(x, y, z) (x ^ y ^ z)
|
||||||
|
#define F4(x, y, z) (y ^ (x | ~z))
|
||||||
|
|
||||||
|
#define MD5STEP(f, w, x, y, z, data, s) \
|
||||||
|
(w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||||
|
* initialization constants.
|
||||||
|
*/
|
||||||
|
void cs_md5_init(cs_md5_ctx *ctx) {
|
||||||
|
ctx->buf[0] = 0x67452301;
|
||||||
|
ctx->buf[1] = 0xefcdab89;
|
||||||
|
ctx->buf[2] = 0x98badcfe;
|
||||||
|
ctx->buf[3] = 0x10325476;
|
||||||
|
|
||||||
|
ctx->bits[0] = 0;
|
||||||
|
ctx->bits[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void cs_md5_transform(uint32_t buf[4], uint32_t const in[16]) {
|
||||||
|
register uint32_t a, b, c, d;
|
||||||
|
|
||||||
|
a = buf[0];
|
||||||
|
b = buf[1];
|
||||||
|
c = buf[2];
|
||||||
|
d = buf[3];
|
||||||
|
|
||||||
|
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
|
||||||
|
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
|
||||||
|
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
|
||||||
|
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
|
||||||
|
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
|
||||||
|
|
||||||
|
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
|
||||||
|
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
|
||||||
|
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
|
||||||
|
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
|
||||||
|
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
|
||||||
|
|
||||||
|
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
|
||||||
|
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
|
||||||
|
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
|
||||||
|
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
|
||||||
|
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
|
||||||
|
|
||||||
|
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
|
||||||
|
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
|
||||||
|
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
|
||||||
|
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
|
||||||
|
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
|
||||||
|
|
||||||
|
buf[0] += a;
|
||||||
|
buf[1] += b;
|
||||||
|
buf[2] += c;
|
||||||
|
buf[3] += d;
|
||||||
|
}
|
||||||
|
|
||||||
|
void cs_md5_update(cs_md5_ctx *ctx, const unsigned char *buf, size_t len) {
|
||||||
|
uint32_t t;
|
||||||
|
|
||||||
|
t = ctx->bits[0];
|
||||||
|
if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) ctx->bits[1]++;
|
||||||
|
ctx->bits[1] += (uint32_t) len >> 29;
|
||||||
|
|
||||||
|
t = (t >> 3) & 0x3f;
|
||||||
|
|
||||||
|
if (t) {
|
||||||
|
unsigned char *p = (unsigned char *) ctx->in + t;
|
||||||
|
|
||||||
|
t = 64 - t;
|
||||||
|
if (len < t) {
|
||||||
|
memcpy(p, buf, len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
memcpy(p, buf, t);
|
||||||
|
byteReverse(ctx->in, 16);
|
||||||
|
cs_md5_transform(ctx->buf, (uint32_t *) ctx->in);
|
||||||
|
buf += t;
|
||||||
|
len -= t;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (len >= 64) {
|
||||||
|
memcpy(ctx->in, buf, 64);
|
||||||
|
byteReverse(ctx->in, 16);
|
||||||
|
cs_md5_transform(ctx->buf, (uint32_t *) ctx->in);
|
||||||
|
buf += 64;
|
||||||
|
len -= 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(ctx->in, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
void cs_md5_final(unsigned char digest[16], cs_md5_ctx *ctx) {
|
||||||
|
unsigned count;
|
||||||
|
unsigned char *p;
|
||||||
|
uint32_t *a;
|
||||||
|
|
||||||
|
count = (ctx->bits[0] >> 3) & 0x3F;
|
||||||
|
|
||||||
|
p = ctx->in + count;
|
||||||
|
*p++ = 0x80;
|
||||||
|
count = 64 - 1 - count;
|
||||||
|
if (count < 8) {
|
||||||
|
memset(p, 0, count);
|
||||||
|
byteReverse(ctx->in, 16);
|
||||||
|
cs_md5_transform(ctx->buf, (uint32_t *) ctx->in);
|
||||||
|
memset(ctx->in, 0, 56);
|
||||||
|
} else {
|
||||||
|
memset(p, 0, count - 8);
|
||||||
|
}
|
||||||
|
byteReverse(ctx->in, 14);
|
||||||
|
|
||||||
|
a = (uint32_t *) ctx->in;
|
||||||
|
a[14] = ctx->bits[0];
|
||||||
|
a[15] = ctx->bits[1];
|
||||||
|
|
||||||
|
cs_md5_transform(ctx->buf, (uint32_t *) ctx->in);
|
||||||
|
byteReverse((unsigned char *) ctx->buf, 4);
|
||||||
|
memcpy(digest, ctx->buf, 16);
|
||||||
|
memset((char *) ctx, 0, sizeof(*ctx));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CS_DISABLE_MD5 */
|
||||||
|
#endif /* EXCLUDE_COMMON */
|
33
src/mongoose-6.11/src/common/cs_md5.h
Normal file
33
src/mongoose-6.11/src/common/cs_md5.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_MD5_H_
|
||||||
|
#define CS_COMMON_MD5_H_
|
||||||
|
|
||||||
|
#include "common/platform.h"
|
||||||
|
|
||||||
|
#ifndef CS_DISABLE_MD5
|
||||||
|
#define CS_DISABLE_MD5 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32_t buf[4];
|
||||||
|
uint32_t bits[2];
|
||||||
|
unsigned char in[64];
|
||||||
|
} cs_md5_ctx;
|
||||||
|
|
||||||
|
void cs_md5_init(cs_md5_ctx *c);
|
||||||
|
void cs_md5_update(cs_md5_ctx *c, const unsigned char *data, size_t len);
|
||||||
|
void cs_md5_final(unsigned char *md, cs_md5_ctx *c);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_MD5_H_ */
|
83
src/mongoose-6.11/src/common/cs_time.c
Normal file
83
src/mongoose-6.11/src/common/cs_time.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "common/cs_time.h"
|
||||||
|
|
||||||
|
#ifndef _WIN32
|
||||||
|
#include <stddef.h>
|
||||||
|
/*
|
||||||
|
* There is no sys/time.h on ARMCC.
|
||||||
|
*/
|
||||||
|
#if !(defined(__ARMCC_VERSION) || defined(__ICCARM__)) && \
|
||||||
|
!defined(__TI_COMPILER_VERSION__) && \
|
||||||
|
(!defined(CS_PLATFORM) || CS_PLATFORM != CS_P_NXP_LPC)
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
double cs_time(void) WEAK;
|
||||||
|
double cs_time(void) {
|
||||||
|
double now;
|
||||||
|
#ifndef _WIN32
|
||||||
|
struct timeval tv;
|
||||||
|
if (gettimeofday(&tv, NULL /* tz */) != 0) return 0;
|
||||||
|
now = (double) tv.tv_sec + (((double) tv.tv_usec) / 1000000.0);
|
||||||
|
#else
|
||||||
|
SYSTEMTIME sysnow;
|
||||||
|
FILETIME ftime;
|
||||||
|
GetLocalTime(&sysnow);
|
||||||
|
SystemTimeToFileTime(&sysnow, &ftime);
|
||||||
|
/*
|
||||||
|
* 1. VC 6.0 doesn't support conversion uint64 -> double, so, using int64
|
||||||
|
* This should not cause a problems in this (21th) century
|
||||||
|
* 2. Windows FILETIME is a number of 100-nanosecond intervals since January
|
||||||
|
* 1, 1601 while time_t is a number of _seconds_ since January 1, 1970 UTC,
|
||||||
|
* thus, we need to convert to seconds and adjust amount (subtract 11644473600
|
||||||
|
* seconds)
|
||||||
|
*/
|
||||||
|
now = (double) (((int64_t) ftime.dwLowDateTime +
|
||||||
|
((int64_t) ftime.dwHighDateTime << 32)) /
|
||||||
|
10000000.0) -
|
||||||
|
11644473600;
|
||||||
|
#endif /* _WIN32 */
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
|
||||||
|
double cs_timegm(const struct tm *tm) {
|
||||||
|
/* Month-to-day offset for non-leap-years. */
|
||||||
|
static const int month_day[12] = {0, 31, 59, 90, 120, 151,
|
||||||
|
181, 212, 243, 273, 304, 334};
|
||||||
|
|
||||||
|
/* Most of the calculation is easy; leap years are the main difficulty. */
|
||||||
|
int month = tm->tm_mon % 12;
|
||||||
|
int year = tm->tm_year + tm->tm_mon / 12;
|
||||||
|
int year_for_leap;
|
||||||
|
int64_t rt;
|
||||||
|
|
||||||
|
if (month < 0) { /* Negative values % 12 are still negative. */
|
||||||
|
month += 12;
|
||||||
|
--year;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is the number of Februaries since 1900. */
|
||||||
|
year_for_leap = (month > 1) ? year + 1 : year;
|
||||||
|
|
||||||
|
rt =
|
||||||
|
tm->tm_sec /* Seconds */
|
||||||
|
+
|
||||||
|
60 *
|
||||||
|
(tm->tm_min /* Minute = 60 seconds */
|
||||||
|
+
|
||||||
|
60 * (tm->tm_hour /* Hour = 60 minutes */
|
||||||
|
+
|
||||||
|
24 * (month_day[month] + tm->tm_mday - 1 /* Day = 24 hours */
|
||||||
|
+ 365 * (year - 70) /* Year = 365 days */
|
||||||
|
+ (year_for_leap - 69) / 4 /* Every 4 years is leap... */
|
||||||
|
- (year_for_leap - 1) / 100 /* Except centuries... */
|
||||||
|
+ (year_for_leap + 299) / 400))); /* Except 400s. */
|
||||||
|
return rt < 0 ? -1 : (double) rt;
|
||||||
|
}
|
30
src/mongoose-6.11/src/common/cs_time.h
Normal file
30
src/mongoose-6.11/src/common/cs_time.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_CS_TIME_H_
|
||||||
|
#define CS_COMMON_CS_TIME_H_
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
#include "common/platform.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
/* Sub-second granularity time(). */
|
||||||
|
double cs_time(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Similar to (non-standard) timegm, converts broken-down time into the number
|
||||||
|
* of seconds since Unix Epoch.
|
||||||
|
*/
|
||||||
|
double cs_timegm(const struct tm *tm);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif /* __cplusplus */
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_CS_TIME_H_ */
|
33
src/mongoose-6.11/src/common/mg_mem.h
Normal file
33
src/mongoose-6.11/src/common/mg_mem.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_MG_MEM_H_
|
||||||
|
#define CS_COMMON_MG_MEM_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_MALLOC
|
||||||
|
#define MG_MALLOC malloc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_CALLOC
|
||||||
|
#define MG_CALLOC calloc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_REALLOC
|
||||||
|
#define MG_REALLOC realloc
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MG_FREE
|
||||||
|
#define MG_FREE free
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_MG_MEM_H_ */
|
121
src/mongoose-6.11/src/common/platform.h
Normal file
121
src/mongoose-6.11/src/common/platform.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
#ifndef CS_COMMON_PLATFORM_H_
|
||||||
|
#define CS_COMMON_PLATFORM_H_
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For the "custom" platform, includes and dependencies can be
|
||||||
|
* provided through mg_locals.h.
|
||||||
|
*/
|
||||||
|
#define CS_P_CUSTOM 0
|
||||||
|
#define CS_P_UNIX 1
|
||||||
|
#define CS_P_WINDOWS 2
|
||||||
|
#define CS_P_ESP32 15
|
||||||
|
#define CS_P_ESP8266 3
|
||||||
|
#define CS_P_CC3100 6
|
||||||
|
#define CS_P_CC3200 4
|
||||||
|
#define CS_P_CC3220 17
|
||||||
|
#define CS_P_MSP432 5
|
||||||
|
#define CS_P_TM4C129 14
|
||||||
|
#define CS_P_MBED 7
|
||||||
|
#define CS_P_WINCE 8
|
||||||
|
#define CS_P_NXP_LPC 13
|
||||||
|
#define CS_P_NXP_KINETIS 9
|
||||||
|
#define CS_P_NRF51 12
|
||||||
|
#define CS_P_NRF52 10
|
||||||
|
#define CS_P_PIC32 11
|
||||||
|
#define CS_P_STM32 16
|
||||||
|
/* Next id: 18 */
|
||||||
|
|
||||||
|
/* If not specified explicitly, we guess platform by defines. */
|
||||||
|
#ifndef CS_PLATFORM
|
||||||
|
|
||||||
|
#if defined(TARGET_IS_MSP432P4XX) || defined(__MSP432P401R__)
|
||||||
|
#define CS_PLATFORM CS_P_MSP432
|
||||||
|
#elif defined(cc3200) || defined(TARGET_IS_CC3200)
|
||||||
|
#define CS_PLATFORM CS_P_CC3200
|
||||||
|
#elif defined(cc3220) || defined(TARGET_IS_CC3220)
|
||||||
|
#define CS_PLATFORM CS_P_CC3220
|
||||||
|
#elif defined(__unix__) || defined(__APPLE__)
|
||||||
|
#define CS_PLATFORM CS_P_UNIX
|
||||||
|
#elif defined(WINCE)
|
||||||
|
#define CS_PLATFORM CS_P_WINCE
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
#define CS_PLATFORM CS_P_WINDOWS
|
||||||
|
#elif defined(__MBED__)
|
||||||
|
#define CS_PLATFORM CS_P_MBED
|
||||||
|
#elif defined(__USE_LPCOPEN)
|
||||||
|
#define CS_PLATFORM CS_P_NXP_LPC
|
||||||
|
#elif defined(FRDM_K64F) || defined(FREEDOM)
|
||||||
|
#define CS_PLATFORM CS_P_NXP_KINETIS
|
||||||
|
#elif defined(PIC32)
|
||||||
|
#define CS_PLATFORM CS_P_PIC32
|
||||||
|
#elif defined(ESP_PLATFORM)
|
||||||
|
#define CS_PLATFORM CS_P_ESP32
|
||||||
|
#elif defined(ICACHE_FLASH)
|
||||||
|
#define CS_PLATFORM CS_P_ESP8266
|
||||||
|
#elif defined(TARGET_IS_TM4C129_RA0) || defined(TARGET_IS_TM4C129_RA1) || \
|
||||||
|
defined(TARGET_IS_TM4C129_RA2)
|
||||||
|
#define CS_PLATFORM CS_P_TM4C129
|
||||||
|
#elif defined(STM32)
|
||||||
|
#define CS_PLATFORM CS_P_STM32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef CS_PLATFORM
|
||||||
|
#error "CS_PLATFORM is not specified and we couldn't guess it."
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* !defined(CS_PLATFORM) */
|
||||||
|
|
||||||
|
#define MG_NET_IF_SOCKET 1
|
||||||
|
#define MG_NET_IF_SIMPLELINK 2
|
||||||
|
#define MG_NET_IF_LWIP_LOW_LEVEL 3
|
||||||
|
#define MG_NET_IF_PIC32 4
|
||||||
|
|
||||||
|
#define MG_SSL_IF_OPENSSL 1
|
||||||
|
#define MG_SSL_IF_MBEDTLS 2
|
||||||
|
#define MG_SSL_IF_SIMPLELINK 3
|
||||||
|
|
||||||
|
#include "common/platforms/platform_unix.h"
|
||||||
|
#include "common/platforms/platform_windows.h"
|
||||||
|
#include "common/platforms/platform_esp32.h"
|
||||||
|
#include "common/platforms/platform_esp8266.h"
|
||||||
|
#include "common/platforms/platform_cc3100.h"
|
||||||
|
#include "common/platforms/platform_cc3200.h"
|
||||||
|
#include "common/platforms/platform_cc3220.h"
|
||||||
|
#include "common/platforms/platform_mbed.h"
|
||||||
|
#include "common/platforms/platform_nrf51.h"
|
||||||
|
#include "common/platforms/platform_nrf52.h"
|
||||||
|
#include "common/platforms/platform_wince.h"
|
||||||
|
#include "common/platforms/platform_nxp_lpc.h"
|
||||||
|
#include "common/platforms/platform_nxp_kinetis.h"
|
||||||
|
#include "common/platforms/platform_pic32.h"
|
||||||
|
#include "common/platforms/platform_stm32.h"
|
||||||
|
|
||||||
|
/* Common stuff */
|
||||||
|
|
||||||
|
#if !defined(WEAK)
|
||||||
|
#if (defined(__GNUC__) || defined(__TI_COMPILER_VERSION__)) && !defined(_WIN32)
|
||||||
|
#define WEAK __attribute__((weak))
|
||||||
|
#else
|
||||||
|
#define WEAK
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define NORETURN __attribute__((noreturn))
|
||||||
|
#define NOINLINE __attribute__((noinline))
|
||||||
|
#define WARN_UNUSED_RESULT __attribute__((warn_unused_result))
|
||||||
|
#define NOINSTR __attribute__((no_instrument_function))
|
||||||
|
#define DO_NOT_WARN_UNUSED __attribute__((unused))
|
||||||
|
#else
|
||||||
|
#define NORETURN
|
||||||
|
#define NOINLINE
|
||||||
|
#define WARN_UNUSED_RESULT
|
||||||
|
#define NOINSTR
|
||||||
|
#define DO_NOT_WARN_UNUSED
|
||||||
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
#ifndef ARRAY_SIZE
|
||||||
|
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORM_H_ */
|
168
src/mongoose-6.11/src/common/platforms/arm/arm_exc.c
Normal file
168
src/mongoose-6.11/src/common/platforms/arm/arm_exc.c
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2017 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
|
||||||
|
#include "common/platform.h"
|
||||||
|
|
||||||
|
#include "mgos_core_dump.h"
|
||||||
|
#include "mgos_hal.h"
|
||||||
|
|
||||||
|
struct arm_exc_frame {
|
||||||
|
uint32_t r0;
|
||||||
|
uint32_t r1;
|
||||||
|
uint32_t r2;
|
||||||
|
uint32_t r3;
|
||||||
|
uint32_t r12;
|
||||||
|
uint32_t lr;
|
||||||
|
uint32_t pc;
|
||||||
|
uint32_t xpsr;
|
||||||
|
#ifdef ARM_HAVE_FPU
|
||||||
|
uint32_t s[16];
|
||||||
|
uint32_t fpscr;
|
||||||
|
uint32_t reserved;
|
||||||
|
#endif
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
struct arm_gdb_reg_file {
|
||||||
|
uint32_t r[13];
|
||||||
|
uint32_t sp;
|
||||||
|
uint32_t lr;
|
||||||
|
uint32_t pc;
|
||||||
|
uint32_t cpsr;
|
||||||
|
uint64_t d[16];
|
||||||
|
uint32_t fpscr;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#if ARM_HAVE_FPU
|
||||||
|
static void save_s16_s31(uint32_t *dst) {
|
||||||
|
__asm volatile(
|
||||||
|
"\
|
||||||
|
vmov r1, s16\n str r1, [%0, 0]\n\
|
||||||
|
vmov r1, s17\n str r1, [%0, 4]\n\
|
||||||
|
vmov r1, s18\n str r1, [%0, 8]\n\
|
||||||
|
vmov r1, s19\n str r1, [%0, 12]\n\
|
||||||
|
vmov r1, s20\n str r1, [%0, 16]\n\
|
||||||
|
vmov r1, s21\n str r1, [%0, 20]\n\
|
||||||
|
vmov r1, s22\n str r1, [%0, 24]\n\
|
||||||
|
vmov r1, s23\n str r1, [%0, 28]\n\
|
||||||
|
vmov r1, s24\n str r1, [%0, 32]\n\
|
||||||
|
vmov r1, s25\n str r1, [%0, 36]\n\
|
||||||
|
vmov r1, s26\n str r1, [%0, 40]\n\
|
||||||
|
vmov r1, s27\n str r1, [%0, 44]\n\
|
||||||
|
vmov r1, s28\n str r1, [%0, 48]\n\
|
||||||
|
vmov r1, s29\n str r1, [%0, 52]\n\
|
||||||
|
vmov r1, s30\n str r1, [%0, 56]\n\
|
||||||
|
vmov r1, s31\n str r1, [%0, 60]\n\
|
||||||
|
"
|
||||||
|
:
|
||||||
|
: "r"(dst)
|
||||||
|
: "r1");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void print_fpu_regs(const uint32_t *regs, int off, int n) {
|
||||||
|
for (int i = 0, j = off; i < n; i++, j++) {
|
||||||
|
if (j % 4 == 0) mgos_cd_putc('\n');
|
||||||
|
mgos_cd_printf(" S%d: %s0x%08lx", j, (j < 10 ? " " : ""), regs[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void arm_exc_handler_bottom(uint8_t isr_no, struct arm_exc_frame *ef,
|
||||||
|
struct arm_gdb_reg_file *rf) {
|
||||||
|
char buf[8];
|
||||||
|
const char *name;
|
||||||
|
portDISABLE_INTERRUPTS();
|
||||||
|
switch (isr_no) {
|
||||||
|
case 0:
|
||||||
|
name = "ThreadMode";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
case 7:
|
||||||
|
case 8:
|
||||||
|
case 9:
|
||||||
|
case 10:
|
||||||
|
case 13:
|
||||||
|
name = "Reserved";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
name = "NMI";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
name = "HardFault";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
name = "MemManage";
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
name = "BusFault";
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
name = "UsageFault";
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
name = "SVCall";
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
name = "ReservedDebug";
|
||||||
|
break;
|
||||||
|
case 14:
|
||||||
|
name = "PendSV";
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
name = "SysTick";
|
||||||
|
break;
|
||||||
|
default: {
|
||||||
|
sprintf(buf, "IRQ%u", isr_no - 16);
|
||||||
|
name = buf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mgos_cd_printf("\n\n--- Exception %u (%s) ---\n", isr_no, name);
|
||||||
|
if (rf != NULL) {
|
||||||
|
mgos_cd_printf(" R0: 0x%08lx R1: 0x%08lx R2: 0x%08lx R3: 0x%08lx\n",
|
||||||
|
rf->r[0], rf->r[1], rf->r[2], rf->r[3]);
|
||||||
|
mgos_cd_printf(" R4: 0x%08lx R5: 0x%08lx R6: 0x%08lx R7: 0x%08lx\n",
|
||||||
|
rf->r[4], rf->r[5], rf->r[6], rf->r[7]);
|
||||||
|
mgos_cd_printf(" R8: 0x%08lx R9: 0x%08lx R10: 0x%08lx R11: 0x%08lx\n",
|
||||||
|
rf->r[8], rf->r[9], rf->r[10], rf->r[11]);
|
||||||
|
mgos_cd_printf(" R12: 0x%08lx SP: 0x%08lx LR: 0x%08lx PC: 0x%08lx\n",
|
||||||
|
rf->r[12], rf->sp, rf->lr, rf->pc);
|
||||||
|
mgos_cd_printf(" PSR: 0x%08lx\n", rf->cpsr);
|
||||||
|
}
|
||||||
|
memset(rf->d, 0, sizeof(rf->d));
|
||||||
|
#if ARM_HAVE_FPU
|
||||||
|
rf->fpscr = ef->fpscr;
|
||||||
|
memcpy((uint8_t *) rf->d, ef->s, sizeof(ef->s));
|
||||||
|
print_fpu_regs((uint32_t *) rf->d, 0, ARRAY_SIZE(ef->s));
|
||||||
|
save_s16_s31(ef->s);
|
||||||
|
memcpy(((uint8_t *) rf->d) + sizeof(ef->s), ef->s, sizeof(ef->s));
|
||||||
|
print_fpu_regs((uint32_t *) (((uint8_t *) rf->d) + sizeof(ef->s)), 16,
|
||||||
|
ARRAY_SIZE(ef->s));
|
||||||
|
mgos_cd_putc('\n');
|
||||||
|
mgos_cd_printf("FPSCR: 0x%08lx\n", rf->fpscr);
|
||||||
|
#else
|
||||||
|
rf->fpscr = 0;
|
||||||
|
#endif
|
||||||
|
mgos_cd_emit_header();
|
||||||
|
mgos_cd_emit_section(MGOS_CORE_DUMP_SECTION_REGS, rf, sizeof(*rf));
|
||||||
|
mgos_cd_emit_section("SRAM", (void *) SRAM_BASE_ADDR, SRAM_SIZE);
|
||||||
|
mgos_cd_emit_footer();
|
||||||
|
#ifdef MGOS_HALT_ON_EXCEPTION
|
||||||
|
mgos_cd_printf("Halting\n");
|
||||||
|
while (1) {
|
||||||
|
mgos_wdt_feed();
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
mgos_cd_printf("Rebooting\n");
|
||||||
|
mgos_dev_system_restart();
|
||||||
|
#endif
|
||||||
|
}
|
69
src/mongoose-6.11/src/common/platforms/arm/arm_exc_top.S
Normal file
69
src/mongoose-6.11/src/common/platforms/arm/arm_exc_top.S
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2017 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
.arch armv7e-m
|
||||||
|
.syntax unified
|
||||||
|
.thumb
|
||||||
|
|
||||||
|
/* These are required to satisfy TI linker. */
|
||||||
|
.eabi_attribute Tag_ABI_align_needed, 1
|
||||||
|
.eabi_attribute Tag_ABI_align_preserved, 1
|
||||||
|
|
||||||
|
.global arm_exc_handler_top
|
||||||
|
.global arm_exc_handler_bottom
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Determines the stack pointer, populates most of the GDB frame
|
||||||
|
* and hands off to the C routine.
|
||||||
|
*/
|
||||||
|
.section .text.arm_exc_handler_top
|
||||||
|
.type arm_exc_handler_top, %function
|
||||||
|
.align 8
|
||||||
|
|
||||||
|
arm_exc_handler_top:
|
||||||
|
tst lr, #4
|
||||||
|
ite eq
|
||||||
|
mrseq r1, msp
|
||||||
|
mrsne r1, psp
|
||||||
|
// r1 -> arm_exc_frame prepared for us by the CPU
|
||||||
|
#if ARM_HAVE_FPU
|
||||||
|
add r0, r1, #104 // sizeof(arm_exc_frame)
|
||||||
|
sub sp, #328 // sizeof(arm_gdb_reg_file)
|
||||||
|
#else
|
||||||
|
add r0, r1, #32 // sizeof(arm_exc_frame)
|
||||||
|
sub sp, #328 // sizeof(arm_gdb_reg_file)
|
||||||
|
#endif
|
||||||
|
mov r2, sp
|
||||||
|
// r0 -> original sp, r2 -> arm_gdb_reg_file to fill
|
||||||
|
// r3 - scratch
|
||||||
|
ldr r3, [r1, #0] // r0
|
||||||
|
str r3, [r2, #0]
|
||||||
|
ldr r3, [r1, #4] // r2
|
||||||
|
str r3, [r2, #4]
|
||||||
|
ldr r3, [r1, #8] // r1
|
||||||
|
str r3, [r2, #8]
|
||||||
|
ldr r3, [r1, #12] // r3
|
||||||
|
str r3, [r2, #12]
|
||||||
|
str r4, [r2, #16] // r4
|
||||||
|
str r5, [r2, #20] // r5
|
||||||
|
str r6, [r2, #24] // r6
|
||||||
|
str r7, [r2, #28] // r7
|
||||||
|
str r8, [r2, #32] // r8
|
||||||
|
str r9, [r2, #36] // r9
|
||||||
|
str r10, [r2, #40] // r10
|
||||||
|
str r11, [r2, #44] // r11
|
||||||
|
ldr r3, [r1, #16] // r12
|
||||||
|
str r3, [r2, #48]
|
||||||
|
str r0, [r2, #52] // sp
|
||||||
|
ldr r3, [r1, #20] // lr
|
||||||
|
str r3, [r2, #56]
|
||||||
|
ldr r3, [r1, #24] // pc
|
||||||
|
str r3, [r2, #60]
|
||||||
|
ldr r3, [r1, #28] // xpsr
|
||||||
|
str r3, [r2, #64]
|
||||||
|
|
||||||
|
mrs r0, ipsr
|
||||||
|
b arm_exc_handler_bottom
|
||||||
|
.size arm_exc_handler_top, . - arm_exc_handler_top
|
92
src/mongoose-6.11/src/common/platforms/cc3200/cc3200.ld
Normal file
92
src/mongoose-6.11/src/common/platforms/cc3200/cc3200.ld
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
*
|
||||||
|
* GCC Linker script for CC3200. Based on TI's example "blinky.ld".
|
||||||
|
*
|
||||||
|
* Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* 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 Texas Instruments Incorporated 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
|
||||||
|
* OWNER 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.
|
||||||
|
*
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
ORG = DEFINED(ORG) ? ORG : 0x20004000;
|
||||||
|
RAM_SIZE = DEFINED(RAM_SIZE) ? RAM_SIZE : 0x3C000;
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/* SRAM size of 240KB for cc3200 ES 1.33 device onward */
|
||||||
|
SRAM (rwx) : ORIGIN = ORG, LENGTH = RAM_SIZE
|
||||||
|
}
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.text :
|
||||||
|
{
|
||||||
|
_text = .;
|
||||||
|
KEEP(*(.intvecs))
|
||||||
|
*(.text*)
|
||||||
|
*(.rodata*)
|
||||||
|
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||||
|
. = ALIGN(8);
|
||||||
|
_etext = .;
|
||||||
|
} > SRAM
|
||||||
|
|
||||||
|
.ARM : {
|
||||||
|
__exidx_start = .;
|
||||||
|
*(.ARM.exidx*)
|
||||||
|
__exidx_end = .;
|
||||||
|
} > SRAM
|
||||||
|
|
||||||
|
__init_data = .;
|
||||||
|
|
||||||
|
.data : AT(__init_data)
|
||||||
|
{
|
||||||
|
_data = .;
|
||||||
|
*(.data*)
|
||||||
|
. = ALIGN (8);
|
||||||
|
_edata = .;
|
||||||
|
} > SRAM
|
||||||
|
|
||||||
|
.bss :
|
||||||
|
{
|
||||||
|
_bss = .;
|
||||||
|
*(.bss*)
|
||||||
|
*(COMMON)
|
||||||
|
_ebss = .;
|
||||||
|
} > SRAM
|
||||||
|
|
||||||
|
.heap :
|
||||||
|
{
|
||||||
|
_heap = .;
|
||||||
|
. = . + (LENGTH(SRAM) - SIZEOF(.text) - SIZEOF(.ARM) - SIZEOF(.data) - SIZEOF(.bss));
|
||||||
|
. = ALIGN(8);
|
||||||
|
_eheap = .;
|
||||||
|
|
||||||
|
} > SRAM
|
||||||
|
}
|
103
src/mongoose-6.11/src/common/platforms/cc3200/cc3200_libc.c
Normal file
103
src/mongoose-6.11/src/common/platforms/cc3200/cc3200_libc.c
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if CS_PLATFORM == CS_P_CC3200
|
||||||
|
|
||||||
|
#include "common/mg_mem.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifndef __TI_COMPILER_VERSION__
|
||||||
|
#include <reent.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <inc/hw_types.h>
|
||||||
|
#include <inc/hw_memmap.h>
|
||||||
|
#include <driverlib/prcm.h>
|
||||||
|
#include <driverlib/rom.h>
|
||||||
|
#include <driverlib/rom_map.h>
|
||||||
|
#include <driverlib/uart.h>
|
||||||
|
#include <driverlib/utils.h>
|
||||||
|
|
||||||
|
#define CONSOLE_UART UARTA0_BASE
|
||||||
|
|
||||||
|
#ifdef __TI_COMPILER_VERSION__
|
||||||
|
int asprintf(char **strp, const char *fmt, ...) {
|
||||||
|
va_list ap;
|
||||||
|
int len;
|
||||||
|
|
||||||
|
*strp = MG_MALLOC(BUFSIZ);
|
||||||
|
if (*strp == NULL) return -1;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
len = vsnprintf(*strp, BUFSIZ, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
if (len > 0) {
|
||||||
|
*strp = MG_REALLOC(*strp, len + 1);
|
||||||
|
if (*strp == NULL) return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len >= BUFSIZ) {
|
||||||
|
va_start(ap, fmt);
|
||||||
|
len = vsnprintf(*strp, len + 1, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MG_TI_NO_HOST_INTERFACE
|
||||||
|
time_t HOSTtime() {
|
||||||
|
struct timeval tp;
|
||||||
|
gettimeofday(&tp, NULL);
|
||||||
|
return tp.tv_sec;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __TI_COMPILER_VERSION__ */
|
||||||
|
|
||||||
|
void fprint_str(FILE *fp, const char *str) {
|
||||||
|
while (*str != '\0') {
|
||||||
|
if (*str == '\n') MAP_UARTCharPut(CONSOLE_UART, '\r');
|
||||||
|
MAP_UARTCharPut(CONSOLE_UART, *str++);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _exit(int status) {
|
||||||
|
fprint_str(stderr, "_exit\n");
|
||||||
|
/* cause an unaligned access exception, that will drop you into gdb */
|
||||||
|
*(int *) 1 = status;
|
||||||
|
while (1)
|
||||||
|
; /* avoid gcc warning because stdlib abort() has noreturn attribute */
|
||||||
|
}
|
||||||
|
|
||||||
|
void _not_implemented(const char *what) {
|
||||||
|
fprint_str(stderr, what);
|
||||||
|
fprint_str(stderr, " is not implemented\n");
|
||||||
|
_exit(42);
|
||||||
|
}
|
||||||
|
|
||||||
|
int _kill(int pid, int sig) {
|
||||||
|
(void) pid;
|
||||||
|
(void) sig;
|
||||||
|
_not_implemented("_kill");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _getpid() {
|
||||||
|
fprint_str(stderr, "_getpid is not implemented\n");
|
||||||
|
return 42;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _isatty(int fd) {
|
||||||
|
/* 0, 1 and 2 are TTYs. */
|
||||||
|
return fd < 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* CS_PLATFORM == CS_P_CC3200 */
|
@ -0,0 +1,82 @@
|
|||||||
|
//*****************************************************************************
|
||||||
|
// cc3200v1p32.cmd
|
||||||
|
//
|
||||||
|
// CCS linker configuration file for cc3200 ES 1.32.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// 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 Texas Instruments Incorporated 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
|
||||||
|
// OWNER 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.
|
||||||
|
//
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
--retain=g_pfnVectors
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// The following command line options are set as part of the CCS project.
|
||||||
|
// If you are building using the command line, or for some reason want to
|
||||||
|
// define them here, you can uncomment and modify these lines as needed.
|
||||||
|
// If you are using CCS for building, it is probably better to make any such
|
||||||
|
// modifications in your CCS project and leave this file alone.
|
||||||
|
//*****************************************************************************
|
||||||
|
|
||||||
|
|
||||||
|
//*****************************************************************************
|
||||||
|
// The starting address of the application. Normally the interrupt vectors
|
||||||
|
// must be located at the beginning of the application.
|
||||||
|
//*****************************************************************************
|
||||||
|
#define RAM_BASE 0x20004000
|
||||||
|
|
||||||
|
/* System memory map */
|
||||||
|
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
/* Application uses internal RAM for program and data */
|
||||||
|
SRAM_CODE (RWX) : origin = 0x20004000, length = 0x2F000
|
||||||
|
SRAM_DATA (RWX) : origin = 0x20033000, length = 0xD000
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section allocation in memory */
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
.intvecs: > RAM_BASE
|
||||||
|
.init_array : > SRAM_CODE
|
||||||
|
.vtable : > SRAM_CODE
|
||||||
|
.text : > SRAM_CODE
|
||||||
|
.const : > SRAM_CODE
|
||||||
|
.cinit : > SRAM_CODE
|
||||||
|
.pinit : > SRAM_CODE
|
||||||
|
.data : > SRAM_DATA
|
||||||
|
.bss : > SRAM_DATA
|
||||||
|
.sysmem : > SRAM_DATA
|
||||||
|
.stack : > SRAM_DATA(HIGH)
|
||||||
|
}
|
||||||
|
|
52
src/mongoose-6.11/src/common/platforms/cc3200/gcc.mk
Normal file
52
src/mongoose-6.11/src/common/platforms/cc3200/gcc.mk
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
APP_LDFLAGS ?=
|
||||||
|
CC_WRAPPER ?=
|
||||||
|
GENFILES_LIST ?=
|
||||||
|
CC = arm-none-eabi-gcc
|
||||||
|
CXX = arm-none-eabi-g++
|
||||||
|
AR = arm-none-eabi-ar
|
||||||
|
NM = arm-none-eabi-nm
|
||||||
|
|
||||||
|
IPATH += $(SDK_PATH)/third_party/FreeRTOS/source/portable/GCC/ARM_CM4
|
||||||
|
VPATH += $(SDK_PATH)/third_party/FreeRTOS/source/portable/GCC/ARM_CM4
|
||||||
|
|
||||||
|
C_CXX_FLAGS = -mthumb -mcpu=cortex-m4 -ffunction-sections -fdata-sections \
|
||||||
|
-MD -Os -ggdb -Wall -Werror -Dgcc
|
||||||
|
CFLAGS += -std=c99 $(C_CXX_FLAGS)
|
||||||
|
CXXFLAGS += -std=g++11 $(C_CXX_FLAGS)
|
||||||
|
|
||||||
|
AR = arm-none-eabi-ar
|
||||||
|
LD = arm-none-eabi-ld
|
||||||
|
OBJCOPY = arm-none-eabi-objcopy
|
||||||
|
LIBGCC := ${shell ${CC} -mthumb ${CFLAGS} -print-libgcc-file-name}
|
||||||
|
LIBC := ${shell ${CC} ${CFLAGS} -print-file-name=libc.a}
|
||||||
|
LIBM := ${shell ${CC} ${CFLAGS} -print-file-name=libm.a}
|
||||||
|
|
||||||
|
# Disable certain warnings on SDK sources, we have no control over them anyway.
|
||||||
|
# We also force-include platform.h which resolves some symbol conflicts
|
||||||
|
# between system includes and simplelink.h
|
||||||
|
$(SDK_OBJS): CFLAGS += -Wno-missing-braces -Wno-strict-aliasing -Wno-parentheses -Wno-unused-variable -Wno-builtin-macro-redefined
|
||||||
|
$(SDK_OBJS): CFLAGS += -include common/platform.h
|
||||||
|
|
||||||
|
# cc flags,file
|
||||||
|
define cc
|
||||||
|
$(vecho) "GCC $2 -> $@"
|
||||||
|
$(Q) $(CC_WRAPPER) $(CC) -c $1 -o $@ $2
|
||||||
|
endef
|
||||||
|
define cxx
|
||||||
|
$(vecho) "G++ $2 -> $@"
|
||||||
|
$(Q) $(CC_WRAPPER) $(CXX) -c $1 -o $@ $2
|
||||||
|
endef
|
||||||
|
|
||||||
|
# ar files
|
||||||
|
define ar
|
||||||
|
$(vecho) "AR $@"
|
||||||
|
$(Q) $(AR) cru $@ $1
|
||||||
|
endef
|
||||||
|
|
||||||
|
# link script,flags,objs
|
||||||
|
define link
|
||||||
|
$(vecho) "LD $@"
|
||||||
|
$(Q) $(CC_WRAPPER) $(LD) \
|
||||||
|
--gc-sections -o $@ -T $1 $2 $3 \
|
||||||
|
$(LIBM) $(LIBC) $(LIBGCC)
|
||||||
|
endef
|
52
src/mongoose-6.11/src/common/platforms/cc3200/ti.mk
Normal file
52
src/mongoose-6.11/src/common/platforms/cc3200/ti.mk
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
IPATH += $(SDK_PATH)/third_party/FreeRTOS/source/portable/CCS/ARM_CM3
|
||||||
|
VPATH += $(SDK_PATH)/third_party/FreeRTOS/source/portable/CCS/ARM_CM3
|
||||||
|
|
||||||
|
CC_WRAPPER ?=
|
||||||
|
CC = $(TOOLCHAIN)/bin/armcl
|
||||||
|
AR = $(TOOLCHAIN)/bin/armar
|
||||||
|
NM = nm
|
||||||
|
GENFILES_LIST ?=
|
||||||
|
|
||||||
|
C_CXX_FLAGS = -Dccs -I$(TOOLCHAIN)/include
|
||||||
|
TI_C_CXX_FLAGS = -mv7M4 --little_endian --code_state=16 --float_support=vfplib --abi=eabi \
|
||||||
|
-O4 --opt_for_speed=0 --unaligned_access=on --small_enum \
|
||||||
|
--gen_func_subsections=on --diag_wrap=off --display_error_number \
|
||||||
|
--emit_warnings_as_errors
|
||||||
|
CFLAGS += --c99 $(TI_C_CXX_FLAGS) $(C_CXX_FLAGS)
|
||||||
|
CXXFLAGS += $(TI_C_CXX_FLAGS) $(C_CXX_FLAGS)
|
||||||
|
|
||||||
|
# cc flags,file
|
||||||
|
define cc
|
||||||
|
$(vecho) "TICC $2 -> $@"
|
||||||
|
$(Q) $(CC_WRAPPER) $(CC) -c --preproc_with_compile -ppd=$@.d $1 --output_file=$@ $2
|
||||||
|
endef
|
||||||
|
define cxx
|
||||||
|
$(vecho) "TICXX $2 -> $@"
|
||||||
|
$(Q) $(CC_WRAPPER) $(CC) -c --preproc_with_compile -ppd=$@.d $1 --output_file=$@ $2
|
||||||
|
endef
|
||||||
|
|
||||||
|
# asm flags,file
|
||||||
|
define asm
|
||||||
|
$(vecho) "TIASM $2 -> $@"
|
||||||
|
$(Q) $(CC_WRAPPER) $(CC) -c $1 --output_file=$@ $2
|
||||||
|
endef
|
||||||
|
|
||||||
|
# ar files
|
||||||
|
define ar
|
||||||
|
$(vecho) "TIAR $@"
|
||||||
|
$(Q) $(AR) qru $@ $1
|
||||||
|
endef
|
||||||
|
|
||||||
|
# link script,flags,objs
|
||||||
|
define link
|
||||||
|
$(vecho) "TILD $@"
|
||||||
|
$(Q) $(CC_WRAPPER) $(CC) \
|
||||||
|
-mv7M4 --code_state=16 --float_support=vfplib --abi=eabi --little_endian \
|
||||||
|
--run_linker \
|
||||||
|
--generate_dead_funcs_list=$@.garbage.xml \
|
||||||
|
-i $(TOOLCHAIN)/lib \
|
||||||
|
--reread_libs --warn_sections --display_error_number \
|
||||||
|
--unused_section_elimination=on \
|
||||||
|
-o $@ --map_file=$@.map --xml_link_info=$@.map.xml \
|
||||||
|
$2 $1 $3
|
||||||
|
endef
|
2133
src/mongoose-6.11/src/common/platforms/esp/esptool.py
Executable file
2133
src/mongoose-6.11/src/common/platforms/esp/esptool.py
Executable file
File diff suppressed because it is too large
Load Diff
35
src/mongoose-6.11/src/common/platforms/esp/slip.c
Normal file
35
src/mongoose-6.11/src/common/platforms/esp/slip.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include "rom_functions.h"
|
||||||
|
|
||||||
|
void SLIP_send(uint8_t *pkt, uint32_t size) {
|
||||||
|
send_packet(pkt, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t SLIP_recv(void *pkt, uint32_t max_len) {
|
||||||
|
uint8_t c;
|
||||||
|
uint32_t len = 0;
|
||||||
|
uint8_t *p = (uint8_t *) pkt;
|
||||||
|
do {
|
||||||
|
c = uart_rx_one_char_block();
|
||||||
|
} while (c != '\xc0');
|
||||||
|
while (len < max_len) {
|
||||||
|
c = uart_rx_one_char_block();
|
||||||
|
if (c == '\xc0') return len;
|
||||||
|
if (c == '\xdb') {
|
||||||
|
c = uart_rx_one_char_block();
|
||||||
|
if (c == '\xdc') {
|
||||||
|
c = '\xc0';
|
||||||
|
} else if (c == '\xdd') {
|
||||||
|
c = '\xdb';
|
||||||
|
} else {
|
||||||
|
len = 0;
|
||||||
|
break; /* Bad esc sequence. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*p++ = c;
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
c = uart_rx_one_char_block();
|
||||||
|
} while (c != '\xc0');
|
||||||
|
return len;
|
||||||
|
}
|
9
src/mongoose-6.11/src/common/platforms/esp/slip.h
Normal file
9
src/mongoose-6.11/src/common/platforms/esp/slip.h
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_STUBS_SLIP_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_STUBS_SLIP_H_
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
void SLIP_send(const void *pkt, uint32_t size);
|
||||||
|
uint32_t SLIP_recv(void *pkt, uint32_t max_len);
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_STUBS_SLIP_H_ */
|
559
src/mongoose-6.11/src/common/platforms/esp/stub_flasher.c
Normal file
559
src/mongoose-6.11/src/common/platforms/esp/stub_flasher.c
Normal file
@ -0,0 +1,559 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
* Spiffy flasher. Implements strong checksums (MD5) and can use higher
|
||||||
|
* baud rates. Actual max baud rate will differe from device to device,
|
||||||
|
* but 921K seems to be common.
|
||||||
|
*
|
||||||
|
* SLIP protocol is used for communication.
|
||||||
|
* First packet is a single byte - command number.
|
||||||
|
* After that, a packet with a variable number of 32-bit (LE) arguments,
|
||||||
|
* depending on command.
|
||||||
|
*
|
||||||
|
* Then command produces variable number of packets of output, but first
|
||||||
|
* packet of length 1 is the response code: 0 for success, non-zero - error.
|
||||||
|
*
|
||||||
|
* See individual command description below.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stub_flasher.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "rom_functions.h"
|
||||||
|
|
||||||
|
#if defined(ESP8266)
|
||||||
|
#include "eagle_soc.h"
|
||||||
|
#include "ets_sys.h"
|
||||||
|
#include "../../../miniz.c"
|
||||||
|
#elif defined(ESP32)
|
||||||
|
#include "rom/efuse.h"
|
||||||
|
#include "rom/miniz.h"
|
||||||
|
#include "rom/spi_flash.h"
|
||||||
|
#include "soc/uart_reg.h"
|
||||||
|
#include "led.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "slip.h"
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
/* Param: baud rate. */
|
||||||
|
uint32_t params[1] __attribute__((section(".params")));
|
||||||
|
|
||||||
|
#define FLASH_BLOCK_SIZE 65536
|
||||||
|
#define FLASH_SECTOR_SIZE 4096
|
||||||
|
#define FLASH_PAGE_SIZE 256
|
||||||
|
|
||||||
|
/* These consts should be in sync with flasher_client.go */
|
||||||
|
#define NUM_BUFS 4
|
||||||
|
#define BUF_SIZE 4096
|
||||||
|
#define FLASH_WRITE_SIZE BUF_SIZE
|
||||||
|
|
||||||
|
#define UART_RX_INTS (UART_RXFIFO_FULL_INT_ENA | UART_RXFIFO_TOUT_INT_ENA)
|
||||||
|
|
||||||
|
extern uint32_t _bss_start, _bss_end;
|
||||||
|
|
||||||
|
#ifdef ESP8266
|
||||||
|
#define REG_SPI_BASE(i) (0x60000200 - i * 0x100)
|
||||||
|
|
||||||
|
#define SPI_CMD_REG(i) (REG_SPI_BASE(i) + 0x0)
|
||||||
|
#define SPI_FLASH_WREN (BIT(30))
|
||||||
|
#define SPI_FLASH_RDID (BIT(28))
|
||||||
|
#define SPI_FLASH_SE (BIT(24))
|
||||||
|
#define SPI_FLASH_BE (BIT(23))
|
||||||
|
|
||||||
|
#define SPI_ADDR_REG(i) (REG_SPI_BASE(i) + 0x4)
|
||||||
|
|
||||||
|
#define SPI_USER_REG(i) (REG_SPI_BASE(i) + 0x1C)
|
||||||
|
|
||||||
|
#define SPI_W0_REG(i) (REG_SPI_BASE(i) + 0x40)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
enum read_state {
|
||||||
|
READ_WAIT_START = 0,
|
||||||
|
READ_FLAGS,
|
||||||
|
READ_DATA,
|
||||||
|
READ_UNESCAPE,
|
||||||
|
READ_ERROR,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct data_buf {
|
||||||
|
uint32_t len;
|
||||||
|
uint8_t data[BUF_SIZE];
|
||||||
|
uint8_t flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define FLAG_COMPRESSED 1
|
||||||
|
|
||||||
|
struct uart_buf {
|
||||||
|
enum read_state state;
|
||||||
|
struct data_buf bufs[NUM_BUFS];
|
||||||
|
uint32_t bri, bwi;
|
||||||
|
uint32_t ps;
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline uint32_t ccount(void) {
|
||||||
|
uint32_t r;
|
||||||
|
__asm volatile("rsr.ccount %0" : "=a"(r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct write_progress {
|
||||||
|
uint32_t num_written;
|
||||||
|
uint32_t buf_level;
|
||||||
|
uint8_t digest[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
struct write_result {
|
||||||
|
uint32_t wait_time;
|
||||||
|
uint32_t decomp_time;
|
||||||
|
uint32_t write_time;
|
||||||
|
uint32_t erase_time;
|
||||||
|
uint32_t total_time;
|
||||||
|
uint8_t digest[16];
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct uart_buf ub;
|
||||||
|
static uint32_t inflate_buf[TINFL_LZ_DICT_SIZE / sizeof(uint32_t)];
|
||||||
|
|
||||||
|
static void next_write_buf(void) {
|
||||||
|
ub.bwi++;
|
||||||
|
if (ub.bwi == NUM_BUFS) ub.bwi = 0;
|
||||||
|
ub.bufs[ub.bwi].len = 0;
|
||||||
|
ub.bufs[ub.bwi].flags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void add_byte(uint8_t byte) {
|
||||||
|
struct data_buf *buf = &ub.bufs[ub.bwi];
|
||||||
|
if (buf->len < BUF_SIZE) {
|
||||||
|
buf->data[buf->len++] = byte;
|
||||||
|
ub.ps++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uart_isr(void *arg) {
|
||||||
|
uint32_t int_st = READ_PERI_REG(UART_INT_ST_REG(0));
|
||||||
|
uint8_t fifo_len, i;
|
||||||
|
while ((fifo_len = READ_PERI_REG(UART_STATUS_REG(0))) > 0) {
|
||||||
|
for (i = 0; i < fifo_len; i++) {
|
||||||
|
uint8_t byte = READ_PERI_REG(UART_FIFO_REG(0));
|
||||||
|
switch (ub.state) {
|
||||||
|
case READ_WAIT_START: {
|
||||||
|
if (byte == 0xc0) {
|
||||||
|
ub.state = READ_FLAGS;
|
||||||
|
ub.ps = 0;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case READ_FLAGS:
|
||||||
|
case READ_DATA: {
|
||||||
|
struct data_buf *buf = &ub.bufs[ub.bwi];
|
||||||
|
if (byte == 0xdb) {
|
||||||
|
ub.state = READ_UNESCAPE;
|
||||||
|
} else if (byte == 0xc0) {
|
||||||
|
next_write_buf();
|
||||||
|
if (ub.ps == 0) {
|
||||||
|
/* Empty packet, sender aborted. */
|
||||||
|
ub.state = READ_ERROR;
|
||||||
|
SET_PERI_REG_MASK(UART_INT_ENA_REG(0), 0);
|
||||||
|
goto out;
|
||||||
|
} else {
|
||||||
|
ub.state = READ_WAIT_START;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (ub.state == READ_FLAGS) {
|
||||||
|
buf->flags = byte;
|
||||||
|
ub.state = READ_DATA;
|
||||||
|
} else {
|
||||||
|
add_byte(byte);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case READ_UNESCAPE: {
|
||||||
|
if (byte == 0xdc) {
|
||||||
|
byte = 0xc0;
|
||||||
|
} else if (byte == 0xdd) {
|
||||||
|
byte = 0xdb;
|
||||||
|
} else {
|
||||||
|
ub.state = READ_ERROR;
|
||||||
|
SET_PERI_REG_MASK(UART_INT_ENA_REG(0), 0);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
add_byte(byte);
|
||||||
|
ub.state = READ_DATA;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case READ_ERROR: {
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
out:
|
||||||
|
WRITE_PERI_REG(UART_INT_CLR_REG(0), int_st);
|
||||||
|
(void) arg;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t tinfl_decompress_mem_to_mem(void *pOut_buf, size_t out_buf_len,
|
||||||
|
const void *pSrc_buf, size_t src_buf_len,
|
||||||
|
int flags);
|
||||||
|
#define TINFL_DECOMPRESS_MEM_TO_MEM_FAILED ((size_t)(-1))
|
||||||
|
#define TINFL_FLAG_PARSE_ZLIB_HEADER 1
|
||||||
|
|
||||||
|
#if defined(ESP8266)
|
||||||
|
int esp_rom_spiflash_erase_start(uint32_t addr, uint32_t cmd) {
|
||||||
|
SPI_write_enable(flashchip);
|
||||||
|
WRITE_PERI_REG(SPI_ADDR_REG(0), addr);
|
||||||
|
WRITE_PERI_REG(SPI_CMD_REG(0), cmd);
|
||||||
|
while (READ_PERI_REG(SPI_CMD_REG(0)) & cmd) {
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#elif defined(ESP32)
|
||||||
|
extern esp_rom_spiflash_chip_t g_rom_spiflash_chip;
|
||||||
|
|
||||||
|
esp_rom_spiflash_result_t esp_rom_spiflash_erase_start(uint32_t addr,
|
||||||
|
uint32_t cmd) {
|
||||||
|
esp_rom_spiflash_chip_t *spi = &g_rom_spiflash_chip;
|
||||||
|
esp_rom_spiflash_wait_idle(spi);
|
||||||
|
|
||||||
|
REG_CLR_BIT(PERIPHS_SPI_FLASH_USRREG, SPI_USR_DUMMY);
|
||||||
|
REG_SET_FIELD(PERIPHS_SPI_FLASH_USRREG1, SPI_USR_ADDR_BITLEN,
|
||||||
|
ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN);
|
||||||
|
|
||||||
|
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, SPI_FLASH_WREN);
|
||||||
|
while (READ_PERI_REG(PERIPHS_SPI_FLASH_CMD) != 0) {
|
||||||
|
}
|
||||||
|
|
||||||
|
WRITE_PERI_REG(PERIPHS_SPI_FLASH_ADDR, addr);
|
||||||
|
WRITE_PERI_REG(PERIPHS_SPI_FLASH_CMD, cmd);
|
||||||
|
|
||||||
|
return ESP_ROM_SPIFLASH_RESULT_OK;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int do_flash_write(uint32_t addr, uint32_t len, uint32_t erase) {
|
||||||
|
int ret = 0;
|
||||||
|
uint32_t num_erased = 0;
|
||||||
|
struct MD5Context ctx;
|
||||||
|
MD5Init(&ctx);
|
||||||
|
|
||||||
|
if (addr % FLASH_SECTOR_SIZE != 0) return 0x32;
|
||||||
|
if (len % FLASH_SECTOR_SIZE != 0) return 0x33;
|
||||||
|
if (esp_rom_spiflash_unlock() != 0) return 0x34;
|
||||||
|
|
||||||
|
memset(&ub, 0, sizeof(ub));
|
||||||
|
memset(&inflate_buf, 0, sizeof(inflate_buf));
|
||||||
|
ets_isr_attach(ETS_UART0_INUM, uart_isr, &ub);
|
||||||
|
uint32_t saved_conf1 = READ_PERI_REG(UART_CONF1_REG(0));
|
||||||
|
/* Reduce frequency of UART interrupts */
|
||||||
|
WRITE_PERI_REG(UART_CONF1_REG(0), UART_RX_TOUT_EN |
|
||||||
|
(20 << UART_RX_TOUT_THRHD_S) |
|
||||||
|
(100 << UART_RXFIFO_FULL_THRHD_S));
|
||||||
|
SET_PERI_REG_MASK(UART_INT_ENA_REG(0), UART_RX_INTS);
|
||||||
|
ets_isr_unmask(1 << ETS_UART0_INUM);
|
||||||
|
|
||||||
|
struct write_result wr;
|
||||||
|
memset(&wr, 0, sizeof(wr));
|
||||||
|
|
||||||
|
struct write_progress wp = {.num_written = 0, .buf_level = 0};
|
||||||
|
wp.buf_level = (uint32_t) &addr;
|
||||||
|
SLIP_send(&wp, sizeof(wp));
|
||||||
|
wr.total_time = ccount();
|
||||||
|
while (wp.num_written < len) {
|
||||||
|
/* Prepare the space ahead. */
|
||||||
|
uint32_t start_count = ccount();
|
||||||
|
while (erase && num_erased < wp.num_written + FLASH_WRITE_SIZE) {
|
||||||
|
const uint32_t num_left = (len - num_erased);
|
||||||
|
if (num_left >= FLASH_BLOCK_SIZE && addr % FLASH_BLOCK_SIZE == 0) {
|
||||||
|
if (esp_rom_spiflash_erase_start(addr, SPI_FLASH_BE) != 0) {
|
||||||
|
ret = 0x35;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
num_erased += FLASH_BLOCK_SIZE;
|
||||||
|
} else {
|
||||||
|
/* len % FLASH_SECTOR_SIZE == 0 is enforced, no further checks needed */
|
||||||
|
if (esp_rom_spiflash_erase_start(addr, SPI_FLASH_SE) != 0) {
|
||||||
|
ret = 0x36;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
num_erased += FLASH_SECTOR_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wr.erase_time += ccount() - start_count;
|
||||||
|
start_count = ccount();
|
||||||
|
/* Wait for data to arrive. */
|
||||||
|
wp.buf_level = 0;
|
||||||
|
for (int i = 0; i < NUM_BUFS; i++) wp.buf_level += ub.bufs[i].len;
|
||||||
|
volatile uint32_t *bwi = &ub.bwi;
|
||||||
|
while (*bwi == ub.bri && ub.state != READ_ERROR) {
|
||||||
|
}
|
||||||
|
struct data_buf *buf = &ub.bufs[ub.bri];
|
||||||
|
if (ub.state == READ_ERROR) {
|
||||||
|
ret = 0x37;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
wr.wait_time += ccount() - start_count;
|
||||||
|
start_count = ccount();
|
||||||
|
uint32_t *data = (uint32_t *) buf->data;
|
||||||
|
uint32_t write_len = buf->len;
|
||||||
|
if (buf->flags & FLAG_COMPRESSED) {
|
||||||
|
data = inflate_buf;
|
||||||
|
write_len = tinfl_decompress_mem_to_mem(
|
||||||
|
&inflate_buf[0], sizeof(inflate_buf), buf->data, write_len,
|
||||||
|
TINFL_FLAG_PARSE_ZLIB_HEADER);
|
||||||
|
if (write_len == TINFL_DECOMPRESS_MEM_TO_MEM_FAILED) {
|
||||||
|
ret = 0x40;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
wr.decomp_time += ccount() - start_count;
|
||||||
|
MD5Update(&ctx, (uint8_t *) data, write_len);
|
||||||
|
start_count = ccount();
|
||||||
|
wr.erase_time += ccount() - start_count;
|
||||||
|
start_count = ccount();
|
||||||
|
if (esp_rom_spiflash_write(addr, data, write_len) != 0) {
|
||||||
|
ret = 0x38;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
wr.write_time += ccount() - start_count;
|
||||||
|
buf->len = 0;
|
||||||
|
ub.bri++;
|
||||||
|
if (ub.bri == NUM_BUFS) ub.bri = 0;
|
||||||
|
addr += write_len;
|
||||||
|
wp.num_written += write_len;
|
||||||
|
struct MD5Context ctx2;
|
||||||
|
memcpy(&ctx2, &ctx, sizeof(ctx));
|
||||||
|
MD5Final(wp.digest, &ctx2);
|
||||||
|
SLIP_send(&wp, sizeof(wp));
|
||||||
|
}
|
||||||
|
|
||||||
|
MD5Final(wr.digest, &ctx);
|
||||||
|
|
||||||
|
wr.total_time = ccount() - wr.total_time;
|
||||||
|
SLIP_send(&wr, sizeof(wr));
|
||||||
|
|
||||||
|
out:
|
||||||
|
WRITE_PERI_REG(UART_CONF1_REG(0), saved_conf1);
|
||||||
|
ets_isr_mask(1 << ETS_UART0_INUM);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_flash_read(uint32_t addr, uint32_t len, uint32_t block_size,
|
||||||
|
uint32_t max_in_flight) {
|
||||||
|
uint8_t buf[FLASH_SECTOR_SIZE];
|
||||||
|
uint8_t digest[16];
|
||||||
|
struct MD5Context ctx;
|
||||||
|
uint32_t num_sent = 0, num_acked = 0;
|
||||||
|
if (block_size > sizeof(buf)) return 0x52;
|
||||||
|
MD5Init(&ctx);
|
||||||
|
while (num_acked < len) {
|
||||||
|
while (num_sent < len && num_sent - num_acked < max_in_flight) {
|
||||||
|
uint32_t n = len - num_sent;
|
||||||
|
if (n > block_size) n = block_size;
|
||||||
|
if (esp_rom_spiflash_read(addr, (uint32_t *) buf, n) != 0) return 0x53;
|
||||||
|
send_packet(buf, n);
|
||||||
|
MD5Update(&ctx, buf, n);
|
||||||
|
addr += n;
|
||||||
|
num_sent += n;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
if (SLIP_recv(&num_acked, sizeof(num_acked)) != 4) return 0x54;
|
||||||
|
if (num_acked > num_sent) return 0x55;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MD5Final(digest, &ctx);
|
||||||
|
send_packet(digest, sizeof(digest));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_flash_digest(uint32_t addr, uint32_t len, uint32_t digest_block_size) {
|
||||||
|
uint8_t buf[FLASH_SECTOR_SIZE];
|
||||||
|
uint8_t digest[16];
|
||||||
|
uint32_t read_block_size =
|
||||||
|
digest_block_size ? digest_block_size : sizeof(buf);
|
||||||
|
struct MD5Context ctx;
|
||||||
|
if (digest_block_size > sizeof(buf)) return 0x62;
|
||||||
|
MD5Init(&ctx);
|
||||||
|
while (len > 0) {
|
||||||
|
uint32_t n = len;
|
||||||
|
struct MD5Context block_ctx;
|
||||||
|
MD5Init(&block_ctx);
|
||||||
|
if (n > read_block_size) n = read_block_size;
|
||||||
|
if (esp_rom_spiflash_read(addr, (uint32_t *) buf, n) != 0) return 0x63;
|
||||||
|
MD5Update(&ctx, buf, n);
|
||||||
|
if (digest_block_size > 0) {
|
||||||
|
MD5Update(&block_ctx, buf, n);
|
||||||
|
MD5Final(digest, &block_ctx);
|
||||||
|
send_packet(digest, sizeof(digest));
|
||||||
|
}
|
||||||
|
addr += n;
|
||||||
|
len -= n;
|
||||||
|
}
|
||||||
|
MD5Final(digest, &ctx);
|
||||||
|
send_packet(digest, sizeof(digest));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int do_flash_read_chip_id(void) {
|
||||||
|
uint32_t chip_id = 0;
|
||||||
|
WRITE_PERI_REG(SPI_CMD_REG(0), SPI_FLASH_RDID);
|
||||||
|
while (READ_PERI_REG(SPI_CMD_REG(0)) & SPI_FLASH_RDID) {
|
||||||
|
}
|
||||||
|
chip_id = READ_PERI_REG(SPI_W0_REG(0)) & 0xFFFFFF;
|
||||||
|
send_packet((uint8_t *) &chip_id, sizeof(chip_id));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t cmd_loop(void) {
|
||||||
|
uint8_t cmd = 0x55;
|
||||||
|
do {
|
||||||
|
/* Reset FIFO to re-sync */
|
||||||
|
SET_PERI_REG_MASK(UART_CONF0_REG(0), UART_RXFIFO_RST);
|
||||||
|
CLEAR_PERI_REG_MASK(UART_CONF0_REG(0), UART_RXFIFO_RST);
|
||||||
|
uint32_t args[4];
|
||||||
|
uint32_t len = SLIP_recv(&cmd, 1);
|
||||||
|
if (len != 1) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
uint8_t resp = 0xff;
|
||||||
|
switch (cmd) {
|
||||||
|
case CMD_FLASH_WRITE: {
|
||||||
|
len = SLIP_recv(args, sizeof(args));
|
||||||
|
if (len == 12) {
|
||||||
|
resp = do_flash_write(args[0] /* addr */, args[1] /* len */,
|
||||||
|
args[2] /* erase */);
|
||||||
|
} else {
|
||||||
|
resp = 0x41;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_FLASH_READ: {
|
||||||
|
len = SLIP_recv(args, sizeof(args));
|
||||||
|
if (len == 16) {
|
||||||
|
resp = do_flash_read(args[0] /* addr */, args[1], /* len */
|
||||||
|
args[2] /* block_size */,
|
||||||
|
args[3] /* max_in_flight */);
|
||||||
|
} else {
|
||||||
|
resp = 0x51;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_FLASH_DIGEST: {
|
||||||
|
len = SLIP_recv(args, sizeof(args));
|
||||||
|
if (len == 12) {
|
||||||
|
resp = do_flash_digest(args[0] /* addr */, args[1], /* len */
|
||||||
|
args[2] /* digest_block_size */);
|
||||||
|
} else {
|
||||||
|
resp = 0x61;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_FLASH_READ_CHIP_ID: {
|
||||||
|
resp = do_flash_read_chip_id();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_FLASH_ERASE_CHIP: {
|
||||||
|
resp = esp_rom_spiflash_erase_chip();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CMD_BOOT_FW:
|
||||||
|
case CMD_REBOOT: {
|
||||||
|
resp = 0;
|
||||||
|
SLIP_send(&resp, 1);
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
case CMD_ECHO: {
|
||||||
|
len = SLIP_recv(args, sizeof(args));
|
||||||
|
SLIP_send(args, len);
|
||||||
|
resp = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
SLIP_send(&resp, 1);
|
||||||
|
} while (cmd != CMD_BOOT_FW && cmd != CMD_REBOOT);
|
||||||
|
return cmd;
|
||||||
|
}
|
||||||
|
|
||||||
|
void stub_main1(void) {
|
||||||
|
uint32_t baud_rate = params[0];
|
||||||
|
uint32_t greeting = 0x4941484f; /* OHAI */
|
||||||
|
uint8_t last_cmd;
|
||||||
|
|
||||||
|
/* This points at us right now, reset for next boot. */
|
||||||
|
ets_set_user_start(0);
|
||||||
|
|
||||||
|
/* Selects SPI functions for flash pins. */
|
||||||
|
#if defined(ESP8266)
|
||||||
|
SelectSpiFunction();
|
||||||
|
SET_PERI_REG_MASK(0x3FF00014, 1); /* Switch to 160 MHz */
|
||||||
|
#elif defined(ESP32)
|
||||||
|
esp_rom_spiflash_attach(ets_efuse_get_spiconfig(), 0 /* legacy */);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
esp_rom_spiflash_config_param(
|
||||||
|
0 /* deviceId */, 16 * 1024 * 1024 /* chip_size */, FLASH_BLOCK_SIZE,
|
||||||
|
FLASH_SECTOR_SIZE, FLASH_PAGE_SIZE, 0xffff /* status_mask */);
|
||||||
|
|
||||||
|
if (baud_rate > 0) {
|
||||||
|
ets_delay_us(10000);
|
||||||
|
set_baud_rate(0, baud_rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Give host time to get ready too. */
|
||||||
|
ets_delay_us(50000);
|
||||||
|
|
||||||
|
#ifdef BAUD_TEST
|
||||||
|
while (1) {
|
||||||
|
WRITE_PERI_REG(UART_FIFO_REG(0), 0x55);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
SLIP_send(&greeting, 4);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
last_cmd = cmd_loop();
|
||||||
|
|
||||||
|
ets_delay_us(10000);
|
||||||
|
|
||||||
|
if (last_cmd == CMD_BOOT_FW) {
|
||||||
|
#if defined(ESP8266)
|
||||||
|
/*
|
||||||
|
* Find the return address in our own stack and change it.
|
||||||
|
* "flash_finish" it gets to the same point, except it doesn't need to
|
||||||
|
* patch up its RA: it returns from UartDwnLdProc, then from f_400011ac,
|
||||||
|
* then jumps to 0x4000108a, then checks strapping bits again (which will
|
||||||
|
* not have changed), and then proceeds to 0x400010a8.
|
||||||
|
*/
|
||||||
|
volatile uint32_t *sp = &baud_rate;
|
||||||
|
while (*sp != (uint32_t) 0x40001100) sp++;
|
||||||
|
*sp = 0x400010a8;
|
||||||
|
/*
|
||||||
|
* The following dummy asm fragment acts as a barrier, to make sure function
|
||||||
|
* epilogue, including return address loading, is added after our stack
|
||||||
|
* patching.
|
||||||
|
*/
|
||||||
|
__asm volatile("nop.n");
|
||||||
|
return; /* To 0x400010a8 */
|
||||||
|
#elif defined(ESP32)
|
||||||
|
/* TODO(rojer) */
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
software_reset();
|
||||||
|
}
|
||||||
|
/* Not reached */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* miniz requires at least 12K of stack */
|
||||||
|
uint32_t stack[3071];
|
||||||
|
uint32_t stack_end;
|
||||||
|
|
||||||
|
void stub_main(void) {
|
||||||
|
memset(&_bss_start, 0, (&_bss_end - &_bss_start));
|
||||||
|
__asm volatile("movi a1, stack_end\n");
|
||||||
|
stub_main1();
|
||||||
|
// Keep the stack vars alive.
|
||||||
|
stack[0] = stack_end = 0xff;
|
||||||
|
}
|
96
src/mongoose-6.11/src/common/platforms/esp/stub_flasher.h
Normal file
96
src/mongoose-6.11/src/common/platforms/esp/stub_flasher.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_STUBS_STUB_FLASHER_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_STUBS_STUB_FLASHER_H_
|
||||||
|
|
||||||
|
enum stub_cmd {
|
||||||
|
/*
|
||||||
|
* Write to the SPI flash.
|
||||||
|
*
|
||||||
|
* Args: addr, len, erase; addr and len must be SECTOR_SIZE-aligned.
|
||||||
|
* If erase != 0, perform erase before writing.
|
||||||
|
* Input: Stream of data to be written, note: no SLIP encapsulation here.
|
||||||
|
* Output: SLIP packets with number of bytes written after every write.
|
||||||
|
* This can (and should) be used for flow control. Flasher will
|
||||||
|
* write in 1K chunks but will buffer up to 4K of data
|
||||||
|
* Use this feedback to keep buffer above 1K but below 4K.
|
||||||
|
* Final packet will contain MD5 digest of the data written.
|
||||||
|
*/
|
||||||
|
CMD_FLASH_WRITE = 1,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read from the SPI flash.
|
||||||
|
*
|
||||||
|
* Args: addr, len, block_size; no alignment requirements, block_size <= 4K.
|
||||||
|
* Input: None.
|
||||||
|
* Output: Packets of up to block_size with data. An acknowledgement is
|
||||||
|
*expected
|
||||||
|
* after every packet, in the form of a packet with total number of
|
||||||
|
* bytes received so far.
|
||||||
|
* Last packet is the MD5 digest of the data sent.
|
||||||
|
*
|
||||||
|
* Note: No flow control is performed, it is assumed that the host can cope
|
||||||
|
* with the inbound stream.
|
||||||
|
*/
|
||||||
|
CMD_FLASH_READ = 2,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute MD5 digest of the specified flash region.
|
||||||
|
*
|
||||||
|
* Args: addr, len, digest_block_size; no alignment requirements.
|
||||||
|
* Input: None.
|
||||||
|
* Output: If block digests are not enabled (digest_block_size == 0),
|
||||||
|
* only overall digest is produced.
|
||||||
|
* Otherwise, there will be a separate digest for each block,
|
||||||
|
* the remainder (if any) and the overall digest at the end.
|
||||||
|
*/
|
||||||
|
CMD_FLASH_DIGEST = 3,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read flash chip ID.
|
||||||
|
* This is the JEDEC ID, containinf manufactirer, SPI mode and capacity.
|
||||||
|
*
|
||||||
|
* Args: None.
|
||||||
|
* Input: None.
|
||||||
|
* Output: 32 bit chip id (only 24 bits are meaningful).
|
||||||
|
*/
|
||||||
|
CMD_FLASH_READ_CHIP_ID = 4,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Zap the whole chip at once.
|
||||||
|
*
|
||||||
|
* Args: None.
|
||||||
|
* Input: None.
|
||||||
|
* Output: None.
|
||||||
|
*/
|
||||||
|
CMD_FLASH_ERASE_CHIP = 5,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Boots the firmware from flash.
|
||||||
|
*
|
||||||
|
* Args: None.
|
||||||
|
* Input: None.
|
||||||
|
* Output: None.
|
||||||
|
*/
|
||||||
|
CMD_BOOT_FW = 6,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reboot the CPU.
|
||||||
|
* Since strapping settings are not reset, this will reboot into whatever mode
|
||||||
|
* got us here, most likely UART loader.
|
||||||
|
*
|
||||||
|
* Args: None.
|
||||||
|
* Input: None.
|
||||||
|
* Output: None.
|
||||||
|
*/
|
||||||
|
CMD_REBOOT = 7,
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Echo the arguments back to the host.
|
||||||
|
*
|
||||||
|
* Args: variable.
|
||||||
|
* Input: None.
|
||||||
|
* Output: arguments.
|
||||||
|
*/
|
||||||
|
CMD_ECHO = 8,
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_STUBS_STUB_FLASHER_H_ */
|
1
src/mongoose-6.11/src/common/platforms/esp31/rom/.gitattributes
vendored
Normal file
1
src/mongoose-6.11/src/common/platforms/esp31/rom/.gitattributes
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
rom.bin -nodiff
|
11917
src/mongoose-6.11/src/common/platforms/esp31/rom/ESP31B_ROM.txt
Normal file
11917
src/mongoose-6.11/src/common/platforms/esp31/rom/ESP31B_ROM.txt
Normal file
File diff suppressed because it is too large
Load Diff
4
src/mongoose-6.11/src/common/platforms/esp31/rom/disasm.sh
Executable file
4
src/mongoose-6.11/src/common/platforms/esp31/rom/disasm.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
xtensa-esp108-elf-gcc -Wl,-N,-Ttext,0x40000000 -nostdlib rom.S -o rom.elf && \
|
||||||
|
xtensa-esp108-elf-objdump -d rom.elf > ESP31B_ROM.txt
|
163
src/mongoose-6.11/src/common/platforms/esp31/rom/notes.c
Normal file
163
src/mongoose-6.11/src/common/platforms/esp31/rom/notes.c
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
/* Just some notes scribbled while disassembling */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RTC = 0x60008000
|
||||||
|
* RTC+0x18: ??c????? ???????? ???????? ????????
|
||||||
|
* RTC+0x34: ???????? ??bbbbbb bbbb???? ??aaaaaa
|
||||||
|
*/
|
||||||
|
int _X_get_rst_cause(void) {
|
||||||
|
int ret;
|
||||||
|
int a = GET_PERI_REG_BITS(RTC_STATE1, 6, 0);
|
||||||
|
if (a == 5) {
|
||||||
|
int b = (RTC_STATE1 >> 12) && 0xfff;
|
||||||
|
if (b != 1) {
|
||||||
|
ret = (b == 8 ? a : 0);
|
||||||
|
} else {
|
||||||
|
ret = 20;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = a;
|
||||||
|
}
|
||||||
|
CLEAR_PERI_REG_MASK(RTC_STATE0, RTC_CNTL_SLP_WAKEUP);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* RTC = 0x60008000
|
||||||
|
* RTC+0x38: ???????? ???????? ???????? ??cccccc
|
||||||
|
* RTC+0x74: ???????? ???????? ???????? dddddddd
|
||||||
|
* RTC+0x80: ???????? ??????a? ???b???? ????????
|
||||||
|
*/
|
||||||
|
void main(void) {
|
||||||
|
uint32_t rst_cause = _X_get_rst_cause();
|
||||||
|
CLEAR_PERI_REG_MASK(RTC+0x80, BIT(17)); // a
|
||||||
|
SET_PERI_REG_MASK(RTC+0x80, BIT(12)); // b
|
||||||
|
uint32_t boot_mode = GET_PERI_REG_BITS(GPIO_STRAP, 6, 0); // c
|
||||||
|
if (boot_mode & (BIT(5) | BIT(4)) == (BIT(5) | BIT(4)) || boot_mode == 24 || boot_mode == 26) {
|
||||||
|
CLEAR_PERI_REG_MASK(RTC+0x74, 0xff);
|
||||||
|
}
|
||||||
|
if (boot_mode & (BIT(5) | BIT(4)) == BIT(5)) {
|
||||||
|
CLEAR_PERI_REG_MASK(RTC+0x94, BIT(31));
|
||||||
|
CLEAR_PERI_REG_MASK(RTC+0x98, BIT(31));
|
||||||
|
CLEAR_PERI_REG_MASK(RTC+0x9c, BIT(31));
|
||||||
|
CLEAR_PERI_REG_MASK(RTC+0xa0, BIT(31));
|
||||||
|
CLEAR_PERI_REG_MASK(RTC+0xa4, BIT(31));
|
||||||
|
CLEAR_PERI_REG_MASK(RTC+0xa8, BIT(31));
|
||||||
|
CLEAR_PERI_REG_MASK(RTC+0xac, BIT(31));
|
||||||
|
}
|
||||||
|
if (boot_mode & (BIT(5) | BIT(3)) == 0) {
|
||||||
|
// ... 1405
|
||||||
|
}
|
||||||
|
CLEAR_PERI_REG_MASK(RTC+0x74, 0xff);
|
||||||
|
_X_uart_attach();
|
||||||
|
_X_uart_init(0);
|
||||||
|
// GPIO_STRAP ...
|
||||||
|
ets_printf(boot_banner, fw_build, rst_cause, boot_mode);
|
||||||
|
// rst_cause
|
||||||
|
if (rst_cause == 1 || rst_cause == 2) {
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
ets_printf("%s %u", "ets_main.c", 305);
|
||||||
|
while(1) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GPIO strap mapping:
|
||||||
|
*
|
||||||
|
* 0011 1111 1011 0011
|
||||||
|
* || |||| |||| ||||
|
||||||
|
* || |||| |||| |||`- IO5
|
||||||
|
* || |||| |||| ||`-- IO15
|
||||||
|
* || |||| |||| |`--- IO4
|
||||||
|
* || |||| |||| `---- IO2
|
||||||
|
* || |||| |||`------ ?
|
||||||
|
* || |||| ||`------- IO0
|
||||||
|
* || |||| |`-------- IO12
|
||||||
|
* || |||| `--------- ?
|
||||||
|
* || |||`----------- CLK
|
||||||
|
* || ||`------------ ?
|
||||||
|
* || |`------------- SD0
|
||||||
|
* || `-------------- SD1
|
||||||
|
* |`---------------- ? SD2
|
||||||
|
* `----------------- SD3
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct uartdev {
|
||||||
|
uint32_t baud_rate; // 0
|
||||||
|
uint32_t ud4;
|
||||||
|
uint32_t ud8;
|
||||||
|
uint32_t ud12;
|
||||||
|
uint32_t ud16;
|
||||||
|
uint32_t ud20;
|
||||||
|
uint8_t ud24;
|
||||||
|
uint8_t ud25;
|
||||||
|
uint32_t ud28;
|
||||||
|
uint32_t ud32;
|
||||||
|
uint32_t ud36;
|
||||||
|
uint8_t ud40;
|
||||||
|
uint32_t ud48;
|
||||||
|
uint32_t ud52;
|
||||||
|
};
|
||||||
|
|
||||||
|
void _X_uart_attach(void) {
|
||||||
|
// zero uartdev
|
||||||
|
uartdev.baud_rate = 115200;
|
||||||
|
_X_xtos_ints_off(1 << ETS_UART_INUM);
|
||||||
|
// INTR_MAP_REG_C
|
||||||
|
// 11111111 11111111 11111100 00011111 &
|
||||||
|
// 00000000 00000000 00000000 10100000 |
|
||||||
|
// PRODPORT_INTR_MAP_13 -> 5 = ETS_UART_INUM
|
||||||
|
// 11111111 11111111 10000011 11111111 &
|
||||||
|
// 00000000 00000000 00010100 11111111 |
|
||||||
|
// PRODPORT_INTR_MAP_14 -> 5 = ETS_UART_INUM
|
||||||
|
_xtos_set_interrupt_handler_arg(ETS_UART_INUM, uart_int_handler, _c_0x3fffdb2c_uart_int_handler_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void _X_uart_init(uint32_t a) {
|
||||||
|
// GPIO_FUNC_IN_SEL3
|
||||||
|
// xx999999 88888877 77776666 66555555
|
||||||
|
// 11111111 11111100 00001111 11111111 = 0xfffc0fff
|
||||||
|
// 00000000 00000000 10010000 00000000 = 0x00009000
|
||||||
|
// GPIO17 func => 9
|
||||||
|
// 00000000 00000010 00000000 00000000
|
||||||
|
uart_div_modify(13000000 / uartdev.baud_rate);
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
struct _st_0x3fffdc90 {
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _st_0x3fffdf70 {
|
||||||
|
void *fp1; // 20
|
||||||
|
void *fp2; // 24
|
||||||
|
uint32_t d28;
|
||||||
|
uint32_t d32;
|
||||||
|
uint32_t d36;
|
||||||
|
struct _st_0x3fffdc90 *st; // 44
|
||||||
|
} stdf70;
|
||||||
|
|
||||||
|
void _X_slc_init_attach(void *fp1, void *fp2, struct _st_0x3fffdc90 *st, uint32_t gpio_mode) {
|
||||||
|
stdf70.fp1 = fp1;
|
||||||
|
stdf70.fp2 = fp2;
|
||||||
|
stdf70.st = st;
|
||||||
|
d28 = d32 = d36 = 0;
|
||||||
|
SET_PERI_REG_MASK(WIFI_RST_EN, PRODPORT_SDIO_RST);
|
||||||
|
CLEAR_PERI_REG_MASK(WIFI_RST_EN, PRODPORT_SDIO_RST);
|
||||||
|
if (gpio_mode == 4) {
|
||||||
|
SET_PERI_REG((READ_PERI_REG(PERIPHS_HINF_BASEADDR+4) & 0xf0000000) | 0x01110013);
|
||||||
|
} else {
|
||||||
|
SET_PERI_REG((READ_PERI_REG(PERIPHS_HINF_BASEADDR+4) & 0xf0000000) | 0x02320017);
|
||||||
|
}
|
||||||
|
SET_PERI_REG(PERIPHS_HINF_BASEADDR, 0x11116666);
|
||||||
|
_X_slc_set_host_io_max_window();
|
||||||
|
...
|
||||||
|
}
|
||||||
|
|
||||||
|
#define SLC_TOKEN1 (PERIPHS_SLC_BASEADDR + 0x54)
|
||||||
|
#define SLC_BRIDGE_CONF (PERIPHS_SLC_BASEADDR + 0x74)
|
||||||
|
|
||||||
|
void _X_slc_set_host_io_max_window(void) {
|
||||||
|
SET_PERI_REG(SLC_BRIDGE_CONF, (READ_PERI_REG(SLC_BRIDGE_CONF) & 0xfffff0c0) | 0x720);
|
||||||
|
}
|
16
src/mongoose-6.11/src/common/platforms/esp31/rom/rom.S
Normal file
16
src/mongoose-6.11/src/common/platforms/esp31/rom/rom.S
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
.text
|
||||||
|
.org 0
|
||||||
|
.globl _start
|
||||||
|
|
||||||
|
// xtensa-esp108-elf-gcc -Wl,-N,-Ttext,0x40000000 -nostdlib rom.S -o rom.elf
|
||||||
|
|
||||||
|
here = .
|
||||||
|
#define PROVIDE(name, addr) name = here + addr - 0x40000000
|
||||||
|
|
||||||
|
#include "rom_functions.S"
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
_start:
|
||||||
|
.incbin "rom.bin"
|
||||||
|
_end:
|
BIN
src/mongoose-6.11/src/common/platforms/esp31/rom/rom.bin
Normal file
BIN
src/mongoose-6.11/src/common/platforms/esp31/rom/rom.bin
Normal file
Binary file not shown.
294
src/mongoose-6.11/src/common/platforms/esp31/rom/rom_functions.S
Normal file
294
src/mongoose-6.11/src/common/platforms/esp31/rom/rom_functions.S
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
// These come from linker script
|
||||||
|
|
||||||
|
PROVIDE ( Cache_Read_Disable , 0x4000444c );
|
||||||
|
PROVIDE ( Cache_Read_Enable , 0x4000438c );
|
||||||
|
|
||||||
|
PROVIDE ( ets_delay_us , 0x40002db4 );
|
||||||
|
|
||||||
|
PROVIDE ( bzero , 0x40002a54 );
|
||||||
|
|
||||||
|
PROVIDE ( memcmp , 0x400068ec );
|
||||||
|
PROVIDE ( memcpy , 0x40006974 );
|
||||||
|
PROVIDE ( memmove , 0x40006a6c );
|
||||||
|
PROVIDE ( memset , 0x40006be4 );
|
||||||
|
|
||||||
|
PROVIDE ( strcmp , 0x40005bb8 );
|
||||||
|
PROVIDE ( strcpy , 0x40005cdc );
|
||||||
|
PROVIDE ( strlen , 0x40005d6c );
|
||||||
|
PROVIDE ( strncmp , 0x40005dd0 );
|
||||||
|
PROVIDE ( strncpy , 0x40005e90 );
|
||||||
|
PROVIDE ( strstr , 0x40005f6c );
|
||||||
|
|
||||||
|
PROVIDE ( ets_install_putc1 , 0x40002774 );
|
||||||
|
PROVIDE ( ets_printf , 0x40002804 );
|
||||||
|
PROVIDE ( ets_putc , 0x40002b14 );
|
||||||
|
|
||||||
|
PROVIDE ( ets_str2macaddr , 0x40002a64 );
|
||||||
|
|
||||||
|
PROVIDE ( gpio_output_set , 0x400049d8 );
|
||||||
|
PROVIDE ( gpio_output_set_high , 0x400049f8 );
|
||||||
|
|
||||||
|
PROVIDE ( ets_get_cpu_frequency , 0x40002de8 );
|
||||||
|
PROVIDE ( ets_update_cpu_frequency , 0x40002ddc );
|
||||||
|
|
||||||
|
PROVIDE ( lldesc_build_chain , 0x40004c8c );
|
||||||
|
|
||||||
|
PROVIDE ( multofup , 0x400068a0 );
|
||||||
|
PROVIDE ( roundup2 , 0x40006890 );
|
||||||
|
|
||||||
|
PROVIDE (software_reset_cpu , 0x40002998 );
|
||||||
|
|
||||||
|
PROVIDE ( SPIEraseSector , 0x40004708 );
|
||||||
|
PROVIDE ( SPIRead , 0x40004898 );
|
||||||
|
PROVIDE ( SPIWrite , 0x40004738 );
|
||||||
|
|
||||||
|
PROVIDE ( uart_div_modify , 0x400034e8 );
|
||||||
|
PROVIDE ( uart_tx_one_char , 0x4000362c );
|
||||||
|
|
||||||
|
PROVIDE ( __divsi3 , 0x40006888 );
|
||||||
|
PROVIDE ( __udivdi3 , 0x40006c30 );
|
||||||
|
PROVIDE ( __umoddi3 , 0x40006e64 );
|
||||||
|
|
||||||
|
PROVIDE ( _xtos_set_intlevel , 0x40006670 );
|
||||||
|
|
||||||
|
// These have been reverse-engineered.
|
||||||
|
|
||||||
|
PROVIDE(_XX_Vec40, 0x40000040)
|
||||||
|
PROVIDE(_XX_ExcVec50, 0x40000050)
|
||||||
|
PROVIDE(_XX_ExcVec80, 0x40000080)
|
||||||
|
|
||||||
|
PROVIDE(_XX_Vec400, 0x40000300)
|
||||||
|
|
||||||
|
PROVIDE(_WindowOverflowHandler, 0x40000100)
|
||||||
|
PROVIDE(_WindowUnderflowHandler, 0x40000140)
|
||||||
|
|
||||||
|
PROVIDE(_X_ResetVector, 0x40000500)
|
||||||
|
|
||||||
|
PROVIDE(_c_stack, 0x40000700)
|
||||||
|
PROVIDE(_c_bss_start, 0x40000708)
|
||||||
|
PROVIDE(_c_bss_end, 0x4000070c)
|
||||||
|
PROVIDE(_c_0x3fffc210, 0x40000734)
|
||||||
|
PROVIDE(_c_0x80000000, 0x40000738)
|
||||||
|
PROVIDE(_c_0x40000000, 0x40000760)
|
||||||
|
PROVIDE(_c_0x7fffffff, 0x40000780)
|
||||||
|
PROVIDE(_c_0x00ff0000, 0x40000798)
|
||||||
|
|
||||||
|
PROVIDE(_X_start, 0x400007ac)
|
||||||
|
|
||||||
|
PROVIDE(_c_0x3fffd820, 0x40000f50)
|
||||||
|
PROVIDE(_X_ets_task, 0x40000f54)
|
||||||
|
PROVIDE(_XX_unk0f84, 0x40000f84)
|
||||||
|
PROVIDE(_XX_unk0f96, 0x40000f98)
|
||||||
|
|
||||||
|
PROVIDE(_c_ets_critical_level, 0x400010a4)
|
||||||
|
PROVIDE(_X_ets_enter_critical, 0x400010a8)
|
||||||
|
PROVIDE(_X_ets_exit_critical, 0x400010bc)
|
||||||
|
PROVIDE(_X_ets_exit_critical_and_wait_int, 0x400010d4)
|
||||||
|
PROVIDE(_X_ets_isr_attach, 0x400010e8) // 3 args
|
||||||
|
PROVIDE(_X_ets_isr_mask, 0x400010f8) // 1 arg
|
||||||
|
PROVIDE(_X_ets_isr_unmask, 0x40001104) // 1 arg
|
||||||
|
|
||||||
|
PROVIDE(_c_0x3fffda30, 0x40001110)
|
||||||
|
PROVIDE(_XX_set_0x3fffda30_0, 0x40001114)
|
||||||
|
PROVIDE(_XX_set_0x3fffda30_4, 0x40001120)
|
||||||
|
PROVIDE(_c_0xfffdffff, 0x4000112c)
|
||||||
|
PROVIDE(_c_0x60003e00, 0x40001130)
|
||||||
|
PROVIDE(_c_0x60008200, 0x40001134)
|
||||||
|
PROVIDE(_c_0x60007e00, 0x40001138)
|
||||||
|
PROVIDE(_c_0x1000, 0x4000113c)
|
||||||
|
PROVIDE(_s_fw_build, 0x40001140)
|
||||||
|
PROVIDE(_s_boot_banner, 0x40001144)
|
||||||
|
PROVIDE(_s_pct_s_pct_u, 0x40001148)
|
||||||
|
PROVIDE(_s_ets_main_c, 0x4000114c)
|
||||||
|
PROVIDE(_X_main, 0x4000115c)
|
||||||
|
|
||||||
|
PROVIDE(_l_strap_0x0xxx, 0x4000125a)
|
||||||
|
PROVIDE(_l_strap_init_uart0, 0x40001269)
|
||||||
|
PROVIDE(_l_strap_0x0x00, 0x400012e2)
|
||||||
|
PROVIDE(_l_boot, 0x400012ea)
|
||||||
|
PROVIDE(_l_rst_cause_345, 0x40001336)
|
||||||
|
PROVIDE(_l_rst_cause_12, 0x40001342)
|
||||||
|
PROVIDE(_l_strap_NxNxxx, 0x40001405)
|
||||||
|
PROVIDE(_l_strap_0010xx, 0x4000144c)
|
||||||
|
PROVIDE(_l_strap_001000_0x110x, 0x400014b0)
|
||||||
|
PROVIDE(_l_strap_0x0x11_loader, 0x400014c9) // loader
|
||||||
|
PROVIDE(_l_strap_0x0x01, 0x400014d4)
|
||||||
|
PROVIDE(_l_strap_0x0x10, 0x400014e6)
|
||||||
|
PROVIDE(_c_0xffff8fff, 0x400014f0)
|
||||||
|
PROVIDE(_c_0x60008e00, 0x400014f4)
|
||||||
|
|
||||||
|
PROVIDE(_s_waiting_for_host, 0x4000152c)
|
||||||
|
PROVIDE(_s_mem_banner, 0x40001cdc)
|
||||||
|
PROVIDE(_c_stack_sentry, 0x40001ce0)
|
||||||
|
PROVIDE(_XX_unk153c, 0x4000153c)
|
||||||
|
|
||||||
|
PROVIDE(_c_data_end, 0x40001cd8)
|
||||||
|
PROVIDE(_c_data_start, 0x40001ce4)
|
||||||
|
PROVIDE(_X_print_mem_banner, 0x40001ce8)
|
||||||
|
|
||||||
|
PROVIDE(_s_exc_sp_fmt, 0x40001d0c)
|
||||||
|
PROVIDE(_s_exc_sf_dump_fmt, 0x40001d10)
|
||||||
|
PROVIDE(_s_exc_regs_fmt, 0x40001d14)
|
||||||
|
PROVIDE(_X_exc_handler, 0x40001d18)
|
||||||
|
|
||||||
|
PROVIDE(_XX_unk1d90, 0x40001d90)
|
||||||
|
|
||||||
|
PROVIDE(_X_ets_memset, 0x40001db4)
|
||||||
|
PROVIDE(_X_ets_memcpy, 0x40001dc4)
|
||||||
|
PROVIDE(_X_ets_memmove, 0x40001dd4)
|
||||||
|
PROVIDE(_X_ets_memcmp, 0x40001de4)
|
||||||
|
|
||||||
|
PROVIDE(_st_0x3fffda9c, 0x40002150) // struct
|
||||||
|
|
||||||
|
PROVIDE(_X_ets_uart_putc, 0x4000223c)
|
||||||
|
PROVIDE(_X_ets_unk225c, 0x4000225c)
|
||||||
|
|
||||||
|
PROVIDE(_c_0x4000223c_ets_uart_putc, 0x40002780)
|
||||||
|
PROVIDE(_X_ets_install_uart_printf, 0x40002784)
|
||||||
|
PROVIDE(_c_0x400027dc, 0x40002790)
|
||||||
|
PROVIDE(_X_ets_install_external_printf, 0x40002794)
|
||||||
|
PROVIDE(_X_ets_install_putc2, 0x400027b4)
|
||||||
|
PROVIDE(_X_ets_get_printf_buf_remain_len, 0x400027c0)
|
||||||
|
PROVIDE(_X_ets_reset_printf_buf_len, 0x400027cc)
|
||||||
|
PROVIDE(_X_ets_putc, 0x400027dc)
|
||||||
|
|
||||||
|
PROVIDE(_c_0xdfffffff, 0x400028d4)
|
||||||
|
PROVIDE(_X_get_rst_cause, 0x400028d8)
|
||||||
|
PROVIDE(_XX_unk2948, 0x40002948)
|
||||||
|
PROVIDE(_l_2970, 0x40002970)
|
||||||
|
PROVIDE(_X_sw_sys_rst, 0x4000297c)
|
||||||
|
PROVIDE(_c_0x00400000, 0x400029b4)
|
||||||
|
PROVIDE(_c_0xffbfffff, 0x400029b8)
|
||||||
|
PROVIDE(_XX_apb_bridge_toggle, 0x400029bc) // turns RTC_CNTL_APB2RTC_BRIDGE_SEL on and off
|
||||||
|
PROVIDE(_X_ets_strcpy, 0x400029ec)
|
||||||
|
PROVIDE(_X_ets_strncpy, 0x40002a00)
|
||||||
|
PROVIDE(_X_ets_strcmp, 0x40002a10)
|
||||||
|
PROVIDE(_X_ets_strncmp, 0x40002a24)
|
||||||
|
PROVIDE(_X_ets_strlen, 0x40002a34)
|
||||||
|
PROVIDE(_X_ets_strstr, 0x40002a40)
|
||||||
|
|
||||||
|
PROVIDE(_st_0x3fffdb10_uartdev, 0x40002e4c) // some struct - uartdev?
|
||||||
|
|
||||||
|
PROVIDE(_c_0x3fffdb00, 0x40002e50)
|
||||||
|
PROVIDE(_c_0x3fffdb04, 0x40002f64)
|
||||||
|
PROVIDE(_XX_unk2e58, 0x40002e58)
|
||||||
|
PROVIDE(_X_UartDwnLdProc, 0x40002f6c)
|
||||||
|
PROVIDE(_c_0x00001800, 0x400030ec)
|
||||||
|
PROVIDE(_X_FlashDwnLdStartMsgProc, 0x400030f0)
|
||||||
|
PROVIDE(_XX_unk313c, 0x4000313c)
|
||||||
|
PROVIDE(_XX_unk31bc, 0x400031bc)
|
||||||
|
PROVIDE(_XX_unk31e4, 0x400031e4)
|
||||||
|
PROVIDE(_XX_unk3210, 0x40003210)
|
||||||
|
PROVIDE(_XX_unk3240, 0x40003240)
|
||||||
|
PROVIDE(_X_MemDwnLdStopReqMsgProc, 0x4000329c)
|
||||||
|
PROVIDE(_X_UartConnectProc, 0x400032c4)
|
||||||
|
PROVIDE(_X_UartRegWriteProc, 0x400032d4)
|
||||||
|
PROVIDE(_X_UartRegReadProc, 0x40003318)
|
||||||
|
|
||||||
|
PROVIDE(_c_115200, 0x4000332c)
|
||||||
|
PROVIDE(_c_0x3feffe00, 0x40003330)
|
||||||
|
PROVIDE(_c_0xffff83ff, 0x40003334)
|
||||||
|
PROVIDE(_c_0x00001400, 0x40003338)
|
||||||
|
PROVIDE(_c_0x40003728_uart_int_handler, 0x4000333c)
|
||||||
|
PROVIDE(_c_0x3fffdb2c_uart_int_handler_arg, 0x40003340)
|
||||||
|
PROVIDE(_X_uart_attach, 0x40003344)
|
||||||
|
PROVIDE(_XX_uart_set_unk33c0, 0x400033c0)
|
||||||
|
PROVIDE(_c_0x5ffffe00, 0x400033cc)
|
||||||
|
PROVIDE(_c_0x0000ffff, 0x400033d0)
|
||||||
|
PROVIDE(_c_0x000fffff, 0x40003448)
|
||||||
|
PROVIDE(_c_0x00060000, 0x400034e0)
|
||||||
|
PROVIDE(_c_0xfff9ffff, 0x400034e4)
|
||||||
|
|
||||||
|
PROVIDE(_c_0xfffc0fff, 0x40003520)
|
||||||
|
PROVIDE(_c_0x00009000, 0x40003524)
|
||||||
|
PROVIDE(_c_0x00020000, 0x40003528)
|
||||||
|
PROVIDE(_c_13000000, 0x4000352c)
|
||||||
|
PROVIDE(_c_0x08000000, 0x40003530)
|
||||||
|
PROVIDE(_X_uart_init, 0x40003534)
|
||||||
|
PROVIDE(_l_35f4, 0x400035f4)
|
||||||
|
PROVIDE(_X_uart_wait_tx_empty, 0x4000369c)
|
||||||
|
|
||||||
|
PROVIDE(_X_uart_int_handler, 0x40003728)
|
||||||
|
|
||||||
|
PROVIDE(_X_uart_tx_one_char2, 0x40003664)
|
||||||
|
|
||||||
|
PROVIDE(_X_send_packet, 0x400037d4)
|
||||||
|
PROVIDE(_X_SendMsg, 0x40003828)
|
||||||
|
PROVIDE(_X_recv_packet, 0x4000383c)
|
||||||
|
PROVIDE(_X_RcvMsg, 0x40003988)
|
||||||
|
PROVIDE(_X_uart_rx_readbuff, 0x400039a0)
|
||||||
|
|
||||||
|
PROVIDE(_c_0x60004e00, 0x40003a18)
|
||||||
|
PROVIDE(_X_SelectSpiFunction, 0x40003a1c) // 1 arg - SPI number
|
||||||
|
PROVIDE(_c_0x60002e00, 0x40003c78)
|
||||||
|
PROVIDE(_X_SPI_chip_erase, 0x40003c7c)
|
||||||
|
PROVIDE(_c_0x00ffffff, 0x40003cb4)
|
||||||
|
PROVIDE(_c_0x01000000, 0x40003cb8)
|
||||||
|
PROVIDE(_XX_unk3cbc, 0x40003cbc)
|
||||||
|
PROVIDE(_c_0x00800000, 0x40003d00)
|
||||||
|
PROVIDE(_c_0x02000000, 0x40003d4c)
|
||||||
|
PROVIDE(_XX_unk3e24, 0x40003e24)
|
||||||
|
PROVIDE(_X_SPI_read_status, 0x40003efc)
|
||||||
|
PROVIDE(_c_0x90000000, 0x40003f48)
|
||||||
|
PROVIDE(_c_0x70000035, 0x40003f4c)
|
||||||
|
PROVIDE(_c_0x00040000, 0x40003f50)
|
||||||
|
PROVIDE(_XX_unk3f54, 0x40003f54)
|
||||||
|
PROVIDE(_c_0x04000000, 0x40003fcc)
|
||||||
|
PROVIDE(_XX_unk4010, 0x40004010)
|
||||||
|
PROVIDE(_X_SPI_write_enable, 0x400041bc)
|
||||||
|
PROVIDE(_X_Wait_SPI_Idle, 0x40004208)
|
||||||
|
PROVIDE(_l_4228, 0x40004228)
|
||||||
|
PROVIDE(_l_4234, 0x40004234)
|
||||||
|
PROVIDE(_XX_unk4238, 0x40004238)
|
||||||
|
PROVIDE(_X_SPIFlashModeConfig, 0x400042d8)
|
||||||
|
PROVIDE(_X_spi_flash_attach, 0x40004370) // 2 args: SPI num, ???
|
||||||
|
PROVIDE(_X_SPIReadModeConfig, 0x40004538)
|
||||||
|
|
||||||
|
PROVIDE(_X_SPIEraseArea, 0x400048b4)
|
||||||
|
PROVIDE(_XX_unk4940, 0x40004940)
|
||||||
|
|
||||||
|
PROVIDE(_st_0x3fffdc90, 0x40004d80)
|
||||||
|
PROVIDE(_XX_unk4d88, 0x40004d88)
|
||||||
|
PROVIDE(_XX_unk4f6c, 0x40004f6c)
|
||||||
|
PROVIDE(_XX_unk4fc8, 0x40004fc8)
|
||||||
|
|
||||||
|
PROVIDE(_c_0xbfffffff, 0x40004c80)
|
||||||
|
PROVIDE(_c_0xff000fff, 0x40004c88)
|
||||||
|
PROVIDE(_XX_unk4f14, 0x40004f14)
|
||||||
|
PROVIDE(_s_no_rds, 0x40005008)
|
||||||
|
PROVIDE(_XX_unk500c, 0x4000500c)
|
||||||
|
|
||||||
|
PROVIDE(_fp_0x40004f6c, 0x40005164)
|
||||||
|
PROVIDE(_fp_0x40004fc8, 0x40005168)
|
||||||
|
PROVIDE(_X_sip_init_attach, 0x40005170) // 1 arg, boot_mode?
|
||||||
|
PROVIDE(_XX_unk51ac, 0x400051ac)
|
||||||
|
PROVIDE(_c_0x60017e00, 0x40005478)
|
||||||
|
PROVIDE(_st_0x3fffdf70, 0x400054a4)
|
||||||
|
PROVIDE(_c_0x6000ae00, 0x400054b8)
|
||||||
|
PROVIDE(_c_0xf0000000, 0x400054bc)
|
||||||
|
PROVIDE(_c_0x02320017, 0x400054c0)
|
||||||
|
PROVIDE(_c_0x11116666, 0x400054c4)
|
||||||
|
PROVIDE(_c_0x01110013, 0x400054e4)
|
||||||
|
PROVIDE(_X_slc_init_attach, 0x400054e8) // 4 args - fp, fp, st, boot_mode; PRODPORT_SDIO_RST
|
||||||
|
PROVIDE(_l_slc_boot_mode_4, 0x40005654)
|
||||||
|
PROVIDE(_X_slc_enable, 0x40005678)
|
||||||
|
PROVIDE(_X_slc_select_tohost_gpio_mode, 0x400056fc)
|
||||||
|
PROVIDE(_X_slc_select_tohost_gpio, 0x40005708)
|
||||||
|
PROVIDE(_c_0xff300000, 0x40005730)
|
||||||
|
PROVIDE(_XX_unk5734, 0x40005734)
|
||||||
|
PROVIDE(_XX_unk57b8, 0x400057b8)
|
||||||
|
PROVIDE(_XX_unk57f4, 0x400057f4)
|
||||||
|
PROVIDE(_XX_unk5848, 0x40005848)
|
||||||
|
|
||||||
|
PROVIDE(_c_0xfffff0c0, 0x40005988)
|
||||||
|
PROVIDE(_X_slc_set_host_io_max_window, 0x4000598c)
|
||||||
|
PROVIDE(_X_slc_init_credit, 0x400059ac)
|
||||||
|
PROVIDE(_X_slc_add_credits, 0x400059c4)
|
||||||
|
|
||||||
|
PROVIDE(_X_xtos_set_interrupt_handler_arg, 0x400059d8)
|
||||||
|
PROVIDE(_X_xtos_set_interrupt_handler, 0x40005a24)
|
||||||
|
PROVIDE(_X_xtos_ints_on, 0x40005a34)
|
||||||
|
PROVIDE(_X_xtos_ints_off, 0x40005a58)
|
||||||
|
|
||||||
|
PROVIDE(_XX_xtos_exc_unk5a80, 0x40005a80)
|
||||||
|
PROVIDE(_XX_xtos_exc_unk5b94, 0x40005b94)
|
2
src/mongoose-6.11/src/common/platforms/esp32/rom/.gitattributes
vendored
Normal file
2
src/mongoose-6.11/src/common/platforms/esp32/rom/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
rom.bin -nodiff
|
||||||
|
rom.elf -nodiff
|
4
src/mongoose-6.11/src/common/platforms/esp32/rom/disasm.sh
Executable file
4
src/mongoose-6.11/src/common/platforms/esp32/rom/disasm.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
xtensa-esp32-elf-gcc -Wl,-N,-Ttext,0x40000000 -nostdlib rom.S -o rom.elf && \
|
||||||
|
xtensa-esp32-elf-objdump -d rom.elf > ESP32_ROM.txt
|
28
src/mongoose-6.11/src/common/platforms/esp32/rom/rom.S
Normal file
28
src/mongoose-6.11/src/common/platforms/esp32/rom/rom.S
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
.text
|
||||||
|
.org 0
|
||||||
|
.globl _start
|
||||||
|
|
||||||
|
// xtensa-esp32-elf-gcc -Wl,-N,-Ttext,0x40000000 -nostdlib rom.S -o rom.elf
|
||||||
|
|
||||||
|
here = .
|
||||||
|
#define PROVIDE(name, addr) name = here + addr - 0x40000000
|
||||||
|
|
||||||
|
#include "rom_functions.S"
|
||||||
|
|
||||||
|
PROVIDE ( _x_unk_40061b88, 0x40061b88 )
|
||||||
|
PROVIDE ( _x_unk_spi_400622c0, 0x400622c0 )
|
||||||
|
PROVIDE ( _c_3ff000c8, 0x40062df0 )
|
||||||
|
PROVIDE ( _c_3ff5b024, 0x40062e0c )
|
||||||
|
PROVIDE ( _c_3ff5b000, 0x40062e10 )
|
||||||
|
PROVIDE ( _c_3ff5b020, 0x40062e14 )
|
||||||
|
PROVIDE ( _c_3ff5b028, 0x40062e18 )
|
||||||
|
PROVIDE ( _l_40062e90, 0x40062e90 )
|
||||||
|
PROVIDE ( _l_SPI_Prepare_Encrypt_Data_loop, 0x40062e34 )
|
||||||
|
PROVIDE ( _l_SPI_Prepare_Encrypt_Data_wait, 0x40062e54 )
|
||||||
|
PROVIDE ( _l_SPI_Prepare_Encrypt_Data_out, 0x40062e5e )
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
_start:
|
||||||
|
.incbin "rom.bin"
|
||||||
|
_end:
|
BIN
src/mongoose-6.11/src/common/platforms/esp32/rom/rom.bin
Normal file
BIN
src/mongoose-6.11/src/common/platforms/esp32/rom/rom.bin
Normal file
Binary file not shown.
BIN
src/mongoose-6.11/src/common/platforms/esp32/rom/rom.elf
Executable file
BIN
src/mongoose-6.11/src/common/platforms/esp32/rom/rom.elf
Executable file
Binary file not shown.
1852
src/mongoose-6.11/src/common/platforms/esp32/rom/rom_functions.S
Normal file
1852
src/mongoose-6.11/src/common/platforms/esp32/rom/rom_functions.S
Normal file
File diff suppressed because it is too large
Load Diff
51
src/mongoose-6.11/src/common/platforms/esp32/stubs/Makefile
Normal file
51
src/mongoose-6.11/src/common/platforms/esp32/stubs/Makefile
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2015 Cesanta Software Limited
|
||||||
|
# All rights reserved
|
||||||
|
#
|
||||||
|
|
||||||
|
STUB = stub_hello.c
|
||||||
|
LIBS =
|
||||||
|
PARAMS =
|
||||||
|
PORT = /dev/ttyUSB0
|
||||||
|
|
||||||
|
BUILD_DIR = .build
|
||||||
|
COMMON_STUB_DIR = ../../esp
|
||||||
|
STUB_ELF = $(BUILD_DIR)/$(patsubst %.c,%.elf,$(notdir $(STUB)))
|
||||||
|
STUB_JSON ?= $(BUILD_DIR)/$(patsubst %.c,%.json,$(notdir $(STUB)))
|
||||||
|
SDK = $(shell cat ../../../../fw/platforms/esp32/sdk.version)
|
||||||
|
XT_CC = xtensa-esp32-elf-gcc
|
||||||
|
|
||||||
|
.PHONY: all clean run wrap
|
||||||
|
|
||||||
|
all: $(STUB_ELF)
|
||||||
|
|
||||||
|
$(STUB_ELF): $(STUB) $(LIBS)
|
||||||
|
@echo " CC $^ -> $@"
|
||||||
|
@[ -d $(BUILD_DIR) ] || mkdir $(BUILD_DIR)
|
||||||
|
@docker run --rm -i -v $(CURDIR)/../../../..:/src $(SDK) //bin/bash -c \
|
||||||
|
"cd /src/common/platforms/esp32/stubs && \
|
||||||
|
$(XT_CC) -std=c99 -Wall -Werror -Os -DESP32 \
|
||||||
|
-mtext-section-literals -mlongcalls -nostdlib -fno-builtin \
|
||||||
|
-I. -I/src/common/platforms/esp \
|
||||||
|
-I/opt/Espressif/esp-idf/components/esp32/include \
|
||||||
|
-I/opt/Espressif/esp-idf/components/soc/esp32/include \
|
||||||
|
-L/opt/Espressif/esp-idf -Wl,-static \
|
||||||
|
-ffunction-sections -Wl,--gc-sections \
|
||||||
|
-Tstub.ld -o $@ $^"
|
||||||
|
|
||||||
|
wrap: $(STUB_JSON)
|
||||||
|
|
||||||
|
$(STUB_JSON): $(STUB_ELF) $(COMMON_STUB_DIR)/esptool.py
|
||||||
|
@echo " WRAP $< -> $@"
|
||||||
|
@docker run --rm -i -v $(CURDIR)/../../../..:/src $(SDK) //bin/bash -c \
|
||||||
|
"cd /src/common/platforms/esp32/stubs && \
|
||||||
|
$(COMMON_STUB_DIR)/esptool.py wrap_stub $<" > $@
|
||||||
|
|
||||||
|
run: $(STUB_JSON)
|
||||||
|
@echo " RUN $< $(PARAMS) -> $(PORT)"
|
||||||
|
@docker run --rm -i --privileged -v $(CURDIR)/../../../..:/src $(SDK) //bin/bash -c \
|
||||||
|
"cd /src/common/platforms/esp32/stubs && \
|
||||||
|
$(COMMON_STUB_DIR)/esptool.py --port $(PORT) run_stub $< $(PARAMS)"
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -rf $(BUILD_DIR)
|
13
src/mongoose-6.11/src/common/platforms/esp32/stubs/README.md
Normal file
13
src/mongoose-6.11/src/common/platforms/esp32/stubs/README.md
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
This is a ESP boot loader stub development environment.
|
||||||
|
|
||||||
|
Code produced in this environment can be loaded and executed
|
||||||
|
in the bootloader environment. Usually it is used to implement
|
||||||
|
functionality not found in the bootloader.
|
||||||
|
|
||||||
|
Stubs can be executed using the `run_stub` command of the modified esptool.py provided.
|
||||||
|
`wrap_stub` produces a JSON represenattion of the stub that can later be reused
|
||||||
|
or built into other tools.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
$ make run STUB=stub_flash_size.c PORT=/dev/ttyUSB0
|
||||||
|
$ make run STUB=stub_md5.c PORT=/dev/ttyUSB0 PARAMS="0x11000 10000 1"
|
38
src/mongoose-6.11/src/common/platforms/esp32/stubs/led.c
Normal file
38
src/mongoose-6.11/src/common/platforms/esp32/stubs/led.c
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2017 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "soc/gpio_reg.h"
|
||||||
|
|
||||||
|
void led_setup(int io) {
|
||||||
|
if (io < 32) {
|
||||||
|
WRITE_PERI_REG(GPIO_ENABLE_W1TS_REG, 1 << io);
|
||||||
|
} else {
|
||||||
|
WRITE_PERI_REG(GPIO_ENABLE1_W1TS_REG, 1 << (io - 32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_on(int io) {
|
||||||
|
if (io < 32) {
|
||||||
|
WRITE_PERI_REG(GPIO_OUT_W1TS_REG, 1 << io);
|
||||||
|
} else {
|
||||||
|
WRITE_PERI_REG(GPIO_OUT1_W1TS_REG, 1 << (io - 32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_off(int io) {
|
||||||
|
if (io < 32) {
|
||||||
|
WRITE_PERI_REG(GPIO_OUT_W1TC_REG, 1 << io);
|
||||||
|
} else {
|
||||||
|
WRITE_PERI_REG(GPIO_OUT1_W1TC_REG, 1 << (io - 32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void led_toggle(int io) {
|
||||||
|
if (READ_PERI_REG(GPIO_OUT_REG & (1 << io))) {
|
||||||
|
WRITE_PERI_REG(GPIO_OUT_W1TC_REG, 1 << io);
|
||||||
|
} else {
|
||||||
|
WRITE_PERI_REG(GPIO_OUT_W1TS_REG, 1 << io);
|
||||||
|
}
|
||||||
|
}
|
11
src/mongoose-6.11/src/common/platforms/esp32/stubs/led.h
Normal file
11
src/mongoose-6.11/src/common/platforms/esp32/stubs/led.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2017 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
void led_setup(int io);
|
||||||
|
void led_on(int io);
|
||||||
|
void led_off(int io);
|
||||||
|
void led_toggle(int io);
|
@ -0,0 +1,10 @@
|
|||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP32_STUBS_ROM_FUNCTIONS_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP32_STUBS_ROM_FUNCTIONS_H_
|
||||||
|
|
||||||
|
#include "rom/ets_sys.h"
|
||||||
|
#include "rom/spi_flash.h"
|
||||||
|
#include "rom/md5_hash.h"
|
||||||
|
#include "rom/uart.h"
|
||||||
|
#include "rom/rtc.h"
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP32_STUBS_ROM_FUNCTIONS_H_ */
|
@ -0,0 +1 @@
|
|||||||
|
#define CONFIG_SPI_FLASH_ROM_DRIVER_PATCH 1
|
46
src/mongoose-6.11/src/common/platforms/esp32/stubs/stub.ld
Normal file
46
src/mongoose-6.11/src/common/platforms/esp32/stubs/stub.ld
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
iram : org = 0x40090000, len = 0x10000
|
||||||
|
/* DRAM startin at 0x3FFC0000 gets stomped by something before mem_finish
|
||||||
|
* and is thus not suitable for initialized data, but works fine for BSS. */
|
||||||
|
dram_bss : org = 0x3FFC0000, len = 0x10000
|
||||||
|
dram : org = 0x3FFD0000, len = 0x10000
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTRY(stub_main)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
.params 0x40090000 : {
|
||||||
|
_params_start = ABSOLUTE(.);
|
||||||
|
*(.params)
|
||||||
|
_params_end = ABSOLUTE(.);
|
||||||
|
} > iram
|
||||||
|
|
||||||
|
.text : ALIGN(4) {
|
||||||
|
_code_start = ABSOLUTE(.);
|
||||||
|
*(.literal)
|
||||||
|
*(.text .text.*)
|
||||||
|
} > iram
|
||||||
|
|
||||||
|
.bss : ALIGN(4) {
|
||||||
|
_bss_start = ABSOLUTE(.);
|
||||||
|
*(.bss)
|
||||||
|
_bss_end = ABSOLUTE(.);
|
||||||
|
} > dram
|
||||||
|
|
||||||
|
.data : ALIGN(4) {
|
||||||
|
_data_start = ABSOLUTE(.);
|
||||||
|
*(.data)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
} > dram
|
||||||
|
}
|
||||||
|
|
||||||
|
INCLUDE "components/esp32/ld/esp32.rom.ld"
|
||||||
|
INCLUDE "components/esp32/ld/esp32.rom.spiram_incompatible_fns.ld"
|
||||||
|
|
||||||
|
PROVIDE(esp_rom_spiflash_attach = 0x40062a6c);
|
||||||
|
PROVIDE(esp_rom_spiflash_config_clk = 0x40062bc8);
|
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Stub template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "slip.h"
|
||||||
|
|
||||||
|
/* Define the args vector and put it into the ".params" section. */
|
||||||
|
uint32_t params[3] __attribute__((section(".params")));
|
||||||
|
|
||||||
|
/* Define a function called stub_main. Do not return or reboot.
|
||||||
|
* Use send_packet to communicate to the host. */
|
||||||
|
|
||||||
|
const char *hello = "Hello";
|
||||||
|
|
||||||
|
static char buf[1024];
|
||||||
|
extern uint32_t _bss_start, _bss_end;
|
||||||
|
|
||||||
|
void stub_main(void) {
|
||||||
|
uint32_t greeting = 0x4941484f;
|
||||||
|
SLIP_send(&greeting, 4);
|
||||||
|
memset(&_bss_start, 0, (&_bss_end - &_bss_start));
|
||||||
|
buf[1] = 123;
|
||||||
|
SLIP_send(hello, 5);
|
||||||
|
while (1) {
|
||||||
|
}
|
||||||
|
}
|
15
src/mongoose-6.11/src/common/platforms/esp32/stubs/uart.c
Normal file
15
src/mongoose-6.11/src/common/platforms/esp32/stubs/uart.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
|
||||||
|
#include "rom_functions.h"
|
||||||
|
|
||||||
|
void set_baud_rate(uint32_t uart_no, uint32_t baud_rate) {
|
||||||
|
uint32_t master_freq = ets_get_detected_xtal_freq() << 4;
|
||||||
|
master_freq += (baud_rate / 2);
|
||||||
|
uint32_t div = master_freq / baud_rate;
|
||||||
|
uart_div_modify(uart_no, div);
|
||||||
|
}
|
13
src/mongoose-6.11/src/common/platforms/esp32/stubs/uart.h
Normal file
13
src/mongoose-6.11/src/common/platforms/esp32/stubs/uart.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP32_STUBS_UART_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP32_STUBS_UART_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void set_baud_rate(uint32_t uart_no, uint32_t baud_rate);
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP32_STUBS_UART_H_ */
|
76
src/mongoose-6.11/src/common/platforms/esp8266/common.mk
Normal file
76
src/mongoose-6.11/src/common/platforms/esp8266/common.mk
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
CFLAGS_EXTRA ?=
|
||||||
|
|
||||||
|
XTENSA_TOOLS_ROOT ?= /opt/Espressif/crosstool-NG/builds/xtensa-lx106-elf/bin
|
||||||
|
SDK_PATH ?= /opt/Espressif/ESP8266_SDK
|
||||||
|
ESPTOOL ?= esptool.py
|
||||||
|
ESPPORT ?= /dev/ttyACM0
|
||||||
|
ESPSPEED ?= 230400
|
||||||
|
# For flash = > 16Mbit
|
||||||
|
ESPFLASHARGS = --flash_mode dio --flash_size 32m
|
||||||
|
|
||||||
|
VERBOSE ?= 0
|
||||||
|
|
||||||
|
CC := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
|
||||||
|
CXX := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-g++
|
||||||
|
AR := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-ar
|
||||||
|
LD := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-gcc
|
||||||
|
OBJCOPY := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-objcopy
|
||||||
|
NM := $(XTENSA_TOOLS_ROOT)/xtensa-lx106-elf-nm
|
||||||
|
CC_WRAPPER ?=
|
||||||
|
|
||||||
|
define link
|
||||||
|
$(vecho) "LD $@"
|
||||||
|
$(Q) $(CC_WRAPPER) $(LD) $(LIBDIRS) -T$(LD_SCRIPT) $(LDFLAGS) -o $@ \
|
||||||
|
-Wl,-Map=$@.map -Wl,--start-group $1 -Wl,--end-group
|
||||||
|
endef
|
||||||
|
|
||||||
|
define compile_params
|
||||||
|
$(vecho) "$5 $1 -> $2"
|
||||||
|
$(Q) $(CC_WRAPPER) $3 -MD -MP $(INCDIRS) $4 -c $1 -o $2
|
||||||
|
endef
|
||||||
|
|
||||||
|
define compile
|
||||||
|
$(call compile_params,$<,$@, $(CC), $(CFLAGS),"CC")
|
||||||
|
endef
|
||||||
|
|
||||||
|
define compile_cxx
|
||||||
|
$(call compile_params,$<,$@, $(CXX), $(CXXFLAGS),"CXX")
|
||||||
|
endef
|
||||||
|
|
||||||
|
# some of these flags works around for gdb 7.5.x stacktrace issue
|
||||||
|
# while still allowing -Os to remove padding between data in .rodata
|
||||||
|
# section, allowing us to gain about 1k of ram.
|
||||||
|
# text section is 4k bigger, but we care more about ram at the moment.
|
||||||
|
# TODO(mkm): figure out which flag(s).
|
||||||
|
NO_Os_FLAGS= -fno-expensive-optimizations -fno-thread-jumps \
|
||||||
|
-fno-align-functions -fno-align-jumps \
|
||||||
|
-fno-align-loops -fno-align-labels -fno-caller-saves \
|
||||||
|
-fno-crossjumping -fno-cse-follow-jumps -fno-cse-skip-blocks \
|
||||||
|
-fno-delete-null-pointer-checks -fno-devirtualize \
|
||||||
|
-fno-gcse -fno-gcse-lm -fno-hoist-adjacent-loads \
|
||||||
|
-fno-inline-small-functions -fno-indirect-inlining -fno-partial-inlining \
|
||||||
|
-fno-ipa-cp -fno-ipa-sra -fno-peephole2 -fno-optimize-sibling-calls -fno-optimize-strlen \
|
||||||
|
-fno-reorder-blocks -fno-reorder-blocks-and-partition -fno-reorder-functions \
|
||||||
|
-fno-sched-interblock -fno-sched-spec -fno-rerun-cse-after-loop \
|
||||||
|
-fno-schedule-insns -fno-schedule-insns2 -fno-strict-aliasing -fno-strict-overflow \
|
||||||
|
-fno-tree-builtin-call-dce -fno-tree-switch-conversion -fno-tree-tail-merge \
|
||||||
|
-fno-tree-pre -fno-tree-vrp
|
||||||
|
|
||||||
|
C_CXX_FLAGS = -W -Wall -Werror -Wundef -Wno-comment -Wno-variadic-macros -Wpointer-arith \
|
||||||
|
-Os $(NO_Os_FLAGS) -g3 \
|
||||||
|
-Wl,-EL -fno-inline-functions \
|
||||||
|
-D_XOPEN_SOURCE=500 \
|
||||||
|
-nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DSTATIC=static \
|
||||||
|
-Wno-parentheses \
|
||||||
|
-DIRAM='__attribute__((section(".fast.text")))' \
|
||||||
|
-DICACHE_RAM_ATTR=IRAM \
|
||||||
|
-DNOINSTR='__attribute__((no_instrument_function))' \
|
||||||
|
-DCS_PLATFORM=3 \
|
||||||
|
-ffunction-sections -fdata-sections
|
||||||
|
|
||||||
|
CFLAGS = -std=c99 $(C_CXX_FLAGS)
|
||||||
|
CXXFLAGS = -std=gnu++11 -fno-exceptions $(C_CXX_FLAGS)
|
||||||
|
|
||||||
|
# linker flags used to generate the main object file
|
||||||
|
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start \
|
||||||
|
-Wl,-static -Wl,--gc-sections
|
111
src/mongoose-6.11/src/common/platforms/esp8266/esp_crypto.c
Normal file
111
src/mongoose-6.11/src/common/platforms/esp8266/esp_crypto.c
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "mongoose/mongoose.h"
|
||||||
|
|
||||||
|
#ifdef RTOS_SDK
|
||||||
|
#include "esp_libc.h"
|
||||||
|
#else
|
||||||
|
#include "osapi.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern int sha1_vector(size_t num_msgs, const uint8_t *msgs[],
|
||||||
|
const size_t *msg_lens, uint8_t *digest);
|
||||||
|
|
||||||
|
extern int md5_vector(size_t num_msgs, const uint8_t *msgs[],
|
||||||
|
const size_t *msg_lens, uint8_t *digest);
|
||||||
|
|
||||||
|
/* For digest auth. */
|
||||||
|
void mg_hash_md5_v(size_t num_msgs, const uint8_t *msgs[],
|
||||||
|
const size_t *msg_lens, uint8_t *digest) {
|
||||||
|
(void) md5_vector(num_msgs, msgs, msg_lens, digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For WebSocket handshake. */
|
||||||
|
void mg_hash_sha1_v(size_t num_msgs, const uint8_t *msgs[],
|
||||||
|
const size_t *msg_lens, uint8_t *digest) {
|
||||||
|
(void) sha1_vector(num_msgs, msgs, msg_lens, digest);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if MG_ENABLE_SSL
|
||||||
|
|
||||||
|
#include "mbedtls/aes.h"
|
||||||
|
#include "mbedtls/sha256.h"
|
||||||
|
|
||||||
|
#define AES_PRIV_NR_POS (4 * 15)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Crypto functions in ROM/SDK.
|
||||||
|
* They come from wpa_supplicant, you can find them here https://w1.fi/cgit/
|
||||||
|
*
|
||||||
|
* Note that ROM version of the key setup function is older, does not take the
|
||||||
|
* number of bits argument and only supports AES-128. This prototype doesn't
|
||||||
|
* suit it, but since the difference is in the last aegument, it doesn't matter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
extern void rijndaelKeySetupDec(void *ctx, const uint8_t *key, int bits);
|
||||||
|
extern int rijndaelKeySetupEnc(void *ctx, const uint8_t *key, int bits);
|
||||||
|
void aes_encrypt(void *ctx, const uint8_t *plain, uint8_t *crypt);
|
||||||
|
void aes_decrypt(void *ctx, const uint8_t *crypt, uint8_t *plain);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* AES that comes with wpa_supplicant allocates its own AES context in
|
||||||
|
* aes_{encrypt,decrypt}_init. Ideally, we'd take that pointer and store it in
|
||||||
|
* our mbedtls_aes_context, but then a lot of space would be wasted.
|
||||||
|
* We do not call _init and go directly to key setup functions and poke number
|
||||||
|
* of rounds into the right place too. This is a bit hacky, but works fine.
|
||||||
|
* There is also a difference between older function in ROM and the one coming
|
||||||
|
* with SDK which is newer: the older one actually takes two arguments, not 3.
|
||||||
|
* But it doesn't matter, extra argument doesn't hurt and this works with both.
|
||||||
|
*/
|
||||||
|
int mbedtls_aes_setkey_enc(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||||
|
unsigned int keybits) {
|
||||||
|
if (keybits != 128) return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||||
|
((uint32_t *) ctx)[AES_PRIV_NR_POS] = 10;
|
||||||
|
rijndaelKeySetupEnc(ctx, key, 128);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_aes_setkey_dec(mbedtls_aes_context *ctx, const unsigned char *key,
|
||||||
|
unsigned int keybits) {
|
||||||
|
if (keybits != 128) return MBEDTLS_ERR_AES_INVALID_KEY_LENGTH;
|
||||||
|
((uint32_t *) ctx)[AES_PRIV_NR_POS] = 10;
|
||||||
|
rijndaelKeySetupDec(ctx, key, 128);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_internal_aes_encrypt(mbedtls_aes_context *ctx,
|
||||||
|
const unsigned char input[16],
|
||||||
|
unsigned char output[16]) {
|
||||||
|
aes_encrypt(ctx, input, output);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int mbedtls_internal_aes_decrypt(mbedtls_aes_context *ctx,
|
||||||
|
const unsigned char input[16],
|
||||||
|
unsigned char output[16]) {
|
||||||
|
aes_decrypt(ctx, input, output);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* os_get_random uses hardware RNG, so it's cool. */
|
||||||
|
int mg_ssl_if_mbed_random(void *ctx, unsigned char *buf, size_t len) {
|
||||||
|
os_get_random(buf, len);
|
||||||
|
(void) ctx;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For CryptoAuthLib host crypto. */
|
||||||
|
int atcac_sw_sha2_256(const uint8_t *data, size_t data_size,
|
||||||
|
uint8_t digest[32]) {
|
||||||
|
mbedtls_sha256(data, data_size, digest, false /* is_224 */);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MG_ENABLE_SSL */
|
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2017 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_HW_WDT_REGISTER_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_ESP_HW_WDT_REGISTER_H_
|
||||||
|
|
||||||
|
#ifdef RTOS_SDK
|
||||||
|
#include <esp_common.h>
|
||||||
|
#else
|
||||||
|
#include <user_interface.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define REG_WDT_BASE 0x60000900
|
||||||
|
|
||||||
|
#define WDT_CTL (REG_WDT_BASE + 0x0)
|
||||||
|
#define WDT_CTL_ENABLE (BIT(0))
|
||||||
|
#define WDT_CTL_STAGE1_NO_RESET (BIT(1))
|
||||||
|
#define WDT_CTL_STAGE1_DISABLE (BIT(2))
|
||||||
|
#define WDT_CTL_UNK3 (BIT(3))
|
||||||
|
#define WDT_CTL_UNK4 (BIT(4))
|
||||||
|
#define WDT_CTL_UNK5 (BIT(5))
|
||||||
|
|
||||||
|
/* Bits 3, 4, 5 - ???; set to 1 by ROM. */
|
||||||
|
|
||||||
|
#define WDT_RELOAD_STAGE0 (REG_WDT_BASE + 0x4)
|
||||||
|
#define WDT_RELOAD_STAGE0_V (0xf)
|
||||||
|
#define WDT_RELOAD_STAGE0_S (0)
|
||||||
|
|
||||||
|
#define WDT_RELOAD_STAGE1 (REG_WDT_BASE + 0x8)
|
||||||
|
#define WDT_RELOAD_STAGE1_V (0xf)
|
||||||
|
#define WDT_RELOAD_STAGE1_S (0)
|
||||||
|
|
||||||
|
#define WDT_COUNT (REG_WDT_BASE + 0xc) /* Counts at CPU_CLK (80 MHz) */
|
||||||
|
#define WDT_COUNT_V (0xffffffff)
|
||||||
|
#define WDT_COUNT_S (0)
|
||||||
|
|
||||||
|
#define WDT_STAGE (REG_WDT_BASE + 0x10)
|
||||||
|
#define WDT_STAGE_V (1)
|
||||||
|
#define WDT_STAGE_S (0)
|
||||||
|
|
||||||
|
#define WDT_RESET (REG_WDT_BASE + 0x14)
|
||||||
|
#define WDT_RESET_V (0xff)
|
||||||
|
#define WDT_RESET_S (0)
|
||||||
|
|
||||||
|
#define WDT_RESET_STAGE (REG_WDT_BASE + 0x18)
|
||||||
|
#define WDT_RESET_STAGE_V (0xff)
|
||||||
|
#define WDT_RESET_STAGE_S (0)
|
||||||
|
|
||||||
|
#define WDT_RESET_VALUE 0x73
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_ESP_HW_WDT_REGISTER_H_ */
|
@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_MISSING_INCLUDES_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_ESP_MISSING_INCLUDES_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
void pp_soft_wdt_init(void);
|
||||||
|
void pp_soft_wdt_stop(void);
|
||||||
|
void pp_soft_wdt_feed(void);
|
||||||
|
void pp_soft_wdt_restart(void);
|
||||||
|
void system_soft_wdt_stop(void); /* Alias for pp_soft_wdt_stop */
|
||||||
|
|
||||||
|
void Cache_Read_Disable(void);
|
||||||
|
void Cache_Read_Enable(uint32_t, uint32_t, uint32_t);
|
||||||
|
void Cache_Read_Disable_2(void);
|
||||||
|
void Cache_Read_Enable_2(void);
|
||||||
|
void Cache_Read_Enable_New(void);
|
||||||
|
|
||||||
|
int SPIEraseBlock(uint32_t block);
|
||||||
|
uint32_t SPIRead(uint32_t addr, void *dst, uint32_t size);
|
||||||
|
|
||||||
|
#ifndef RTOS_SDK
|
||||||
|
|
||||||
|
#include <ets_sys.h>
|
||||||
|
|
||||||
|
/* There are no declarations for these anywhere in the SDK (as of 1.2.0). */
|
||||||
|
void ets_isr_mask(unsigned intr);
|
||||||
|
void ets_isr_unmask(unsigned intr);
|
||||||
|
void system_restart_local(void);
|
||||||
|
int os_printf_plus(const char *format, ...);
|
||||||
|
|
||||||
|
void ets_wdt_init(void);
|
||||||
|
void ets_wdt_enable(uint32_t mode, uint32_t arg1, uint32_t arg2);
|
||||||
|
void ets_wdt_disable(void);
|
||||||
|
void ets_wdt_restore(uint32_t mode);
|
||||||
|
uint32_t ets_wdt_get_mode(void);
|
||||||
|
|
||||||
|
void _xtos_l1int_handler(void);
|
||||||
|
void _xtos_set_exception_handler();
|
||||||
|
void xthal_set_intenable(unsigned);
|
||||||
|
|
||||||
|
/* These are present in mem.h but are commented out. */
|
||||||
|
void *pvPortMalloc(size_t xWantedSize, const char *file, int line);
|
||||||
|
void vPortFree(void *pv, const char *file, int line);
|
||||||
|
void *pvPortZalloc(size_t size, const char *file, int line);
|
||||||
|
void *pvPortRealloc(void *pv, size_t size, const char *file, int line);
|
||||||
|
|
||||||
|
#else /* !RTOS_SDK */
|
||||||
|
|
||||||
|
#define BIT(nr) (1UL << (nr))
|
||||||
|
void system_soft_wdt_feed(void);
|
||||||
|
void system_soft_wdt_restart(void);
|
||||||
|
void ets_putc(char c);
|
||||||
|
|
||||||
|
#endif /* RTOS_SDK */
|
||||||
|
|
||||||
|
void _ResetVector(void);
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_ESP_MISSING_INCLUDES_H_ */
|
@ -0,0 +1,17 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_ESP_SSL_KRYPTON_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_ESP_SSL_KRYPTON_H_
|
||||||
|
|
||||||
|
#include "krypton/krypton.h"
|
||||||
|
|
||||||
|
struct mg_connection;
|
||||||
|
|
||||||
|
void mg_lwip_ssl_do_hs(struct mg_connection *nc);
|
||||||
|
void mg_lwip_ssl_send(struct mg_connection *nc);
|
||||||
|
void mg_lwip_ssl_recv(struct mg_connection *nc);
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_ESP_SSL_KRYPTON_H_ */
|
108
src/mongoose-6.11/src/common/platforms/esp8266/esp_umm_malloc.c
Normal file
108
src/mongoose-6.11/src/common/platforms/esp8266/esp_umm_malloc.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "common/umm_malloc/umm_malloc.h"
|
||||||
|
#include "esp_umm_malloc.h"
|
||||||
|
|
||||||
|
#if ESP_UMM_ENABLE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ESP-specific glue for the `umm_malloc`.
|
||||||
|
*
|
||||||
|
* In SDK (https://github.com/cesanta/esp-open-sdk), there is an archive
|
||||||
|
* `sdk/lib/libmain.a` which contains some files, including `mem_manager.o`.
|
||||||
|
*
|
||||||
|
* The `mem_manager.o` contains all the heap-related functions: `pvPortMalloc`,
|
||||||
|
* etc. We have weaken all symbols from `mem_manager.o` by
|
||||||
|
* `xtensa-lx106-elf-objcopy` (see exact commands in Dockerfile:
|
||||||
|
* `docker/esp8266/Dockerfile-esp8266-build-oss`), and provide our own
|
||||||
|
* implementations in this file.
|
||||||
|
*
|
||||||
|
* ------------------------------------
|
||||||
|
*
|
||||||
|
* NOTE that not all public functions from `mem_manager.o` need to be replaced:
|
||||||
|
* some of them are used only internally:
|
||||||
|
*
|
||||||
|
* - system_show_malloc()
|
||||||
|
* - pvShowMalloc()
|
||||||
|
* - prvInsertBlockIntoUsedList()
|
||||||
|
* - prvRemoveBlockFromUsedList()
|
||||||
|
* - check_memleak_debug_enable()
|
||||||
|
* - vPortInitialiseBlocks()
|
||||||
|
*
|
||||||
|
* So when we replace all the rest (`pvPortMalloc`, etc), we can check with
|
||||||
|
* `objdump` that resulting binary (for SJ, it's `fw.out`) doesn't contain
|
||||||
|
* any of the "internal" functions.
|
||||||
|
*
|
||||||
|
* ------------------------------------
|
||||||
|
*
|
||||||
|
* NOTE that to make linker actually consider implementations in this file,
|
||||||
|
* you should explicitly reference some function from it. This is what
|
||||||
|
* `esp_umm_init()` is for: it is a dummy no-op function that must be called
|
||||||
|
* from somewhere outside.
|
||||||
|
*
|
||||||
|
* If you don't do this, linker will merely garbage-collect this file, and
|
||||||
|
* will use heap implementation from SDK.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void *pvPortMalloc(size_t size, const char *file, unsigned line) {
|
||||||
|
(void) file;
|
||||||
|
(void) line;
|
||||||
|
|
||||||
|
return umm_malloc(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *pvPortCalloc(size_t num, size_t size, const char *file, unsigned line) {
|
||||||
|
(void) file;
|
||||||
|
(void) line;
|
||||||
|
|
||||||
|
return umm_calloc(num, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *pvPortZalloc(size_t size, const char *file, unsigned line) {
|
||||||
|
void *ret;
|
||||||
|
|
||||||
|
(void) file;
|
||||||
|
(void) line;
|
||||||
|
|
||||||
|
ret = umm_malloc(size);
|
||||||
|
if (ret != NULL) memset(ret, 0, size);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *pvPortRealloc(void *ptr, size_t size, const char *file, unsigned line) {
|
||||||
|
(void) file;
|
||||||
|
(void) line;
|
||||||
|
|
||||||
|
return umm_realloc(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void vPortFree(void *ptr, const char *file, unsigned line) {
|
||||||
|
(void) file;
|
||||||
|
(void) line;
|
||||||
|
|
||||||
|
umm_free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t xPortGetFreeHeapSize(void) {
|
||||||
|
return umm_free_heap_size();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t xPortWantedSizeAlign(void) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
void esp_umm_init(void) {
|
||||||
|
/* Nothing to do, see header for details */
|
||||||
|
}
|
||||||
|
|
||||||
|
void esp_umm_oom_cb(size_t size, size_t blocks_cnt) {
|
||||||
|
fprintf(stderr, "E:M %u (%u blocks)\n", (unsigned int) size,
|
||||||
|
(unsigned int) blocks_cnt);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ESP_UMM_ENABLE */
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if ESP_UMM_ENABLE
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is a no-op dummy function that is merely needed because we have to
|
||||||
|
* reference any function from the file `esp_umm_malloc.c`, so that linker
|
||||||
|
* won't garbage-collect the whole compilation unit.
|
||||||
|
*/
|
||||||
|
void esp_umm_init(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback that gets called by umm_malloc in case of Out-of-memory error.
|
||||||
|
*
|
||||||
|
* `size` is the size requested by user, and `block_cnt` is a number of heap
|
||||||
|
* blocks that umm_malloc failed to allocate
|
||||||
|
*/
|
||||||
|
void esp_umm_oom_cb(size_t size, size_t blocks_cnt);
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_ESP_UMM_MALLOC_H_ */
|
@ -0,0 +1,26 @@
|
|||||||
|
#
|
||||||
|
# Makefile for esptool2
|
||||||
|
# https://github.com/raburton/esp8266
|
||||||
|
#
|
||||||
|
|
||||||
|
CFLAGS = -O2 -Wall
|
||||||
|
CC = gcc
|
||||||
|
LD = gcc
|
||||||
|
BUILD_DIR = ../../build
|
||||||
|
|
||||||
|
all: $(BUILD_DIR) $(BUILD_DIR)/esptool2
|
||||||
|
|
||||||
|
$(BUILD_DIR):
|
||||||
|
@mkdir -p $(BUILD_DIR)
|
||||||
|
|
||||||
|
$(BUILD_DIR)/esptool2.o: esptool2.c esptool2.h esptool2_elf.h elf.h
|
||||||
|
@echo "CC $<"
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/esptool2_elf.o: esptool2_elf.c esptool2.h esptool2_elf.h elf.h
|
||||||
|
@echo "CC $<"
|
||||||
|
$(CC) $(CFLAGS) -c $< -o $@
|
||||||
|
|
||||||
|
$(BUILD_DIR)/esptool2: $(BUILD_DIR)/esptool2.o $(BUILD_DIR)/esptool2_elf.o
|
||||||
|
@echo "LD $@"
|
||||||
|
$(LD) -o $@ $^
|
@ -0,0 +1,76 @@
|
|||||||
|
// Based on a small portion of ELF.h from LLVM
|
||||||
|
|
||||||
|
//===-- llvm/Support/ELF.h - ELF constants and data structures --*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This header contains common, non-processor-specific data structures and
|
||||||
|
// constants for the ELF file format.
|
||||||
|
//
|
||||||
|
// The details of the ELF32 bits in this file are largely based on the Tool
|
||||||
|
// Interface Standard (TIS) Executable and Linking Format (ELF) Specification
|
||||||
|
// Version 1.2, May 1995. The ELF64 stuff is based on ELF-64 Object File Format
|
||||||
|
// Version 1.5, Draft 2, May 1998 as well as OpenBSD header files.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_RBOOT_ESPTOOL2_ELF_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_RBOOT_ESPTOOL2_ELF_H_
|
||||||
|
|
||||||
|
typedef uint32_t Elf32_Addr; // Program address
|
||||||
|
typedef uint32_t Elf32_Off; // File offset
|
||||||
|
typedef uint16_t Elf32_Half;
|
||||||
|
typedef uint32_t Elf32_Word;
|
||||||
|
typedef int32_t Elf32_Sword;
|
||||||
|
|
||||||
|
// e_ident size and indices
|
||||||
|
enum {
|
||||||
|
EI_MAG0 = 0, // File identification index.
|
||||||
|
EI_MAG1 = 1, // File identification index.
|
||||||
|
EI_MAG2 = 2, // File identification index.
|
||||||
|
EI_MAG3 = 3, // File identification index.
|
||||||
|
EI_CLASS = 4, // File class.
|
||||||
|
EI_DATA = 5, // Data encoding.
|
||||||
|
EI_VERSION = 6, // File version.
|
||||||
|
EI_OSABI = 7, // OS/ABI identification.
|
||||||
|
EI_ABIVERSION = 8, // ABI version.
|
||||||
|
EI_PAD = 9, // Start of padding bytes.
|
||||||
|
EI_NIDENT = 16 // Number of bytes in e_ident.
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char e_ident[EI_NIDENT]; // ELF Identification bytes
|
||||||
|
Elf32_Half e_type; // Type of file (see ET_* below)
|
||||||
|
Elf32_Half e_machine; // Required architecture for this file (see EM_*)
|
||||||
|
Elf32_Word e_version; // Must be equal to 1
|
||||||
|
Elf32_Addr e_entry; // Address to jump to in order to start program
|
||||||
|
Elf32_Off e_phoff; // Program header table's file offset, in bytes
|
||||||
|
Elf32_Off e_shoff; // Section header table's file offset, in bytes
|
||||||
|
Elf32_Word e_flags; // Processor-specific flags
|
||||||
|
Elf32_Half e_ehsize; // Size of ELF header, in bytes
|
||||||
|
Elf32_Half e_phentsize; // Size of an entry in the program header table
|
||||||
|
Elf32_Half e_phnum; // Number of entries in the program header table
|
||||||
|
Elf32_Half e_shentsize; // Size of an entry in the section header table
|
||||||
|
Elf32_Half e_shnum; // Number of entries in the section header table
|
||||||
|
Elf32_Half e_shstrndx; // Sect hdr table index of sect name string table
|
||||||
|
} Elf32_Ehdr;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Word sh_name; // Section name (index into string table)
|
||||||
|
Elf32_Word sh_type; // Section type (SHT_*)
|
||||||
|
Elf32_Word sh_flags; // Section flags (SHF_*)
|
||||||
|
Elf32_Addr sh_addr; // Address where section is to be loaded
|
||||||
|
Elf32_Off sh_offset; // File offset of section data, in bytes
|
||||||
|
Elf32_Word sh_size; // Size of section, in bytes
|
||||||
|
Elf32_Word sh_link; // Section type-specific header table index link
|
||||||
|
Elf32_Word sh_info; // Section type-specific extra information
|
||||||
|
Elf32_Word sh_addralign; // Section address alignment
|
||||||
|
Elf32_Word sh_entsize; // Size of records contained within the section
|
||||||
|
} Elf32_Shdr;
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_RBOOT_ESPTOOL2_ELF_H_ */
|
@ -0,0 +1,561 @@
|
|||||||
|
/**********************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Richard A Burton <richardaburton@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of esptool2.
|
||||||
|
*
|
||||||
|
* esptool2 is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* esptool2 is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with esptool2. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
**********************************************************************************/
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "esptool2.h"
|
||||||
|
#include "esptool2_elf.h"
|
||||||
|
|
||||||
|
#define IMAGE_PADDING 16
|
||||||
|
#define SECTION_PADDING 4
|
||||||
|
#define IROM_SECTION_PADDING 4096
|
||||||
|
#define CHECKSUM_INIT 0xEF
|
||||||
|
#define BIN_MAGIC_IROM 0xEA
|
||||||
|
#define BIN_MAGIC_FLASH 0xE9
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Addr addr;
|
||||||
|
Elf32_Word size;
|
||||||
|
} Section_Header;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
unsigned char magic;
|
||||||
|
unsigned char count;
|
||||||
|
unsigned char byte2;
|
||||||
|
unsigned char byte3;
|
||||||
|
Elf32_Addr entry;
|
||||||
|
} Image_Header;
|
||||||
|
|
||||||
|
static const char PADDING[IROM_SECTION_PADDING] = {0};
|
||||||
|
|
||||||
|
static bool debugon = false;
|
||||||
|
static bool quieton = false;
|
||||||
|
|
||||||
|
// Print a standard info message (unless quiet mode)
|
||||||
|
void print(const char* format, ...) {
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
if (!quieton) {
|
||||||
|
va_start(args, format);
|
||||||
|
vprintf(format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print a debug message (if debug mode)
|
||||||
|
void debug(const char* format, ...) {
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
if (debugon) {
|
||||||
|
va_start(args, format);
|
||||||
|
vprintf(format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print an error message (always)
|
||||||
|
void error(const char* format, ...) {
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, format);
|
||||||
|
vfprintf(stderr, format, args);
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write an elf section (by name) to an existing file.
|
||||||
|
// Parameters:
|
||||||
|
// headed - add a header to the output
|
||||||
|
// zeroaddr - force zero entry point in header (default is the real entry point)
|
||||||
|
// padded - output will be padded to multiple of SECTION_PADDING bytes
|
||||||
|
// chksum - pointer to existing checksum to add this data to (zero if not needed)
|
||||||
|
// Produces error message on failure (so caller doesn't need to).
|
||||||
|
bool WriteElfSection(MyElf_File *elf, FILE *outfile, char* name, bool headed,
|
||||||
|
bool zeroaddr, int padto, unsigned char *chksum) {
|
||||||
|
|
||||||
|
int i, pad = 0;
|
||||||
|
bool ret = false;
|
||||||
|
unsigned char *bindata = 0;
|
||||||
|
Section_Header sechead;
|
||||||
|
MyElf_Section *sect;
|
||||||
|
|
||||||
|
// get elf section header
|
||||||
|
sect = GetElfSection(elf, name);
|
||||||
|
if(!sect) {
|
||||||
|
error("Error: Section '%s' not found in elf file.\r\n", name);
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// create image section header
|
||||||
|
sechead.addr = (zeroaddr ? 0 : sect->address);
|
||||||
|
sechead.size = sect->size;
|
||||||
|
|
||||||
|
// do we need to pad the section?
|
||||||
|
if (padto) {
|
||||||
|
pad = sechead.size % padto;
|
||||||
|
if (pad > 0) {
|
||||||
|
pad = padto - pad;
|
||||||
|
sechead.size += pad;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("Adding section '%s', addr: 0x%08x, size: %d (+%d bytes(s) padding).\r\n",
|
||||||
|
name, sect->address, sect->size, pad);
|
||||||
|
|
||||||
|
// get elf section binary data
|
||||||
|
bindata = GetElfSectionData(elf, sect);
|
||||||
|
if (!bindata) {
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write section (and pad if required)
|
||||||
|
if((headed && fwrite(&sechead, 1, sizeof(sechead), outfile) != sizeof(sechead))
|
||||||
|
|| fwrite(bindata, 1, sect->size, outfile) != sect->size
|
||||||
|
|| (pad > 0 && fwrite(PADDING, 1, pad, outfile) != pad)) {
|
||||||
|
error("Error: Failed to write section '%s' to image file.\r\n", name);
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// include section data in the checksum
|
||||||
|
if(chksum) {
|
||||||
|
for(i = 0; i < (int)sect->size; i++) {
|
||||||
|
*chksum ^= bindata[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
end_function:
|
||||||
|
if (bindata) free(bindata);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load an elf file and export a section of it to a new file, without
|
||||||
|
// header, padding or checksum. For exporting the .irom0.text library.
|
||||||
|
// Produces error message on failure (so caller doesn't need to).
|
||||||
|
bool ExportElfSection(char *infile, char *outfile, char *name) {
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
FILE *fd = 0;
|
||||||
|
MyElf_File *elf = 0;
|
||||||
|
|
||||||
|
// load elf file
|
||||||
|
elf = LoadElf(infile);
|
||||||
|
if (!elf) {
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open output file
|
||||||
|
fd = fopen(outfile, "wb");
|
||||||
|
if(!fd) {
|
||||||
|
error("Error: Can't open output file '%s' for writing.\r\n", outfile);
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// actually do the export
|
||||||
|
ret = WriteElfSection(elf, fd, name, false, false, false, 0);
|
||||||
|
|
||||||
|
end_function:
|
||||||
|
// clean up
|
||||||
|
if (fd) fclose(fd);
|
||||||
|
UnloadElf(elf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the main binary firmware image, from specified elf sections.
|
||||||
|
// Can produce for standard standalone app (separate .irom0.text)
|
||||||
|
// or sdk bootloaded apps (integrated .irom0.text).
|
||||||
|
// Choice of type requires appropriately linked elf file.
|
||||||
|
// Produces error message on failure (so caller doesn't need to).
|
||||||
|
bool CreateHeaderFile(char *elffile, char *imagefile, char *sections[], int numsec) {
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
int i;
|
||||||
|
unsigned int j, len;
|
||||||
|
FILE *outfile = 0;
|
||||||
|
MyElf_File *elf = 0;
|
||||||
|
MyElf_Section *sect;
|
||||||
|
unsigned char *bindata = 0;
|
||||||
|
char name[31];
|
||||||
|
|
||||||
|
// load elf file
|
||||||
|
elf = LoadElf(elffile);
|
||||||
|
if (!elf) {
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open output file
|
||||||
|
outfile = fopen(imagefile, "wb");
|
||||||
|
if(outfile == NULL) {
|
||||||
|
error("Error: Failed to open output file '%s' for writing.\r\n", imagefile);
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add entry point
|
||||||
|
fprintf(outfile, "const uint32 entry_addr = 0x%08x;\r\n", elf->header.e_entry);
|
||||||
|
|
||||||
|
// add sections
|
||||||
|
for (i = 0; i < numsec; i++) {
|
||||||
|
// get elf section header
|
||||||
|
sect = GetElfSection(elf, sections[i]);
|
||||||
|
if(!sect) {
|
||||||
|
error("Error: Section '%s' not found in elf file.\r\n", sections[i]);
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// simple name fix name
|
||||||
|
strncpy(name, sect->name, 31);
|
||||||
|
len = strlen(name);
|
||||||
|
for (j = 0; j < len; j++) {
|
||||||
|
if (name[j] == '.') name[j] = '_';
|
||||||
|
}
|
||||||
|
|
||||||
|
// add address, length and start the data block
|
||||||
|
debug("Adding section '%s', addr: 0x%08x, size: %d.\r\n", sections[i], sect->address, sect->size);
|
||||||
|
fprintf(outfile, "\r\nconst uint32 %s_addr = 0x%08x;\r\nconst uint32 %s_len = %d;\r\nconst uint8 %s_data[] = {",
|
||||||
|
name, sect->address, name, sect->size, name);
|
||||||
|
|
||||||
|
// get elf section binary data
|
||||||
|
bindata = GetElfSectionData(elf, sect);
|
||||||
|
if (!bindata) {
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the data and finish off the block
|
||||||
|
for (j = 0; j < sect->size; j++) {
|
||||||
|
if (j % 16 == 0) fprintf(outfile, "\r\n 0x%02x,", bindata[j]);
|
||||||
|
else fprintf(outfile, " 0x%02x,", bindata[j]);
|
||||||
|
}
|
||||||
|
fprintf(outfile, "\r\n};\r\n");
|
||||||
|
free(bindata);
|
||||||
|
bindata = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we got this far everything worked!
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
end_function:
|
||||||
|
// clean up
|
||||||
|
if (outfile) fclose(outfile);
|
||||||
|
if (elf) UnloadElf(elf);
|
||||||
|
if (bindata) free(bindata);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create the main binary firmware image, from specified elf sections.
|
||||||
|
// Can produce for standard standalone app (separate .irom0.text)
|
||||||
|
// or sdk bootloaded apps (integrated .irom0.text).
|
||||||
|
// Choice of type requires appropriately linked elf file.
|
||||||
|
// Produces error message on failure (so caller doesn't need to).
|
||||||
|
bool CreateBinFile(char *elffile, char *imagefile, int bootver, unsigned char mode,
|
||||||
|
unsigned char clock, unsigned char size, bool iromchksum, char *sections[], int numsec) {
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
int i, pad, len;
|
||||||
|
unsigned char chksum = CHECKSUM_INIT;
|
||||||
|
unsigned char *data = 0;
|
||||||
|
FILE *outfile = 0;
|
||||||
|
MyElf_File *elf = 0;
|
||||||
|
Image_Header imghead;
|
||||||
|
|
||||||
|
// load elf file
|
||||||
|
elf = LoadElf(elffile);
|
||||||
|
if (!elf) {
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// open output file
|
||||||
|
outfile = fopen(imagefile, "wb");
|
||||||
|
if(outfile == NULL) {
|
||||||
|
error("Error: Failed to open output file '%s' for writing.\r\n", imagefile);
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set options common to standard and boot v1.2+ headers
|
||||||
|
imghead.byte2 = mode;
|
||||||
|
//imghead.byte3 = (int)((int)size << 4 | clock) && 0xff;
|
||||||
|
imghead.byte3 = ((size << 4) | clock) & 0xff;
|
||||||
|
imghead.entry = elf->header.e_entry;
|
||||||
|
debug("Size = %02x\r\n", size);
|
||||||
|
debug("Byte2 = %02x\r\n", imghead.byte2);
|
||||||
|
debug("Byte3 = %02x\r\n", imghead.byte3);
|
||||||
|
debug("Entry = %08x\r\n", imghead.entry);
|
||||||
|
|
||||||
|
// boot v1.2+ header
|
||||||
|
if (bootver == 2) {
|
||||||
|
// extra header
|
||||||
|
imghead.magic = BIN_MAGIC_IROM;
|
||||||
|
imghead.count = 4; // probably a version number here, not a count
|
||||||
|
if(fwrite(&imghead, 1, sizeof(imghead), outfile) != sizeof(imghead)) {
|
||||||
|
error("Error: Failed to write header to image file.\r\n");
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
if(!WriteElfSection(elf, outfile, ".irom0.text", true, true, IROM_SECTION_PADDING, (iromchksum ? &chksum : 0))) {
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// standard header
|
||||||
|
imghead.magic = BIN_MAGIC_FLASH;
|
||||||
|
imghead.count = numsec;
|
||||||
|
// write header
|
||||||
|
if(fwrite(&imghead, 1, sizeof(imghead), outfile) != sizeof(imghead)) {
|
||||||
|
error("Error: Failed to write header to image file.\r\n");
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add sections
|
||||||
|
for (i = 0; i < numsec; i++) {
|
||||||
|
if(!WriteElfSection(elf, outfile, sections[i], true, false, SECTION_PADDING, &chksum)) {
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get image length (plus a byte for the checksum)
|
||||||
|
len = ftell(outfile) + 1;
|
||||||
|
|
||||||
|
// do we need to pad the image?
|
||||||
|
pad = len % IMAGE_PADDING;
|
||||||
|
if (pad > 0) {
|
||||||
|
pad = IMAGE_PADDING - pad;
|
||||||
|
debug("Padding image with %d byte(s).\r\n", pad);
|
||||||
|
if(fwrite(PADDING, 1, pad, outfile) != pad) {
|
||||||
|
error("Error: Failed to write padding to image file.\r\n");
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write checksum
|
||||||
|
if(fwrite(&chksum, 1, 1, outfile) != 1) {
|
||||||
|
error("Error: Failed to write checksum to image file.\r\n");
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// boot v1.1
|
||||||
|
if(bootver == 1) {
|
||||||
|
// write 'ff' padding up to the position of the library
|
||||||
|
len = 0x10000 - ftell(outfile);
|
||||||
|
debug("Adding boot v1.1 padding, %d bytes of '0xff'.\r\n", len);
|
||||||
|
data = (unsigned char*)malloc(len);
|
||||||
|
memset(data, 0xff, len);
|
||||||
|
if(fwrite(data, 1, len, outfile) != len) {
|
||||||
|
error("Error: Failed to write boot v1.1 spacer.\r\n");
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the library
|
||||||
|
if(!WriteElfSection(elf, outfile, ".irom0.text", false, false, 0, 0)) {
|
||||||
|
goto end_function;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// if we got this far everything worked!
|
||||||
|
ret = true;
|
||||||
|
|
||||||
|
end_function:
|
||||||
|
// clean up
|
||||||
|
if (outfile) fclose(outfile);
|
||||||
|
if (data) free(data);
|
||||||
|
if (elf) UnloadElf(elf);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
char *infile;
|
||||||
|
char *outfile;
|
||||||
|
int numstr;
|
||||||
|
bool binfile = false;
|
||||||
|
bool libfile = false;
|
||||||
|
bool headerfile = false;
|
||||||
|
bool paramerror = false;
|
||||||
|
bool iromchksum = false;
|
||||||
|
int bootver = 0;
|
||||||
|
/* Overwrite-friendly by default */
|
||||||
|
unsigned char mode = 0xff;
|
||||||
|
unsigned char size = 0xff;
|
||||||
|
unsigned char clock = 0;
|
||||||
|
int opts = 0;
|
||||||
|
|
||||||
|
// parse options
|
||||||
|
for (i = 1; i < argc; i++) {
|
||||||
|
if (!strcmp(argv[i], "-bin")) {
|
||||||
|
binfile = true;
|
||||||
|
opts++;
|
||||||
|
} else if (!strcmp(argv[i], "-lib")) {
|
||||||
|
libfile = true;
|
||||||
|
opts++;
|
||||||
|
} else if (!strcmp(argv[i], "-header")) {
|
||||||
|
headerfile = true;
|
||||||
|
opts++;
|
||||||
|
} else if (!strcmp(argv[i], "-quiet")) {
|
||||||
|
quieton = true;
|
||||||
|
} else if (!strcmp(argv[i], "-debug")) {
|
||||||
|
debugon = true;
|
||||||
|
} else if (!strcmp(argv[i], "-boot0")) {
|
||||||
|
bootver = 0;
|
||||||
|
} else if (!strcmp(argv[i], "-boot1")) {
|
||||||
|
bootver = 1;
|
||||||
|
} else if (!strcmp(argv[i], "-boot2")) {
|
||||||
|
bootver = 2;
|
||||||
|
} else if (!strcmp(argv[i], "-qio")) {
|
||||||
|
mode = 0;
|
||||||
|
} else if (!strcmp(argv[i], "-qout")) {
|
||||||
|
mode = 1;
|
||||||
|
} else if (!strcmp(argv[i], "-dio")) {
|
||||||
|
mode = 2;
|
||||||
|
} else if (!strcmp(argv[i], "-dout")) {
|
||||||
|
mode = 3;
|
||||||
|
} else if (!strcmp(argv[i], "-256")) {
|
||||||
|
size = 1;
|
||||||
|
} else if (!strcmp(argv[i], "-512")) {
|
||||||
|
size = 0;
|
||||||
|
} else if (!strcmp(argv[i], "-1024")) {
|
||||||
|
size = 2;
|
||||||
|
} else if (!strcmp(argv[i], "-2048")) {
|
||||||
|
size = 3;
|
||||||
|
} else if (!strcmp(argv[i], "-4096")) {
|
||||||
|
size = 4;
|
||||||
|
} else if (!strcmp(argv[i], "-20")) {
|
||||||
|
clock = 2;
|
||||||
|
} else if (!strcmp(argv[i], "-26.7")) {
|
||||||
|
clock = 1;
|
||||||
|
} else if (!strcmp(argv[i], "-40")) {
|
||||||
|
clock = 0;
|
||||||
|
} else if (!strcmp(argv[i], "-80")) {
|
||||||
|
clock = 15;
|
||||||
|
} else if (!strcmp(argv[i], "-iromchksum")) {
|
||||||
|
iromchksum = true;
|
||||||
|
} else if (!strcmp(argv[i], "--")) {
|
||||||
|
i++;
|
||||||
|
break;
|
||||||
|
} else if (argv[i][0] == '-') {
|
||||||
|
paramerror = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
print("esptool2 v2.0.0 - (c) 2015 Richard A Burton <richardaburton@gmail.com>\r\n");
|
||||||
|
print("This program is licensed under the GPL v3.\r\n");
|
||||||
|
print("See the file LICENSE for details.\r\n\r\n");
|
||||||
|
|
||||||
|
if (paramerror) {
|
||||||
|
error("Error: Unrecognised option '%s'.\r\n", argv[i]);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 2) {
|
||||||
|
print("Usage:\r\n");
|
||||||
|
print("esptool2 -lib [options] <input_file> <output_file>\r\n");
|
||||||
|
print("esptool2 -bin [options] <input_file> <output_file> <elf_section>...\r\n");
|
||||||
|
print("esptool2 -header [options] <input_file> <output_file> <elf_section>...\r\n");
|
||||||
|
print("\r\n");
|
||||||
|
print(" -lib\r\n");
|
||||||
|
print(" Export the sdk library (.irom0.text), for a standalone app.\r\n");
|
||||||
|
print(" e.g. esptool2 -elf esp8266_iot.out out.bin\r\n");
|
||||||
|
print("\r\n");
|
||||||
|
print(" -header\r\n");
|
||||||
|
print(" Export elf sections as bytes to a C header file.\r\n");
|
||||||
|
print(" e.g. esptool2 -elf esp8266_iot.out out.h .text .data .rodata\r\n");
|
||||||
|
print("\r\n");
|
||||||
|
print(" -bin\r\n");
|
||||||
|
print(" Create binary program image, for standalone and bootloaded apps, with\r\n");
|
||||||
|
print(" specified elf sections. Includes sdk library for bootloaded apps.\r\n");
|
||||||
|
print(" e.g. esptool2 -bin esp8266_iot.out out.bin .text .data .rodata\r\n");
|
||||||
|
print(" Options:\r\n");
|
||||||
|
print(" bootloader: -boot0 -boot1 -boot2 (default -boot0)\r\n");
|
||||||
|
print(" -boot0 = standalone app, not built for bootloader use\r\n");
|
||||||
|
print(" -boot1 = built for bootloader v1.1\r\n");
|
||||||
|
print(" -boot2 = built for bootloader v1.2+ (use for rBoot roms)\r\n");
|
||||||
|
print(" (elf file must have been linked appropriately for chosen option)\r\n");
|
||||||
|
print(" spi size (kb): -256 -512 -1024 -2048 -4096 (default -512)\r\n");
|
||||||
|
print(" spi mode: -qio -qout -dio -dout (default -qio)\r\n");
|
||||||
|
print(" spi speed: -20 -26.7 -40 -80 (default -40)\r\n");
|
||||||
|
print(" include irom in checksum: -iromchksum (also needs enabling in rBoot)\r\n");
|
||||||
|
print("\r\n");
|
||||||
|
print("General options:\r\n");
|
||||||
|
print(" -quiet prints only error messages\r\n");
|
||||||
|
print(" -debug print extra debug information\r\n");
|
||||||
|
print(" -- no more options follow (needed if your elf file starts with a '-')\r\n");
|
||||||
|
print("\r\n");
|
||||||
|
print("Returns:\r\n");
|
||||||
|
print(" 0 on success\r\n");
|
||||||
|
print(" -1 on failure\r\n");
|
||||||
|
print("\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// validate command line options
|
||||||
|
if (opts != 1) {
|
||||||
|
error("Error: You must specify -bin OR -lib OR -header for build type.\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quieton && debugon) {
|
||||||
|
error("Error: You cannot specify -quiet and -debug.\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check enough parameters
|
||||||
|
if ((libfile && i + 2 > argc) || ((binfile | headerfile) && i + 3 > argc)) {
|
||||||
|
error("Error: Not enough arguments supplied.\r\n");
|
||||||
|
return -1;
|
||||||
|
} else if (libfile && i + 2 < argc) {
|
||||||
|
error("Error: Too many arguments supplied.\r\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get parameters
|
||||||
|
infile = argv[i++];
|
||||||
|
outfile = argv[i++];
|
||||||
|
numstr = argc - i;
|
||||||
|
|
||||||
|
// do it
|
||||||
|
if (binfile) {
|
||||||
|
if (!CreateBinFile(infile, outfile, bootver, mode, clock, size, iromchksum, &argv[i], numstr)) {
|
||||||
|
remove(outfile);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else if (headerfile) {
|
||||||
|
if (!CreateHeaderFile(infile, outfile, &argv[i], numstr)) {
|
||||||
|
remove(outfile);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!ExportElfSection(infile, outfile, ".irom0.text")) {
|
||||||
|
remove(outfile);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
print("Successfully created '%s'.\r\n", outfile);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/**********************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Richard A Burton <richardaburton@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of esptool2.
|
||||||
|
*
|
||||||
|
* esptool2 is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* esptool2 is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with esptool2. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
**********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_RBOOT_ESPTOOL2_ESPTOOL2_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_RBOOT_ESPTOOL2_ESPTOOL2_H_
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
typedef signed __int8 int8_t;
|
||||||
|
typedef signed __int16 int16_t;
|
||||||
|
typedef signed __int32 int32_t;
|
||||||
|
typedef unsigned __int8 uint8_t;
|
||||||
|
typedef unsigned __int16 uint16_t;
|
||||||
|
typedef unsigned __int32 uint32_t;
|
||||||
|
#else
|
||||||
|
#include <stdint.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#define bool char
|
||||||
|
|
||||||
|
void debug( const char* format, ... );
|
||||||
|
void print( const char* format, ... );
|
||||||
|
void error( const char* format, ... );
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_RBOOT_ESPTOOL2_ESPTOOL2_H_ */
|
@ -0,0 +1,183 @@
|
|||||||
|
/**********************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Richard A Burton <richardaburton@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of esptool2.
|
||||||
|
*
|
||||||
|
* esptool2 is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* esptool2 is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with esptool2. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
**********************************************************************************/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "esptool2.h"
|
||||||
|
#include "esptool2_elf.h"
|
||||||
|
|
||||||
|
// Find a section in an elf file by name.
|
||||||
|
// Returns pointer to section if found, else returns zero.
|
||||||
|
// Does not produce any messages.
|
||||||
|
MyElf_Section* GetElfSection(MyElf_File *elf, char *name) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for(i = 0; i < elf->header.e_shnum - 1; i++) {
|
||||||
|
if(!strcmp(name, elf->sections[i].name)) {
|
||||||
|
debug("Found section '%s'.\r\n", name);
|
||||||
|
return &elf->sections[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug("Could not find section '%s'.\r\n", name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reads an elf section (actual data) from the elf file.
|
||||||
|
// Returns a pointer to newly allocated memory (or zero on error),
|
||||||
|
// which should be freed by the caller when finished with.
|
||||||
|
// Produces error message on failure (so caller doesn't need to).
|
||||||
|
unsigned char* GetElfSectionData(MyElf_File *elf, MyElf_Section *section) {
|
||||||
|
|
||||||
|
unsigned char *data = 0;
|
||||||
|
|
||||||
|
if (section->size && section->offset) {
|
||||||
|
|
||||||
|
data = (unsigned char*)malloc(section->size);
|
||||||
|
if(!data) {
|
||||||
|
error("Error: Out of memory!\r\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(fseek(elf->fd, section->offset, SEEK_SET) ||
|
||||||
|
fread(data, 1, section->size, elf->fd) != section->size) {
|
||||||
|
error("Error: Can't read section '%s' data from elf file.\r\n", section->name);
|
||||||
|
free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
error("Error: Section '%s' has no data to read.\r\n", section->name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Opens an elf file and reads the string table and file & section headers.
|
||||||
|
// Returns a pointer to a MyElf_File structure (or zero on error).
|
||||||
|
// UnloadElf should be called to dispose of the MyElf_File structure.
|
||||||
|
// Produces error message on failure (so caller doesn't need to).
|
||||||
|
MyElf_File* LoadElf(char *infile) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
MyElf_File *elf;
|
||||||
|
Elf32_Shdr temp;
|
||||||
|
|
||||||
|
// allocate the elf structure
|
||||||
|
elf = (MyElf_File*)malloc(sizeof(MyElf_File));
|
||||||
|
if(!elf) {
|
||||||
|
error("Error: Out of memory!\r\n");
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
memset(elf, 0, sizeof(MyElf_File));
|
||||||
|
|
||||||
|
// open the file
|
||||||
|
elf->fd = fopen(infile, "rb");
|
||||||
|
if(!elf->fd) {
|
||||||
|
error("Error: Can't open elf file '%s'.\r\n", infile);
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the header
|
||||||
|
if(fread(&elf->header, 1, sizeof(Elf32_Ehdr), elf->fd) != sizeof(Elf32_Ehdr)) {
|
||||||
|
error("Error: Can't read elf file header.\r\n");
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check the file header
|
||||||
|
if (memcmp(elf->header.e_ident, "\x7f" "ELF", 4)) {
|
||||||
|
error("Error: Input files doesn't look like an elf file (bad header).\r\n");
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// is there a string table section (we need one)
|
||||||
|
if(!elf->header.e_shstrndx) {
|
||||||
|
error("Error: Elf file does not contain a string table.\r\n");
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the string table section header
|
||||||
|
if(fseek(elf->fd, elf->header.e_shoff + (elf->header.e_shentsize * elf->header.e_shstrndx), SEEK_SET) ||
|
||||||
|
fread(&temp, 1, sizeof(Elf32_Shdr), elf->fd) != sizeof(Elf32_Shdr)) {
|
||||||
|
|
||||||
|
error("Error: Can't read string table section from elf file.\r\n");
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read the actual string table
|
||||||
|
if(!temp.sh_size) {
|
||||||
|
error("Error: Elf file contains an empty string table.\r\n");
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
elf->strings = (char*)malloc(temp.sh_size);
|
||||||
|
if(!elf->strings) {
|
||||||
|
error("Error: Out of memory!\r\n");
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
if(fseek(elf->fd, temp.sh_offset, SEEK_SET) ||
|
||||||
|
fread(elf->strings, 1, temp.sh_size, elf->fd) != temp.sh_size) {
|
||||||
|
error("Error: Failed to read string stable from elf file.\r\n");
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read section headers
|
||||||
|
elf->sections = (MyElf_Section*)malloc(sizeof(MyElf_Section) * elf->header.e_shnum);
|
||||||
|
if(!elf->sections) {
|
||||||
|
error("Error: Out of memory!\r\n");
|
||||||
|
goto error_exit;
|
||||||
|
}
|
||||||
|
for(i = 1; i < elf->header.e_shnum; i++) {
|
||||||
|
if(fseek(elf->fd, elf->header.e_shoff + (elf->header.e_shentsize * i), SEEK_SET)
|
||||||
|
|| fread(&temp, 1, sizeof(Elf32_Shdr), elf->fd) != sizeof(Elf32_Shdr)) {
|
||||||
|
error("Error: Can't read section %d from elf file.\r\n", i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
debug("Read section %d '%s'.\r\n", i, elf->strings + temp.sh_name);
|
||||||
|
elf->sections[i-1].address = temp.sh_addr;
|
||||||
|
elf->sections[i-1].offset = temp.sh_offset;
|
||||||
|
elf->sections[i-1].size = temp.sh_size;
|
||||||
|
elf->sections[i-1].name = elf->strings + temp.sh_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return elf;
|
||||||
|
|
||||||
|
error_exit:
|
||||||
|
if (elf) {
|
||||||
|
if (elf->fd) fclose(elf->fd);
|
||||||
|
if (elf->strings) free(elf->strings);
|
||||||
|
free(elf);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Close an elf file and dispose of the MyElf_File structure.
|
||||||
|
void UnloadElf(MyElf_File *elf) {
|
||||||
|
if (elf) {
|
||||||
|
debug("Unloading elf file.\r\n");
|
||||||
|
if(elf->fd) fclose(elf->fd);
|
||||||
|
if(elf->strings) free(elf->strings);
|
||||||
|
if(elf->sections) free(elf->sections);
|
||||||
|
free(elf);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
/**********************************************************************************
|
||||||
|
*
|
||||||
|
* Copyright (c) 2015 Richard A Burton <richardaburton@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of esptool2.
|
||||||
|
*
|
||||||
|
* esptool2 is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* esptool2 is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with esptool2. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
**********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_RBOOT_ESPTOOL2_ESPTOOL2_ELF_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_RBOOT_ESPTOOL2_ESPTOOL2_ELF_H_
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "elf.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
Elf32_Off offset;
|
||||||
|
Elf32_Addr address;
|
||||||
|
Elf32_Word size;
|
||||||
|
char *name;
|
||||||
|
} MyElf_Section;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
FILE *fd;
|
||||||
|
Elf32_Ehdr header;
|
||||||
|
char *strings;
|
||||||
|
MyElf_Section *sections;
|
||||||
|
} MyElf_File;
|
||||||
|
|
||||||
|
MyElf_File* LoadElf(char *infile);
|
||||||
|
void UnloadElf(MyElf_File *e_object);
|
||||||
|
MyElf_Section* GetElfSection(MyElf_File *e_object, char *name);
|
||||||
|
unsigned char* GetElfSectionData(MyElf_File *e_object, MyElf_Section *section);
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_RBOOT_ESPTOOL2_ESPTOOL2_ELF_H_ */
|
@ -0,0 +1,674 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 3, 29 June 2007
|
||||||
|
|
||||||
|
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The GNU General Public License is a free, copyleft license for
|
||||||
|
software and other kinds of works.
|
||||||
|
|
||||||
|
The licenses for most software and other practical works are designed
|
||||||
|
to take away your freedom to share and change the works. By contrast,
|
||||||
|
the GNU General Public License is intended to guarantee your freedom to
|
||||||
|
share and change all versions of a program--to make sure it remains free
|
||||||
|
software for all its users. We, the Free Software Foundation, use the
|
||||||
|
GNU General Public License for most of our software; it applies also to
|
||||||
|
any other work released this way by its authors. You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
them if you wish), that you receive source code or can get it if you
|
||||||
|
want it, that you can change the software or use pieces of it in new
|
||||||
|
free programs, and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to prevent others from denying you
|
||||||
|
these rights or asking you to surrender the rights. Therefore, you have
|
||||||
|
certain responsibilities if you distribute copies of the software, or if
|
||||||
|
you modify it: responsibilities to respect the freedom of others.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must pass on to the recipients the same
|
||||||
|
freedoms that you received. You must make sure that they, too, receive
|
||||||
|
or can get the source code. And you must show them these terms so they
|
||||||
|
know their rights.
|
||||||
|
|
||||||
|
Developers that use the GNU GPL protect your rights with two steps:
|
||||||
|
(1) assert copyright on the software, and (2) offer you this License
|
||||||
|
giving you legal permission to copy, distribute and/or modify it.
|
||||||
|
|
||||||
|
For the developers' and authors' protection, the GPL clearly explains
|
||||||
|
that there is no warranty for this free software. For both users' and
|
||||||
|
authors' sake, the GPL requires that modified versions be marked as
|
||||||
|
changed, so that their problems will not be attributed erroneously to
|
||||||
|
authors of previous versions.
|
||||||
|
|
||||||
|
Some devices are designed to deny users access to install or run
|
||||||
|
modified versions of the software inside them, although the manufacturer
|
||||||
|
can do so. This is fundamentally incompatible with the aim of
|
||||||
|
protecting users' freedom to change the software. The systematic
|
||||||
|
pattern of such abuse occurs in the area of products for individuals to
|
||||||
|
use, which is precisely where it is most unacceptable. Therefore, we
|
||||||
|
have designed this version of the GPL to prohibit the practice for those
|
||||||
|
products. If such problems arise substantially in other domains, we
|
||||||
|
stand ready to extend this provision to those domains in future versions
|
||||||
|
of the GPL, as needed to protect the freedom of users.
|
||||||
|
|
||||||
|
Finally, every program is threatened constantly by software patents.
|
||||||
|
States should not allow patents to restrict development and use of
|
||||||
|
software on general-purpose computers, but in those that do, we wish to
|
||||||
|
avoid the special danger that patents applied to a free program could
|
||||||
|
make it effectively proprietary. To prevent this, the GPL assures that
|
||||||
|
patents cannot be used to render the program non-free.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
0. Definitions.
|
||||||
|
|
||||||
|
"This License" refers to version 3 of the GNU General Public License.
|
||||||
|
|
||||||
|
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||||
|
works, such as semiconductor masks.
|
||||||
|
|
||||||
|
"The Program" refers to any copyrightable work licensed under this
|
||||||
|
License. Each licensee is addressed as "you". "Licensees" and
|
||||||
|
"recipients" may be individuals or organizations.
|
||||||
|
|
||||||
|
To "modify" a work means to copy from or adapt all or part of the work
|
||||||
|
in a fashion requiring copyright permission, other than the making of an
|
||||||
|
exact copy. The resulting work is called a "modified version" of the
|
||||||
|
earlier work or a work "based on" the earlier work.
|
||||||
|
|
||||||
|
A "covered work" means either the unmodified Program or a work based
|
||||||
|
on the Program.
|
||||||
|
|
||||||
|
To "propagate" a work means to do anything with it that, without
|
||||||
|
permission, would make you directly or secondarily liable for
|
||||||
|
infringement under applicable copyright law, except executing it on a
|
||||||
|
computer or modifying a private copy. Propagation includes copying,
|
||||||
|
distribution (with or without modification), making available to the
|
||||||
|
public, and in some countries other activities as well.
|
||||||
|
|
||||||
|
To "convey" a work means any kind of propagation that enables other
|
||||||
|
parties to make or receive copies. Mere interaction with a user through
|
||||||
|
a computer network, with no transfer of a copy, is not conveying.
|
||||||
|
|
||||||
|
An interactive user interface displays "Appropriate Legal Notices"
|
||||||
|
to the extent that it includes a convenient and prominently visible
|
||||||
|
feature that (1) displays an appropriate copyright notice, and (2)
|
||||||
|
tells the user that there is no warranty for the work (except to the
|
||||||
|
extent that warranties are provided), that licensees may convey the
|
||||||
|
work under this License, and how to view a copy of this License. If
|
||||||
|
the interface presents a list of user commands or options, such as a
|
||||||
|
menu, a prominent item in the list meets this criterion.
|
||||||
|
|
||||||
|
1. Source Code.
|
||||||
|
|
||||||
|
The "source code" for a work means the preferred form of the work
|
||||||
|
for making modifications to it. "Object code" means any non-source
|
||||||
|
form of a work.
|
||||||
|
|
||||||
|
A "Standard Interface" means an interface that either is an official
|
||||||
|
standard defined by a recognized standards body, or, in the case of
|
||||||
|
interfaces specified for a particular programming language, one that
|
||||||
|
is widely used among developers working in that language.
|
||||||
|
|
||||||
|
The "System Libraries" of an executable work include anything, other
|
||||||
|
than the work as a whole, that (a) is included in the normal form of
|
||||||
|
packaging a Major Component, but which is not part of that Major
|
||||||
|
Component, and (b) serves only to enable use of the work with that
|
||||||
|
Major Component, or to implement a Standard Interface for which an
|
||||||
|
implementation is available to the public in source code form. A
|
||||||
|
"Major Component", in this context, means a major essential component
|
||||||
|
(kernel, window system, and so on) of the specific operating system
|
||||||
|
(if any) on which the executable work runs, or a compiler used to
|
||||||
|
produce the work, or an object code interpreter used to run it.
|
||||||
|
|
||||||
|
The "Corresponding Source" for a work in object code form means all
|
||||||
|
the source code needed to generate, install, and (for an executable
|
||||||
|
work) run the object code and to modify the work, including scripts to
|
||||||
|
control those activities. However, it does not include the work's
|
||||||
|
System Libraries, or general-purpose tools or generally available free
|
||||||
|
programs which are used unmodified in performing those activities but
|
||||||
|
which are not part of the work. For example, Corresponding Source
|
||||||
|
includes interface definition files associated with source files for
|
||||||
|
the work, and the source code for shared libraries and dynamically
|
||||||
|
linked subprograms that the work is specifically designed to require,
|
||||||
|
such as by intimate data communication or control flow between those
|
||||||
|
subprograms and other parts of the work.
|
||||||
|
|
||||||
|
The Corresponding Source need not include anything that users
|
||||||
|
can regenerate automatically from other parts of the Corresponding
|
||||||
|
Source.
|
||||||
|
|
||||||
|
The Corresponding Source for a work in source code form is that
|
||||||
|
same work.
|
||||||
|
|
||||||
|
2. Basic Permissions.
|
||||||
|
|
||||||
|
All rights granted under this License are granted for the term of
|
||||||
|
copyright on the Program, and are irrevocable provided the stated
|
||||||
|
conditions are met. This License explicitly affirms your unlimited
|
||||||
|
permission to run the unmodified Program. The output from running a
|
||||||
|
covered work is covered by this License only if the output, given its
|
||||||
|
content, constitutes a covered work. This License acknowledges your
|
||||||
|
rights of fair use or other equivalent, as provided by copyright law.
|
||||||
|
|
||||||
|
You may make, run and propagate covered works that you do not
|
||||||
|
convey, without conditions so long as your license otherwise remains
|
||||||
|
in force. You may convey covered works to others for the sole purpose
|
||||||
|
of having them make modifications exclusively for you, or provide you
|
||||||
|
with facilities for running those works, provided that you comply with
|
||||||
|
the terms of this License in conveying all material for which you do
|
||||||
|
not control copyright. Those thus making or running the covered works
|
||||||
|
for you must do so exclusively on your behalf, under your direction
|
||||||
|
and control, on terms that prohibit them from making any copies of
|
||||||
|
your copyrighted material outside their relationship with you.
|
||||||
|
|
||||||
|
Conveying under any other circumstances is permitted solely under
|
||||||
|
the conditions stated below. Sublicensing is not allowed; section 10
|
||||||
|
makes it unnecessary.
|
||||||
|
|
||||||
|
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||||
|
|
||||||
|
No covered work shall be deemed part of an effective technological
|
||||||
|
measure under any applicable law fulfilling obligations under article
|
||||||
|
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||||
|
similar laws prohibiting or restricting circumvention of such
|
||||||
|
measures.
|
||||||
|
|
||||||
|
When you convey a covered work, you waive any legal power to forbid
|
||||||
|
circumvention of technological measures to the extent such circumvention
|
||||||
|
is effected by exercising rights under this License with respect to
|
||||||
|
the covered work, and you disclaim any intention to limit operation or
|
||||||
|
modification of the work as a means of enforcing, against the work's
|
||||||
|
users, your or third parties' legal rights to forbid circumvention of
|
||||||
|
technological measures.
|
||||||
|
|
||||||
|
4. Conveying Verbatim Copies.
|
||||||
|
|
||||||
|
You may convey verbatim copies of the Program's source code as you
|
||||||
|
receive it, in any medium, provided that you conspicuously and
|
||||||
|
appropriately publish on each copy an appropriate copyright notice;
|
||||||
|
keep intact all notices stating that this License and any
|
||||||
|
non-permissive terms added in accord with section 7 apply to the code;
|
||||||
|
keep intact all notices of the absence of any warranty; and give all
|
||||||
|
recipients a copy of this License along with the Program.
|
||||||
|
|
||||||
|
You may charge any price or no price for each copy that you convey,
|
||||||
|
and you may offer support or warranty protection for a fee.
|
||||||
|
|
||||||
|
5. Conveying Modified Source Versions.
|
||||||
|
|
||||||
|
You may convey a work based on the Program, or the modifications to
|
||||||
|
produce it from the Program, in the form of source code under the
|
||||||
|
terms of section 4, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) The work must carry prominent notices stating that you modified
|
||||||
|
it, and giving a relevant date.
|
||||||
|
|
||||||
|
b) The work must carry prominent notices stating that it is
|
||||||
|
released under this License and any conditions added under section
|
||||||
|
7. This requirement modifies the requirement in section 4 to
|
||||||
|
"keep intact all notices".
|
||||||
|
|
||||||
|
c) You must license the entire work, as a whole, under this
|
||||||
|
License to anyone who comes into possession of a copy. This
|
||||||
|
License will therefore apply, along with any applicable section 7
|
||||||
|
additional terms, to the whole of the work, and all its parts,
|
||||||
|
regardless of how they are packaged. This License gives no
|
||||||
|
permission to license the work in any other way, but it does not
|
||||||
|
invalidate such permission if you have separately received it.
|
||||||
|
|
||||||
|
d) If the work has interactive user interfaces, each must display
|
||||||
|
Appropriate Legal Notices; however, if the Program has interactive
|
||||||
|
interfaces that do not display Appropriate Legal Notices, your
|
||||||
|
work need not make them do so.
|
||||||
|
|
||||||
|
A compilation of a covered work with other separate and independent
|
||||||
|
works, which are not by their nature extensions of the covered work,
|
||||||
|
and which are not combined with it such as to form a larger program,
|
||||||
|
in or on a volume of a storage or distribution medium, is called an
|
||||||
|
"aggregate" if the compilation and its resulting copyright are not
|
||||||
|
used to limit the access or legal rights of the compilation's users
|
||||||
|
beyond what the individual works permit. Inclusion of a covered work
|
||||||
|
in an aggregate does not cause this License to apply to the other
|
||||||
|
parts of the aggregate.
|
||||||
|
|
||||||
|
6. Conveying Non-Source Forms.
|
||||||
|
|
||||||
|
You may convey a covered work in object code form under the terms
|
||||||
|
of sections 4 and 5, provided that you also convey the
|
||||||
|
machine-readable Corresponding Source under the terms of this License,
|
||||||
|
in one of these ways:
|
||||||
|
|
||||||
|
a) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by the
|
||||||
|
Corresponding Source fixed on a durable physical medium
|
||||||
|
customarily used for software interchange.
|
||||||
|
|
||||||
|
b) Convey the object code in, or embodied in, a physical product
|
||||||
|
(including a physical distribution medium), accompanied by a
|
||||||
|
written offer, valid for at least three years and valid for as
|
||||||
|
long as you offer spare parts or customer support for that product
|
||||||
|
model, to give anyone who possesses the object code either (1) a
|
||||||
|
copy of the Corresponding Source for all the software in the
|
||||||
|
product that is covered by this License, on a durable physical
|
||||||
|
medium customarily used for software interchange, for a price no
|
||||||
|
more than your reasonable cost of physically performing this
|
||||||
|
conveying of source, or (2) access to copy the
|
||||||
|
Corresponding Source from a network server at no charge.
|
||||||
|
|
||||||
|
c) Convey individual copies of the object code with a copy of the
|
||||||
|
written offer to provide the Corresponding Source. This
|
||||||
|
alternative is allowed only occasionally and noncommercially, and
|
||||||
|
only if you received the object code with such an offer, in accord
|
||||||
|
with subsection 6b.
|
||||||
|
|
||||||
|
d) Convey the object code by offering access from a designated
|
||||||
|
place (gratis or for a charge), and offer equivalent access to the
|
||||||
|
Corresponding Source in the same way through the same place at no
|
||||||
|
further charge. You need not require recipients to copy the
|
||||||
|
Corresponding Source along with the object code. If the place to
|
||||||
|
copy the object code is a network server, the Corresponding Source
|
||||||
|
may be on a different server (operated by you or a third party)
|
||||||
|
that supports equivalent copying facilities, provided you maintain
|
||||||
|
clear directions next to the object code saying where to find the
|
||||||
|
Corresponding Source. Regardless of what server hosts the
|
||||||
|
Corresponding Source, you remain obligated to ensure that it is
|
||||||
|
available for as long as needed to satisfy these requirements.
|
||||||
|
|
||||||
|
e) Convey the object code using peer-to-peer transmission, provided
|
||||||
|
you inform other peers where the object code and Corresponding
|
||||||
|
Source of the work are being offered to the general public at no
|
||||||
|
charge under subsection 6d.
|
||||||
|
|
||||||
|
A separable portion of the object code, whose source code is excluded
|
||||||
|
from the Corresponding Source as a System Library, need not be
|
||||||
|
included in conveying the object code work.
|
||||||
|
|
||||||
|
A "User Product" is either (1) a "consumer product", which means any
|
||||||
|
tangible personal property which is normally used for personal, family,
|
||||||
|
or household purposes, or (2) anything designed or sold for incorporation
|
||||||
|
into a dwelling. In determining whether a product is a consumer product,
|
||||||
|
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||||
|
product received by a particular user, "normally used" refers to a
|
||||||
|
typical or common use of that class of product, regardless of the status
|
||||||
|
of the particular user or of the way in which the particular user
|
||||||
|
actually uses, or expects or is expected to use, the product. A product
|
||||||
|
is a consumer product regardless of whether the product has substantial
|
||||||
|
commercial, industrial or non-consumer uses, unless such uses represent
|
||||||
|
the only significant mode of use of the product.
|
||||||
|
|
||||||
|
"Installation Information" for a User Product means any methods,
|
||||||
|
procedures, authorization keys, or other information required to install
|
||||||
|
and execute modified versions of a covered work in that User Product from
|
||||||
|
a modified version of its Corresponding Source. The information must
|
||||||
|
suffice to ensure that the continued functioning of the modified object
|
||||||
|
code is in no case prevented or interfered with solely because
|
||||||
|
modification has been made.
|
||||||
|
|
||||||
|
If you convey an object code work under this section in, or with, or
|
||||||
|
specifically for use in, a User Product, and the conveying occurs as
|
||||||
|
part of a transaction in which the right of possession and use of the
|
||||||
|
User Product is transferred to the recipient in perpetuity or for a
|
||||||
|
fixed term (regardless of how the transaction is characterized), the
|
||||||
|
Corresponding Source conveyed under this section must be accompanied
|
||||||
|
by the Installation Information. But this requirement does not apply
|
||||||
|
if neither you nor any third party retains the ability to install
|
||||||
|
modified object code on the User Product (for example, the work has
|
||||||
|
been installed in ROM).
|
||||||
|
|
||||||
|
The requirement to provide Installation Information does not include a
|
||||||
|
requirement to continue to provide support service, warranty, or updates
|
||||||
|
for a work that has been modified or installed by the recipient, or for
|
||||||
|
the User Product in which it has been modified or installed. Access to a
|
||||||
|
network may be denied when the modification itself materially and
|
||||||
|
adversely affects the operation of the network or violates the rules and
|
||||||
|
protocols for communication across the network.
|
||||||
|
|
||||||
|
Corresponding Source conveyed, and Installation Information provided,
|
||||||
|
in accord with this section must be in a format that is publicly
|
||||||
|
documented (and with an implementation available to the public in
|
||||||
|
source code form), and must require no special password or key for
|
||||||
|
unpacking, reading or copying.
|
||||||
|
|
||||||
|
7. Additional Terms.
|
||||||
|
|
||||||
|
"Additional permissions" are terms that supplement the terms of this
|
||||||
|
License by making exceptions from one or more of its conditions.
|
||||||
|
Additional permissions that are applicable to the entire Program shall
|
||||||
|
be treated as though they were included in this License, to the extent
|
||||||
|
that they are valid under applicable law. If additional permissions
|
||||||
|
apply only to part of the Program, that part may be used separately
|
||||||
|
under those permissions, but the entire Program remains governed by
|
||||||
|
this License without regard to the additional permissions.
|
||||||
|
|
||||||
|
When you convey a copy of a covered work, you may at your option
|
||||||
|
remove any additional permissions from that copy, or from any part of
|
||||||
|
it. (Additional permissions may be written to require their own
|
||||||
|
removal in certain cases when you modify the work.) You may place
|
||||||
|
additional permissions on material, added by you to a covered work,
|
||||||
|
for which you have or can give appropriate copyright permission.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, for material you
|
||||||
|
add to a covered work, you may (if authorized by the copyright holders of
|
||||||
|
that material) supplement the terms of this License with terms:
|
||||||
|
|
||||||
|
a) Disclaiming warranty or limiting liability differently from the
|
||||||
|
terms of sections 15 and 16 of this License; or
|
||||||
|
|
||||||
|
b) Requiring preservation of specified reasonable legal notices or
|
||||||
|
author attributions in that material or in the Appropriate Legal
|
||||||
|
Notices displayed by works containing it; or
|
||||||
|
|
||||||
|
c) Prohibiting misrepresentation of the origin of that material, or
|
||||||
|
requiring that modified versions of such material be marked in
|
||||||
|
reasonable ways as different from the original version; or
|
||||||
|
|
||||||
|
d) Limiting the use for publicity purposes of names of licensors or
|
||||||
|
authors of the material; or
|
||||||
|
|
||||||
|
e) Declining to grant rights under trademark law for use of some
|
||||||
|
trade names, trademarks, or service marks; or
|
||||||
|
|
||||||
|
f) Requiring indemnification of licensors and authors of that
|
||||||
|
material by anyone who conveys the material (or modified versions of
|
||||||
|
it) with contractual assumptions of liability to the recipient, for
|
||||||
|
any liability that these contractual assumptions directly impose on
|
||||||
|
those licensors and authors.
|
||||||
|
|
||||||
|
All other non-permissive additional terms are considered "further
|
||||||
|
restrictions" within the meaning of section 10. If the Program as you
|
||||||
|
received it, or any part of it, contains a notice stating that it is
|
||||||
|
governed by this License along with a term that is a further
|
||||||
|
restriction, you may remove that term. If a license document contains
|
||||||
|
a further restriction but permits relicensing or conveying under this
|
||||||
|
License, you may add to a covered work material governed by the terms
|
||||||
|
of that license document, provided that the further restriction does
|
||||||
|
not survive such relicensing or conveying.
|
||||||
|
|
||||||
|
If you add terms to a covered work in accord with this section, you
|
||||||
|
must place, in the relevant source files, a statement of the
|
||||||
|
additional terms that apply to those files, or a notice indicating
|
||||||
|
where to find the applicable terms.
|
||||||
|
|
||||||
|
Additional terms, permissive or non-permissive, may be stated in the
|
||||||
|
form of a separately written license, or stated as exceptions;
|
||||||
|
the above requirements apply either way.
|
||||||
|
|
||||||
|
8. Termination.
|
||||||
|
|
||||||
|
You may not propagate or modify a covered work except as expressly
|
||||||
|
provided under this License. Any attempt otherwise to propagate or
|
||||||
|
modify it is void, and will automatically terminate your rights under
|
||||||
|
this License (including any patent licenses granted under the third
|
||||||
|
paragraph of section 11).
|
||||||
|
|
||||||
|
However, if you cease all violation of this License, then your
|
||||||
|
license from a particular copyright holder is reinstated (a)
|
||||||
|
provisionally, unless and until the copyright holder explicitly and
|
||||||
|
finally terminates your license, and (b) permanently, if the copyright
|
||||||
|
holder fails to notify you of the violation by some reasonable means
|
||||||
|
prior to 60 days after the cessation.
|
||||||
|
|
||||||
|
Moreover, your license from a particular copyright holder is
|
||||||
|
reinstated permanently if the copyright holder notifies you of the
|
||||||
|
violation by some reasonable means, this is the first time you have
|
||||||
|
received notice of violation of this License (for any work) from that
|
||||||
|
copyright holder, and you cure the violation prior to 30 days after
|
||||||
|
your receipt of the notice.
|
||||||
|
|
||||||
|
Termination of your rights under this section does not terminate the
|
||||||
|
licenses of parties who have received copies or rights from you under
|
||||||
|
this License. If your rights have been terminated and not permanently
|
||||||
|
reinstated, you do not qualify to receive new licenses for the same
|
||||||
|
material under section 10.
|
||||||
|
|
||||||
|
9. Acceptance Not Required for Having Copies.
|
||||||
|
|
||||||
|
You are not required to accept this License in order to receive or
|
||||||
|
run a copy of the Program. Ancillary propagation of a covered work
|
||||||
|
occurring solely as a consequence of using peer-to-peer transmission
|
||||||
|
to receive a copy likewise does not require acceptance. However,
|
||||||
|
nothing other than this License grants you permission to propagate or
|
||||||
|
modify any covered work. These actions infringe copyright if you do
|
||||||
|
not accept this License. Therefore, by modifying or propagating a
|
||||||
|
covered work, you indicate your acceptance of this License to do so.
|
||||||
|
|
||||||
|
10. Automatic Licensing of Downstream Recipients.
|
||||||
|
|
||||||
|
Each time you convey a covered work, the recipient automatically
|
||||||
|
receives a license from the original licensors, to run, modify and
|
||||||
|
propagate that work, subject to this License. You are not responsible
|
||||||
|
for enforcing compliance by third parties with this License.
|
||||||
|
|
||||||
|
An "entity transaction" is a transaction transferring control of an
|
||||||
|
organization, or substantially all assets of one, or subdividing an
|
||||||
|
organization, or merging organizations. If propagation of a covered
|
||||||
|
work results from an entity transaction, each party to that
|
||||||
|
transaction who receives a copy of the work also receives whatever
|
||||||
|
licenses to the work the party's predecessor in interest had or could
|
||||||
|
give under the previous paragraph, plus a right to possession of the
|
||||||
|
Corresponding Source of the work from the predecessor in interest, if
|
||||||
|
the predecessor has it or can get it with reasonable efforts.
|
||||||
|
|
||||||
|
You may not impose any further restrictions on the exercise of the
|
||||||
|
rights granted or affirmed under this License. For example, you may
|
||||||
|
not impose a license fee, royalty, or other charge for exercise of
|
||||||
|
rights granted under this License, and you may not initiate litigation
|
||||||
|
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||||
|
any patent claim is infringed by making, using, selling, offering for
|
||||||
|
sale, or importing the Program or any portion of it.
|
||||||
|
|
||||||
|
11. Patents.
|
||||||
|
|
||||||
|
A "contributor" is a copyright holder who authorizes use under this
|
||||||
|
License of the Program or a work on which the Program is based. The
|
||||||
|
work thus licensed is called the contributor's "contributor version".
|
||||||
|
|
||||||
|
A contributor's "essential patent claims" are all patent claims
|
||||||
|
owned or controlled by the contributor, whether already acquired or
|
||||||
|
hereafter acquired, that would be infringed by some manner, permitted
|
||||||
|
by this License, of making, using, or selling its contributor version,
|
||||||
|
but do not include claims that would be infringed only as a
|
||||||
|
consequence of further modification of the contributor version. For
|
||||||
|
purposes of this definition, "control" includes the right to grant
|
||||||
|
patent sublicenses in a manner consistent with the requirements of
|
||||||
|
this License.
|
||||||
|
|
||||||
|
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||||
|
patent license under the contributor's essential patent claims, to
|
||||||
|
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||||
|
propagate the contents of its contributor version.
|
||||||
|
|
||||||
|
In the following three paragraphs, a "patent license" is any express
|
||||||
|
agreement or commitment, however denominated, not to enforce a patent
|
||||||
|
(such as an express permission to practice a patent or covenant not to
|
||||||
|
sue for patent infringement). To "grant" such a patent license to a
|
||||||
|
party means to make such an agreement or commitment not to enforce a
|
||||||
|
patent against the party.
|
||||||
|
|
||||||
|
If you convey a covered work, knowingly relying on a patent license,
|
||||||
|
and the Corresponding Source of the work is not available for anyone
|
||||||
|
to copy, free of charge and under the terms of this License, through a
|
||||||
|
publicly available network server or other readily accessible means,
|
||||||
|
then you must either (1) cause the Corresponding Source to be so
|
||||||
|
available, or (2) arrange to deprive yourself of the benefit of the
|
||||||
|
patent license for this particular work, or (3) arrange, in a manner
|
||||||
|
consistent with the requirements of this License, to extend the patent
|
||||||
|
license to downstream recipients. "Knowingly relying" means you have
|
||||||
|
actual knowledge that, but for the patent license, your conveying the
|
||||||
|
covered work in a country, or your recipient's use of the covered work
|
||||||
|
in a country, would infringe one or more identifiable patents in that
|
||||||
|
country that you have reason to believe are valid.
|
||||||
|
|
||||||
|
If, pursuant to or in connection with a single transaction or
|
||||||
|
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||||
|
covered work, and grant a patent license to some of the parties
|
||||||
|
receiving the covered work authorizing them to use, propagate, modify
|
||||||
|
or convey a specific copy of the covered work, then the patent license
|
||||||
|
you grant is automatically extended to all recipients of the covered
|
||||||
|
work and works based on it.
|
||||||
|
|
||||||
|
A patent license is "discriminatory" if it does not include within
|
||||||
|
the scope of its coverage, prohibits the exercise of, or is
|
||||||
|
conditioned on the non-exercise of one or more of the rights that are
|
||||||
|
specifically granted under this License. You may not convey a covered
|
||||||
|
work if you are a party to an arrangement with a third party that is
|
||||||
|
in the business of distributing software, under which you make payment
|
||||||
|
to the third party based on the extent of your activity of conveying
|
||||||
|
the work, and under which the third party grants, to any of the
|
||||||
|
parties who would receive the covered work from you, a discriminatory
|
||||||
|
patent license (a) in connection with copies of the covered work
|
||||||
|
conveyed by you (or copies made from those copies), or (b) primarily
|
||||||
|
for and in connection with specific products or compilations that
|
||||||
|
contain the covered work, unless you entered into that arrangement,
|
||||||
|
or that patent license was granted, prior to 28 March 2007.
|
||||||
|
|
||||||
|
Nothing in this License shall be construed as excluding or limiting
|
||||||
|
any implied license or other defenses to infringement that may
|
||||||
|
otherwise be available to you under applicable patent law.
|
||||||
|
|
||||||
|
12. No Surrender of Others' Freedom.
|
||||||
|
|
||||||
|
If conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot convey a
|
||||||
|
covered work so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you may
|
||||||
|
not convey it at all. For example, if you agree to terms that obligate you
|
||||||
|
to collect a royalty for further conveying from those to whom you convey
|
||||||
|
the Program, the only way you could satisfy both those terms and this
|
||||||
|
License would be to refrain entirely from conveying the Program.
|
||||||
|
|
||||||
|
13. Use with the GNU Affero General Public License.
|
||||||
|
|
||||||
|
Notwithstanding any other provision of this License, you have
|
||||||
|
permission to link or combine any covered work with a work licensed
|
||||||
|
under version 3 of the GNU Affero General Public License into a single
|
||||||
|
combined work, and to convey the resulting work. The terms of this
|
||||||
|
License will continue to apply to the part which is the covered work,
|
||||||
|
but the special requirements of the GNU Affero General Public License,
|
||||||
|
section 13, concerning interaction through a network will apply to the
|
||||||
|
combination as such.
|
||||||
|
|
||||||
|
14. Revised Versions of this License.
|
||||||
|
|
||||||
|
The Free Software Foundation may publish revised and/or new versions of
|
||||||
|
the GNU General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the
|
||||||
|
Program specifies that a certain numbered version of the GNU General
|
||||||
|
Public License "or any later version" applies to it, you have the
|
||||||
|
option of following the terms and conditions either of that numbered
|
||||||
|
version or of any later version published by the Free Software
|
||||||
|
Foundation. If the Program does not specify a version number of the
|
||||||
|
GNU General Public License, you may choose any version ever published
|
||||||
|
by the Free Software Foundation.
|
||||||
|
|
||||||
|
If the Program specifies that a proxy can decide which future
|
||||||
|
versions of the GNU General Public License can be used, that proxy's
|
||||||
|
public statement of acceptance of a version permanently authorizes you
|
||||||
|
to choose that version for the Program.
|
||||||
|
|
||||||
|
Later license versions may give you additional or different
|
||||||
|
permissions. However, no additional obligations are imposed on any
|
||||||
|
author or copyright holder as a result of your choosing to follow a
|
||||||
|
later version.
|
||||||
|
|
||||||
|
15. Disclaimer of Warranty.
|
||||||
|
|
||||||
|
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||||
|
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||||
|
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||||
|
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||||
|
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||||
|
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
16. Limitation of Liability.
|
||||||
|
|
||||||
|
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||||
|
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||||
|
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||||
|
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||||
|
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||||
|
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||||
|
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGES.
|
||||||
|
|
||||||
|
17. Interpretation of Sections 15 and 16.
|
||||||
|
|
||||||
|
If the disclaimer of warranty and limitation of liability provided
|
||||||
|
above cannot be given local legal effect according to their terms,
|
||||||
|
reviewing courts shall apply local law that most closely approximates
|
||||||
|
an absolute waiver of all civil liability in connection with the
|
||||||
|
Program, unless a warranty or assumption of liability accompanies a
|
||||||
|
copy of the Program in return for a fee.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
state the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program does terminal interaction, make it output a short
|
||||||
|
notice like this when it starts in an interactive mode:
|
||||||
|
|
||||||
|
<program> Copyright (C) <year> <name of author>
|
||||||
|
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, your program's commands
|
||||||
|
might be different; for a GUI interface, you would use an "about box".
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or school,
|
||||||
|
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||||
|
For more information on this, and how to apply and follow the GNU GPL, see
|
||||||
|
<http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
The GNU General Public License does not permit incorporating your program
|
||||||
|
into proprietary programs. If your program is a subroutine library, you
|
||||||
|
may consider it more useful to permit linking proprietary applications with
|
||||||
|
the library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License. But first, please read
|
||||||
|
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
@ -0,0 +1,19 @@
|
|||||||
|
Esptool2
|
||||||
|
richardaburton@gmail.com
|
||||||
|
http://richard.burtons.org/
|
||||||
|
|
||||||
|
Esptool2 is a tool for creating rom images for the ESP8266. It is an alternative
|
||||||
|
to using the SDK supplied shell script/Makefile/python script combo, which is a
|
||||||
|
mess. It was inspired by the windows esptool v0.0.2 by mamalala and found on
|
||||||
|
www.esp8266.com but made somewhat simpler in code and usage. It also adds
|
||||||
|
support for boot loader v1.2+ rom types, which was the main reason I wrote it.
|
||||||
|
|
||||||
|
It was written for my own use and the name was simply to distinguish it for the
|
||||||
|
other version on my system. The 2 is not intended to imply it is better than the
|
||||||
|
original. The original has since been updated to v0.0.3 which can write to the
|
||||||
|
flash, but I currently have no intention to add that to esptool2, it is purely a
|
||||||
|
rom creating utility. It has become an integral part of my build process now and
|
||||||
|
has added functionality needed for building the rBoot boot loader. Since I have
|
||||||
|
released rBoot I needed to release this as well.
|
||||||
|
|
||||||
|
Run tool for full usage instructions, or look at the code.
|
@ -0,0 +1,152 @@
|
|||||||
|
//////////////////////////////////////////////////
|
||||||
|
// rBoot OTA and config API for ESP8266.
|
||||||
|
// Copyright 2015 Richard A Burton
|
||||||
|
// richardaburton@gmail.com
|
||||||
|
// See license.txt for license terms.
|
||||||
|
// OTA code based on SDK sample from Espressif.
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef RBOOT_INTEGRATION
|
||||||
|
#include <rboot-integration.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <c_types.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef RTOS_SDK
|
||||||
|
#include "spi_flash.h"
|
||||||
|
#else
|
||||||
|
#include <user_interface.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rboot-api.h"
|
||||||
|
#include "../rboot-private.h"
|
||||||
|
#include "esp_missing_includes.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// get the rboot config
|
||||||
|
rboot_config ICACHE_FLASH_ATTR rboot_get_config(void) {
|
||||||
|
rboot_config conf;
|
||||||
|
spi_flash_read(BOOT_CONFIG_SECTOR * SECTOR_SIZE, (uint32*)&conf, sizeof(rboot_config));
|
||||||
|
return conf;
|
||||||
|
}
|
||||||
|
|
||||||
|
// write the rboot config
|
||||||
|
// preserves the contents of the rest of the sector,
|
||||||
|
// so the rest of the sector can be used to store user data
|
||||||
|
// updates checksum automatically (if enabled)
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_config(rboot_config *conf) {
|
||||||
|
uint32_t buffer[sizeof(*conf) / sizeof(uint32_t) + 1];
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
uint8 chksum;
|
||||||
|
uint8 *ptr;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
chksum = CHKSUM_INIT;
|
||||||
|
for (ptr = (uint8*)conf; ptr < &conf->chksum; ptr++) {
|
||||||
|
chksum ^= *ptr;
|
||||||
|
}
|
||||||
|
conf->chksum = chksum;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memset(buffer, 0xff, sizeof(buffer));
|
||||||
|
memcpy(buffer, conf, sizeof(*conf));
|
||||||
|
if (spi_flash_erase_sector(BOOT_CONFIG_SECTOR) != SPI_FLASH_RESULT_OK ||
|
||||||
|
spi_flash_write(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, sizeof(buffer)) != SPI_FLASH_RESULT_OK) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get current boot rom
|
||||||
|
uint8 ICACHE_FLASH_ATTR rboot_get_current_rom(void) {
|
||||||
|
rboot_config conf;
|
||||||
|
conf = rboot_get_config();
|
||||||
|
return conf.current_rom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set current boot rom
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_current_rom(uint8 rom) {
|
||||||
|
rboot_config conf;
|
||||||
|
conf = rboot_get_config();
|
||||||
|
if (rom >= conf.count) return false;
|
||||||
|
conf.current_rom = rom;
|
||||||
|
return rboot_set_config(&conf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// create the write status struct, based on supplied start address
|
||||||
|
rboot_write_status ICACHE_FLASH_ATTR rboot_write_init(uint32 start_addr) {
|
||||||
|
rboot_write_status status = {0};
|
||||||
|
status.start_addr = start_addr;
|
||||||
|
status.start_sector = start_addr / SECTOR_SIZE;
|
||||||
|
//status.max_sector_count = 200;
|
||||||
|
//os_printf("init addr: 0x%08x\r\n", start_addr);
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// function to do the actual writing to flash
|
||||||
|
// call repeatedly with more data (max len per write is the flash sector size (4k))
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_write_flash(rboot_write_status *status, uint8 *data, uint16 len) {
|
||||||
|
|
||||||
|
bool ret = false;
|
||||||
|
uint8 *buffer;
|
||||||
|
|
||||||
|
if (data == NULL || len == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a buffer
|
||||||
|
buffer = (uint8 *) calloc(1, len + status->extra_count);
|
||||||
|
if (!buffer) {
|
||||||
|
//os_printf("No ram!\r\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy in any remaining bytes from last chunk
|
||||||
|
memcpy(buffer, status->extra_bytes, status->extra_count);
|
||||||
|
// copy in new data
|
||||||
|
memcpy(buffer + status->extra_count, data, len);
|
||||||
|
|
||||||
|
// calculate length, must be multiple of 4
|
||||||
|
// save any remaining bytes for next go
|
||||||
|
len += status->extra_count;
|
||||||
|
status->extra_count = len % 4;
|
||||||
|
len -= status->extra_count;
|
||||||
|
memcpy(status->extra_bytes, buffer + len, status->extra_count);
|
||||||
|
|
||||||
|
// check data will fit
|
||||||
|
//if (status->start_addr + len < (status->start_sector + status->max_sector_count) * SECTOR_SIZE) {
|
||||||
|
|
||||||
|
if (len > SECTOR_SIZE) {
|
||||||
|
// to support larger writes we would need to erase current
|
||||||
|
// (if not already done), next and possibly later sectors too
|
||||||
|
} else {
|
||||||
|
// check if the sector the write finishes in has been erased yet,
|
||||||
|
// this is fine as long as data len < sector size
|
||||||
|
if (status->last_sector_erased != (status->start_addr + len) / SECTOR_SIZE) {
|
||||||
|
status->last_sector_erased = (status->start_addr + len) / SECTOR_SIZE;
|
||||||
|
spi_flash_erase_sector(status->last_sector_erased);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// write current chunk
|
||||||
|
//os_printf("write addr: 0x%08x, len: 0x%04x\r\n", status->start_addr, len);
|
||||||
|
if (spi_flash_write(status->start_addr, (uint32 *)buffer, len) == SPI_FLASH_RESULT_OK) {
|
||||||
|
ret = true;
|
||||||
|
status->start_addr += len;
|
||||||
|
}
|
||||||
|
//}
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_RBOOT_RBOOT_APPCODE_RBOOT_API_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_RBOOT_RBOOT_APPCODE_RBOOT_API_H_
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// rBoot OTA and config API for ESP8266.
|
||||||
|
// Copyright 2015 Richard A Burton
|
||||||
|
// richardaburton@gmail.com
|
||||||
|
// See license.txt for license terms.
|
||||||
|
// OTA code based on SDK sample from Espressif.
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "../rboot.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 start_addr;
|
||||||
|
uint32 start_sector;
|
||||||
|
//uint32 max_sector_count;
|
||||||
|
uint32 last_sector_erased;
|
||||||
|
uint8 extra_count;
|
||||||
|
uint8 extra_bytes[4];
|
||||||
|
} rboot_write_status;
|
||||||
|
|
||||||
|
rboot_config ICACHE_FLASH_ATTR rboot_get_config(void);
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_config(rboot_config *conf);
|
||||||
|
uint8 ICACHE_FLASH_ATTR rboot_get_current_rom(void);
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_set_current_rom(uint8 rom);
|
||||||
|
rboot_write_status ICACHE_FLASH_ATTR rboot_write_init(uint32 start_addr);
|
||||||
|
bool ICACHE_FLASH_ATTR rboot_write_flash(rboot_write_status *status, uint8 *data, uint16 len);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_RBOOT_RBOOT_APPCODE_RBOOT_API_H_ */
|
@ -0,0 +1,61 @@
|
|||||||
|
//////////////////////////////////////////////////
|
||||||
|
// rBoot open source boot loader for ESP8266.
|
||||||
|
// Copyright 2015 Richard A Burton
|
||||||
|
// richardaburton@gmail.com
|
||||||
|
// See license.txt for license terms.
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
#ifdef RBOOT_INTEGRATION
|
||||||
|
#include <rboot-integration.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef unsigned int uint32;
|
||||||
|
typedef unsigned char uint8;
|
||||||
|
|
||||||
|
#include <rboot.h>
|
||||||
|
|
||||||
|
#if 0 //def BOOT_BIG_FLASH
|
||||||
|
|
||||||
|
// plain sdk defaults to iram
|
||||||
|
#ifndef IRAM_ATTR
|
||||||
|
#define IRAM_ATTR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
extern void Cache_Read_Disable();
|
||||||
|
extern uint32 SPIRead(uint32, void*, uint32);
|
||||||
|
extern void Cache_Read_Enable(uint32, uint32, uint32);
|
||||||
|
|
||||||
|
uint8 rBoot_mmap_1 = 0xff;
|
||||||
|
uint8 rBoot_mmap_2 = 0xff;
|
||||||
|
|
||||||
|
// this function must remain in iram
|
||||||
|
IRAM NOINSTR void __wrap_Cache_Read_Enable_New(void) {
|
||||||
|
if (rBoot_mmap_1 == 0xff) {
|
||||||
|
uint32 addr;
|
||||||
|
rboot_config conf;
|
||||||
|
|
||||||
|
Cache_Read_Disable();
|
||||||
|
|
||||||
|
SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, &conf, sizeof(rboot_config));
|
||||||
|
|
||||||
|
addr = conf.roms[conf.current_rom];
|
||||||
|
addr /= 0x100000;
|
||||||
|
|
||||||
|
rBoot_mmap_2 = addr / 2;
|
||||||
|
rBoot_mmap_1 = addr % 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
Cache_Read_Enable(rBoot_mmap_1, rBoot_mmap_2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
Binary file not shown.
@ -0,0 +1,21 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2015 Richard A Burton (richardaburton@gmail.com)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
@ -0,0 +1,74 @@
|
|||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_RBOOT_RBOOT_RBOOT_PRIVATE_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_RBOOT_RBOOT_RBOOT_PRIVATE_H_
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// rBoot open source boot loader for ESP8266.
|
||||||
|
// Copyright 2015 Richard A Burton
|
||||||
|
// richardaburton@gmail.com
|
||||||
|
// See license.txt for license terms.
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
typedef int int32;
|
||||||
|
typedef unsigned int uint32;
|
||||||
|
typedef unsigned char uint8;
|
||||||
|
|
||||||
|
#include "rboot.h"
|
||||||
|
|
||||||
|
#define NOINLINE __attribute__ ((noinline))
|
||||||
|
|
||||||
|
#define ROM_MAGIC 0xe9
|
||||||
|
#define ROM_MAGIC_NEW1 0xea
|
||||||
|
#define ROM_MAGIC_NEW2 0x04
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef FALSE
|
||||||
|
#define FALSE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// buffer size, must be at least 0x10 (size of rom_header_new structure)
|
||||||
|
#define BUFFER_SIZE 0x100
|
||||||
|
|
||||||
|
// esp8266 built in rom functions
|
||||||
|
extern void ets_printf(const char*, ...);
|
||||||
|
extern uint32 SPIRead(uint32 addr, void *outptr, uint32 len);
|
||||||
|
extern uint32 SPIEraseSector(int);
|
||||||
|
extern uint32 SPIWrite(uint32 addr, void *inptr, uint32 len);
|
||||||
|
|
||||||
|
// functions we'll call by address
|
||||||
|
typedef void stage2a(uint32);
|
||||||
|
typedef void usercode(void);
|
||||||
|
|
||||||
|
// standard rom header
|
||||||
|
typedef struct {
|
||||||
|
// general rom header
|
||||||
|
uint8 magic;
|
||||||
|
uint8 count;
|
||||||
|
uint8 flags1;
|
||||||
|
uint8 flags2;
|
||||||
|
usercode* entry;
|
||||||
|
} rom_header;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8* address;
|
||||||
|
uint32 length;
|
||||||
|
} section_header;
|
||||||
|
|
||||||
|
// new rom header (irom section first) there is
|
||||||
|
// another 8 byte header straight afterward the
|
||||||
|
// standard header
|
||||||
|
typedef struct {
|
||||||
|
// general rom header
|
||||||
|
uint8 magic;
|
||||||
|
uint8 count; // second magic for new header
|
||||||
|
uint8 flags1;
|
||||||
|
uint8 flags2;
|
||||||
|
uint32 entry;
|
||||||
|
// new type rom, lib header
|
||||||
|
uint32 add; // zero
|
||||||
|
uint32 len; // length of irom section
|
||||||
|
} rom_header_new;
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_RBOOT_RBOOT_RBOOT_PRIVATE_H_ */
|
@ -0,0 +1,80 @@
|
|||||||
|
//////////////////////////////////////////////////
|
||||||
|
// rBoot open source boot loader for ESP8266.
|
||||||
|
// Copyright 2015 Richard A Burton
|
||||||
|
// richardaburton@gmail.com
|
||||||
|
// See license.txt for license terms.
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef RBOOT_INTEGRATION
|
||||||
|
#include <rboot-integration.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rboot-private.h"
|
||||||
|
|
||||||
|
usercode* NOINLINE load_rom(uint32 readpos) {
|
||||||
|
|
||||||
|
uint8 buffer[BUFFER_SIZE];
|
||||||
|
uint8 sectcount;
|
||||||
|
uint8 *writepos;
|
||||||
|
uint32 remaining;
|
||||||
|
usercode* usercode;
|
||||||
|
|
||||||
|
rom_header *header = (rom_header*)buffer;
|
||||||
|
section_header *section = (section_header*)buffer;
|
||||||
|
|
||||||
|
// read rom header
|
||||||
|
SPIRead(readpos, header, sizeof(rom_header));
|
||||||
|
readpos += sizeof(rom_header);
|
||||||
|
|
||||||
|
// create function pointer for entry point
|
||||||
|
usercode = header->entry;
|
||||||
|
|
||||||
|
// copy all the sections
|
||||||
|
for (sectcount = header->count; sectcount > 0; sectcount--) {
|
||||||
|
|
||||||
|
// read section header
|
||||||
|
SPIRead(readpos, section, sizeof(section_header));
|
||||||
|
readpos += sizeof(section_header);
|
||||||
|
|
||||||
|
// get section address and length
|
||||||
|
writepos = section->address;
|
||||||
|
remaining = section->length;
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
// work out how much to read, up to 16 bytes at a time
|
||||||
|
uint32 readlen = (remaining < BUFFER_SIZE) ? remaining : BUFFER_SIZE;
|
||||||
|
// read the block
|
||||||
|
SPIRead(readpos, buffer, readlen);
|
||||||
|
readpos += readlen;
|
||||||
|
// copy the block
|
||||||
|
ets_memcpy(writepos, buffer, readlen);
|
||||||
|
// increment next write position
|
||||||
|
writepos += readlen;
|
||||||
|
// decrement remaining count
|
||||||
|
remaining -= readlen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return usercode;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOT_NO_ASM
|
||||||
|
|
||||||
|
void call_user_start(uint32 readpos) {
|
||||||
|
usercode* user;
|
||||||
|
user = load_rom(readpos);
|
||||||
|
user();
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
void call_user_start(uint32 readpos) {
|
||||||
|
__asm volatile (
|
||||||
|
"mov a15, a0\n" // store return addr, we already splatted a15!
|
||||||
|
"call0 load_rom\n" // load the rom
|
||||||
|
"mov a0, a15\n" // restore return addr
|
||||||
|
"jx a2\n" // now jump to the rom code
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,211 @@
|
|||||||
|
/* This linker script generated from xt-genldscripts.tpp for LSP . */
|
||||||
|
/* Linker Script for ld -N */
|
||||||
|
MEMORY
|
||||||
|
{
|
||||||
|
dport0_0_seg : org = 0x3FF00000, len = 0x10
|
||||||
|
dram0_0_seg : org = 0x3FFE8000, len = 0x14000
|
||||||
|
iram1_0_seg : org = 0x4010FC00, len = 0x400
|
||||||
|
irom0_0_seg : org = 0x40240000, len = 0x3C000
|
||||||
|
}
|
||||||
|
|
||||||
|
PHDRS
|
||||||
|
{
|
||||||
|
dport0_0_phdr PT_LOAD;
|
||||||
|
dram0_0_phdr PT_LOAD;
|
||||||
|
dram0_0_bss_phdr PT_LOAD;
|
||||||
|
iram1_0_phdr PT_LOAD;
|
||||||
|
irom0_0_phdr PT_LOAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Default entry point: */
|
||||||
|
ENTRY(call_user_start)
|
||||||
|
EXTERN(_DebugExceptionVector)
|
||||||
|
EXTERN(_DoubleExceptionVector)
|
||||||
|
EXTERN(_KernelExceptionVector)
|
||||||
|
EXTERN(_NMIExceptionVector)
|
||||||
|
EXTERN(_UserExceptionVector)
|
||||||
|
PROVIDE(_memmap_vecbase_reset = 0x40000000);
|
||||||
|
/* Various memory-map dependent cache attribute settings: */
|
||||||
|
_memmap_cacheattr_wb_base = 0x00000110;
|
||||||
|
_memmap_cacheattr_wt_base = 0x00000110;
|
||||||
|
_memmap_cacheattr_bp_base = 0x00000220;
|
||||||
|
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
|
||||||
|
_memmap_cacheattr_wb_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_wba_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_wt_trapnull = 0x2222211F;
|
||||||
|
_memmap_cacheattr_bp_trapnull = 0x2222222F;
|
||||||
|
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
|
||||||
|
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
|
||||||
|
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
|
||||||
|
_memmap_cacheattr_wb_allvalid = 0x22222112;
|
||||||
|
_memmap_cacheattr_wt_allvalid = 0x22222112;
|
||||||
|
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
||||||
|
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
||||||
|
|
||||||
|
SECTIONS
|
||||||
|
{
|
||||||
|
|
||||||
|
.dport0.rodata : ALIGN(4)
|
||||||
|
{
|
||||||
|
_dport0_rodata_start = ABSOLUTE(.);
|
||||||
|
*(.dport0.rodata)
|
||||||
|
*(.dport.rodata)
|
||||||
|
_dport0_rodata_end = ABSOLUTE(.);
|
||||||
|
} >dport0_0_seg :dport0_0_phdr
|
||||||
|
|
||||||
|
.dport0.literal : ALIGN(4)
|
||||||
|
{
|
||||||
|
_dport0_literal_start = ABSOLUTE(.);
|
||||||
|
*(.dport0.literal)
|
||||||
|
*(.dport.literal)
|
||||||
|
_dport0_literal_end = ABSOLUTE(.);
|
||||||
|
} >dport0_0_seg :dport0_0_phdr
|
||||||
|
|
||||||
|
.dport0.data : ALIGN(4)
|
||||||
|
{
|
||||||
|
_dport0_data_start = ABSOLUTE(.);
|
||||||
|
*(.dport0.data)
|
||||||
|
*(.dport.data)
|
||||||
|
_dport0_data_end = ABSOLUTE(.);
|
||||||
|
} >dport0_0_seg :dport0_0_phdr
|
||||||
|
|
||||||
|
.data : ALIGN(4)
|
||||||
|
{
|
||||||
|
_data_start = ABSOLUTE(.);
|
||||||
|
*(.data)
|
||||||
|
*(.data.*)
|
||||||
|
*(.gnu.linkonce.d.*)
|
||||||
|
*(.data1)
|
||||||
|
*(.sdata)
|
||||||
|
*(.sdata.*)
|
||||||
|
*(.gnu.linkonce.s.*)
|
||||||
|
*(.sdata2)
|
||||||
|
*(.sdata2.*)
|
||||||
|
*(.gnu.linkonce.s2.*)
|
||||||
|
*(.jcr)
|
||||||
|
_data_end = ABSOLUTE(.);
|
||||||
|
} >dram0_0_seg :dram0_0_phdr
|
||||||
|
|
||||||
|
.rodata : ALIGN(4)
|
||||||
|
{
|
||||||
|
_rodata_start = ABSOLUTE(.);
|
||||||
|
*(.rodata)
|
||||||
|
*(.rodata.*)
|
||||||
|
*(.gnu.linkonce.r.*)
|
||||||
|
*(.rodata1)
|
||||||
|
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_table)
|
||||||
|
*(.gcc_except_table)
|
||||||
|
*(.gnu.linkonce.e.*)
|
||||||
|
*(.gnu.version_r)
|
||||||
|
*(.eh_frame)
|
||||||
|
/* C++ constructor and destructor tables, properly ordered: */
|
||||||
|
KEEP (*crtbegin.o(.ctors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||||
|
KEEP (*(SORT(.ctors.*)))
|
||||||
|
KEEP (*(.ctors))
|
||||||
|
KEEP (*crtbegin.o(.dtors))
|
||||||
|
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||||
|
KEEP (*(SORT(.dtors.*)))
|
||||||
|
KEEP (*(.dtors))
|
||||||
|
/* C++ exception handlers table: */
|
||||||
|
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_desc)
|
||||||
|
*(.gnu.linkonce.h.*)
|
||||||
|
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||||
|
*(.xt_except_desc_end)
|
||||||
|
*(.dynamic)
|
||||||
|
*(.gnu.version_d)
|
||||||
|
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
||||||
|
_bss_table_start = ABSOLUTE(.);
|
||||||
|
LONG(_bss_start)
|
||||||
|
LONG(_bss_end)
|
||||||
|
_bss_table_end = ABSOLUTE(.);
|
||||||
|
_rodata_end = ABSOLUTE(.);
|
||||||
|
} >dram0_0_seg :dram0_0_phdr
|
||||||
|
|
||||||
|
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
|
||||||
|
{
|
||||||
|
. = ALIGN (8);
|
||||||
|
_bss_start = ABSOLUTE(.);
|
||||||
|
*(.dynsbss)
|
||||||
|
*(.sbss)
|
||||||
|
*(.sbss.*)
|
||||||
|
*(.gnu.linkonce.sb.*)
|
||||||
|
*(.scommon)
|
||||||
|
*(.sbss2)
|
||||||
|
*(.sbss2.*)
|
||||||
|
*(.gnu.linkonce.sb2.*)
|
||||||
|
*(.dynbss)
|
||||||
|
*(.bss)
|
||||||
|
*(.bss.*)
|
||||||
|
*(.gnu.linkonce.b.*)
|
||||||
|
*(COMMON)
|
||||||
|
. = ALIGN (8);
|
||||||
|
_bss_end = ABSOLUTE(.);
|
||||||
|
_heap_start = ABSOLUTE(.);
|
||||||
|
/* _stack_sentry = ALIGN(0x8); */
|
||||||
|
} >dram0_0_seg :dram0_0_bss_phdr
|
||||||
|
/* __stack = 0x3ffc8000; */
|
||||||
|
|
||||||
|
.text : ALIGN(4)
|
||||||
|
{
|
||||||
|
_stext = .;
|
||||||
|
_text_start = ABSOLUTE(.);
|
||||||
|
*(.UserEnter.text)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.DebugExceptionVector.text)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.NMIExceptionVector.text)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.KernelExceptionVector.text)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.UserExceptionVector.text)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
. = ALIGN(16);
|
||||||
|
*(.DoubleExceptionVector.text)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
LONG(0)
|
||||||
|
. = ALIGN (16);
|
||||||
|
*(.entry.text)
|
||||||
|
*(.init.literal)
|
||||||
|
*(.init)
|
||||||
|
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||||
|
*(.fini.literal)
|
||||||
|
*(.fini)
|
||||||
|
*(.gnu.version)
|
||||||
|
_text_end = ABSOLUTE(.);
|
||||||
|
_etext = .;
|
||||||
|
} >iram1_0_seg :iram1_0_phdr
|
||||||
|
|
||||||
|
.lit4 : ALIGN(4)
|
||||||
|
{
|
||||||
|
_lit4_start = ABSOLUTE(.);
|
||||||
|
*(*.lit4)
|
||||||
|
*(.lit4.*)
|
||||||
|
*(.gnu.linkonce.lit4.*)
|
||||||
|
_lit4_end = ABSOLUTE(.);
|
||||||
|
} >iram1_0_seg :iram1_0_phdr
|
||||||
|
|
||||||
|
.irom0.text : ALIGN(4)
|
||||||
|
{
|
||||||
|
_irom0_text_start = ABSOLUTE(.);
|
||||||
|
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
||||||
|
_irom0_text_end = ABSOLUTE(.);
|
||||||
|
} >irom0_0_seg :irom0_0_phdr
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get ROM code address */
|
||||||
|
INCLUDE "rboot_rom.ld"
|
@ -0,0 +1,414 @@
|
|||||||
|
//////////////////////////////////////////////////
|
||||||
|
// rBoot open source boot loader for ESP8266.
|
||||||
|
// Copyright 2015 Richard A Burton
|
||||||
|
// richardaburton@gmail.com
|
||||||
|
// See license.txt for license terms.
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
/* clang-format off */
|
||||||
|
|
||||||
|
#ifdef RBOOT_INTEGRATION
|
||||||
|
#include <rboot-integration.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "rboot-private.h"
|
||||||
|
#include <rboot-hex2a.h>
|
||||||
|
|
||||||
|
static uint32 check_image(uint32 readpos) {
|
||||||
|
|
||||||
|
uint8 buffer[BUFFER_SIZE];
|
||||||
|
uint8 sectcount;
|
||||||
|
uint8 sectcurrent;
|
||||||
|
uint8 *writepos;
|
||||||
|
uint8 chksum = CHKSUM_INIT;
|
||||||
|
uint32 loop;
|
||||||
|
uint32 remaining;
|
||||||
|
uint32 romaddr;
|
||||||
|
|
||||||
|
rom_header_new *header = (rom_header_new*)buffer;
|
||||||
|
section_header *section = (section_header*)buffer;
|
||||||
|
|
||||||
|
if (readpos == 0 || readpos == 0xffffffff) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// read rom header
|
||||||
|
if (SPIRead(readpos, header, sizeof(rom_header_new)) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check header type
|
||||||
|
if (header->magic == ROM_MAGIC) {
|
||||||
|
// old type, no extra header or irom section to skip over
|
||||||
|
romaddr = readpos;
|
||||||
|
readpos += sizeof(rom_header);
|
||||||
|
sectcount = header->count;
|
||||||
|
} else if (header->magic == ROM_MAGIC_NEW1 && header->count == ROM_MAGIC_NEW2) {
|
||||||
|
// new type, has extra header and irom section first
|
||||||
|
romaddr = readpos + header->len + sizeof(rom_header_new);
|
||||||
|
#ifdef BOOT_IROM_CHKSUM
|
||||||
|
// we will set the real section count later, when we read the header
|
||||||
|
sectcount = 0xff;
|
||||||
|
// just skip the first part of the header
|
||||||
|
// rest is processed for the chksum
|
||||||
|
readpos += sizeof(rom_header);
|
||||||
|
#else
|
||||||
|
// skip the extra header and irom section
|
||||||
|
readpos = romaddr;
|
||||||
|
// read the normal header that follows
|
||||||
|
if (SPIRead(readpos, header, sizeof(rom_header)) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sectcount = header->count;
|
||||||
|
readpos += sizeof(rom_header);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// test each section
|
||||||
|
for (sectcurrent = 0; sectcurrent < sectcount; sectcurrent++) {
|
||||||
|
|
||||||
|
// read section header
|
||||||
|
if (SPIRead(readpos, section, sizeof(section_header)) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
readpos += sizeof(section_header);
|
||||||
|
|
||||||
|
// get section address and length
|
||||||
|
writepos = section->address;
|
||||||
|
remaining = section->length;
|
||||||
|
|
||||||
|
while (remaining > 0) {
|
||||||
|
// work out how much to read, up to BUFFER_SIZE
|
||||||
|
uint32 readlen = (remaining < BUFFER_SIZE) ? remaining : BUFFER_SIZE;
|
||||||
|
// read the block
|
||||||
|
if (SPIRead(readpos, buffer, readlen) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// increment next read and write positions
|
||||||
|
readpos += readlen;
|
||||||
|
writepos += readlen;
|
||||||
|
// decrement remaining count
|
||||||
|
remaining -= readlen;
|
||||||
|
// add to chksum
|
||||||
|
for (loop = 0; loop < readlen; loop++) {
|
||||||
|
chksum ^= buffer[loop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOT_IROM_CHKSUM
|
||||||
|
if (sectcount == 0xff) {
|
||||||
|
// just processed the irom section, now
|
||||||
|
// read the normal header that follows
|
||||||
|
if (SPIRead(readpos, header, sizeof(rom_header)) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
sectcount = header->count + 1;
|
||||||
|
readpos += sizeof(rom_header);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// round up to next 16 and get checksum
|
||||||
|
readpos = readpos | 0x0f;
|
||||||
|
if (SPIRead(readpos, buffer, 1) != 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compare calculated and stored checksums
|
||||||
|
if (buffer[0] != chksum) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return romaddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ETS_UNCACHED_ADDR(addr) (addr)
|
||||||
|
#define READ_PERI_REG(addr) (*((volatile uint32 *)ETS_UNCACHED_ADDR(addr)))
|
||||||
|
#define WRITE_PERI_REG(addr, val) (*((volatile uint32 *)ETS_UNCACHED_ADDR(addr))) = (uint32)(val)
|
||||||
|
#define PERIPHS_RTC_BASEADDR 0x60000700
|
||||||
|
#define REG_RTC_BASE PERIPHS_RTC_BASEADDR
|
||||||
|
#define RTC_GPIO_OUT (REG_RTC_BASE + 0x068)
|
||||||
|
#define RTC_GPIO_ENABLE (REG_RTC_BASE + 0x074)
|
||||||
|
#define RTC_GPIO_IN_DATA (REG_RTC_BASE + 0x08C)
|
||||||
|
#define RTC_GPIO_CONF (REG_RTC_BASE + 0x090)
|
||||||
|
#define PAD_XPD_DCDC_CONF (REG_RTC_BASE + 0x0A0)
|
||||||
|
static uint32 get_gpio16(void) {
|
||||||
|
// set output level to 1
|
||||||
|
WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & (uint32)0xfffffffe) | (uint32)(1));
|
||||||
|
|
||||||
|
// read level
|
||||||
|
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | (uint32)0x1); // mux configuration for XPD_DCDC and rtc_gpio0 connection
|
||||||
|
WRITE_PERI_REG(RTC_GPIO_CONF, (READ_PERI_REG(RTC_GPIO_CONF) & (uint32)0xfffffffe) | (uint32)0x0); //mux configuration for out enable
|
||||||
|
WRITE_PERI_REG(RTC_GPIO_ENABLE, READ_PERI_REG(RTC_GPIO_ENABLE) & (uint32)0xfffffffe); //out disable
|
||||||
|
|
||||||
|
uint32 x = (READ_PERI_REG(RTC_GPIO_IN_DATA) & 1);
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
// calculate checksum for block of data
|
||||||
|
// from start up to (but excluding) end
|
||||||
|
static uint8 calc_chksum(uint8 *start, uint8 *end) {
|
||||||
|
uint8 chksum = CHKSUM_INIT;
|
||||||
|
while(start < end) {
|
||||||
|
chksum ^= *start;
|
||||||
|
start++;
|
||||||
|
}
|
||||||
|
return chksum;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define UART_CLKDIV_26MHZ(B) (52000000 + B / 2) / B
|
||||||
|
|
||||||
|
// prevent this function being placed inline with main
|
||||||
|
// to keep main's stack size as small as possible
|
||||||
|
// don't mark as static or it'll be optimised out when
|
||||||
|
// using the assembler stub
|
||||||
|
uint32 NOINLINE find_image(void) {
|
||||||
|
|
||||||
|
uint8 flag;
|
||||||
|
uint32 runAddr;
|
||||||
|
uint32 flashsize;
|
||||||
|
int32 romToBoot;
|
||||||
|
uint8 gpio_boot = FALSE;
|
||||||
|
uint8 updateConfig = FALSE;
|
||||||
|
uint8 buffer[SECTOR_SIZE];
|
||||||
|
|
||||||
|
rboot_config *romconf = (rboot_config*)buffer;
|
||||||
|
rom_header *header = (rom_header*)buffer;
|
||||||
|
|
||||||
|
// delay to slow boot (help see messages when debugging)
|
||||||
|
//ets_delay_us(2000000);
|
||||||
|
|
||||||
|
uart_div_modify(0, UART_CLKDIV_26MHZ(115200));
|
||||||
|
ets_delay_us(1000);
|
||||||
|
|
||||||
|
ets_printf("\r\nrBoot v1.2.1 - richardaburton@gmail.com\r\n");
|
||||||
|
|
||||||
|
// read rom header
|
||||||
|
SPIRead(0, header, sizeof(rom_header));
|
||||||
|
|
||||||
|
// print and get flash size
|
||||||
|
ets_printf("Flash Size: ");
|
||||||
|
flag = header->flags2 >> 4;
|
||||||
|
if (flag == 0) {
|
||||||
|
ets_printf("4 Mbit\r\n");
|
||||||
|
flashsize = 0x80000;
|
||||||
|
} else if (flag == 1) {
|
||||||
|
ets_printf("2 Mbit\r\n");
|
||||||
|
flashsize = 0x40000;
|
||||||
|
} else if (flag == 2) {
|
||||||
|
ets_printf("8 Mbit\r\n");
|
||||||
|
flashsize = 0x100000;
|
||||||
|
} else {
|
||||||
|
#ifdef BOOT_BIG_FLASH
|
||||||
|
if (flag == 3) {
|
||||||
|
ets_printf("16 Mbit\r\n");
|
||||||
|
flashsize = 0x200000;
|
||||||
|
} else if (flag == 4) {
|
||||||
|
ets_printf("32 Mbit\r\n");
|
||||||
|
flashsize = 0x400000;
|
||||||
|
} else if (flag == 8) {
|
||||||
|
ets_printf("64 Mbit\r\n");
|
||||||
|
flashsize = 0x800000;
|
||||||
|
} else if (flag == 9) {
|
||||||
|
ets_printf("128 Mbit\r\n");
|
||||||
|
flashsize = 0x1000000;
|
||||||
|
} else {
|
||||||
|
ets_printf("unknown\r\n");
|
||||||
|
flashsize = 0x100000; // assume 8Mbit
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
ets_printf("8 Mbit\r\n");
|
||||||
|
flashsize = 0x100000; // limit to 8Mbit
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
// print spi mode
|
||||||
|
ets_printf("Flash Mode: ");
|
||||||
|
if (header->flags1 == 0) {
|
||||||
|
ets_printf("QIO\r\n");
|
||||||
|
} else if (header->flags1 == 1) {
|
||||||
|
ets_printf("QOUT\r\n");
|
||||||
|
} else if (header->flags1 == 2) {
|
||||||
|
ets_printf("DIO\r\n");
|
||||||
|
} else if (header->flags1 == 3) {
|
||||||
|
ets_printf("DOUT\r\n");
|
||||||
|
} else {
|
||||||
|
ets_printf("unknown\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// print spi speed
|
||||||
|
ets_printf("Flash Speed: ");
|
||||||
|
flag = header->flags2 & 0x0f;
|
||||||
|
if (flag == 0) ets_printf("40 MHz\r\n");
|
||||||
|
else if (flag == 1) ets_printf("26.7 MHz\r\n");
|
||||||
|
else if (flag == 2) ets_printf("20 MHz\r\n");
|
||||||
|
else if (flag == 0x0f) ets_printf("80 MHz\r\n");
|
||||||
|
else ets_printf("unknown\r\n");
|
||||||
|
|
||||||
|
// print enabled options
|
||||||
|
#ifdef BOOT_BIG_FLASH
|
||||||
|
ets_printf("rBoot Option: Big flash\r\n");
|
||||||
|
#endif
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
ets_printf("rBoot Option: Config chksum\r\n");
|
||||||
|
#endif
|
||||||
|
#ifdef BOOT_IROM_CHKSUM
|
||||||
|
ets_printf("rBoot Option: irom chksum\r\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ets_printf("\r\n");
|
||||||
|
|
||||||
|
// read boot config
|
||||||
|
SPIRead(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
|
||||||
|
// fresh install or old version?
|
||||||
|
if (romconf->magic != BOOT_CONFIG_MAGIC || romconf->version != BOOT_CONFIG_VERSION
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
|| romconf->chksum != calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
/* Modified by Cesanta */
|
||||||
|
ets_printf("Writing default boot config @ 0x%x.\r\n", BOOT_CONFIG_SECTOR * SECTOR_SIZE);
|
||||||
|
ets_memset(romconf, 0x00, sizeof(rboot_config));
|
||||||
|
romconf->magic = BOOT_CONFIG_MAGIC;
|
||||||
|
romconf->version = BOOT_CONFIG_VERSION;
|
||||||
|
romconf->count = 2;
|
||||||
|
romconf->mode = MODE_STANDARD;
|
||||||
|
/* FWx_ADDR, FWx_FS_ADDR and FS_SIZE, FW_SIZE must be defined by -D */
|
||||||
|
romconf->roms[0] = FW1_ADDR;
|
||||||
|
romconf->roms[1] = FW2_ADDR;
|
||||||
|
romconf->fs_addresses[0] = FW1_FS_ADDR;
|
||||||
|
romconf->fs_addresses[1] = FW2_FS_ADDR;
|
||||||
|
romconf->fs_sizes[0] = romconf->fs_sizes[1] = FS_SIZE;
|
||||||
|
romconf->roms_sizes[0] = romconf->roms_sizes[1] = FW_SIZE;
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
romconf->chksum = calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum);
|
||||||
|
#endif
|
||||||
|
// write new config sector
|
||||||
|
SPIEraseSector(BOOT_CONFIG_SECTOR);
|
||||||
|
SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if gpio mode enabled check status of the gpio
|
||||||
|
if ((romconf->mode & MODE_GPIO_ROM) && (get_gpio16() == 0)) {
|
||||||
|
ets_printf("Booting GPIO-selected.\r\n");
|
||||||
|
romToBoot = romconf->previous_rom;
|
||||||
|
/*
|
||||||
|
* Modified by Cesanta
|
||||||
|
* Make FD current
|
||||||
|
*/
|
||||||
|
updateConfig = TRUE;
|
||||||
|
romconf->fw_updated = 0;
|
||||||
|
romconf->is_first_boot = 0;
|
||||||
|
gpio_boot = TRUE;
|
||||||
|
} else if (romconf->current_rom >= romconf->count) {
|
||||||
|
// if invalid rom selected try rom 0
|
||||||
|
ets_printf("Invalid rom selected, defaulting.\r\n");
|
||||||
|
romToBoot = 0;
|
||||||
|
romconf->current_rom = 0;
|
||||||
|
romconf->fw_updated = 0;
|
||||||
|
romconf->is_first_boot = 0;
|
||||||
|
updateConfig = TRUE;
|
||||||
|
} else {
|
||||||
|
/* Modified by Cesanta */
|
||||||
|
if (romconf->is_first_boot != 0) {
|
||||||
|
ets_printf("First boot, attempt %d\n", romconf->boot_attempts);
|
||||||
|
/* boot is unconfirmed */
|
||||||
|
if (romconf->boot_attempts == 0) {
|
||||||
|
/* haven't try to load yes */
|
||||||
|
ets_printf("Boot is unconfirmed\r\n");
|
||||||
|
romconf->boot_attempts++;
|
||||||
|
} else {
|
||||||
|
ets_printf("Boot failed, fallback to fw #%d\r\n",
|
||||||
|
romconf->previous_rom);
|
||||||
|
romconf->current_rom = romconf->previous_rom;
|
||||||
|
/* clear fw update flag, to avoid post-update acttions */
|
||||||
|
romconf->fw_updated = 0;
|
||||||
|
romconf->boot_attempts = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateConfig = TRUE;
|
||||||
|
}
|
||||||
|
/* End of Cesanta modifications */
|
||||||
|
// try rom selected in the config
|
||||||
|
romToBoot = romconf->current_rom;
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to find a good rom
|
||||||
|
do {
|
||||||
|
runAddr = check_image(romconf->roms[romToBoot]);
|
||||||
|
if (runAddr == 0) {
|
||||||
|
ets_printf("Rom %d is bad.\r\n", romToBoot);
|
||||||
|
if (gpio_boot) {
|
||||||
|
// don't switch to backup for gpio-selected rom
|
||||||
|
ets_printf("GPIO boot failed.\r\n");
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
// for normal mode try each previous rom
|
||||||
|
// until we find a good one or run out
|
||||||
|
updateConfig = TRUE;
|
||||||
|
romToBoot--;
|
||||||
|
if (romToBoot < 0) romToBoot = romconf->count - 1;
|
||||||
|
if (romToBoot == romconf->current_rom) {
|
||||||
|
// tried them all and all are bad!
|
||||||
|
ets_printf("No good rom available.\r\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while (runAddr == 0);
|
||||||
|
|
||||||
|
// re-write config, if required
|
||||||
|
if (updateConfig) {
|
||||||
|
romconf->current_rom = romToBoot;
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
romconf->chksum = calc_chksum((uint8*)romconf, (uint8*)&romconf->chksum);
|
||||||
|
#endif
|
||||||
|
SPIEraseSector(BOOT_CONFIG_SECTOR);
|
||||||
|
SPIWrite(BOOT_CONFIG_SECTOR * SECTOR_SIZE, buffer, SECTOR_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ets_printf("Booting rom %d (0x%x).\r\n", romToBoot, romconf->roms[romToBoot]);
|
||||||
|
// copy the loader to top of iram
|
||||||
|
ets_memcpy((void*)_text_addr, _text_data, _text_len);
|
||||||
|
// return address to load from
|
||||||
|
return runAddr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef BOOT_NO_ASM
|
||||||
|
|
||||||
|
// small stub method to ensure minimum stack space used
|
||||||
|
void call_user_start(void) {
|
||||||
|
uint32 addr;
|
||||||
|
stage2a *loader;
|
||||||
|
|
||||||
|
addr = find_image();
|
||||||
|
if (addr != 0) {
|
||||||
|
loader = (stage2a*)entry_addr;
|
||||||
|
loader(addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
// assembler stub uses no stack space
|
||||||
|
// works with gcc
|
||||||
|
void call_user_start(void) {
|
||||||
|
__asm volatile (
|
||||||
|
"mov a15, a0\n" // store return addr, hope nobody wanted a15!
|
||||||
|
"call0 find_image\n" // find a good rom to boot
|
||||||
|
"mov a0, a15\n" // restore return addr
|
||||||
|
"bnez a2, 1f\n" // ?success
|
||||||
|
"ret\n" // no, return
|
||||||
|
"1:\n" // yes...
|
||||||
|
"movi a3, entry_addr\n" // actually gives us a pointer to entry_addr
|
||||||
|
"l32i a3, a3, 0\n" // now really load entry_addr
|
||||||
|
"jx a3\n" // now jump to it
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,82 @@
|
|||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_RBOOT_RBOOT_RBOOT_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_RBOOT_RBOOT_RBOOT_H_
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
// rBoot open source boot loader for ESP8266.
|
||||||
|
// Copyright 2015 Richard A Burton
|
||||||
|
// richardaburton@gmail.com
|
||||||
|
// See license.txt for license terms.
|
||||||
|
//////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// uncomment to use only c code
|
||||||
|
// if you aren't using gcc you may need to do this
|
||||||
|
//#define BOOT_NO_ASM
|
||||||
|
|
||||||
|
// uncomment to have a checksum on the boot config
|
||||||
|
//#define BOOT_CONFIG_CHKSUM
|
||||||
|
|
||||||
|
// uncomment to enable big flash support (>1MB)
|
||||||
|
//#define BOOT_BIG_FLASH
|
||||||
|
|
||||||
|
// uncomment to include .irom0.text section in the checksum
|
||||||
|
// roms must be built with esptool2 using -iromchksum option
|
||||||
|
//#define BOOT_IROM_CHKSUM
|
||||||
|
|
||||||
|
// increase if required
|
||||||
|
#define MAX_ROMS 4
|
||||||
|
|
||||||
|
#define CHKSUM_INIT 0xef
|
||||||
|
|
||||||
|
#define SECTOR_SIZE 0x1000
|
||||||
|
|
||||||
|
#ifndef BOOT_CONFIG_ADDR
|
||||||
|
#define BOOT_CONFIG_ADDR 0x1000
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define BOOT_CONFIG_SECTOR (BOOT_CONFIG_ADDR / SECTOR_SIZE)
|
||||||
|
|
||||||
|
#define BOOT_CONFIG_MAGIC 0xe1
|
||||||
|
#define BOOT_CONFIG_VERSION 0x01
|
||||||
|
|
||||||
|
#define MODE_STANDARD 0x00
|
||||||
|
#define MODE_GPIO_ROM 0x01
|
||||||
|
|
||||||
|
// boot config structure
|
||||||
|
// rom addresses must be multiples of 0x1000 (flash sector aligned)
|
||||||
|
// without BOOT_BIG_FLASH only the first 8Mbit of the chip will be memory mapped
|
||||||
|
// so rom slots containing .irom0.text sections must remain below 0x100000
|
||||||
|
// slots beyond this will only be accessible via spi read calls, so
|
||||||
|
// use these for stored resources, not code
|
||||||
|
// with BOOT_BIG_FLASH the flash will be mapped in chunks of 8MBit, so roms can
|
||||||
|
// be anywhere, but must not straddle two 8MBit blocks
|
||||||
|
typedef struct {
|
||||||
|
uint8 magic; // our magic
|
||||||
|
uint8 version; // config struct version
|
||||||
|
uint8 mode; // boot loader mode
|
||||||
|
uint8 current_rom; // currently selected rom
|
||||||
|
uint8 gpio_rom; // rom to use for gpio boot
|
||||||
|
uint8 count; // number of roms in use
|
||||||
|
uint8 previous_rom; // previously selected rom
|
||||||
|
uint8 is_first_boot;
|
||||||
|
uint8 boot_attempts;
|
||||||
|
uint8 fw_updated;
|
||||||
|
uint8 padding[2];
|
||||||
|
uint32 roms[MAX_ROMS]; // flash addresses of the roms
|
||||||
|
uint32 roms_sizes[MAX_ROMS]; // sizes of the roms
|
||||||
|
uint32 fs_addresses[MAX_ROMS]; // file system addresses
|
||||||
|
uint32 fs_sizes[MAX_ROMS]; // file system sizes
|
||||||
|
uint32 user_flags;
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
uint8 chksum; // config chksum
|
||||||
|
#endif
|
||||||
|
} rboot_config;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_RBOOT_RBOOT_RBOOT_H_ */
|
@ -0,0 +1,2 @@
|
|||||||
|
INCLUDE "eagle.app.v6.ld"
|
||||||
|
INCLUDE "rboot_rom.ld"
|
@ -0,0 +1,89 @@
|
|||||||
|
#
|
||||||
|
# Makefile for rBoot
|
||||||
|
# https://github.com/raburton/esp8266
|
||||||
|
#
|
||||||
|
|
||||||
|
ESPTOOL2 ?= ../../build/esptool2
|
||||||
|
SDK_BASE ?= /opt/Espressif/ESP8266_SDK
|
||||||
|
SPI_SIZE ?=
|
||||||
|
RBOOT_INTEGRATION ?=
|
||||||
|
RBOOT_EXTRA_INCDIR ?=
|
||||||
|
|
||||||
|
# RBOOT_BUILD_BASE and RBOOT_GEN_BASE should be provided via makefile parameters
|
||||||
|
RBOOT_BUILD_BASE ?=
|
||||||
|
# RBOOT_GEN_BASE is the directory for generated inputs
|
||||||
|
RBOOT_GEN_BASE ?=
|
||||||
|
|
||||||
|
ifndef XTENSA_BINDIR
|
||||||
|
CC := xtensa-lx106-elf-gcc
|
||||||
|
LD := xtensa-lx106-elf-gcc
|
||||||
|
else
|
||||||
|
CC := $(addprefix $(XTENSA_BINDIR)/,xtensa-lx106-elf-gcc)
|
||||||
|
LD := $(addprefix $(XTENSA_BINDIR)/,xtensa-lx106-elf-gcc)
|
||||||
|
endif
|
||||||
|
CC_WRAPPER ?=
|
||||||
|
|
||||||
|
CFLAGS = -Os -O3 -Wpointer-arith -Wundef -Werror -Wl,-EL \
|
||||||
|
-fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals \
|
||||||
|
-D__ets__ -DIRAM='__attribute__((section(".fast.text")))' \
|
||||||
|
-DNOINSTR='__attribute__((no_instrument_function))' \
|
||||||
|
-DICACHE_FLASH $(CFLAGS_EXTRA)
|
||||||
|
|
||||||
|
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static -L $(SDK_BASE)/ld/
|
||||||
|
|
||||||
|
LD_SCRIPT = rboot.ld
|
||||||
|
|
||||||
|
E2_OPTS = -quiet -bin -boot0
|
||||||
|
|
||||||
|
ifeq ($(RBOOT_BIG_FLASH),1)
|
||||||
|
CFLAGS += -DBOOT_BIG_FLASH
|
||||||
|
endif
|
||||||
|
ifeq ($(RBOOT_INTEGRATION),1)
|
||||||
|
CFLAGS += -DRBOOT_INTEGRATION
|
||||||
|
endif
|
||||||
|
ifeq ($(SPI_SIZE), 256K)
|
||||||
|
E2_OPTS += -256
|
||||||
|
else ifeq ($(SPI_SIZE), 512K)
|
||||||
|
E2_OPTS += -512
|
||||||
|
else ifeq ($(SPI_SIZE), 1M)
|
||||||
|
E2_OPTS += -1024
|
||||||
|
else ifeq ($(SPI_SIZE), 2M)
|
||||||
|
E2_OPTS += -2048
|
||||||
|
else ifeq ($(SPI_SIZE), 4M)
|
||||||
|
E2_OPTS += -4096
|
||||||
|
endif
|
||||||
|
|
||||||
|
RBOOT_EXTRA_INCDIR := $(addprefix -I,$(RBOOT_EXTRA_INCDIR))
|
||||||
|
|
||||||
|
.SECONDARY:
|
||||||
|
|
||||||
|
all: $(RBOOT_BUILD_BASE)/rboot.bin
|
||||||
|
|
||||||
|
$(RBOOT_BUILD_BASE)/rboot-stage2a.o: rboot-stage2a.c rboot-private.h rboot.h
|
||||||
|
@echo "CC $<"
|
||||||
|
@$(CC_WRAPPER) $(CC) $(CFLAGS) $(RBOOT_EXTRA_INCDIR) -c $< -o $@
|
||||||
|
|
||||||
|
$(RBOOT_BUILD_BASE)/rboot-stage2a.elf: $(RBOOT_BUILD_BASE)/rboot-stage2a.o
|
||||||
|
@echo "LD $@"
|
||||||
|
@$(CC_WRAPPER) $(LD) -Trboot-stage2a.ld $(LDFLAGS) -Wl,--start-group $^ -Wl,--end-group -o $@
|
||||||
|
|
||||||
|
$(RBOOT_GEN_BASE)/rboot-hex2a.h: $(RBOOT_BUILD_BASE)/rboot-stage2a.elf
|
||||||
|
@echo "E2 $@"
|
||||||
|
@$(ESPTOOL2) -quiet -header $< $@ .text
|
||||||
|
|
||||||
|
$(RBOOT_BUILD_BASE)/rboot.o: rboot.c rboot-private.h rboot.h $(RBOOT_GEN_BASE)/rboot-hex2a.h
|
||||||
|
@echo "CC $<"
|
||||||
|
@$(CC) $(CFLAGS) -I$(RBOOT_GEN_BASE) $(RBOOT_EXTRA_INCDIR) -c $< -o $@
|
||||||
|
|
||||||
|
$(RBOOT_BUILD_BASE)/%.o: %.c %.h
|
||||||
|
@echo "CC $<"
|
||||||
|
@$(CC) $(CFLAGS) $(RBOOT_EXTRA_INCDIR) -c $< -o $@
|
||||||
|
|
||||||
|
$(RBOOT_BUILD_BASE)/%.elf: $(RBOOT_BUILD_BASE)/%.o
|
||||||
|
@echo "LD $@"
|
||||||
|
@$(LD) -T$(LD_SCRIPT) $(LDFLAGS) -Wl,--start-group $^ -Wl,--end-group -o $@
|
||||||
|
|
||||||
|
$(RBOOT_BUILD_BASE)/%.bin: $(RBOOT_BUILD_BASE)/%.elf
|
||||||
|
@echo "E2 $@"
|
||||||
|
@$(ESPTOOL2) $(E2_OPTS) $< $@ .text .rodata
|
||||||
|
|
@ -0,0 +1,8 @@
|
|||||||
|
PROVIDE ( ets_delay_us = 0x40002ecc );
|
||||||
|
PROVIDE ( ets_memcpy = 0x400018b4 );
|
||||||
|
PROVIDE ( ets_memset = 0x400018a4 );
|
||||||
|
PROVIDE ( ets_printf = 0x400024cc );
|
||||||
|
PROVIDE ( SPIEraseSector = 0x40004a00 );
|
||||||
|
PROVIDE ( SPIRead = 0x40004b1c );
|
||||||
|
PROVIDE ( SPIWrite = 0x40004a4c );
|
||||||
|
PROVIDE ( uart_div_modify = 0x400039d8 );
|
@ -0,0 +1,40 @@
|
|||||||
|
rBoot - User API for rBoot on the ESP8266
|
||||||
|
------------------------------------------
|
||||||
|
by Richard A Burton, richardaburton@gmail.com
|
||||||
|
http://richard.burtons.org/
|
||||||
|
|
||||||
|
This provides a few simple APIs for getting & setting rBoot config and for
|
||||||
|
writing data from OTA updates. API source files are in the appcode directory.
|
||||||
|
|
||||||
|
Actual OTA network code is implementation specific and no longer included in
|
||||||
|
rBoot itself, see the rBoot sample projects for this code (which you can then
|
||||||
|
use in your own projects).
|
||||||
|
|
||||||
|
rboot_config rboot_get_config();
|
||||||
|
Returns rboot_config (defined in rboot.h) allowing you to modify any values
|
||||||
|
in it, including the rom layout.
|
||||||
|
|
||||||
|
bool rboot_set_config(rboot_config *conf);
|
||||||
|
Saves the rboot_config structure back to sector 2 of the flash, while
|
||||||
|
maintaining the contents of the rest of the sector. You can use the rest of
|
||||||
|
this sector for your app settings, as long as you protect this structure
|
||||||
|
when you do so.
|
||||||
|
|
||||||
|
uint8 rboot_get_current_rom();
|
||||||
|
Get the currently selected boot rom (the currently running rom, as long as
|
||||||
|
you haven't changed it since boot).
|
||||||
|
|
||||||
|
bool rboot_set_current_rom(uint8 rom);
|
||||||
|
Set the current boot rom, which will be used when next restarted.
|
||||||
|
|
||||||
|
rboot_write_status rboot_write_init(uint32 start_addr);
|
||||||
|
Call once before starting to pass data to write to the flash. start_addr is
|
||||||
|
the address on the SPI flash to write from. Returns a status structure which
|
||||||
|
must be passed back on each write. The contents of the structure should not
|
||||||
|
be modified by the calling code.
|
||||||
|
|
||||||
|
bool rboot_write_flash(rboot_write_status *status, uint8 *data, uint16 len);
|
||||||
|
Call repeatedly to write data to the flash, starting at the address
|
||||||
|
specified on the prior call to rboot_write_init. Current write position is
|
||||||
|
tracked automatically. This method is likely to be called each time a packet
|
||||||
|
of OTA data is received over the network.
|
@ -0,0 +1,218 @@
|
|||||||
|
rBoot - An open source boot loader for the ESP8266
|
||||||
|
--------------------------------------------------
|
||||||
|
by Richard A Burton, richardaburton@gmail.com
|
||||||
|
http://richard.burtons.org/
|
||||||
|
|
||||||
|
|
||||||
|
rBoot is designed to be a flexible open source boot loader, a replacement for
|
||||||
|
the binary blob supplied with the SDK. It has the following advantages over the
|
||||||
|
Espressif loader:
|
||||||
|
|
||||||
|
- Open source (written in C).
|
||||||
|
- Supports up to 256 roms.
|
||||||
|
- Roms can be variable size.
|
||||||
|
- Able to test multiple roms to find a valid backup (without resetting).
|
||||||
|
- Flash layout can be changed on the fly (with care and appropriately linked
|
||||||
|
rom images).
|
||||||
|
- GPIO support for rom selection.
|
||||||
|
- Wastes no stack space (SDK boot loader uses 144 bytes).
|
||||||
|
- Documented config structure to allow easy editing from user code.
|
||||||
|
- Can validate .irom0.text section with checksum.
|
||||||
|
|
||||||
|
Limitations
|
||||||
|
-----------
|
||||||
|
The ESP8266 can only map 8Mbits (1MB) of flash to memory, but which 8Mbits to
|
||||||
|
map is selectable. This allows individual roms to be up to 1MB in size, so long
|
||||||
|
as they do not straddle an 8Mbit boundary on the flash. This means you could
|
||||||
|
have four 1MB roms or 8 512KB roms on a 32Mbit flash (such as on the ESP-12), or
|
||||||
|
a combination. Note, however, that you could not have, for example, a 512KB rom
|
||||||
|
followed immediately by a 1MB rom because the 2nd rom would then straddle an
|
||||||
|
8MBit boundary. By default support for using more than the first 8Mbit of the
|
||||||
|
flash is disabled, because it requires several steps to get it working. See
|
||||||
|
below for instructions.
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
A Makefile is included, which should work with the gcc xtensa cross compiler.
|
||||||
|
There are two source files, the first is compiled and included as data in the
|
||||||
|
second. When run this code is copied to memory and executed (there is a good
|
||||||
|
reason for this, see my blog for an explanation). The make file will handle this
|
||||||
|
for you, but you'll need my esptool2 (see github).
|
||||||
|
|
||||||
|
To use the Makefile set SDK_BASE to point to the root of the Espressif SDK and
|
||||||
|
either set XTENSA_BINDIR to the gcc xtensa bin directory or include it in your
|
||||||
|
PATH. These can be set as environment variables or by editing the Makefile.
|
||||||
|
|
||||||
|
Two small assembler stub functions allow the bootloader to launch the user code
|
||||||
|
without reserving any space on the stack (while the SDK boot loader uses 144
|
||||||
|
bytes). This compiles fine with GCC, but if you use another compiler and it
|
||||||
|
will not compile/work for you then uncomment the #define BOOT_NO_ASM in rboot.h
|
||||||
|
to use a C version of these functions (this uses 32 bytes).
|
||||||
|
|
||||||
|
Tested with SDK v1.3 and GCC v4.8.2.
|
||||||
|
|
||||||
|
Installation
|
||||||
|
------------
|
||||||
|
Simply write rboot.bin to the first sector of the flash. Remember to set your
|
||||||
|
flash size correctly with your chosen flash tool (e.g. for esptool.py use the
|
||||||
|
-fs option). When run rBoot will create it's own config at the start of sector
|
||||||
|
two for a simple two rom system. You can can then write your two roms to flash
|
||||||
|
addresses 0x2000 and (half chip size + 0x2000). E.g. for 8Mbit flash:
|
||||||
|
esptool.py -fs 8m 0x0000 rboot.bin 0x2000 user1.bin 0x82000 user2.bin
|
||||||
|
|
||||||
|
Note: your device may need other options specified. E.g. The nodemcu devkit v1.0
|
||||||
|
(commonly, but incorrectly, sold as v2) also needs the "-fm dio" option.
|
||||||
|
|
||||||
|
For more interesting rom layouts you'll need to write an rBoot config sector
|
||||||
|
manually, see next step.
|
||||||
|
|
||||||
|
The two testload bin files can be flashed in place of normal user roms for
|
||||||
|
testing rBoot. You do not need these for normal use.
|
||||||
|
|
||||||
|
rBoot Config
|
||||||
|
------------
|
||||||
|
typedef struct {
|
||||||
|
uint8 magic; // our magic
|
||||||
|
uint8 version; // config struct version
|
||||||
|
uint8 mode; // boot loader mode
|
||||||
|
uint8 current_rom; // currently selected rom
|
||||||
|
uint8 gpio_rom; // rom to use for gpio boot
|
||||||
|
uint8 count; // number of roms in use
|
||||||
|
uint8 unused[2]; // padding
|
||||||
|
uint32 roms[MAX_ROMS]; // flash addresses of the roms
|
||||||
|
#ifdef BOOT_CONFIG_CHKSUM
|
||||||
|
uint8 chksum; // boot config chksum
|
||||||
|
#endif
|
||||||
|
} rboot_config;
|
||||||
|
|
||||||
|
Write a config structure as above to address 0x1000 on the flash. If you want
|
||||||
|
more than 4 roms (default) just increase MAX_ROMS when you compile rBoot.
|
||||||
|
Think about how you intend to layout your flash before you start!
|
||||||
|
Rom addresses must be sector aligned i.e start on a multiple of 4096.
|
||||||
|
|
||||||
|
- magic should have value 0xe1 (defined as BOOT_CONFIG_MAGIC).
|
||||||
|
- version is used in case the config structure changes after deployment. It is
|
||||||
|
defined as 0x01 (BOOT_CONFIG_VERSION). I don't intend to increase this, but
|
||||||
|
you should if you choose to reflash the bootloader after deployment and
|
||||||
|
the config structure has changed.
|
||||||
|
- mode can be 0x00 (MODE_STANDARD) or 0x01 (MODE_GPIO_ROM). If you set GPIO
|
||||||
|
you will need to set gpio_rom as well. The sample GPIO code uses GPIO 16 on
|
||||||
|
a nodemcu dev board, if you want to use a different GPIO you'll need to
|
||||||
|
adapt the code in rBoot slightly.
|
||||||
|
- current_rom is the rom to boot, numbered 0 to count-1.
|
||||||
|
- gpio_rom is the rom to boot when the GPIO is triggered at boot.
|
||||||
|
- count is the number of roms available (may be less than MAX_ROMS, but not
|
||||||
|
more).
|
||||||
|
- unused[2] is padding so the uint32 rom addresses are 4 bytes aligned.
|
||||||
|
- roms is the array of flash address for the roms. The default generated
|
||||||
|
config will contain two entries: 0x00002000 and 0x00082000.
|
||||||
|
- chksum (if enabled, not by deafult) should be the xor of 0xef followed by
|
||||||
|
each of the bytes of the config structure up to (but obviously not
|
||||||
|
including) the chksum byte itself.
|
||||||
|
|
||||||
|
Linking user code
|
||||||
|
-----------------
|
||||||
|
Each rom will need to be linked with an appropriate linker file, specifying
|
||||||
|
where it will reside on the flash. If you are only flashing one rom to multiple
|
||||||
|
places on the flash it must be linked multiple times to produce the set of rom
|
||||||
|
images. This is the same as with the SDK loader.
|
||||||
|
|
||||||
|
Because there are endless possibilities for layout with this loader I don't
|
||||||
|
supply sample linker files. Instead I'll tell you how to make them.
|
||||||
|
|
||||||
|
For each rom slot on the flash take a copy of the eagle.app.v6.ld linker script
|
||||||
|
from the sdk. You then need to modify just one line in it for each rom:
|
||||||
|
irom0_0_seg : org = 0x40240000, len = 0x3C000
|
||||||
|
|
||||||
|
Change the org address to be 0x40200000 (base memory mapped location of the
|
||||||
|
flash) + flash address + 0x10 (offset of data after the header).
|
||||||
|
The logical place for your first rom is the third sector, address 0x2000.
|
||||||
|
0x40200000 + 0x2000 + 0x10 = 0x40202010
|
||||||
|
If you use the default generated config the loader will expect to find the
|
||||||
|
second rom at flash address half-chip-size + 0x2000 (e.g. 0x82000 on an 8MBit
|
||||||
|
flash) so the irom0_0_seg should be:
|
||||||
|
0x40200000 + 0x82000 + 0x10 = 0x40282010
|
||||||
|
Due to the limitation of mapped flash (max 8MBit) if you use a larger chip and
|
||||||
|
do not have big flash support enabled the second rom in the default config will
|
||||||
|
still be placed at 0x082000, not truly half-chip-size + 0x2000.
|
||||||
|
Ideally you should also adjust the len to help detect over sized sections at
|
||||||
|
link time, but more important is the overall size of the rom which you need to
|
||||||
|
ensure fits in the space you have allocated for it in your flash layout plan.
|
||||||
|
|
||||||
|
Then simply compile and link as you would normally for OTA updates with the SDK
|
||||||
|
boot loader, except using the linker scripts you've just prepared rather than
|
||||||
|
the ones supplied with the SDK. Remember when building roms to create them as
|
||||||
|
'new' type roms (for use with SDK boot loader v1.2+). Or if using my esptool2
|
||||||
|
use the -boot2 option. Note: the test loads included with rBoot are built with
|
||||||
|
-boot0 because they do not contain a .irom0.text section (and so the value of
|
||||||
|
irom0_0_seg in the linker file is irrelevant to them) but 'normal' user apps
|
||||||
|
always do.
|
||||||
|
|
||||||
|
irom checksum
|
||||||
|
-------------
|
||||||
|
The SDK boot loader checksum only covers sections loaded into ram (data and some
|
||||||
|
code). Most of the SDK and user code remains on the flash and that is not
|
||||||
|
included in the checksum. This means you could attempt to boot a corrupt rom
|
||||||
|
and, because it looks ok to the boot loader, there will be no attempt to switch
|
||||||
|
to a backup rom. rBoot improves on this by allowing the .irom0.text section to
|
||||||
|
be included in the checksum. To enable this uncomment #define BOOT_IROM_CHKSUM
|
||||||
|
in rboot.h and build your roms with esptool2 using the -iromchksum option.
|
||||||
|
|
||||||
|
Big flash support
|
||||||
|
-----------------
|
||||||
|
This only needs to be enabled if you wish to be able to memory map more than the
|
||||||
|
first 8MBit of the flash. Note you can still only map 8Mbit at a time. Use this
|
||||||
|
if you want to have multiple 1MB roms, or more smaller roms than will fit in
|
||||||
|
8Mbits. If you have a large flash but only need, for example, two 512KB roms you
|
||||||
|
do not need to enable this mode.
|
||||||
|
|
||||||
|
Support in rBoot is enabled by uncommenting the #define BOOT_BIG_FLASH in
|
||||||
|
rboot.h.
|
||||||
|
|
||||||
|
Thinking about your linker files is either simpler or more complicated,
|
||||||
|
depending on your usage of the flash. If you intend to use multiple 1MB roms you
|
||||||
|
will only need one linker file and you only need to link once for OTA updates.
|
||||||
|
Although when you perform an OTA update the rom will be written to a different
|
||||||
|
position on the flash, each 8Mbit of flash is mapped (separately) to 0x40200000.
|
||||||
|
So when any given rom is run the code will appear at the same place in memory
|
||||||
|
regardless of where it is on the flash. Your base address for the linker would
|
||||||
|
be 0x40202010. (Actually all but the first rom could base at 0x40200010 (because
|
||||||
|
they don't need to leave space for rBoot and config) but then you're just making
|
||||||
|
it more complicated again!)
|
||||||
|
If you wanted eight 512KB roms you would need two linker files - one for the
|
||||||
|
first half of any given 8Mbits of flash and another for the second half. Just
|
||||||
|
remember you are really laying out within a single 8MBit area, which can then be
|
||||||
|
replicated multiple times on the flash.
|
||||||
|
|
||||||
|
Now the clever bit - rBoot needs to hijack the memory mapping code to select
|
||||||
|
which 8Mbits gets mapped. There is no API for this, but we can override the SDK
|
||||||
|
function. First we need to slightly modify the SDK library libmain.a, like so:
|
||||||
|
|
||||||
|
xtensa-lx106-elf-objcopy -W Cache_Read_Enable_New libmain.a libmain2.a
|
||||||
|
|
||||||
|
This produces a version of libmain with a 'weakened' Cache_Read_Enable_New
|
||||||
|
function, which we can then override with our own. Modify your Makefile to link
|
||||||
|
against the library main2 instead of main.
|
||||||
|
Next add rboot-bigflash.c (from the appcode directory) & rboot.h to your project
|
||||||
|
- this adds the replacement Cache_Read_Enable_New to your code.
|
||||||
|
|
||||||
|
Getting gcc to apply the override correctly can be slightly tricky (I'm not sure
|
||||||
|
why, it shouldn't be). One option is to add "-u Cache_Read_Enable_New" to your
|
||||||
|
LD_FLAGS and change the order of objects on the LD command so your objects/.a
|
||||||
|
file is before the libraries. Another way that seems easier was to #include
|
||||||
|
rboot-bigflash.c into the main .c file, rather than compiling it to a separate
|
||||||
|
object file. I can't make any sense of that, but I suggest you uncomment the
|
||||||
|
message in the Cache_Read_Enable_New function when you first build with it, to
|
||||||
|
make sure you are getting your version into the rom.
|
||||||
|
|
||||||
|
Now when rBoot starts your rom, the SDK code linked in it that normally performs
|
||||||
|
the memory mapping will delegate part of that task to rBoot code (linked in your
|
||||||
|
rom, not in rBoot itself) to choose which part of the flash to map.
|
||||||
|
|
||||||
|
Integration into other frameworks
|
||||||
|
---------------------------------
|
||||||
|
If you wish to integrate rBoot into a development framework (e.g. Sming) you
|
||||||
|
can set the define RBOOT_INTEGRATION and at compile time the file
|
||||||
|
rboot-integration.h will be included into the source. This should allow you to
|
||||||
|
set some platform specific options without having to modify the source of rBoot
|
||||||
|
which makes it easier to integrate and maintain.
|
2
src/mongoose-6.11/src/common/platforms/esp8266/rom/.gitattributes
vendored
Normal file
2
src/mongoose-6.11/src/common/platforms/esp8266/rom/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
rom.bin -nodiff
|
||||||
|
rom.elf -nodiff
|
4
src/mongoose-6.11/src/common/platforms/esp8266/rom/disasm.sh
Executable file
4
src/mongoose-6.11/src/common/platforms/esp8266/rom/disasm.sh
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
xtensa-lx106-elf-gcc -Wl,-N,-Ttext,0x40000000 -nostdlib rom.S -o rom.elf && \
|
||||||
|
xtensa-lx106-elf-objdump -d rom.elf > ESP8266_ROM.txt
|
101
src/mongoose-6.11/src/common/platforms/esp8266/rom/rom.S
Normal file
101
src/mongoose-6.11/src/common/platforms/esp8266/rom/rom.S
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
.text
|
||||||
|
.org 0
|
||||||
|
.globl _start
|
||||||
|
|
||||||
|
// xtensa-esp108-elf-gcc -Wl,-N,-Ttext,0x40000000 -nostdlib rom.S -o rom.elf
|
||||||
|
|
||||||
|
here = .
|
||||||
|
#define PROVIDE(name, addr) name = here + addr - 0x40000000
|
||||||
|
|
||||||
|
#include "rom_functions.S"
|
||||||
|
|
||||||
|
PROVIDE(SPI_chip_erase, 0x40004080)
|
||||||
|
PROVIDE(SPIFlashModeConfig, 0x40004568)
|
||||||
|
|
||||||
|
PROVIDE(_c_0x80000000, 0x400003a4)
|
||||||
|
PROVIDE(_c_0x00400000, 0x40000414)
|
||||||
|
PROVIDE(_c_0x00ffffff, 0x40000418)
|
||||||
|
PROVIDE(_p_user_start, 0x40000fb8) // 0x3fffdcd0
|
||||||
|
PROVIDE(_c_0x60000200, 0x40000fc4)
|
||||||
|
PROVIDE(_s_ets_build, 0x40000fc8) // Jan 8 2013
|
||||||
|
PROVIDE(_s_ets_banner, 0x40000fcc) // ets %s,rst cause:%d, boot mode:(%d,%d)
|
||||||
|
PROVIDE(_s_format_s_s, 0x40000fd0) // %s %s
|
||||||
|
PROVIDE(_s_ets_main_c, 0x40000fd4) // ets_main.c
|
||||||
|
PROVIDE(_s_user_code_done, 0x40000fe0) // user code done
|
||||||
|
PROVIDE(_s_wdt_reset, 0x40000fe4) // wdt reset
|
||||||
|
PROVIDE(_s_unk_reset, 0x40000fe8) // unknown reset
|
||||||
|
PROVIDE(_l_boot_mode_6, 0x40001044)
|
||||||
|
PROVIDE(_l_boot_mode_0_1_2_3, 0x4000104a)
|
||||||
|
PROVIDE(_l_rst_cause_ge_3, 0x40001075)
|
||||||
|
PROVIDE(_l_rst_cause_ge_3_lt_7, 0x40001084)
|
||||||
|
PROVIDE(_l_rst_cause_3_soft_wdt, 0x4000108a)
|
||||||
|
PROVIDE(_l_load_from_flash, 0x400010a8)
|
||||||
|
PROVIDE(_l_run_user_code, 0x400010be)
|
||||||
|
PROVIDE(_l_wdt_reset, 0x40001118)
|
||||||
|
PROVIDE(_l_rst_cause_1_2, 0x40001121)
|
||||||
|
PROVIDE(_l_rst_cause_unknown, 0x40001130)
|
||||||
|
PROVIDE(_l_boot_mode_7, 0x40001148)
|
||||||
|
PROVIDE(_l_boot_mode_4, 0x40001150)
|
||||||
|
PROVIDE(_c_0x60000600, 0x4000115c)
|
||||||
|
PROVIDE(_s_waiting_for_host, 0x4000119c) // waiting for host
|
||||||
|
PROVIDE(_x_unk1160, 0x40001160)
|
||||||
|
PROVIDE(_c_0x3fffa000_uart_buf, 0x400011a0)
|
||||||
|
PROVIDE(_c_0x2000, 0x400011a4)
|
||||||
|
PROVIDE(_c_0x40100000, 0x400011a8) // default user_start
|
||||||
|
PROVIDE(_x_boot2, 0x400011ac) // arg: 0x3fffdcd0 (&user_start)
|
||||||
|
PROVIDE(_l_strapping_2_eq_0, 0x400011d2)
|
||||||
|
PROVIDE(_l_124d, 0x4000124d)
|
||||||
|
PROVIDE(_l_boot_mode2_eq_2, 0x40001265)
|
||||||
|
PROVIDE(_l_boot_mode_eq_2, 0x40001268)
|
||||||
|
PROVIDE(_l_boot_mode_eq_1, 0x4000127a)
|
||||||
|
PROVIDE(_l_setup_uart, 0x40001291)
|
||||||
|
PROVIDE(_l_boot_mode_eq_3, 0x400012b0)
|
||||||
|
PROVIDE(_x_load_from_flash, 0x40001308)
|
||||||
|
PROVIDE(_c_0x00001000, 0x40001994)
|
||||||
|
PROVIDE(_c_0xffdfffff, 0x400025dc)
|
||||||
|
PROVIDE(_l_rr_not_dsleep, 0x40002624)
|
||||||
|
PROVIDE(_c_100000, 0x40002664)
|
||||||
|
PROVIDE(_c_0x3feffe00, 0x40002e5c)
|
||||||
|
PROVIDE(_p_cpu_freq, 0x40002ec8)
|
||||||
|
PROVIDE(_x_wdt_interval, 0x40002f14) // arg: 3 -> 11, 6 -> 12, 12 -> 13
|
||||||
|
PROVIDE(_p_wdt_cfg, 0x40002f30)
|
||||||
|
PROVIDE(_wdt_soft_timer_fn2, 0x40002f3c)
|
||||||
|
PROVIDE(_l_wdt_soft_timer_fn2_exit, 0x40002f59)
|
||||||
|
PROVIDE(_l_wdt_soft_timer_fn2_feed, 0x40002f60)
|
||||||
|
PROVIDE(_l_wdt_soft_timer_fn2_mode2_stage1_feed, 0x40002f74)
|
||||||
|
PROVIDE(_wdt_soft_timer_fn, 0x40002f88)
|
||||||
|
PROVIDE(_p_wdt_soft_timer_fn, 0x40002f98)
|
||||||
|
PROVIDE(_p_wdt_soft_timer, 0x40002f9c) // 0x3fffdde0
|
||||||
|
PROVIDE(_l_skip_wdt_imask, 0x40002fc4)
|
||||||
|
PROVIDE(_l_wdt_enable_and_exit, 0x40002fea)
|
||||||
|
PROVIDE(_l_wdt_mode_1, 0x4000309c)
|
||||||
|
PROVIDE(_l_wdt_mode_2_4, 0x4000300a)
|
||||||
|
PROVIDE(_l_wdt_mode_3, 0x40003060)
|
||||||
|
PROVIDE(_l_recv_req, 0x400033a1)
|
||||||
|
PROVIDE(_l_send_response, 0x400033be)
|
||||||
|
PROVIDE(_l_send_resp_pkt, 0x400033da)
|
||||||
|
PROVIDE(_l_process_req, 0x40003424)
|
||||||
|
PROVIDE(_l_34a3, 0x400034a3)
|
||||||
|
PROVIDE(_l_34b9, 0x400034b9)
|
||||||
|
PROVIDE(_c_0x00001800, 0x40003534)
|
||||||
|
PROVIDE(_c_0x60000a00, 0x40003f54)
|
||||||
|
PROVIDE(_c_0x01000000, 0x400040bc)
|
||||||
|
PROVIDE(_x_SPI_erase_sector, 0x400040c0)
|
||||||
|
PROVIDE(_l_SPI_erase_sector_align_ok, 0x400040dc)
|
||||||
|
PROVIDE(_c_0x00800000, 0x4000411c)
|
||||||
|
PROVIDE(_x_SPI_erase_block, 0x40004120)
|
||||||
|
PROVIDE(_c_0x20000000, 0x4000416c)
|
||||||
|
PROVIDE(_c_0x08000000, 0x400043c4)
|
||||||
|
PROVIDE(_c_0x04000000, 0x400043fc)
|
||||||
|
PROVIDE(_c_0x40000000, 0x40004438)
|
||||||
|
PROVIDE(_p_flashchip, 0x40004874)
|
||||||
|
PROVIDE(_s_bootup, 0x400054cc) // bootup , addr 0x%08x
|
||||||
|
PROVIDE(_p_sip_ctx, 0x40005130)
|
||||||
|
PROVIDE(_l_sip_cmd_out, 0x4000550a)
|
||||||
|
PROVIDE(_c_0x00010000, 0x40005de0)
|
||||||
|
|
||||||
|
.text
|
||||||
|
|
||||||
|
_start:
|
||||||
|
.incbin "rom.bin"
|
||||||
|
_end:
|
BIN
src/mongoose-6.11/src/common/platforms/esp8266/rom/rom.bin
Normal file
BIN
src/mongoose-6.11/src/common/platforms/esp8266/rom/rom.bin
Normal file
Binary file not shown.
BIN
src/mongoose-6.11/src/common/platforms/esp8266/rom/rom.elf
Executable file
BIN
src/mongoose-6.11/src/common/platforms/esp8266/rom/rom.elf
Executable file
Binary file not shown.
@ -0,0 +1,347 @@
|
|||||||
|
PROVIDE ( Cache_Read_Disable , 0x400047f0 );
|
||||||
|
PROVIDE ( Cache_Read_Enable , 0x40004678 );
|
||||||
|
PROVIDE ( FilePacketSendReqMsgProc , 0x400035a0 );
|
||||||
|
PROVIDE ( FlashDwnLdParamCfgMsgProc , 0x4000368c );
|
||||||
|
PROVIDE ( FlashDwnLdStartMsgProc , 0x40003538 );
|
||||||
|
PROVIDE ( FlashDwnLdStopReqMsgProc , 0x40003658 );
|
||||||
|
PROVIDE ( GetUartDevice , 0x40003f4c );
|
||||||
|
PROVIDE ( MD5Final , 0x40009900 );
|
||||||
|
PROVIDE ( MD5Init , 0x40009818 );
|
||||||
|
PROVIDE ( MD5Update , 0x40009834 );
|
||||||
|
PROVIDE ( MemDwnLdStartMsgProc , 0x400036c4 );
|
||||||
|
PROVIDE ( MemDwnLdStopReqMsgProc , 0x4000377c );
|
||||||
|
PROVIDE ( MemPacketSendReqMsgProc , 0x400036f0 );
|
||||||
|
PROVIDE ( RcvMsg , 0x40003eac );
|
||||||
|
PROVIDE ( SHA1Final , 0x4000b648 );
|
||||||
|
PROVIDE ( SHA1Init , 0x4000b584 );
|
||||||
|
PROVIDE ( SHA1Transform , 0x4000a364 );
|
||||||
|
PROVIDE ( SHA1Update , 0x4000b5a8 );
|
||||||
|
PROVIDE ( SPI_read_status , 0x400043c8 );
|
||||||
|
PROVIDE ( SPI_write_status , 0x40004400 );
|
||||||
|
PROVIDE ( SPI_write_enable , 0x4000443c );
|
||||||
|
PROVIDE ( Wait_SPI_Idle , 0x4000448c );
|
||||||
|
PROVIDE ( SPIEraseArea , 0x40004b44 );
|
||||||
|
PROVIDE ( SPIEraseBlock , 0x400049b4 );
|
||||||
|
PROVIDE ( SPIEraseChip , 0x40004984 );
|
||||||
|
PROVIDE ( SPIEraseSector , 0x40004a00 );
|
||||||
|
PROVIDE ( SPILock , 0x400048a8 );
|
||||||
|
PROVIDE ( SPIParamCfg , 0x40004c2c );
|
||||||
|
PROVIDE ( SPIRead , 0x40004b1c );
|
||||||
|
PROVIDE ( SPIReadModeCnfig , 0x400048ec );
|
||||||
|
PROVIDE ( SPIUnlock , 0x40004878 );
|
||||||
|
PROVIDE ( SPIWrite , 0x40004a4c );
|
||||||
|
PROVIDE ( SelectSpiFunction , 0x40003f58 );
|
||||||
|
PROVIDE ( SendMsg , 0x40003cf4 );
|
||||||
|
PROVIDE ( UartConnCheck , 0x40003230 );
|
||||||
|
PROVIDE ( UartConnectProc , 0x400037a0 );
|
||||||
|
PROVIDE ( UartDwnLdProc , 0x40003368 );
|
||||||
|
PROVIDE ( UartGetCmdLn , 0x40003ef4 );
|
||||||
|
PROVIDE ( UartRegReadProc , 0x4000381c );
|
||||||
|
PROVIDE ( UartRegWriteProc , 0x400037ac );
|
||||||
|
PROVIDE ( UartRxString , 0x40003c30 );
|
||||||
|
PROVIDE ( Uart_Init , 0x40003a14 );
|
||||||
|
PROVIDE ( _DebugExceptionVector , 0x40000010 );
|
||||||
|
PROVIDE ( _DoubleExceptionVector , 0x40000070 );
|
||||||
|
PROVIDE ( _KernelExceptionVector , 0x40000030 );
|
||||||
|
PROVIDE ( _NMIExceptionVector , 0x40000020 );
|
||||||
|
PROVIDE ( _ResetHandler , 0x400000a4 );
|
||||||
|
PROVIDE ( _ResetVector , 0x40000080 );
|
||||||
|
PROVIDE ( _UserExceptionVector , 0x40000050 );
|
||||||
|
PROVIDE ( __adddf3 , 0x4000c538 );
|
||||||
|
PROVIDE ( __addsf3 , 0x4000c180 );
|
||||||
|
PROVIDE ( __divdf3 , 0x4000cb94 );
|
||||||
|
PROVIDE ( __divdi3 , 0x4000ce60 );
|
||||||
|
PROVIDE ( __divsi3 , 0x4000dc88 );
|
||||||
|
PROVIDE ( __extendsfdf2 , 0x4000cdfc );
|
||||||
|
PROVIDE ( __fixdfsi , 0x4000ccb8 );
|
||||||
|
PROVIDE ( __fixunsdfsi , 0x4000cd00 );
|
||||||
|
PROVIDE ( __fixunssfsi , 0x4000c4c4 );
|
||||||
|
PROVIDE ( __floatsidf , 0x4000e2f0 );
|
||||||
|
PROVIDE ( __floatsisf , 0x4000e2ac );
|
||||||
|
PROVIDE ( __floatunsidf , 0x4000e2e8 );
|
||||||
|
PROVIDE ( __floatunsisf , 0x4000e2a4 );
|
||||||
|
PROVIDE ( __muldf3 , 0x4000c8f0 );
|
||||||
|
PROVIDE ( __muldi3 , 0x40000650 );
|
||||||
|
PROVIDE ( __mulsf3 , 0x4000c3dc );
|
||||||
|
PROVIDE ( __subdf3 , 0x4000c688 );
|
||||||
|
PROVIDE ( __subsf3 , 0x4000c268 );
|
||||||
|
PROVIDE ( __truncdfsf2 , 0x4000cd5c );
|
||||||
|
PROVIDE ( __udivdi3 , 0x4000d310 );
|
||||||
|
PROVIDE ( __udivsi3 , 0x4000e21c );
|
||||||
|
PROVIDE ( __umoddi3 , 0x4000d770 );
|
||||||
|
PROVIDE ( __umodsi3 , 0x4000e268 );
|
||||||
|
PROVIDE ( __umulsidi3 , 0x4000dcf0 );
|
||||||
|
PROVIDE ( _rom_store , 0x4000e388 );
|
||||||
|
PROVIDE ( _rom_store_table , 0x4000e328 );
|
||||||
|
PROVIDE ( _start , 0x4000042c );
|
||||||
|
PROVIDE ( _xtos_alloca_handler , 0x4000dbe0 );
|
||||||
|
PROVIDE ( _xtos_c_wrapper_handler , 0x40000598 );
|
||||||
|
PROVIDE ( _xtos_cause3_handler , 0x40000590 );
|
||||||
|
PROVIDE ( _xtos_ints_off , 0x4000bda4 );
|
||||||
|
PROVIDE ( _xtos_ints_on , 0x4000bd84 );
|
||||||
|
PROVIDE ( _xtos_l1int_handler , 0x4000048c );
|
||||||
|
PROVIDE ( _xtos_p_none , 0x4000dbf8 );
|
||||||
|
PROVIDE ( _xtos_restore_intlevel , 0x4000056c );
|
||||||
|
PROVIDE ( _xtos_return_from_exc , 0x4000dc54 );
|
||||||
|
PROVIDE ( _xtos_set_exception_handler , 0x40000454 );
|
||||||
|
PROVIDE ( _xtos_set_interrupt_handler , 0x4000bd70 );
|
||||||
|
PROVIDE ( _xtos_set_interrupt_handler_arg , 0x4000bd28 );
|
||||||
|
PROVIDE ( _xtos_set_intlevel , 0x4000dbfc );
|
||||||
|
PROVIDE ( _xtos_set_min_intlevel , 0x4000dc18 );
|
||||||
|
PROVIDE ( _xtos_set_vpri , 0x40000574 );
|
||||||
|
PROVIDE ( _xtos_syscall_handler , 0x4000dbe4 );
|
||||||
|
PROVIDE ( _xtos_unhandled_exception , 0x4000dc44 );
|
||||||
|
PROVIDE ( _xtos_unhandled_interrupt , 0x4000dc3c );
|
||||||
|
PROVIDE ( aes_decrypt , 0x400092d4 );
|
||||||
|
PROVIDE ( aes_decrypt_deinit , 0x400092e4 );
|
||||||
|
PROVIDE ( aes_decrypt_init , 0x40008ea4 );
|
||||||
|
PROVIDE ( aes_unwrap , 0x40009410 );
|
||||||
|
PROVIDE ( base64_decode , 0x40009648 );
|
||||||
|
PROVIDE ( base64_encode , 0x400094fc );
|
||||||
|
PROVIDE ( bzero , 0x4000de84 );
|
||||||
|
PROVIDE ( cmd_parse , 0x40000814 );
|
||||||
|
PROVIDE ( conv_str_decimal , 0x40000b24 );
|
||||||
|
PROVIDE ( conv_str_hex , 0x40000cb8 );
|
||||||
|
PROVIDE ( convert_para_str , 0x40000a60 );
|
||||||
|
PROVIDE ( dtm_get_intr_mask , 0x400026d0 );
|
||||||
|
PROVIDE ( dtm_params_init , 0x4000269c );
|
||||||
|
PROVIDE ( dtm_set_intr_mask , 0x400026c8 );
|
||||||
|
PROVIDE ( dtm_set_params , 0x400026dc );
|
||||||
|
PROVIDE ( eprintf , 0x40001d14 );
|
||||||
|
PROVIDE ( eprintf_init_buf , 0x40001cb8 );
|
||||||
|
PROVIDE ( eprintf_to_host , 0x40001d48 );
|
||||||
|
PROVIDE ( est_get_printf_buf_remain_len , 0x40002494 );
|
||||||
|
PROVIDE ( est_reset_printf_buf_len , 0x4000249c );
|
||||||
|
PROVIDE ( ets_bzero , 0x40002ae8 );
|
||||||
|
PROVIDE ( ets_char2xdigit , 0x40002b74 );
|
||||||
|
PROVIDE ( ets_delay_us , 0x40002ecc );
|
||||||
|
PROVIDE ( ets_enter_sleep , 0x400027b8 );
|
||||||
|
PROVIDE ( ets_external_printf , 0x40002578 );
|
||||||
|
PROVIDE ( ets_get_cpu_frequency , 0x40002f0c );
|
||||||
|
PROVIDE ( ets_getc , 0x40002bcc );
|
||||||
|
PROVIDE ( ets_install_external_printf , 0x40002450 );
|
||||||
|
PROVIDE ( ets_install_putc1 , 0x4000242c );
|
||||||
|
PROVIDE ( ets_install_putc2 , 0x4000248c );
|
||||||
|
PROVIDE ( ets_install_uart_printf , 0x40002438 );
|
||||||
|
PROVIDE ( ets_intr_lock , 0x40000f74 );
|
||||||
|
PROVIDE ( ets_intr_unlock , 0x40000f80 );
|
||||||
|
PROVIDE ( ets_isr_attach , 0x40000f88 );
|
||||||
|
PROVIDE ( ets_isr_mask , 0x40000f98 );
|
||||||
|
PROVIDE ( ets_isr_unmask , 0x40000fa8 );
|
||||||
|
PROVIDE ( ets_memcmp , 0x400018d4 );
|
||||||
|
PROVIDE ( ets_memcpy , 0x400018b4 );
|
||||||
|
PROVIDE ( ets_memmove , 0x400018c4 );
|
||||||
|
PROVIDE ( ets_memset , 0x400018a4 );
|
||||||
|
PROVIDE ( ets_post , 0x40000e24 );
|
||||||
|
PROVIDE ( ets_printf , 0x400024cc );
|
||||||
|
PROVIDE ( ets_putc , 0x40002be8 );
|
||||||
|
PROVIDE ( ets_rtc_int_register , 0x40002a40 );
|
||||||
|
PROVIDE ( ets_run , 0x40000e04 );
|
||||||
|
PROVIDE ( ets_set_idle_cb , 0x40000dc0 );
|
||||||
|
PROVIDE ( ets_set_user_start , 0x40000fbc );
|
||||||
|
PROVIDE ( ets_str2macaddr , 0x40002af8 );
|
||||||
|
PROVIDE ( ets_strcmp , 0x40002aa8 );
|
||||||
|
PROVIDE ( ets_strcpy , 0x40002a88 );
|
||||||
|
PROVIDE ( ets_strlen , 0x40002ac8 );
|
||||||
|
PROVIDE ( ets_strncmp , 0x40002ab8 );
|
||||||
|
PROVIDE ( ets_strncpy , 0x40002a98 );
|
||||||
|
PROVIDE ( ets_strstr , 0x40002ad8 );
|
||||||
|
PROVIDE ( ets_task , 0x40000dd0 );
|
||||||
|
PROVIDE ( ets_timer_arm , 0x40002cc4 );
|
||||||
|
PROVIDE ( ets_timer_disarm , 0x40002d40 );
|
||||||
|
PROVIDE ( ets_timer_done , 0x40002d80 );
|
||||||
|
PROVIDE ( ets_timer_handler_isr , 0x40002da8 );
|
||||||
|
PROVIDE ( ets_timer_init , 0x40002e68 );
|
||||||
|
PROVIDE ( ets_timer_setfn , 0x40002c48 );
|
||||||
|
PROVIDE ( ets_uart_printf , 0x40002544 );
|
||||||
|
PROVIDE ( ets_update_cpu_frequency , 0x40002f04 );
|
||||||
|
PROVIDE ( ets_vprintf , 0x40001f00 );
|
||||||
|
PROVIDE ( ets_wdt_disable , 0x400030f0 );
|
||||||
|
PROVIDE ( ets_wdt_enable , 0x40002fa0 );
|
||||||
|
PROVIDE ( ets_wdt_get_mode , 0x40002f34 );
|
||||||
|
PROVIDE ( ets_wdt_init , 0x40003170 );
|
||||||
|
PROVIDE ( ets_wdt_restore , 0x40003158 );
|
||||||
|
PROVIDE ( ets_write_char , 0x40001da0 );
|
||||||
|
PROVIDE ( get_first_seg , 0x4000091c );
|
||||||
|
PROVIDE ( gpio_init , 0x40004c50 );
|
||||||
|
PROVIDE ( gpio_input_get , 0x40004cf0 );
|
||||||
|
PROVIDE ( gpio_intr_ack , 0x40004dcc );
|
||||||
|
PROVIDE ( gpio_intr_handler_register , 0x40004e28 );
|
||||||
|
PROVIDE ( gpio_intr_pending , 0x40004d88 );
|
||||||
|
PROVIDE ( gpio_intr_test , 0x40004efc );
|
||||||
|
PROVIDE ( gpio_output_set , 0x40004cd0 );
|
||||||
|
PROVIDE ( gpio_pin_intr_state_set , 0x40004d90 );
|
||||||
|
PROVIDE ( gpio_pin_wakeup_disable , 0x40004ed4 );
|
||||||
|
PROVIDE ( gpio_pin_wakeup_enable , 0x40004e90 );
|
||||||
|
PROVIDE ( gpio_register_get , 0x40004d5c );
|
||||||
|
PROVIDE ( gpio_register_set , 0x40004d04 );
|
||||||
|
PROVIDE ( hmac_md5 , 0x4000a2cc );
|
||||||
|
PROVIDE ( hmac_md5_vector , 0x4000a160 );
|
||||||
|
PROVIDE ( hmac_sha1 , 0x4000ba28 );
|
||||||
|
PROVIDE ( hmac_sha1_vector , 0x4000b8b4 );
|
||||||
|
PROVIDE ( lldesc_build_chain , 0x40004f40 );
|
||||||
|
PROVIDE ( lldesc_num2link , 0x40005050 );
|
||||||
|
PROVIDE ( lldesc_set_owner , 0x4000507c );
|
||||||
|
PROVIDE ( main , 0x40000fec );
|
||||||
|
PROVIDE ( md5_vector , 0x400097ac );
|
||||||
|
PROVIDE ( mem_calloc , 0x40001c2c );
|
||||||
|
PROVIDE ( mem_free , 0x400019e0 );
|
||||||
|
PROVIDE ( mem_init , 0x40001998 );
|
||||||
|
PROVIDE ( mem_malloc , 0x40001b40 );
|
||||||
|
PROVIDE ( mem_realloc , 0x40001c6c );
|
||||||
|
PROVIDE ( mem_trim , 0x40001a14 );
|
||||||
|
PROVIDE ( mem_zalloc , 0x40001c58 );
|
||||||
|
PROVIDE ( memcmp , 0x4000dea8 );
|
||||||
|
PROVIDE ( memcpy , 0x4000df48 );
|
||||||
|
PROVIDE ( memmove , 0x4000e04c );
|
||||||
|
PROVIDE ( memset , 0x4000e190 );
|
||||||
|
PROVIDE ( multofup , 0x400031c0 );
|
||||||
|
PROVIDE ( pbkdf2_sha1 , 0x4000b840 );
|
||||||
|
PROVIDE ( phy_get_romfuncs , 0x40006b08 );
|
||||||
|
PROVIDE ( rand , 0x40000600 );
|
||||||
|
PROVIDE ( rc4_skip , 0x4000dd68 );
|
||||||
|
PROVIDE ( recv_packet , 0x40003d08 );
|
||||||
|
PROVIDE ( remove_head_space , 0x40000a04 );
|
||||||
|
PROVIDE ( rijndaelKeySetupDec , 0x40008dd0 );
|
||||||
|
PROVIDE ( rijndaelKeySetupEnc , 0x40009300 );
|
||||||
|
PROVIDE ( rom_abs_temp , 0x400060c0 );
|
||||||
|
PROVIDE ( rom_ana_inf_gating_en , 0x40006b10 );
|
||||||
|
PROVIDE ( rom_cal_tos_v50 , 0x40007a28 );
|
||||||
|
PROVIDE ( rom_chip_50_set_channel , 0x40006f84 );
|
||||||
|
PROVIDE ( rom_chip_v5_disable_cca , 0x400060d0 );
|
||||||
|
PROVIDE ( rom_chip_v5_enable_cca , 0x400060ec );
|
||||||
|
PROVIDE ( rom_chip_v5_rx_init , 0x4000711c );
|
||||||
|
PROVIDE ( rom_chip_v5_sense_backoff , 0x4000610c );
|
||||||
|
PROVIDE ( rom_chip_v5_tx_init , 0x4000718c );
|
||||||
|
PROVIDE ( rom_dc_iq_est , 0x4000615c );
|
||||||
|
PROVIDE ( rom_en_pwdet , 0x400061b8 );
|
||||||
|
PROVIDE ( rom_get_bb_atten , 0x40006238 );
|
||||||
|
PROVIDE ( rom_get_corr_power , 0x40006260 );
|
||||||
|
PROVIDE ( rom_get_fm_sar_dout , 0x400062dc );
|
||||||
|
PROVIDE ( rom_get_noisefloor , 0x40006394 );
|
||||||
|
PROVIDE ( rom_get_power_db , 0x400063b0 );
|
||||||
|
PROVIDE ( rom_i2c_readReg , 0x40007268 );
|
||||||
|
PROVIDE ( rom_i2c_readReg_Mask , 0x4000729c );
|
||||||
|
PROVIDE ( rom_i2c_writeReg , 0x400072d8 );
|
||||||
|
PROVIDE ( rom_i2c_writeReg_Mask , 0x4000730c );
|
||||||
|
PROVIDE ( rom_iq_est_disable , 0x40006400 );
|
||||||
|
PROVIDE ( rom_iq_est_enable , 0x40006430 );
|
||||||
|
PROVIDE ( rom_linear_to_db , 0x40006484 );
|
||||||
|
PROVIDE ( rom_mhz2ieee , 0x400065a4 );
|
||||||
|
PROVIDE ( rom_pbus_dco___SA2 , 0x40007bf0 );
|
||||||
|
PROVIDE ( rom_pbus_debugmode , 0x4000737c );
|
||||||
|
PROVIDE ( rom_pbus_enter_debugmode , 0x40007410 );
|
||||||
|
PROVIDE ( rom_pbus_exit_debugmode , 0x40007448 );
|
||||||
|
PROVIDE ( rom_pbus_force_test , 0x4000747c );
|
||||||
|
PROVIDE ( rom_pbus_rd , 0x400074d8 );
|
||||||
|
PROVIDE ( rom_pbus_set_rxgain , 0x4000754c );
|
||||||
|
PROVIDE ( rom_pbus_set_txgain , 0x40007610 );
|
||||||
|
PROVIDE ( rom_pbus_workmode , 0x40007648 );
|
||||||
|
PROVIDE ( rom_pbus_xpd_rx_off , 0x40007688 );
|
||||||
|
PROVIDE ( rom_pbus_xpd_rx_on , 0x400076cc );
|
||||||
|
PROVIDE ( rom_pbus_xpd_tx_off , 0x400076fc );
|
||||||
|
PROVIDE ( rom_pbus_xpd_tx_on , 0x40007740 );
|
||||||
|
PROVIDE ( rom_pbus_xpd_tx_on__low_gain , 0x400077a0 );
|
||||||
|
PROVIDE ( rom_phy_reset_req , 0x40007804 );
|
||||||
|
PROVIDE ( rom_restart_cal , 0x4000781c );
|
||||||
|
PROVIDE ( rom_rfcal_pwrctrl , 0x40007eb4 );
|
||||||
|
PROVIDE ( rom_rfcal_rxiq , 0x4000804c );
|
||||||
|
PROVIDE ( rom_rfcal_rxiq_set_reg , 0x40008264 );
|
||||||
|
PROVIDE ( rom_rfcal_txcap , 0x40008388 );
|
||||||
|
PROVIDE ( rom_rfcal_txiq , 0x40008610 );
|
||||||
|
PROVIDE ( rom_rfcal_txiq_cover , 0x400088b8 );
|
||||||
|
PROVIDE ( rom_rfcal_txiq_set_reg , 0x40008a70 );
|
||||||
|
PROVIDE ( rom_rfpll_reset , 0x40007868 );
|
||||||
|
PROVIDE ( rom_rfpll_set_freq , 0x40007968 );
|
||||||
|
PROVIDE ( rom_rxiq_cover_mg_mp , 0x40008b6c );
|
||||||
|
PROVIDE ( rom_rxiq_get_mis , 0x40006628 );
|
||||||
|
PROVIDE ( rom_sar_init , 0x40006738 );
|
||||||
|
PROVIDE ( rom_set_ana_inf_tx_scale , 0x4000678c );
|
||||||
|
PROVIDE ( rom_set_channel_freq , 0x40006c50 );
|
||||||
|
PROVIDE ( rom_set_loopback_gain , 0x400067c8 );
|
||||||
|
PROVIDE ( rom_set_noise_floor , 0x40006830 );
|
||||||
|
PROVIDE ( rom_set_rxclk_en , 0x40006550 );
|
||||||
|
PROVIDE ( rom_set_txbb_atten , 0x40008c6c );
|
||||||
|
PROVIDE ( rom_set_txclk_en , 0x4000650c );
|
||||||
|
PROVIDE ( rom_set_txiq_cal , 0x40008d34 );
|
||||||
|
PROVIDE ( rom_start_noisefloor , 0x40006874 );
|
||||||
|
PROVIDE ( rom_start_tx_tone , 0x400068b4 );
|
||||||
|
PROVIDE ( rom_stop_tx_tone , 0x4000698c );
|
||||||
|
PROVIDE ( rom_tx_mac_disable , 0x40006a98 );
|
||||||
|
PROVIDE ( rom_tx_mac_enable , 0x40006ad4 );
|
||||||
|
PROVIDE ( rom_txtone_linear_pwr , 0x40006a1c );
|
||||||
|
PROVIDE ( rom_write_rfpll_sdm , 0x400078dc );
|
||||||
|
PROVIDE ( roundup2 , 0x400031b4 );
|
||||||
|
PROVIDE ( rtc_enter_sleep , 0x40002870 );
|
||||||
|
PROVIDE ( rtc_get_reset_reason , 0x400025e0 );
|
||||||
|
PROVIDE ( rtc_intr_handler , 0x400029ec );
|
||||||
|
PROVIDE ( rtc_set_sleep_mode , 0x40002668 );
|
||||||
|
PROVIDE ( save_rxbcn_mactime , 0x400027a4 );
|
||||||
|
PROVIDE ( save_tsf_us , 0x400027ac );
|
||||||
|
PROVIDE ( send_packet , 0x40003c80 );
|
||||||
|
PROVIDE ( sha1_prf , 0x4000ba48 );
|
||||||
|
PROVIDE ( sha1_vector , 0x4000a2ec );
|
||||||
|
PROVIDE ( sip_alloc_to_host_evt , 0x40005180 );
|
||||||
|
PROVIDE ( sip_get_ptr , 0x400058a8 );
|
||||||
|
PROVIDE ( sip_get_state , 0x40005668 );
|
||||||
|
PROVIDE ( sip_init_attach , 0x4000567c );
|
||||||
|
PROVIDE ( sip_install_rx_ctrl_cb , 0x4000544c );
|
||||||
|
PROVIDE ( sip_install_rx_data_cb , 0x4000545c );
|
||||||
|
PROVIDE ( sip_post , 0x400050fc );
|
||||||
|
PROVIDE ( sip_post_init , 0x400056c4 );
|
||||||
|
PROVIDE ( sip_reclaim_from_host_cmd , 0x4000534c );
|
||||||
|
PROVIDE ( sip_reclaim_tx_data_pkt , 0x400052c0 );
|
||||||
|
PROVIDE ( sip_send , 0x40005808 );
|
||||||
|
PROVIDE ( sip_to_host_chain_append , 0x40005864 );
|
||||||
|
PROVIDE ( sip_to_host_evt_send_done , 0x40005234 );
|
||||||
|
PROVIDE ( slc_add_credits , 0x400060ac );
|
||||||
|
PROVIDE ( slc_enable , 0x40005d90 );
|
||||||
|
PROVIDE ( slc_from_host_chain_fetch , 0x40005f24 );
|
||||||
|
PROVIDE ( slc_from_host_chain_recycle , 0x40005e94 );
|
||||||
|
PROVIDE ( slc_init_attach , 0x40005c50 );
|
||||||
|
PROVIDE ( slc_init_credit , 0x4000608c );
|
||||||
|
PROVIDE ( slc_pause_from_host , 0x40006014 );
|
||||||
|
PROVIDE ( slc_reattach , 0x40005c1c );
|
||||||
|
PROVIDE ( slc_resume_from_host , 0x4000603c );
|
||||||
|
PROVIDE ( slc_select_tohost_gpio , 0x40005dc0 );
|
||||||
|
PROVIDE ( slc_select_tohost_gpio_mode , 0x40005db8 );
|
||||||
|
PROVIDE ( slc_send_to_host_chain , 0x40005de4 );
|
||||||
|
PROVIDE ( slc_set_host_io_max_window , 0x40006068 );
|
||||||
|
PROVIDE ( slc_to_host_chain_recycle , 0x40005f10 );
|
||||||
|
PROVIDE ( software_reset , 0x4000264c );
|
||||||
|
PROVIDE ( spi_flash_attach , 0x40004644 );
|
||||||
|
PROVIDE ( srand , 0x400005f0 );
|
||||||
|
PROVIDE ( strcmp , 0x4000bdc8 );
|
||||||
|
PROVIDE ( strcpy , 0x4000bec8 );
|
||||||
|
PROVIDE ( strlen , 0x4000bf4c );
|
||||||
|
PROVIDE ( strncmp , 0x4000bfa8 );
|
||||||
|
PROVIDE ( strncpy , 0x4000c0a0 );
|
||||||
|
PROVIDE ( strstr , 0x4000e1e0 );
|
||||||
|
PROVIDE ( timer_insert , 0x40002c64 );
|
||||||
|
PROVIDE ( uartAttach , 0x4000383c );
|
||||||
|
PROVIDE ( uart_baudrate_detect , 0x40003924 );
|
||||||
|
PROVIDE ( uart_buff_switch , 0x400038a4 );
|
||||||
|
PROVIDE ( uart_div_modify , 0x400039d8 );
|
||||||
|
PROVIDE ( uart_rx_intr_handler , 0x40003bbc );
|
||||||
|
PROVIDE ( uart_rx_one_char , 0x40003b8c );
|
||||||
|
PROVIDE ( uart_rx_one_char_block , 0x40003b64 );
|
||||||
|
PROVIDE ( uart_rx_readbuff , 0x40003ec8 );
|
||||||
|
PROVIDE ( uart_tx_one_char , 0x40003b30 );
|
||||||
|
PROVIDE ( wepkey_128 , 0x4000bc40 );
|
||||||
|
PROVIDE ( wepkey_64 , 0x4000bb3c );
|
||||||
|
PROVIDE ( xthal_bcopy , 0x40000688 );
|
||||||
|
PROVIDE ( xthal_copy123 , 0x4000074c );
|
||||||
|
PROVIDE ( xthal_get_ccompare , 0x4000dd4c );
|
||||||
|
PROVIDE ( xthal_get_ccount , 0x4000dd38 );
|
||||||
|
PROVIDE ( xthal_get_interrupt , 0x4000dd58 );
|
||||||
|
PROVIDE ( xthal_get_intread , 0x4000dd58 );
|
||||||
|
PROVIDE ( xthal_memcpy , 0x400006c4 );
|
||||||
|
PROVIDE ( xthal_set_ccompare , 0x4000dd40 );
|
||||||
|
PROVIDE ( xthal_set_intclear , 0x4000dd60 );
|
||||||
|
PROVIDE ( xthal_spill_registers_into_stack_nw , 0x4000e320 );
|
||||||
|
PROVIDE ( xthal_window_spill , 0x4000e324 );
|
||||||
|
PROVIDE ( xthal_window_spill_nw , 0x4000e320 );
|
||||||
|
|
||||||
|
PROVIDE ( Te0 , 0x3fffccf0 );
|
||||||
|
PROVIDE ( UartDev , 0x3fffde10 );
|
||||||
|
PROVIDE ( flashchip , 0x3fffc714);
|
@ -0,0 +1,50 @@
|
|||||||
|
#
|
||||||
|
# Copyright (c) 2015 Cesanta Software Limited
|
||||||
|
# All rights reserved
|
||||||
|
#
|
||||||
|
|
||||||
|
STUB = stub_hello.c
|
||||||
|
LIBS =
|
||||||
|
PARAMS =
|
||||||
|
CFLAGS =
|
||||||
|
PORT = /dev/ttyUSB0
|
||||||
|
|
||||||
|
BUILD_DIR = .build
|
||||||
|
COMMON_STUB_DIR = ../../esp
|
||||||
|
STUB_ELF = $(BUILD_DIR)/$(patsubst %.c,%.elf,$(notdir $(STUB)))
|
||||||
|
STUB_JSON ?= $(BUILD_DIR)/$(patsubst %.c,%.json,$(notdir $(STUB)))
|
||||||
|
SDK = $(shell cat ../../../../fw/platforms/esp8266/sdk.version)
|
||||||
|
XT_CC = xtensa-lx106-elf-gcc
|
||||||
|
|
||||||
|
.PHONY: all clean run wrap
|
||||||
|
|
||||||
|
all: $(STUB_ELF)
|
||||||
|
|
||||||
|
$(STUB_ELF): $(STUB) $(LIBS)
|
||||||
|
@echo " CC $^ -> $@"
|
||||||
|
@[ -d $(BUILD_DIR) ] || mkdir $(BUILD_DIR)
|
||||||
|
@docker run --rm -i -v $(CURDIR)/../../../..:/src $(SDK) //bin/bash -c \
|
||||||
|
"cd /src/common/platforms/esp8266/stubs && \
|
||||||
|
$(XT_CC) -std=c99 -Wall -Werror -Os -DESP8266 \
|
||||||
|
-mtext-section-literals -mlongcalls -nostdlib -fno-builtin \
|
||||||
|
-I. -I/src/common/platforms/esp \
|
||||||
|
-I/opt/Espressif/ESP8266_SDK \
|
||||||
|
-Wl,-static -ffunction-sections -Wl,--gc-sections \
|
||||||
|
-Tstub.ld $(CFLAGS) -o $@ $^"
|
||||||
|
|
||||||
|
wrap: $(STUB_JSON)
|
||||||
|
|
||||||
|
$(STUB_JSON): $(STUB_ELF) $(COMMON_STUB_DIR)/esptool.py
|
||||||
|
@echo " WRAP $< -> $@"
|
||||||
|
@docker run --rm -i -v $(CURDIR)/../../../..:/src $(SDK) //bin/bash -c \
|
||||||
|
"cd /src/common/platforms/esp8266/stubs && \
|
||||||
|
$(COMMON_STUB_DIR)/esptool.py wrap_stub $<" > $@
|
||||||
|
|
||||||
|
run: $(STUB_JSON)
|
||||||
|
@echo " RUN $< $(PARAMS) -> $(PORT)"
|
||||||
|
@docker run --rm -i --privileged -v $(CURDIR)/../../../..:/src $(SDK) //bin/bash -c \
|
||||||
|
"cd /src/common/platforms/esp8266/stubs && \
|
||||||
|
$(COMMON_STUB_DIR)/esptool.py --port $(PORT) run_stub $< $(PARAMS)"
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -rf $(BUILD_DIR)
|
@ -0,0 +1,13 @@
|
|||||||
|
This is a ESP boot loader stub development environment.
|
||||||
|
|
||||||
|
Code produced in this environment can be loaded and executed
|
||||||
|
in the bootloader environment. Usually it is used to implement
|
||||||
|
functionality not found in the bootloader.
|
||||||
|
|
||||||
|
Stubs can be executed using the `run_stub` command of the modified esptool.py provided.
|
||||||
|
`wrap_stub` produces a JSON represenattion of the stub that can later be reused
|
||||||
|
or built into other tools.
|
||||||
|
|
||||||
|
Example usage:
|
||||||
|
$ make run STUB=stub_flash_size.c PORT=/dev/ttyUSB0
|
||||||
|
$ make run STUB=stub_md5.c PORT=/dev/ttyUSB0 PARAMS="0x11000 10000 1"
|
14
src/mongoose-6.11/src/common/platforms/esp8266/stubs/chop80.py
Executable file
14
src/mongoose-6.11/src/common/platforms/esp8266/stubs/chop80.py
Executable file
@ -0,0 +1,14 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
for line in open(sys.argv[1]):
|
||||||
|
i = 0
|
||||||
|
while i < len(line):
|
||||||
|
n = len(line) - i
|
||||||
|
if n > 80: n = 80
|
||||||
|
l = line[i:i+n]
|
||||||
|
if n == 80:
|
||||||
|
l += '\\'
|
||||||
|
print l
|
||||||
|
i += n
|
@ -0,0 +1,91 @@
|
|||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_STUBS_ROM_FUNCTIONS_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_STUBS_ROM_FUNCTIONS_H_
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "/opt/Espressif/ESP8266_NONOS_SDK/include/c_types.h"
|
||||||
|
#include "/opt/Espressif/ESP8266_NONOS_SDK/include/spi_flash.h"
|
||||||
|
|
||||||
|
int uart_rx_one_char(uint8_t *ch);
|
||||||
|
uint8_t uart_rx_one_char_block();
|
||||||
|
int uart_tx_one_char(char ch);
|
||||||
|
void uart_div_modify(uint32_t uart_no, uint32_t baud_div);
|
||||||
|
|
||||||
|
int SendMsg(uint8_t *msg, uint8_t size);
|
||||||
|
int send_packet(uint8_t *packet, uint32_t size);
|
||||||
|
// recv_packet depends on global UartDev, better to avoid it.
|
||||||
|
// uint32_t recv_packet(void *packet, uint32_t len, uint8_t no_sync);
|
||||||
|
|
||||||
|
void _putc1(char *ch);
|
||||||
|
|
||||||
|
void ets_delay_us(uint32_t us);
|
||||||
|
|
||||||
|
uint32_t SPILock();
|
||||||
|
uint32_t SPIUnlock();
|
||||||
|
uint32_t SPIRead(uint32_t addr, void *dst, uint32_t size);
|
||||||
|
uint32_t SPIWrite(uint32_t addr, const uint32_t *src, uint32_t size);
|
||||||
|
uint32_t SPIEraseChip();
|
||||||
|
uint32_t SPIEraseBlock(uint32_t block_num);
|
||||||
|
uint32_t SPIEraseSector(uint32_t sector_num);
|
||||||
|
|
||||||
|
extern SpiFlashChip *flashchip;
|
||||||
|
uint32_t Wait_SPI_Idle(SpiFlashChip *spi);
|
||||||
|
uint32_t SPI_chip_erase(SpiFlashChip *spi);
|
||||||
|
uint32_t SPI_read_status(SpiFlashChip *spi);
|
||||||
|
uint32_t SPI_write_enable(SpiFlashChip *spi);
|
||||||
|
|
||||||
|
void spi_flash_attach();
|
||||||
|
|
||||||
|
/* ESP32 API compatibility */
|
||||||
|
#define esp_rom_spiflash_unlock SPIUnlock
|
||||||
|
#define esp_rom_spiflash_erase_sector SPIEraseSector
|
||||||
|
#define esp_rom_spiflash_erase_block SPIEraseBlock
|
||||||
|
#define esp_rom_spiflash_erase_chip SPIEraseChip
|
||||||
|
#define esp_rom_spiflash_read SPIRead
|
||||||
|
#define esp_rom_spiflash_write SPIWrite
|
||||||
|
#define esp_rom_spiflash_config_param SPIParamCfg
|
||||||
|
|
||||||
|
void SelectSpiFunction();
|
||||||
|
void SPIFlashModeConfig(uint32_t a, uint32_t b);
|
||||||
|
void SPIReadModeCnfig(uint32_t a);
|
||||||
|
uint32_t SPIParamCfg(uint32_t deviceId, uint32_t chip_size, uint32_t block_size,
|
||||||
|
uint32_t sector_size, uint32_t page_size,
|
||||||
|
uint32_t status_mask);
|
||||||
|
|
||||||
|
void Cache_Read_Disable();
|
||||||
|
|
||||||
|
void ets_delay_us(uint32_t delay_micros);
|
||||||
|
|
||||||
|
void ets_isr_mask(uint32_t ints);
|
||||||
|
void ets_isr_unmask(uint32_t ints);
|
||||||
|
typedef void (*int_handler_t)(void *arg);
|
||||||
|
|
||||||
|
void ets_intr_lock();
|
||||||
|
void ets_intr_unlock();
|
||||||
|
void ets_set_user_start(void (*user_start_fn)());
|
||||||
|
|
||||||
|
uint32_t rtc_get_reset_reason();
|
||||||
|
void software_reset();
|
||||||
|
void rom_phy_reset_req();
|
||||||
|
|
||||||
|
void uart_rx_intr_handler(void *arg);
|
||||||
|
|
||||||
|
void _ResetVector();
|
||||||
|
|
||||||
|
/* Crypto functions are from wpa_supplicant. */
|
||||||
|
int md5_vector(uint32_t num_msgs, const uint8_t *msgs[],
|
||||||
|
const uint32_t *msg_lens, uint8_t *digest);
|
||||||
|
int sha1_vector(uint32_t num_msgs, const uint8_t *msgs[],
|
||||||
|
const uint32_t *msg_lens, uint8_t *digest);
|
||||||
|
|
||||||
|
struct MD5Context {
|
||||||
|
uint32_t buf[4];
|
||||||
|
uint32_t bits[2];
|
||||||
|
uint8_t in[64];
|
||||||
|
};
|
||||||
|
|
||||||
|
void MD5Init(struct MD5Context *ctx);
|
||||||
|
void MD5Update(struct MD5Context *ctx, void *buf, uint32_t len);
|
||||||
|
void MD5Final(uint8_t digest[16], struct MD5Context *ctx);
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_STUBS_ROM_FUNCTIONS_H_ */
|
43
src/mongoose-6.11/src/common/platforms/esp8266/stubs/stub.ld
Normal file
43
src/mongoose-6.11/src/common/platforms/esp8266/stubs/stub.ld
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
MEMORY {
|
||||||
|
iram : org = 0x40100000, len = 0x8000
|
||||||
|
dram : org = 0x3FFE8000, len = 0x14000
|
||||||
|
}
|
||||||
|
|
||||||
|
ENTRY(stub_main)
|
||||||
|
|
||||||
|
SECTIONS {
|
||||||
|
.params 0x40100000 : {
|
||||||
|
_params_start = ABSOLUTE(.);
|
||||||
|
*(.params)
|
||||||
|
_params_end = ABSOLUTE(.);
|
||||||
|
} > iram
|
||||||
|
|
||||||
|
.text : ALIGN(4) {
|
||||||
|
_code_start = ABSOLUTE(.);
|
||||||
|
*(.literal)
|
||||||
|
*(.text .text.*)
|
||||||
|
} > iram
|
||||||
|
|
||||||
|
.bss : ALIGN(4) {
|
||||||
|
_bss_start = ABSOLUTE(.);
|
||||||
|
*(.bss)
|
||||||
|
_bss_end = ABSOLUTE(.);
|
||||||
|
} > dram
|
||||||
|
|
||||||
|
.data : ALIGN(4) {
|
||||||
|
_data_start = ABSOLUTE(.);
|
||||||
|
*(.data)
|
||||||
|
*(.rodata .rodata.*)
|
||||||
|
} > dram
|
||||||
|
}
|
||||||
|
|
||||||
|
INCLUDE "eagle.rom.addr.v6.ld"
|
||||||
|
|
||||||
|
PROVIDE(SPIFlashModeConfig = 0x40004568);
|
||||||
|
PROVIDE(SPI_erase_sector = 0x400040c0);
|
||||||
|
PROVIDE(SPI_erase_block = 0x40004120);
|
@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2015 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Stub template.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include "rom_functions.h"
|
||||||
|
|
||||||
|
/* Define the args vector and put it into the ".params" section. */
|
||||||
|
uint32_t params[3] __attribute__((section(".params")));
|
||||||
|
|
||||||
|
/* Define a function called stub_main. Do not return or reboot.
|
||||||
|
* Use send_packet to communicate to the host. */
|
||||||
|
|
||||||
|
const char *hello = "Hello";
|
||||||
|
|
||||||
|
void stub_main(void) {
|
||||||
|
send_packet(hello, 5);
|
||||||
|
_ResetVector();
|
||||||
|
}
|
14
src/mongoose-6.11/src/common/platforms/esp8266/stubs/uart.c
Normal file
14
src/mongoose-6.11/src/common/platforms/esp8266/stubs/uart.c
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart.h"
|
||||||
|
#include "ets_sys.h"
|
||||||
|
|
||||||
|
#define UART_CLKDIV_26MHZ(B) (52000000 + B / 2) / B
|
||||||
|
|
||||||
|
void set_baud_rate(uint32_t uart_no, uint32_t baud_rate) {
|
||||||
|
uint32_t div = UART_CLKDIV_26MHZ(baud_rate);
|
||||||
|
WRITE_PERI_REG(UART_CLKDIV_REG(uart_no), div & 0xfffff);
|
||||||
|
}
|
35
src/mongoose-6.11/src/common/platforms/esp8266/stubs/uart.h
Normal file
35
src/mongoose-6.11/src/common/platforms/esp8266/stubs/uart.h
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_STUBS_UART_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_STUBS_UART_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void set_baud_rate(uint32_t uart_no, uint32_t baud_rate);
|
||||||
|
|
||||||
|
#define REG_UART_BASE(i) (0x60000000 + (i) *0xf00)
|
||||||
|
#define UART_FIFO_REG(i) (REG_UART_BASE(i) + 0x0)
|
||||||
|
#define UART_CONF1_REG(i) (REG_UART_BASE(i) + 0x24)
|
||||||
|
#define UART_RX_TOUT_EN (BIT(31))
|
||||||
|
#define UART_RX_TOUT_THRHD_S 24
|
||||||
|
#define UART_RXFIFO_FULL_THRHD_S 0
|
||||||
|
#define UART_INT_ST_REG(i) (REG_UART_BASE(i) + 0x8)
|
||||||
|
#define UART_INT_ENA_REG(i) (REG_UART_BASE(i) + 0xC)
|
||||||
|
#define UART_RXFIFO_TOUT_INT_ENA (BIT(8))
|
||||||
|
#define UART_RXFIFO_FULL_INT_ENA (BIT(0))
|
||||||
|
|
||||||
|
#define UART_INT_CLR_REG(i) (REG_UART_BASE(i) + 0x10)
|
||||||
|
|
||||||
|
#define UART_CLKDIV_REG(i) (REG_UART_BASE(i) + 0x14)
|
||||||
|
|
||||||
|
#define UART_STATUS_REG(i) (REG_UART_BASE(i) + 0x1C)
|
||||||
|
|
||||||
|
#define UART_CONF0_REG(i) (REG_UART_BASE(i) + 0x20)
|
||||||
|
#define UART_RXFIFO_RST (BIT(17))
|
||||||
|
|
||||||
|
#define ETS_UART0_INUM ETS_UART_INUM
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_STUBS_UART_H_ */
|
@ -0,0 +1,23 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
# Analyzers output of firmware compiler with -DESP_ENABLE_MALLOC_TRACES
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
|
||||||
|
allocs = {}
|
||||||
|
|
||||||
|
for l in sys.stdin:
|
||||||
|
m = re.match(r'(ca|ma|re|fr) (\S+)\s*(\S*)\s*(\S*)', l)
|
||||||
|
if not m: continue
|
||||||
|
op = m.group(1)
|
||||||
|
if op in ('ca', 'ma'):
|
||||||
|
allocs[m.group(2)] = long(m.group(3))
|
||||||
|
else:
|
||||||
|
if m.group(2) in allocs:
|
||||||
|
del allocs[m.group(2)]
|
||||||
|
if op == 're':
|
||||||
|
allocs[m.group(3)] = long(m.group(4))
|
||||||
|
|
||||||
|
for k, v in sorted(allocs.iteritems()):
|
||||||
|
print k, v
|
136
src/mongoose-6.11/src/common/platforms/esp8266/uart_register.h
Normal file
136
src/mongoose-6.11/src/common/platforms/esp8266/uart_register.h
Normal file
@ -0,0 +1,136 @@
|
|||||||
|
/* clang-format off */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2010 - 2011 Espressif System
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_PLATFORMS_ESP8266_UART_REGISTER_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_ESP8266_UART_REGISTER_H_
|
||||||
|
|
||||||
|
#define REG_UART_BASE(i) (0x60000000 + (i)*0xf00)
|
||||||
|
//version value:32'h062000
|
||||||
|
|
||||||
|
#define UART_FIFO(i) (REG_UART_BASE(i) + 0x0)
|
||||||
|
#define UART_RXFIFO_RD_BYTE 0x000000FF
|
||||||
|
#define UART_RXFIFO_RD_BYTE_S 0
|
||||||
|
|
||||||
|
#define UART_INT_RAW(i) (REG_UART_BASE(i) + 0x4)
|
||||||
|
#define UART_RXFIFO_TOUT_INT_RAW (BIT(8))
|
||||||
|
#define UART_BRK_DET_INT_RAW (BIT(7))
|
||||||
|
#define UART_CTS_CHG_INT_RAW (BIT(6))
|
||||||
|
#define UART_DSR_CHG_INT_RAW (BIT(5))
|
||||||
|
#define UART_RXFIFO_OVF_INT_RAW (BIT(4))
|
||||||
|
#define UART_FRM_ERR_INT_RAW (BIT(3))
|
||||||
|
#define UART_PARITY_ERR_INT_RAW (BIT(2))
|
||||||
|
#define UART_TXFIFO_EMPTY_INT_RAW (BIT(1))
|
||||||
|
#define UART_RXFIFO_FULL_INT_RAW (BIT(0))
|
||||||
|
|
||||||
|
#define UART_INT_ST(i) (REG_UART_BASE(i) + 0x8)
|
||||||
|
#define UART_RXFIFO_TOUT_INT_ST (BIT(8))
|
||||||
|
#define UART_BRK_DET_INT_ST (BIT(7))
|
||||||
|
#define UART_CTS_CHG_INT_ST (BIT(6))
|
||||||
|
#define UART_DSR_CHG_INT_ST (BIT(5))
|
||||||
|
#define UART_RXFIFO_OVF_INT_ST (BIT(4))
|
||||||
|
#define UART_FRM_ERR_INT_ST (BIT(3))
|
||||||
|
#define UART_PARITY_ERR_INT_ST (BIT(2))
|
||||||
|
#define UART_TXFIFO_EMPTY_INT_ST (BIT(1))
|
||||||
|
#define UART_RXFIFO_FULL_INT_ST (BIT(0))
|
||||||
|
|
||||||
|
#define UART_INT_ENA(i) (REG_UART_BASE(i) + 0xC)
|
||||||
|
#define UART_RXFIFO_TOUT_INT_ENA (BIT(8))
|
||||||
|
#define UART_BRK_DET_INT_ENA (BIT(7))
|
||||||
|
#define UART_CTS_CHG_INT_ENA (BIT(6))
|
||||||
|
#define UART_DSR_CHG_INT_ENA (BIT(5))
|
||||||
|
#define UART_RXFIFO_OVF_INT_ENA (BIT(4))
|
||||||
|
#define UART_FRM_ERR_INT_ENA (BIT(3))
|
||||||
|
#define UART_PARITY_ERR_INT_ENA (BIT(2))
|
||||||
|
#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1))
|
||||||
|
#define UART_RXFIFO_FULL_INT_ENA (BIT(0))
|
||||||
|
|
||||||
|
#define UART_INT_CLR(i) (REG_UART_BASE(i) + 0x10)
|
||||||
|
#define UART_RXFIFO_TOUT_INT_CLR (BIT(8))
|
||||||
|
#define UART_BRK_DET_INT_CLR (BIT(7))
|
||||||
|
#define UART_CTS_CHG_INT_CLR (BIT(6))
|
||||||
|
#define UART_DSR_CHG_INT_CLR (BIT(5))
|
||||||
|
#define UART_RXFIFO_OVF_INT_CLR (BIT(4))
|
||||||
|
#define UART_FRM_ERR_INT_CLR (BIT(3))
|
||||||
|
#define UART_PARITY_ERR_INT_CLR (BIT(2))
|
||||||
|
#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1))
|
||||||
|
#define UART_RXFIFO_FULL_INT_CLR (BIT(0))
|
||||||
|
|
||||||
|
#define UART_CLKDIV(i) (REG_UART_BASE(i) + 0x14)
|
||||||
|
#define UART_CLKDIV_CNT 0x000FFFFF
|
||||||
|
#define UART_CLKDIV_S 0
|
||||||
|
|
||||||
|
#define UART_AUTOBAUD(i) (REG_UART_BASE(i) + 0x18)
|
||||||
|
#define UART_GLITCH_FILT 0x000000FF
|
||||||
|
#define UART_GLITCH_FILT_S 8
|
||||||
|
#define UART_AUTOBAUD_EN (BIT(0))
|
||||||
|
|
||||||
|
#define UART_STATUS(i) (REG_UART_BASE(i) + 0x1C)
|
||||||
|
#define UART_TXD (BIT(31))
|
||||||
|
#define UART_RTSN (BIT(30))
|
||||||
|
#define UART_DTRN (BIT(29))
|
||||||
|
#define UART_TXFIFO_CNT 0x000000FF
|
||||||
|
#define UART_TXFIFO_CNT_S 16
|
||||||
|
#define UART_RXD (BIT(15))
|
||||||
|
#define UART_CTSN (BIT(14))
|
||||||
|
#define UART_DSRN (BIT(13))
|
||||||
|
#define UART_RXFIFO_CNT 0x000000FF
|
||||||
|
#define UART_RXFIFO_CNT_S 0
|
||||||
|
|
||||||
|
#define UART_CONF0(i) (REG_UART_BASE(i) + 0x20)
|
||||||
|
#define UART_DTR_INV (BIT(24))
|
||||||
|
#define UART_RTS_INV (BIT(23))
|
||||||
|
#define UART_TXD_INV (BIT(22))
|
||||||
|
#define UART_DSR_INV (BIT(21))
|
||||||
|
#define UART_CTS_INV (BIT(20))
|
||||||
|
#define UART_RXD_INV (BIT(19))
|
||||||
|
#define UART_TXFIFO_RST (BIT(18))
|
||||||
|
#define UART_RXFIFO_RST (BIT(17))
|
||||||
|
#define UART_IRDA_EN (BIT(16))
|
||||||
|
#define UART_TX_FLOW_EN (BIT(15))
|
||||||
|
#define UART_LOOPBACK (BIT(14))
|
||||||
|
#define UART_IRDA_RX_INV (BIT(13))
|
||||||
|
#define UART_IRDA_TX_INV (BIT(12))
|
||||||
|
#define UART_IRDA_WCTL (BIT(11))
|
||||||
|
#define UART_IRDA_TX_EN (BIT(10))
|
||||||
|
#define UART_IRDA_DPLX (BIT(9))
|
||||||
|
#define UART_TXD_BRK (BIT(8))
|
||||||
|
#define UART_SW_DTR (BIT(7))
|
||||||
|
#define UART_SW_RTS (BIT(6))
|
||||||
|
#define UART_STOP_BIT_NUM 0x00000003
|
||||||
|
#define UART_STOP_BIT_NUM_S 4
|
||||||
|
#define UART_BIT_NUM 0x00000003
|
||||||
|
#define UART_BIT_NUM_S 2
|
||||||
|
#define UART_PARITY_EN (BIT(1))
|
||||||
|
#define UART_PARITY (BIT(0))
|
||||||
|
|
||||||
|
#define UART_CONF1(i) (REG_UART_BASE(i) + 0x24)
|
||||||
|
#define UART_RX_TOUT_EN (BIT(31))
|
||||||
|
#define UART_RX_TOUT_THRHD 0x0000007F
|
||||||
|
#define UART_RX_TOUT_THRHD_S 24
|
||||||
|
#define UART_RX_FLOW_EN (BIT(23))
|
||||||
|
#define UART_RX_FLOW_THRHD 0x0000007F
|
||||||
|
#define UART_RX_FLOW_THRHD_S 16
|
||||||
|
#define UART_TXFIFO_EMPTY_THRHD 0x0000007F
|
||||||
|
#define UART_TXFIFO_EMPTY_THRHD_S 8
|
||||||
|
#define UART_RXFIFO_FULL_THRHD 0x0000007F
|
||||||
|
#define UART_RXFIFO_FULL_THRHD_S 0
|
||||||
|
|
||||||
|
#define UART_LOWPULSE(i) (REG_UART_BASE(i) + 0x28)
|
||||||
|
#define UART_LOWPULSE_MIN_CNT 0x000FFFFF
|
||||||
|
#define UART_LOWPULSE_MIN_CNT_S 0
|
||||||
|
|
||||||
|
#define UART_HIGHPULSE(i) (REG_UART_BASE(i) + 0x2C)
|
||||||
|
#define UART_HIGHPULSE_MIN_CNT 0x000FFFFF
|
||||||
|
#define UART_HIGHPULSE_MIN_CNT_S 0
|
||||||
|
|
||||||
|
#define UART_PULSE_NUM(i) (REG_UART_BASE(i) + 0x30)
|
||||||
|
#define UART_PULSE_NUM_CNT 0x0003FF
|
||||||
|
#define UART_PULSE_NUM_CNT_S 0
|
||||||
|
|
||||||
|
#define UART_DATE(i) (REG_UART_BASE(i) + 0x78)
|
||||||
|
#define UART_ID(i) (REG_UART_BASE(i) + 0x7C)
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_ESP8266_UART_REGISTER_H_ */
|
69
src/mongoose-6.11/src/common/platforms/lwip/mg_lwip.h
Normal file
69
src/mongoose-6.11/src/common/platforms/lwip/mg_lwip.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
|
||||||
|
#define CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_
|
||||||
|
|
||||||
|
#ifndef MG_LWIP
|
||||||
|
#define MG_LWIP 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if MG_LWIP
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When compiling for nRF5x chips with arm-none-eabi-gcc, it has BYTE_ORDER
|
||||||
|
* already defined, so in order to avoid warnings in lwip, we have to undefine
|
||||||
|
* it.
|
||||||
|
*
|
||||||
|
* TODO: Check if in the future versions of nRF5 SDK that changes.
|
||||||
|
* Current version of nRF51 SDK: 0.8.0
|
||||||
|
* nRF5 SDK: 0.9.0
|
||||||
|
*/
|
||||||
|
#if CS_PLATFORM == CS_P_NRF51 || CS_PLATFORM == CS_P_NRF52
|
||||||
|
#undef BYTE_ORDER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <lwip/opt.h>
|
||||||
|
#include <lwip/err.h>
|
||||||
|
#include <lwip/ip_addr.h>
|
||||||
|
#include <lwip/inet.h>
|
||||||
|
#include <lwip/netdb.h>
|
||||||
|
#include <lwip/dns.h>
|
||||||
|
|
||||||
|
#ifndef LWIP_PROVIDE_ERRNO
|
||||||
|
#include <errno.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_SOCKET
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
#else
|
||||||
|
/* We really need the definitions from sockets.h. */
|
||||||
|
#undef LWIP_SOCKET
|
||||||
|
#define LWIP_SOCKET 1
|
||||||
|
#include <lwip/sockets.h>
|
||||||
|
#undef LWIP_SOCKET
|
||||||
|
#define LWIP_SOCKET 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define INVALID_SOCKET (-1)
|
||||||
|
#define SOMAXCONN 10
|
||||||
|
typedef int sock_t;
|
||||||
|
|
||||||
|
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
|
||||||
|
struct mg_mgr;
|
||||||
|
struct mg_connection;
|
||||||
|
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr);
|
||||||
|
void mg_lwip_set_keepalive_params(struct mg_connection *nc, int idle,
|
||||||
|
int interval, int count);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* For older version of LWIP */
|
||||||
|
#ifndef ipX_2_ip
|
||||||
|
#define ipX_2_ip(x) (x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* MG_LWIP */
|
||||||
|
|
||||||
|
#endif /* CS_COMMON_PLATFORMS_LWIP_MG_LWIP_H_ */
|
243
src/mongoose-6.11/src/common/platforms/lwip/mg_lwip_ev_mgr.c
Normal file
243
src/mongoose-6.11/src/common/platforms/lwip/mg_lwip_ev_mgr.c
Normal file
@ -0,0 +1,243 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2014-2016 Cesanta Software Limited
|
||||||
|
* All rights reserved
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL
|
||||||
|
|
||||||
|
#ifndef MG_SIG_QUEUE_LEN
|
||||||
|
#define MG_SIG_QUEUE_LEN 32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct mg_ev_mgr_lwip_signal {
|
||||||
|
int sig;
|
||||||
|
struct mg_connection *nc;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct mg_ev_mgr_lwip_data {
|
||||||
|
struct mg_ev_mgr_lwip_signal sig_queue[MG_SIG_QUEUE_LEN];
|
||||||
|
int sig_queue_len;
|
||||||
|
int start_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
void mg_lwip_post_signal(enum mg_sig_type sig, struct mg_connection *nc) {
|
||||||
|
struct mg_ev_mgr_lwip_data *md =
|
||||||
|
(struct mg_ev_mgr_lwip_data *) nc->iface->data;
|
||||||
|
mgos_lock();
|
||||||
|
if (md->sig_queue_len >= MG_SIG_QUEUE_LEN) {
|
||||||
|
mgos_unlock();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int end_index = (md->start_index + md->sig_queue_len) % MG_SIG_QUEUE_LEN;
|
||||||
|
md->sig_queue[end_index].sig = sig;
|
||||||
|
md->sig_queue[end_index].nc = nc;
|
||||||
|
md->sig_queue_len++;
|
||||||
|
mg_lwip_mgr_schedule_poll(nc->mgr);
|
||||||
|
mgos_unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mg_ev_mgr_lwip_process_signals(struct mg_mgr *mgr) {
|
||||||
|
struct mg_ev_mgr_lwip_data *md =
|
||||||
|
(struct mg_ev_mgr_lwip_data *) mgr->ifaces[MG_MAIN_IFACE]->data;
|
||||||
|
while (md->sig_queue_len > 0) {
|
||||||
|
mgos_lock();
|
||||||
|
int sig = md->sig_queue[md->start_index].sig;
|
||||||
|
struct mg_connection *nc = md->sig_queue[md->start_index].nc;
|
||||||
|
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
|
||||||
|
md->start_index = (md->start_index + 1) % MG_SIG_QUEUE_LEN;
|
||||||
|
md->sig_queue_len--;
|
||||||
|
mgos_unlock();
|
||||||
|
if (nc->iface == NULL || nc->mgr == NULL) continue;
|
||||||
|
switch (sig) {
|
||||||
|
case MG_SIG_CONNECT_RESULT: {
|
||||||
|
#if MG_ENABLE_SSL
|
||||||
|
if (cs->err == 0 && (nc->flags & MG_F_SSL) &&
|
||||||
|
!(nc->flags & MG_F_SSL_HANDSHAKE_DONE)) {
|
||||||
|
mg_lwip_ssl_do_hs(nc);
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
mg_if_connect_cb(nc, cs->err);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MG_SIG_CLOSE_CONN: {
|
||||||
|
nc->flags |= MG_F_SEND_AND_CLOSE;
|
||||||
|
mg_close_conn(nc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MG_SIG_RECV: {
|
||||||
|
cs->recv_pending = 0;
|
||||||
|
if (nc->flags & MG_F_UDP) {
|
||||||
|
mg_lwip_handle_recv_udp(nc);
|
||||||
|
} else {
|
||||||
|
mg_lwip_handle_recv_tcp(nc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MG_SIG_TOMBSTONE: {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MG_SIG_ACCEPT: {
|
||||||
|
mg_lwip_handle_accept(nc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void mg_lwip_if_init(struct mg_iface *iface) {
|
||||||
|
LOG(LL_INFO, ("%p Mongoose init", iface));
|
||||||
|
iface->data = MG_CALLOC(1, sizeof(struct mg_ev_mgr_lwip_data));
|
||||||
|
}
|
||||||
|
|
||||||
|
void mg_lwip_if_free(struct mg_iface *iface) {
|
||||||
|
MG_FREE(iface->data);
|
||||||
|
iface->data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mg_lwip_if_add_conn(struct mg_connection *nc) {
|
||||||
|
(void) nc;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mg_lwip_if_remove_conn(struct mg_connection *nc) {
|
||||||
|
struct mg_ev_mgr_lwip_data *md =
|
||||||
|
(struct mg_ev_mgr_lwip_data *) nc->iface->data;
|
||||||
|
/* Walk the queue and null-out further signals for this conn. */
|
||||||
|
for (int i = 0; i < MG_SIG_QUEUE_LEN; i++) {
|
||||||
|
if (md->sig_queue[i].nc == nc) {
|
||||||
|
md->sig_queue[i].sig = MG_SIG_TOMBSTONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
time_t mg_lwip_if_poll(struct mg_iface *iface, int timeout_ms) {
|
||||||
|
struct mg_mgr *mgr = iface->mgr;
|
||||||
|
int n = 0;
|
||||||
|
double now = mg_time();
|
||||||
|
struct mg_connection *nc, *tmp;
|
||||||
|
double min_timer = 0;
|
||||||
|
int num_timers = 0;
|
||||||
|
#if 0
|
||||||
|
DBG(("begin poll @%u", (unsigned int) (now * 1000)));
|
||||||
|
#endif
|
||||||
|
mg_ev_mgr_lwip_process_signals(mgr);
|
||||||
|
for (nc = mgr->active_connections; nc != NULL; nc = tmp) {
|
||||||
|
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
|
||||||
|
tmp = nc->next;
|
||||||
|
n++;
|
||||||
|
if ((nc->flags & MG_F_CLOSE_IMMEDIATELY) ||
|
||||||
|
((nc->flags & MG_F_SEND_AND_CLOSE) && (nc->flags & MG_F_UDP) &&
|
||||||
|
(nc->send_mbuf.len == 0))) {
|
||||||
|
mg_close_conn(nc);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
mg_if_poll(nc, now);
|
||||||
|
mg_if_timer(nc, now);
|
||||||
|
#if MG_ENABLE_SSL
|
||||||
|
if ((nc->flags & MG_F_SSL) && cs != NULL && cs->pcb.tcp != NULL &&
|
||||||
|
cs->pcb.tcp->state == ESTABLISHED) {
|
||||||
|
if (((nc->flags & MG_F_WANT_WRITE) ||
|
||||||
|
((nc->send_mbuf.len > 0) &&
|
||||||
|
(nc->flags & MG_F_SSL_HANDSHAKE_DONE))) &&
|
||||||
|
cs->pcb.tcp->snd_buf > 0) {
|
||||||
|
/* Can write more. */
|
||||||
|
if (nc->flags & MG_F_SSL_HANDSHAKE_DONE) {
|
||||||
|
if (!(nc->flags & MG_F_CONNECTING)) mg_lwip_ssl_send(nc);
|
||||||
|
} else {
|
||||||
|
mg_lwip_ssl_do_hs(nc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cs->rx_chain != NULL || (nc->flags & MG_F_WANT_READ)) {
|
||||||
|
if (nc->flags & MG_F_SSL_HANDSHAKE_DONE) {
|
||||||
|
if (!(nc->flags & MG_F_CONNECTING)) mg_lwip_ssl_recv(nc);
|
||||||
|
} else {
|
||||||
|
mg_lwip_ssl_do_hs(nc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
#endif /* MG_ENABLE_SSL */
|
||||||
|
{
|
||||||
|
if (nc->send_mbuf.len > 0 && !(nc->flags & MG_F_CONNECTING)) {
|
||||||
|
mg_lwip_send_more(nc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (nc->sock != INVALID_SOCKET &&
|
||||||
|
!(nc->flags & (MG_F_UDP | MG_F_LISTENING)) && cs->pcb.tcp != NULL &&
|
||||||
|
cs->pcb.tcp->unsent != NULL) {
|
||||||
|
tcpip_callback(tcp_output_tcpip, cs->pcb.tcp);
|
||||||
|
}
|
||||||
|
if (nc->ev_timer_time > 0) {
|
||||||
|
if (num_timers == 0 || nc->ev_timer_time < min_timer) {
|
||||||
|
min_timer = nc->ev_timer_time;
|
||||||
|
}
|
||||||
|
num_timers++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nc->sock != INVALID_SOCKET) {
|
||||||
|
/* Try to consume data from cs->rx_chain */
|
||||||
|
mg_lwip_consume_rx_chain_tcp(nc);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the connection is about to close, and rx_chain is finally empty,
|
||||||
|
* send the MG_SIG_CLOSE_CONN signal
|
||||||
|
*/
|
||||||
|
if (cs->draining_rx_chain && cs->rx_chain == NULL) {
|
||||||
|
mg_lwip_post_signal(MG_SIG_CLOSE_CONN, nc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if 0
|
||||||
|
DBG(("end poll @%u, %d conns, %d timers (min %u), next in %d ms",
|
||||||
|
(unsigned int) (now * 1000), n, num_timers,
|
||||||
|
(unsigned int) (min_timer * 1000), timeout_ms));
|
||||||
|
#endif
|
||||||
|
(void) timeout_ms;
|
||||||
|
return now;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t mg_lwip_get_poll_delay_ms(struct mg_mgr *mgr) {
|
||||||
|
struct mg_connection *nc;
|
||||||
|
double now;
|
||||||
|
double min_timer = 0;
|
||||||
|
int num_timers = 0;
|
||||||
|
mg_ev_mgr_lwip_process_signals(mgr);
|
||||||
|
for (nc = mg_next(mgr, NULL); nc != NULL; nc = mg_next(mgr, nc)) {
|
||||||
|
struct mg_lwip_conn_state *cs = (struct mg_lwip_conn_state *) nc->sock;
|
||||||
|
if (nc->ev_timer_time > 0) {
|
||||||
|
if (num_timers == 0 || nc->ev_timer_time < min_timer) {
|
||||||
|
min_timer = nc->ev_timer_time;
|
||||||
|
}
|
||||||
|
num_timers++;
|
||||||
|
}
|
||||||
|
if (nc->send_mbuf.len > 0
|
||||||
|
#if MG_ENABLE_SSL
|
||||||
|
|| (nc->flags & MG_F_WANT_WRITE)
|
||||||
|
#endif
|
||||||
|
) {
|
||||||
|
int can_send = 0;
|
||||||
|
/* We have stuff to send, but can we? */
|
||||||
|
if (nc->flags & MG_F_UDP) {
|
||||||
|
/* UDP is always ready for sending. */
|
||||||
|
can_send = (cs->pcb.udp != NULL);
|
||||||
|
} else {
|
||||||
|
can_send = (cs->pcb.tcp != NULL && cs->pcb.tcp->snd_buf > 0);
|
||||||
|
}
|
||||||
|
/* We want and can send, request a poll immediately. */
|
||||||
|
if (can_send) return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32_t timeout_ms = ~0;
|
||||||
|
now = mg_time();
|
||||||
|
if (num_timers > 0) {
|
||||||
|
/* If we have a timer that is past due, do a poll ASAP. */
|
||||||
|
if (min_timer < now) return 0;
|
||||||
|
double timer_timeout_ms = (min_timer - now) * 1000 + 1 /* rounding */;
|
||||||
|
if (timer_timeout_ms < timeout_ms) {
|
||||||
|
timeout_ms = timer_timeout_ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return timeout_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* MG_NET_IF == MG_NET_IF_LWIP_LOW_LEVEL */
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user