未验证 提交 f49c854f 编写于 作者: M Me No Dev 提交者: GitHub

Update IDF to 97eecfa, enable reboot on WDT and add WDT API (#2248)

* Update IDF to 97eecfa and enable reboot on WDT

* Add API to enable/disable WDT for Core 1 and Arduino Loop
上级 879388e1
......@@ -28,6 +28,7 @@
#include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h"
#include "rom/rtc.h"
#include "esp_task_wdt.h"
#include "esp32-hal.h"
//Undocumented!!! Get chip temperature in Farenheit
......@@ -44,6 +45,47 @@ void yield()
vPortYield();
}
#if CONFIG_AUTOSTART_ARDUINO
extern TaskHandle_t loopTaskHandle;
extern bool loopTaskWDTEnabled;
void enableLoopWDT(){
if(loopTaskHandle != NULL){
if(esp_task_wdt_add(loopTaskHandle) != ESP_OK){
log_e("Failed to add loop task to WDT");
} else {
loopTaskWDTEnabled = true;
}
}
}
void disableLoopWDT(){
if(loopTaskHandle != NULL && loopTaskWDTEnabled){
loopTaskWDTEnabled = false;
if(esp_task_wdt_delete(loopTaskHandle) != ESP_OK){
log_e("Failed to remove loop task from WDT");
}
}
}
#endif
#ifndef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1
void enableCore1WDT(){
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
if(idle_1 == NULL || esp_task_wdt_add(idle_1) != ESP_OK){
log_e("Failed to add Core 1 IDLE task to WDT");
}
}
void disableCore1WDT(){
TaskHandle_t idle_1 = xTaskGetIdleTaskHandleForCPU(1);
if(idle_1 == NULL || esp_task_wdt_delete(idle_1) != ESP_OK){
log_e("Failed to remove Core 1 IDLE task from WDT");
}
}
#endif
static uint32_t _cpu_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
static uint32_t _sys_time_multiplier = 1;
......
......@@ -72,6 +72,18 @@ void yield(void);
//returns chip temperature in Celsius
float temperatureRead();
#if CONFIG_AUTOSTART_ARDUINO
//enable/disable WDT for Arduino's setup and loop functions
void enableLoopWDT();
void disableLoopWDT();
#endif
#ifndef CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1
//enable/disable WDT for the IDLE task on Core 1
void enableCore1WDT();
void disableCore1WDT();
#endif
//function takes the following frequencies as valid values:
// 240, 160, 80 <<< For all XTAL types
// 40, 20, 13, 10, 8, 5, 4, 3, 2, 1 <<< For 40MHz XTAL
......
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_task_wdt.h"
#include "Arduino.h"
TaskHandle_t loopTaskHandle = NULL;
#if CONFIG_AUTOSTART_ARDUINO
#if CONFIG_FREERTOS_UNICORE
......@@ -10,18 +13,24 @@
#define ARDUINO_RUNNING_CORE 1
#endif
bool loopTaskWDTEnabled;
void loopTask(void *pvParameters)
{
setup();
for(;;) {
if(loopTaskWDTEnabled){
esp_task_wdt_reset();
}
loop();
}
}
extern "C" void app_main()
{
loopTaskWDTEnabled = false;
initArduino();
xTaskCreatePinnedToCore(loopTask, "loopTask", 8192, NULL, 1, NULL, ARDUINO_RUNNING_CORE);
xTaskCreatePinnedToCore(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
}
#endif
......@@ -32,7 +32,7 @@ import binascii
import errno
MAX_PARTITION_LENGTH = 0xC00 # 3K for partition data (96 entries) leaves 1K in a 4K sector for signature
MD5_PARTITION_BEGIN = b"\xEB\xEB" + b"\xFF" * 14 # The first 2 bytes are like magic numbers for MD5 sum
MD5_PARTITION_BEGIN = b"\xEB\xEB" + b"\xFF" * 14 # The first 2 bytes are like magic numbers for MD5 sum
PARTITION_TABLE_SIZE = 0x1000 # Size of partition table
MIN_PARTITION_SUBTYPE_APP_OTA = 0x10
......@@ -44,25 +44,25 @@ APP_TYPE = 0x00
DATA_TYPE = 0x01
TYPES = {
"app" : APP_TYPE,
"data" : DATA_TYPE,
"app": APP_TYPE,
"data": DATA_TYPE,
}
# Keep this map in sync with esp_partition_subtype_t enum in esp_partition.h
SUBTYPES = {
APP_TYPE : {
"factory" : 0x00,
"test" : 0x20,
APP_TYPE: {
"factory": 0x00,
"test": 0x20,
},
DATA_TYPE : {
"ota" : 0x00,
"phy" : 0x01,
"nvs" : 0x02,
"coredump" : 0x03,
"nvs_keys" : 0x04,
"esphttpd" : 0x80,
"fat" : 0x81,
"spiffs" : 0x82,
DATA_TYPE: {
"ota": 0x00,
"phy": 0x01,
"nvs": 0x02,
"coredump": 0x03,
"nvs_keys": 0x04,
"esphttpd": 0x80,
"fat": 0x81,
"spiffs": 0x82,
},
}
......@@ -71,16 +71,19 @@ md5sum = True
secure = False
offset_part_table = 0
def status(msg):
""" Print status message to stderr """
if not quiet:
critical(msg)
def critical(msg):
""" Print critical message to stderr """
sys.stderr.write(msg)
sys.stderr.write('\n')
class PartitionTable(list):
def __init__(self):
super(PartitionTable, self).__init__(self)
......@@ -102,15 +105,15 @@ class PartitionTable(list):
if line.startswith("#") or len(line) == 0:
continue
try:
res.append(PartitionDefinition.from_csv(line, line_no+1))
res.append(PartitionDefinition.from_csv(line, line_no + 1))
except InputError as e:
raise InputError("Error at line %d: %s" % (line_no+1, e))
raise InputError("Error at line %d: %s" % (line_no + 1, e))
except Exception:
critical("Unexpected error parsing CSV line %d: %s" % (line_no+1, line))
critical("Unexpected error parsing CSV line %d: %s" % (line_no + 1, line))
raise
# fix up missing offsets & negative sizes
last_end = offset_part_table + PARTITION_TABLE_SIZE # first offset after partition table
last_end = offset_part_table + PARTITION_TABLE_SIZE # first offset after partition table
for e in res:
if e.offset is not None and e.offset < last_end:
if e == res[0]:
......@@ -149,14 +152,14 @@ class PartitionTable(list):
ptype = TYPES[ptype]
except KeyError:
try:
ptypes = int(ptype, 0)
ptype = int(ptype, 0)
except TypeError:
pass
try:
subtype = SUBTYPES[int(ptype)][subtype]
except KeyError:
try:
ptypes = int(ptype, 0)
ptype = int(ptype, 0)
except TypeError:
pass
......@@ -175,11 +178,11 @@ class PartitionTable(list):
# verify each partition individually
for p in self:
p.verify()
# check on duplicate name
names = [ p.name for p in self ]
duplicates = set( n for n in names if names.count(n) > 1 )
names = [p.name for p in self]
duplicates = set(n for n in names if names.count(n) > 1)
# print sorted duplicate partitions by name
if len(duplicates) != 0:
print("A list of partitions that have the same name:")
......@@ -187,14 +190,14 @@ class PartitionTable(list):
if len(duplicates.intersection([p.name])) != 0:
print("%s" % (p.to_csv()))
raise InputError("Partition names must be unique")
# check for overlaps
last = None
for p in sorted(self, key=lambda x:x.offset):
if p.offset < offset_part_table + PARTITION_TABLE_SIZE:
raise InputError("Partition offset 0x%x is below 0x%x" % (p.offset, offset_part_table + PARTITION_TABLE_SIZE))
if last is not None and p.offset < last.offset + last.size:
raise InputError("Partition at 0x%x overlaps 0x%x-0x%x" % (p.offset, last.offset, last.offset+last.size-1))
raise InputError("Partition at 0x%x overlaps 0x%x-0x%x" % (p.offset, last.offset, last.offset + last.size - 1))
last = p
def flash_size(self):
......@@ -209,17 +212,17 @@ class PartitionTable(list):
@classmethod
def from_binary(cls, b):
md5 = hashlib.md5();
md5 = hashlib.md5()
result = cls()
for o in range(0,len(b),32):
data = b[o:o+32]
data = b[o:o + 32]
if len(data) != 32:
raise InputError("Partition table length must be a multiple of 32 bytes")
if data == b'\xFF'*32:
if data == b'\xFF' * 32:
return result # got end marker
if md5sum and data[:2] == MD5_PARTITION_BEGIN[:2]: #check only the magic number part
if md5sum and data[:2] == MD5_PARTITION_BEGIN[:2]: # check only the magic number part
if data[16:] == md5.digest():
continue # the next iteration will check for the end marker
continue # the next iteration will check for the end marker
else:
raise InputError("MD5 checksums don't match! (computed: 0x%s, parsed: 0x%s)" % (md5.hexdigest(), binascii.hexlify(data[16:])))
else:
......@@ -231,29 +234,30 @@ class PartitionTable(list):
result = b"".join(e.to_binary() for e in self)
if md5sum:
result += MD5_PARTITION_BEGIN + hashlib.md5(result).digest()
if len(result )>= MAX_PARTITION_LENGTH:
if len(result) >= MAX_PARTITION_LENGTH:
raise InputError("Binary partition table length (%d) longer than max" % len(result))
result += b"\xFF" * (MAX_PARTITION_LENGTH - len(result)) # pad the sector, for signing
return result
def to_csv(self, simple_formatting=False):
rows = [ "# Espressif ESP32 Partition Table",
"# Name, Type, SubType, Offset, Size, Flags" ]
rows += [ x.to_csv(simple_formatting) for x in self ]
rows = ["# Espressif ESP32 Partition Table",
"# Name, Type, SubType, Offset, Size, Flags"]
rows += [x.to_csv(simple_formatting) for x in self]
return "\n".join(rows) + "\n"
class PartitionDefinition(object):
MAGIC_BYTES = b"\xAA\x50"
ALIGNMENT = {
APP_TYPE : 0x10000,
DATA_TYPE : 0x04,
APP_TYPE: 0x10000,
DATA_TYPE: 0x04,
}
# dictionary maps flag name (as used in CSV flags list, property name)
# to bit set in flags words in binary format
FLAGS = {
"encrypted" : 0
"encrypted": 0
}
# add subtypes for the 16 OTA slot values ("ota_XX, etc.")
......@@ -272,7 +276,7 @@ class PartitionDefinition(object):
def from_csv(cls, line, line_no):
""" Parse a line from the CSV """
line_w_defaults = line + ",,,," # lazy way to support default fields
fields = [ f.strip() for f in line_w_defaults.split(",") ]
fields = [f.strip() for f in line_w_defaults.split(",")]
res = PartitionDefinition()
res.line_no = line_no
......@@ -302,7 +306,7 @@ class PartitionDefinition(object):
def maybe_hex(x):
return "0x%x" % x if x is not None else "None"
return "PartitionDefinition('%s', 0x%x, 0x%x, %s, %s)" % (self.name, self.type, self.subtype or 0,
maybe_hex(self.offset), maybe_hex(self.size))
maybe_hex(self.offset), maybe_hex(self.size))
def __str__(self):
return "Part '%s' %d/%d @ 0x%x size 0x%x" % (self.name, self.type, self.subtype, self.offset or -1, self.size or -1)
......@@ -329,7 +333,7 @@ class PartitionDefinition(object):
def parse_subtype(self, strval):
if strval == "":
return 0 # default
return 0 # default
return parse_int(strval, SUBTYPES.get(self.type, {}))
def parse_address(self, strval):
......@@ -353,12 +357,14 @@ class PartitionDefinition(object):
raise ValidationError(self, "Size field is not set")
if self.name in TYPES and TYPES.get(self.name, "") != self.type:
critical("WARNING: Partition has name '%s' which is a partition type, but does not match this partition's type (0x%x). Mistake in partition table?" % (self.name, self.type))
critical("WARNING: Partition has name '%s' which is a partition type, but does not match this partition's "
"type (0x%x). Mistake in partition table?" % (self.name, self.type))
all_subtype_names = []
for names in (t.keys() for t in SUBTYPES.values()):
all_subtype_names += names
if self.name in all_subtype_names and SUBTYPES.get(self.type, {}).get(self.name, "") != self.subtype:
critical("WARNING: Partition has name '%s' which is a partition subtype, but this partition has non-matching type 0x%x and subtype 0x%x. Mistake in partition table?" % (self.name, self.type, self.subtype))
critical("WARNING: Partition has name '%s' which is a partition subtype, but this partition has "
"non-matching type 0x%x and subtype 0x%x. Mistake in partition table?" % (self.name, self.type, self.subtype))
STRUCT_FORMAT = b"<2sBBLL16sL"
......@@ -369,21 +375,21 @@ class PartitionDefinition(object):
res = cls()
(magic, res.type, res.subtype, res.offset,
res.size, res.name, flags) = struct.unpack(cls.STRUCT_FORMAT, b)
if b"\x00" in res.name: # strip null byte padding from name string
if b"\x00" in res.name: # strip null byte padding from name string
res.name = res.name[:res.name.index(b"\x00")]
res.name = res.name.decode()
if magic != cls.MAGIC_BYTES:
raise InputError("Invalid magic bytes (%r) for partition definition" % magic)
for flag,bit in cls.FLAGS.items():
if flags & (1<<bit):
if flags & (1 << bit):
setattr(res, flag, True)
flags &= ~(1<<bit)
flags &= ~(1 << bit)
if flags != 0:
critical("WARNING: Partition definition had unknown flag(s) 0x%08x. Newer binary format?" % flags)
return res
def get_flags_list(self):
return [ flag for flag in self.FLAGS.keys() if getattr(self, flag) ]
return [flag for flag in self.FLAGS.keys() if getattr(self, flag)]
def to_binary(self):
flags = sum((1 << self.FLAGS[flag]) for flag in self.get_flags_list())
......@@ -397,14 +403,14 @@ class PartitionDefinition(object):
def to_csv(self, simple_formatting=False):
def addr_format(a, include_sizes):
if not simple_formatting and include_sizes:
for (val, suffix) in [ (0x100000, "M"), (0x400, "K") ]:
for (val, suffix) in [(0x100000, "M"), (0x400, "K")]:
if a % val == 0:
return "%d%s" % (a // val, suffix)
return "0x%x" % a
def lookup_keyword(t, keywords):
for k,v in keywords.items():
if simple_formatting == False and t == v:
if simple_formatting is False and t == v:
return k
return "%d" % t
......@@ -412,12 +418,12 @@ class PartitionDefinition(object):
""" colon-delimited list of flags """
return ":".join(self.get_flags_list())
return ",".join([ self.name,
lookup_keyword(self.type, TYPES),
lookup_keyword(self.subtype, SUBTYPES.get(self.type, {})),
addr_format(self.offset, False),
addr_format(self.size, True),
generate_text_flags()])
return ",".join([self.name,
lookup_keyword(self.type, TYPES),
lookup_keyword(self.subtype, SUBTYPES.get(self.type, {})),
addr_format(self.offset, False),
addr_format(self.size, True),
generate_text_flags()])
def parse_int(v, keywords={}):
......@@ -425,7 +431,7 @@ def parse_int(v, keywords={}):
k/m/K/M suffixes and 'keyword' value lookup.
"""
try:
for letter, multiplier in [ ("k",1024), ("m",1024*1024) ]:
for letter, multiplier in [("k", 1024), ("m", 1024 * 1024)]:
if v.lower().endswith(letter):
return parse_int(v[:-1], keywords) * multiplier
return int(v, 0)
......@@ -437,6 +443,7 @@ def parse_int(v, keywords={}):
except KeyError:
raise InputError("Value '%s' is not valid. Known keywords: %s" % (v, ", ".join(keywords)))
def main():
global quiet
global md5sum
......@@ -445,10 +452,11 @@ def main():
parser = argparse.ArgumentParser(description='ESP32 partition table utility')
parser.add_argument('--flash-size', help='Optional flash size limit, checks partition table fits in flash',
nargs='?', choices=[ '1MB', '2MB', '4MB', '8MB', '16MB' ])
nargs='?', choices=['1MB', '2MB', '4MB', '8MB', '16MB'])
parser.add_argument('--disable-md5sum', help='Disable md5 checksum for the partition table', default=False, action='store_true')
parser.add_argument('--no-verify', help="Don't verify partition table fields", action='store_true')
parser.add_argument('--verify', '-v', help="Verify partition table fields (deprecated, this behaviour is enabled by default and this flag does nothing.", action='store_true')
parser.add_argument('--verify', '-v', help="Verify partition table fields (deprecated, this behaviour is "
"enabled by default and this flag does nothing.", action='store_true')
parser.add_argument('--quiet', '-q', help="Don't print non-critical status messages to stderr", action='store_true')
parser.add_argument('--offset', '-o', help='Set offset partition table', default='0x8000')
parser.add_argument('--secure', help="Require app partitions to be suitable for secure boot", action='store_true')
......@@ -481,7 +489,8 @@ def main():
size = size_mb * 1024 * 1024 # flash memory uses honest megabytes!
table_size = table.flash_size()
if size < table_size:
raise InputError("Partitions defined in '%s' occupy %.1fMB of flash (%d bytes) which does not fit in configured flash size %dMB. Change the flash size in menuconfig under the 'Serial Flasher Config' menu." %
raise InputError("Partitions defined in '%s' occupy %.1fMB of flash (%d bytes) which does not fit in configured "
"flash size %dMB. Change the flash size in menuconfig under the 'Serial Flasher Config' menu." %
(args.input.name, table_size / 1024.0 / 1024.0, table_size, size_mb))
# Make sure that the output directory is created
......@@ -490,7 +499,7 @@ def main():
if not os.path.exists(output_dir):
try:
os.makedirs(output_dir)
except OSError as exc:
except OSError as exc:
if exc.errno != errno.EEXIST:
raise
......
......@@ -21,6 +21,7 @@
#include "esp_err.h"
#include "esp_partition.h"
#include "esp_image_format.h"
#include "esp_flash_data_types.h"
#ifdef __cplusplus
extern "C"
......@@ -195,6 +196,52 @@ const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *
*/
esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, esp_app_desc_t *app_desc);
/**
* @brief This function is called to indicate that the running app is working well.
*
* @return
* - ESP_OK: if successful.
*/
esp_err_t esp_ota_mark_app_valid_cancel_rollback();
/**
* @brief This function is called to roll back to the previously workable app with reboot.
*
* If rollback is successful then device will reset else API will return with error code.
* @return
* - ESP_FAIL: if not successful.
*/
esp_err_t esp_ota_mark_app_invalid_rollback_and_reboot();
/**
* @brief Returns last partition with invalid state (ESP_OTA_IMG_INVALID or ESP_OTA_IMG_ABORTED).
*
* @return partition.
*/
const esp_partition_t* esp_ota_get_last_invalid_partition();
/**
* @brief Returns state for given partition.
*
* @param[in] partition Pointer to partition.
* @param[out] ota_state state of partition (if this partition has a record in otadata).
* @return
* - ESP_OK: Successful.
* - ESP_ERR_INVALID_ARG: partition or ota_state arguments were NULL.
* - ESP_ERR_NOT_SUPPORTED: partition is not ota.
* - ESP_ERR_NOT_FOUND: Partition table does not have otadata or state was not found for given partition.
*/
esp_err_t esp_ota_get_state_partition(const esp_partition_t *partition, esp_ota_img_states_t *ota_state);
/**
* @brief Erase previous boot app partition and corresponding otadata select for this partition.
*
* When current app is marked to as valid then you can erase previous app partition.
* @return
* - ESP_OK: Successful, otherwise ESP_ERR.
*/
esp_err_t esp_ota_erase_last_boot_app_partition(void);
#ifdef __cplusplus
}
#endif
......
......@@ -87,7 +87,6 @@
#define CONFIG_TCPIP_TASK_AFFINITY_CPU0 1
#define CONFIG_FATFS_CODEPAGE 850
#define CONFIG_ULP_COPROC_RESERVE_MEM 512
#define CONFIG_MB_UART_RXD 34
#define CONFIG_LWIP_MAX_UDP_PCBS 16
#define CONFIG_ESPTOOLPY_BAUD 921600
#define CONFIG_INT_WDT_CHECK_CPU1 1
......@@ -173,7 +172,6 @@
#define CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_PSK 1
#define CONFIG_TCP_SYNMAXRTX 6
#define CONFIG_MB_UART_RTS 32
#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA 1
#define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF 0
#define CONFIG_HEAP_POISONING_LIGHT 1
......@@ -266,7 +264,6 @@
#define CONFIG_FREERTOS_INTERRUPT_BACKTRACE 1
#define CONFIG_WL_SECTOR_SIZE 4096
#define CONFIG_ESP32_DEBUG_OCDAWARE 1
#define CONFIG_MB_UART_TXD 33
#define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1
#define CONFIG_TIMER_TASK_PRIORITY 1
#define CONFIG_PPP_PAP_SUPPORT 1
......@@ -274,6 +271,7 @@
#define CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI 1
#define CONFIG_BT_ENABLED 1
#define CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY 1
#define CONFIG_BT_SSP_ENABLED 1
#define CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED 1
#define CONFIG_MONITOR_BAUD 115200
#define CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT -1
......@@ -335,6 +333,7 @@
#define CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF 1
#define CONFIG_ESPTOOLPY_PORT "/dev/cu.usbserial-DO00EAB0"
#define CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS 1
#define CONFIG_TASK_WDT_PANIC 1
#define CONFIG_UNITY_ENABLE_DOUBLE 1
#define CONFIG_BLUEDROID_PINNED_TO_CORE 0
#define CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG 1
......
......@@ -20,11 +20,11 @@
//and all variables in shared RAM. These macros can be used to redirect
//particular functions/variables to other memory regions.
// Forces code into IRAM instead of flash.
#define IRAM_ATTR __attribute__((section(".iram1")))
// Forces code into IRAM instead of flash
#define IRAM_ATTR _SECTION_ATTR_IMPL(".iram1", __COUNTER__)
// Forces data into DRAM instead of flash
#define DRAM_ATTR __attribute__((section(".dram1")))
#define DRAM_ATTR _SECTION_ATTR_IMPL(".dram1", __COUNTER__)
// Forces data to be 4 bytes aligned
#define WORD_ALIGNED_ATTR __attribute__((aligned(4)))
......@@ -37,11 +37,11 @@
#define DRAM_STR(str) (__extension__({static const DRAM_ATTR char __c[] = (str); (const char *)&__c;}))
// Forces code into RTC fast memory. See "docs/deep-sleep-stub.rst"
#define RTC_IRAM_ATTR __attribute__((section(".rtc.text")))
#define RTC_IRAM_ATTR _SECTION_ATTR_IMPL(".rtc.text", __COUNTER__)
#if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
// Forces bss variable into external memory. "
#define EXT_RAM_ATTR __attribute__((section(".ext_ram.bss")))
#define EXT_RAM_ATTR _SECTION_ATTR_IMPL(".ext_ram.bss", __COUNTER__)
#else
#define EXT_RAM_ATTR
#endif
......@@ -49,26 +49,37 @@
// Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst"
// Any variable marked with this attribute will keep its value
// during a deep sleep / wake cycle.
#define RTC_DATA_ATTR __attribute__((section(".rtc.data")))
#define RTC_DATA_ATTR _SECTION_ATTR_IMPL(".rtc.data", __COUNTER__)
// Forces read-only data into RTC memory. See "docs/deep-sleep-stub.rst"
#define RTC_RODATA_ATTR __attribute__((section(".rtc.rodata")))
#define RTC_RODATA_ATTR _SECTION_ATTR_IMPL(".rtc.rodata", __COUNTER__)
// Allows to place data into RTC_SLOW memory.
#define RTC_SLOW_ATTR __attribute__((section(".rtc.force_slow")))
#define RTC_SLOW_ATTR _SECTION_ATTR_IMPL(".rtc.force_slow", __COUNTER__)
// Allows to place data into RTC_FAST memory.
#define RTC_FAST_ATTR __attribute__((section(".rtc.force_fast")))
#define RTC_FAST_ATTR _SECTION_ATTR_IMPL(".rtc.force_fast", __COUNTER__)
// Forces data into noinit section to avoid initialization after restart.
#define __NOINIT_ATTR __attribute__((section(".noinit")))
#define __NOINIT_ATTR _SECTION_ATTR_IMPL(".noinit", __COUNTER__)
// Forces data into RTC slow memory of .noinit section.
// Any variable marked with this attribute will keep its value
// after restart or during a deep sleep / wake cycle.
#define RTC_NOINIT_ATTR __attribute__((section(".rtc_noinit")))
#define RTC_NOINIT_ATTR _SECTION_ATTR_IMPL(".rtc_noinit", __COUNTER__)
// Forces to not inline function
#define NOINLINE_ATTR __attribute__((noinline))
// Implementation for a unique custom section
//
// This prevents gcc producing "x causes a section type conflict with y"
// errors if two variables in the same source file have different linkage (maybe const & non-const) but are placed in the same custom section
//
// Using unique sections also means --gc-sections can remove unused
// data with a custom section type set
#define _SECTION_ATTR_IMPL(SECTION, COUNTER) __attribute__((section(SECTION "." _COUNTER_STRINGIFY(COUNTER))))
#define _COUNTER_STRINGIFY(COUNTER) #COUNTER
#endif /* __ESP_ATTR_H__ */
......@@ -24,11 +24,22 @@ extern "C"
#define ESP_PARTITION_MAGIC 0x50AA
#define ESP_PARTITION_MAGIC_MD5 0xEBEB
/// OTA_DATA states for checking operability of the app.
typedef enum {
ESP_OTA_IMG_NEW = 0x0U, /*!< Monitor the first boot. In bootloader this state is changed to ESP_OTA_IMG_PENDING_VERIFY. */
ESP_OTA_IMG_PENDING_VERIFY = 0x1U, /*!< First boot for this app was. If while the second boot this state is then it will be changed to ABORTED. */
ESP_OTA_IMG_VALID = 0x2U, /*!< App was confirmed as workable. App can boot and work without limits. */
ESP_OTA_IMG_INVALID = 0x3U, /*!< App was confirmed as non-workable. This app will not selected to boot at all. */
ESP_OTA_IMG_ABORTED = 0x4U, /*!< App could not confirm the workable or non-workable. In bootloader IMG_PENDING_VERIFY state will be changed to IMG_ABORTED. This app will not selected to boot at all. */
ESP_OTA_IMG_UNDEFINED = 0xFFFFFFFFU, /*!< Undefined. App can boot and work without limits. */
} esp_ota_img_states_t;
/* OTA selection structure (two copies in the OTA data partition.)
Size of 32 bytes is friendly to flash encryption */
typedef struct {
uint32_t ota_seq;
uint8_t seq_label[24];
uint8_t seq_label[20];
uint32_t ota_state;
uint32_t crc; /* CRC32 of ota_seq field only */
} esp_ota_select_entry_t;
......
......@@ -624,6 +624,7 @@ esp_err_t esp_mesh_stop(void);
* - If the packet is to an external IP network, set this parameter to the IPv4:PORT combination.
* This packet will be delivered to the root firstly, then the root will forward this packet to the final IP server address.
* @param[in] data pointer to a sending mesh packet
* - Field size should not exceed MESH_MPS. Note that the size of one mesh packet should not exceed MESH_MTU.
* - Field proto should be set to data protocol in use (default is MESH_PROTO_BIN for binary).
* - Field tos should be set to transmission tos (type of service) in use (default is MESH_TOS_P2P for point-to-point reliable).
* @param[in] flag bitmap for data sent
......@@ -1440,6 +1441,14 @@ esp_err_t esp_mesh_disconnect(void);
*/
esp_err_t esp_mesh_connect(void);
/**
* @brief Flush scan result
*
* @return
* - ESP_OK
*/
esp_err_t esp_mesh_flush_scan_result(void);
/**
* @brief Cause the root device to add Channel Switch Announcement Element (CSA IE) to beacon
* - Set the new channel
......@@ -1457,6 +1466,18 @@ esp_err_t esp_mesh_connect(void);
*/
esp_err_t esp_mesh_switch_channel(const uint8_t *new_bssid, int csa_newchan, int csa_count);
/**
* @brief Get the router BSSID
*
* @param[out] router_bssid pointer to the router BSSID
*
* @return
* - ESP_OK
* - ESP_ERR_WIFI_NOT_INIT
* - ESP_ERR_WIFI_ARG
*/
esp_err_t esp_mesh_get_router_bssid(uint8_t *router_bssid);
#ifdef __cplusplus
}
#endif
......
// Copyright 2015-2018 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#pragma once
#include "tcpip_adapter.h"
#include "rom/queue.h"
struct tcpip_adapter_api_msg_s;
typedef int (*tcpip_adapter_api_fn)(struct tcpip_adapter_api_msg_s *msg);
typedef struct tcpip_adapter_api_msg_s {
int type; /**< The first field MUST be int */
int ret;
tcpip_adapter_api_fn api_fn;
tcpip_adapter_if_t tcpip_if;
tcpip_adapter_ip_info_t *ip_info;
uint8_t *mac;
void *data;
} tcpip_adapter_api_msg_t;
typedef struct tcpip_adapter_dns_param_s {
tcpip_adapter_dns_type_t dns_type;
tcpip_adapter_dns_info_t *dns_info;
} tcpip_adapter_dns_param_t;
typedef struct tcpip_adapter_ip_lost_timer_s {
bool timer_running;
} tcpip_adapter_ip_lost_timer_t;
#define TCPIP_ADAPTER_TRHEAD_SAFE 1
#define TCPIP_ADAPTER_IPC_LOCAL 0
#define TCPIP_ADAPTER_IPC_REMOTE 1
#define TCPIP_ADAPTER_IPC_CALL(_if, _mac, _ip, _data, _fn) do {\
tcpip_adapter_api_msg_t msg;\
if (tcpip_inited == false) {\
ESP_LOGE(TAG, "tcpip_adapter is not initialized!");\
abort();\
}\
memset(&msg, 0, sizeof(msg));\
msg.tcpip_if = (_if);\
msg.mac = (uint8_t*)(_mac);\
msg.ip_info = (tcpip_adapter_ip_info_t*)(_ip);\
msg.data = (void*)(_data);\
msg.api_fn = (_fn);\
if (TCPIP_ADAPTER_IPC_REMOTE == tcpip_adapter_ipc_check(&msg)) {\
ESP_LOGV(TAG, "check: remote, if=%d fn=%p\n", (_if), (_fn));\
return msg.ret;\
} else {\
ESP_LOGV(TAG, "check: local, if=%d fn=%p\n", (_if), (_fn));\
}\
} while(0)
......@@ -14,7 +14,7 @@ SECTIONS
{
. = ALIGN(4);
*( .rtc.literal .rtc.text)
*( .rtc.literal .rtc.text .rtc.text.*)
*rtc_wake_stub*.*(.literal .text .literal.* .text.*)
_rtc_text_end = ABSOLUTE(.);
......@@ -56,7 +56,7 @@ SECTIONS
{
_rtc_data_start = ABSOLUTE(.);
*( .rtc.data .rtc.rodata)
*( .rtc.data .rtc.data.* .rtc.rodata .rtc.rodata.*)
*rtc_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
_rtc_data_end = ABSOLUTE(.);
......
......@@ -12,6 +12,7 @@ SECTIONS
*libpp.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
*liblwip.a:(.dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
*libbt.a:(EXCLUDE_FILE (libbtdm_app.a) .dynsbss .sbss .sbss.* .gnu.linkonce.sb.* .scommon .sbss2.* .gnu.linkonce.sb2.* .dynbss .bss .bss.* .share.mem .gnu.linkonce.b.* COMMON)
. = ALIGN(4);
_ext_ram_bss_end = ABSOLUTE(.);
} > extern_ram_seg
}
无法预览此类型文件
......@@ -15,6 +15,8 @@ CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y
# Application manager
#
CONFIG_APP_COMPILE_TIME_DATE=y
CONFIG_APP_EXCLUDE_PROJECT_VER_VAR=
CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR=
#
# Arduino Configuration
......@@ -60,6 +62,7 @@ CONFIG_BOOTLOADER_APP_TEST=
CONFIG_BOOTLOADER_WDT_ENABLE=y
CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE=
CONFIG_BOOTLOADER_WDT_TIME_MS=9000
CONFIG_APP_ROLLBACK_ENABLE=
#
# Security features
......@@ -207,6 +210,7 @@ CONFIG_HFP_ENABLE=y
CONFIG_HFP_CLIENT_ENABLE=y
CONFIG_HFP_AUDIO_DATA_PATH_PCM=y
CONFIG_HFP_AUDIO_DATA_PATH_HCI=
CONFIG_BT_SSP_ENABLED=y
CONFIG_GATTS_ENABLE=y
CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL=
CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y
......@@ -311,7 +315,7 @@ CONFIG_INT_WDT=y
CONFIG_INT_WDT_TIMEOUT_MS=300
CONFIG_INT_WDT_CHECK_CPU1=y
CONFIG_TASK_WDT=y
CONFIG_TASK_WDT_PANIC=
CONFIG_TASK_WDT_PANIC=y
CONFIG_TASK_WDT_TIMEOUT_S=5
CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=
......@@ -463,9 +467,6 @@ CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
#
# Modbus configuration
#
CONFIG_MB_UART_RXD=34
CONFIG_MB_UART_TXD=33
CONFIG_MB_UART_RTS=32
CONFIG_MB_QUEUE_LENGTH=20
CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048
CONFIG_MB_SERIAL_BUF_SIZE=256
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册