未验证 提交 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 @@ ...@@ -28,6 +28,7 @@
#include "soc/rtc.h" #include "soc/rtc.h"
#include "soc/rtc_cntl_reg.h" #include "soc/rtc_cntl_reg.h"
#include "rom/rtc.h" #include "rom/rtc.h"
#include "esp_task_wdt.h"
#include "esp32-hal.h" #include "esp32-hal.h"
//Undocumented!!! Get chip temperature in Farenheit //Undocumented!!! Get chip temperature in Farenheit
...@@ -44,6 +45,47 @@ void yield() ...@@ -44,6 +45,47 @@ void yield()
vPortYield(); 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 _cpu_freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
static uint32_t _sys_time_multiplier = 1; static uint32_t _sys_time_multiplier = 1;
......
...@@ -72,6 +72,18 @@ void yield(void); ...@@ -72,6 +72,18 @@ void yield(void);
//returns chip temperature in Celsius //returns chip temperature in Celsius
float temperatureRead(); 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: //function takes the following frequencies as valid values:
// 240, 160, 80 <<< For all XTAL types // 240, 160, 80 <<< For all XTAL types
// 40, 20, 13, 10, 8, 5, 4, 3, 2, 1 <<< For 40MHz XTAL // 40, 20, 13, 10, 8, 5, 4, 3, 2, 1 <<< For 40MHz XTAL
......
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/task.h" #include "freertos/task.h"
#include "esp_task_wdt.h"
#include "Arduino.h" #include "Arduino.h"
TaskHandle_t loopTaskHandle = NULL;
#if CONFIG_AUTOSTART_ARDUINO #if CONFIG_AUTOSTART_ARDUINO
#if CONFIG_FREERTOS_UNICORE #if CONFIG_FREERTOS_UNICORE
...@@ -10,18 +13,24 @@ ...@@ -10,18 +13,24 @@
#define ARDUINO_RUNNING_CORE 1 #define ARDUINO_RUNNING_CORE 1
#endif #endif
bool loopTaskWDTEnabled;
void loopTask(void *pvParameters) void loopTask(void *pvParameters)
{ {
setup(); setup();
for(;;) { for(;;) {
if(loopTaskWDTEnabled){
esp_task_wdt_reset();
}
loop(); loop();
} }
} }
extern "C" void app_main() extern "C" void app_main()
{ {
loopTaskWDTEnabled = false;
initArduino(); initArduino();
xTaskCreatePinnedToCore(loopTask, "loopTask", 8192, NULL, 1, NULL, ARDUINO_RUNNING_CORE); xTaskCreatePinnedToCore(loopTask, "loopTask", 8192, NULL, 1, &loopTaskHandle, ARDUINO_RUNNING_CORE);
} }
#endif #endif
...@@ -44,25 +44,25 @@ APP_TYPE = 0x00 ...@@ -44,25 +44,25 @@ APP_TYPE = 0x00
DATA_TYPE = 0x01 DATA_TYPE = 0x01
TYPES = { TYPES = {
"app" : APP_TYPE, "app": APP_TYPE,
"data" : DATA_TYPE, "data": DATA_TYPE,
} }
# Keep this map in sync with esp_partition_subtype_t enum in esp_partition.h # Keep this map in sync with esp_partition_subtype_t enum in esp_partition.h
SUBTYPES = { SUBTYPES = {
APP_TYPE : { APP_TYPE: {
"factory" : 0x00, "factory": 0x00,
"test" : 0x20, "test": 0x20,
}, },
DATA_TYPE : { DATA_TYPE: {
"ota" : 0x00, "ota": 0x00,
"phy" : 0x01, "phy": 0x01,
"nvs" : 0x02, "nvs": 0x02,
"coredump" : 0x03, "coredump": 0x03,
"nvs_keys" : 0x04, "nvs_keys": 0x04,
"esphttpd" : 0x80, "esphttpd": 0x80,
"fat" : 0x81, "fat": 0x81,
"spiffs" : 0x82, "spiffs": 0x82,
}, },
} }
...@@ -71,16 +71,19 @@ md5sum = True ...@@ -71,16 +71,19 @@ md5sum = True
secure = False secure = False
offset_part_table = 0 offset_part_table = 0
def status(msg): def status(msg):
""" Print status message to stderr """ """ Print status message to stderr """
if not quiet: if not quiet:
critical(msg) critical(msg)
def critical(msg): def critical(msg):
""" Print critical message to stderr """ """ Print critical message to stderr """
sys.stderr.write(msg) sys.stderr.write(msg)
sys.stderr.write('\n') sys.stderr.write('\n')
class PartitionTable(list): class PartitionTable(list):
def __init__(self): def __init__(self):
super(PartitionTable, self).__init__(self) super(PartitionTable, self).__init__(self)
...@@ -102,11 +105,11 @@ class PartitionTable(list): ...@@ -102,11 +105,11 @@ class PartitionTable(list):
if line.startswith("#") or len(line) == 0: if line.startswith("#") or len(line) == 0:
continue continue
try: try:
res.append(PartitionDefinition.from_csv(line, line_no+1)) res.append(PartitionDefinition.from_csv(line, line_no + 1))
except InputError as e: 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: 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 raise
# fix up missing offsets & negative sizes # fix up missing offsets & negative sizes
...@@ -149,14 +152,14 @@ class PartitionTable(list): ...@@ -149,14 +152,14 @@ class PartitionTable(list):
ptype = TYPES[ptype] ptype = TYPES[ptype]
except KeyError: except KeyError:
try: try:
ptypes = int(ptype, 0) ptype = int(ptype, 0)
except TypeError: except TypeError:
pass pass
try: try:
subtype = SUBTYPES[int(ptype)][subtype] subtype = SUBTYPES[int(ptype)][subtype]
except KeyError: except KeyError:
try: try:
ptypes = int(ptype, 0) ptype = int(ptype, 0)
except TypeError: except TypeError:
pass pass
...@@ -177,8 +180,8 @@ class PartitionTable(list): ...@@ -177,8 +180,8 @@ class PartitionTable(list):
p.verify() p.verify()
# check on duplicate name # check on duplicate name
names = [ p.name for p in self ] names = [p.name for p in self]
duplicates = set( n for n in names if names.count(n) > 1 ) duplicates = set(n for n in names if names.count(n) > 1)
# print sorted duplicate partitions by name # print sorted duplicate partitions by name
if len(duplicates) != 0: if len(duplicates) != 0:
...@@ -194,7 +197,7 @@ class PartitionTable(list): ...@@ -194,7 +197,7 @@ class PartitionTable(list):
if p.offset < offset_part_table + PARTITION_TABLE_SIZE: 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)) 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: 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 last = p
def flash_size(self): def flash_size(self):
...@@ -209,15 +212,15 @@ class PartitionTable(list): ...@@ -209,15 +212,15 @@ class PartitionTable(list):
@classmethod @classmethod
def from_binary(cls, b): def from_binary(cls, b):
md5 = hashlib.md5(); md5 = hashlib.md5()
result = cls() result = cls()
for o in range(0,len(b),32): for o in range(0,len(b),32):
data = b[o:o+32] data = b[o:o + 32]
if len(data) != 32: if len(data) != 32:
raise InputError("Partition table length must be a multiple of 32 bytes") 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 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(): 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: else:
...@@ -231,29 +234,30 @@ class PartitionTable(list): ...@@ -231,29 +234,30 @@ class PartitionTable(list):
result = b"".join(e.to_binary() for e in self) result = b"".join(e.to_binary() for e in self)
if md5sum: if md5sum:
result += MD5_PARTITION_BEGIN + hashlib.md5(result).digest() 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)) 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 result += b"\xFF" * (MAX_PARTITION_LENGTH - len(result)) # pad the sector, for signing
return result return result
def to_csv(self, simple_formatting=False): def to_csv(self, simple_formatting=False):
rows = [ "# Espressif ESP32 Partition Table", rows = ["# Espressif ESP32 Partition Table",
"# Name, Type, SubType, Offset, Size, Flags" ] "# Name, Type, SubType, Offset, Size, Flags"]
rows += [ x.to_csv(simple_formatting) for x in self ] rows += [x.to_csv(simple_formatting) for x in self]
return "\n".join(rows) + "\n" return "\n".join(rows) + "\n"
class PartitionDefinition(object): class PartitionDefinition(object):
MAGIC_BYTES = b"\xAA\x50" MAGIC_BYTES = b"\xAA\x50"
ALIGNMENT = { ALIGNMENT = {
APP_TYPE : 0x10000, APP_TYPE: 0x10000,
DATA_TYPE : 0x04, DATA_TYPE: 0x04,
} }
# dictionary maps flag name (as used in CSV flags list, property name) # dictionary maps flag name (as used in CSV flags list, property name)
# to bit set in flags words in binary format # to bit set in flags words in binary format
FLAGS = { FLAGS = {
"encrypted" : 0 "encrypted": 0
} }
# add subtypes for the 16 OTA slot values ("ota_XX, etc.") # add subtypes for the 16 OTA slot values ("ota_XX, etc.")
...@@ -272,7 +276,7 @@ class PartitionDefinition(object): ...@@ -272,7 +276,7 @@ class PartitionDefinition(object):
def from_csv(cls, line, line_no): def from_csv(cls, line, line_no):
""" Parse a line from the CSV """ """ Parse a line from the CSV """
line_w_defaults = line + ",,,," # lazy way to support default fields 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 = PartitionDefinition()
res.line_no = line_no res.line_no = line_no
...@@ -353,12 +357,14 @@ class PartitionDefinition(object): ...@@ -353,12 +357,14 @@ class PartitionDefinition(object):
raise ValidationError(self, "Size field is not set") raise ValidationError(self, "Size field is not set")
if self.name in TYPES and TYPES.get(self.name, "") != self.type: 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 = [] all_subtype_names = []
for names in (t.keys() for t in SUBTYPES.values()): for names in (t.keys() for t in SUBTYPES.values()):
all_subtype_names += names all_subtype_names += names
if self.name in all_subtype_names and SUBTYPES.get(self.type, {}).get(self.name, "") != self.subtype: 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" STRUCT_FORMAT = b"<2sBBLL16sL"
...@@ -375,15 +381,15 @@ class PartitionDefinition(object): ...@@ -375,15 +381,15 @@ class PartitionDefinition(object):
if magic != cls.MAGIC_BYTES: if magic != cls.MAGIC_BYTES:
raise InputError("Invalid magic bytes (%r) for partition definition" % magic) raise InputError("Invalid magic bytes (%r) for partition definition" % magic)
for flag,bit in cls.FLAGS.items(): for flag,bit in cls.FLAGS.items():
if flags & (1<<bit): if flags & (1 << bit):
setattr(res, flag, True) setattr(res, flag, True)
flags &= ~(1<<bit) flags &= ~(1 << bit)
if flags != 0: if flags != 0:
critical("WARNING: Partition definition had unknown flag(s) 0x%08x. Newer binary format?" % flags) critical("WARNING: Partition definition had unknown flag(s) 0x%08x. Newer binary format?" % flags)
return res return res
def get_flags_list(self): 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): def to_binary(self):
flags = sum((1 << self.FLAGS[flag]) for flag in self.get_flags_list()) flags = sum((1 << self.FLAGS[flag]) for flag in self.get_flags_list())
...@@ -397,14 +403,14 @@ class PartitionDefinition(object): ...@@ -397,14 +403,14 @@ class PartitionDefinition(object):
def to_csv(self, simple_formatting=False): def to_csv(self, simple_formatting=False):
def addr_format(a, include_sizes): def addr_format(a, include_sizes):
if not simple_formatting and 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: if a % val == 0:
return "%d%s" % (a // val, suffix) return "%d%s" % (a // val, suffix)
return "0x%x" % a return "0x%x" % a
def lookup_keyword(t, keywords): def lookup_keyword(t, keywords):
for k,v in keywords.items(): for k,v in keywords.items():
if simple_formatting == False and t == v: if simple_formatting is False and t == v:
return k return k
return "%d" % t return "%d" % t
...@@ -412,7 +418,7 @@ class PartitionDefinition(object): ...@@ -412,7 +418,7 @@ class PartitionDefinition(object):
""" colon-delimited list of flags """ """ colon-delimited list of flags """
return ":".join(self.get_flags_list()) return ":".join(self.get_flags_list())
return ",".join([ self.name, return ",".join([self.name,
lookup_keyword(self.type, TYPES), lookup_keyword(self.type, TYPES),
lookup_keyword(self.subtype, SUBTYPES.get(self.type, {})), lookup_keyword(self.subtype, SUBTYPES.get(self.type, {})),
addr_format(self.offset, False), addr_format(self.offset, False),
...@@ -425,7 +431,7 @@ def parse_int(v, keywords={}): ...@@ -425,7 +431,7 @@ def parse_int(v, keywords={}):
k/m/K/M suffixes and 'keyword' value lookup. k/m/K/M suffixes and 'keyword' value lookup.
""" """
try: try:
for letter, multiplier in [ ("k",1024), ("m",1024*1024) ]: for letter, multiplier in [("k", 1024), ("m", 1024 * 1024)]:
if v.lower().endswith(letter): if v.lower().endswith(letter):
return parse_int(v[:-1], keywords) * multiplier return parse_int(v[:-1], keywords) * multiplier
return int(v, 0) return int(v, 0)
...@@ -437,6 +443,7 @@ def parse_int(v, keywords={}): ...@@ -437,6 +443,7 @@ def parse_int(v, keywords={}):
except KeyError: except KeyError:
raise InputError("Value '%s' is not valid. Known keywords: %s" % (v, ", ".join(keywords))) raise InputError("Value '%s' is not valid. Known keywords: %s" % (v, ", ".join(keywords)))
def main(): def main():
global quiet global quiet
global md5sum global md5sum
...@@ -445,10 +452,11 @@ def main(): ...@@ -445,10 +452,11 @@ def main():
parser = argparse.ArgumentParser(description='ESP32 partition table utility') parser = argparse.ArgumentParser(description='ESP32 partition table utility')
parser.add_argument('--flash-size', help='Optional flash size limit, checks partition table fits in flash', 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('--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('--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('--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('--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') parser.add_argument('--secure', help="Require app partitions to be suitable for secure boot", action='store_true')
...@@ -481,7 +489,8 @@ def main(): ...@@ -481,7 +489,8 @@ def main():
size = size_mb * 1024 * 1024 # flash memory uses honest megabytes! size = size_mb * 1024 * 1024 # flash memory uses honest megabytes!
table_size = table.flash_size() table_size = table.flash_size()
if size < table_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)) (args.input.name, table_size / 1024.0 / 1024.0, table_size, size_mb))
# Make sure that the output directory is created # Make sure that the output directory is created
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include "esp_err.h" #include "esp_err.h"
#include "esp_partition.h" #include "esp_partition.h"
#include "esp_image_format.h" #include "esp_image_format.h"
#include "esp_flash_data_types.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" extern "C"
...@@ -195,6 +196,52 @@ const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t * ...@@ -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); 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 #ifdef __cplusplus
} }
#endif #endif
......
...@@ -87,7 +87,6 @@ ...@@ -87,7 +87,6 @@
#define CONFIG_TCPIP_TASK_AFFINITY_CPU0 1 #define CONFIG_TCPIP_TASK_AFFINITY_CPU0 1
#define CONFIG_FATFS_CODEPAGE 850 #define CONFIG_FATFS_CODEPAGE 850
#define CONFIG_ULP_COPROC_RESERVE_MEM 512 #define CONFIG_ULP_COPROC_RESERVE_MEM 512
#define CONFIG_MB_UART_RXD 34
#define CONFIG_LWIP_MAX_UDP_PCBS 16 #define CONFIG_LWIP_MAX_UDP_PCBS 16
#define CONFIG_ESPTOOLPY_BAUD 921600 #define CONFIG_ESPTOOLPY_BAUD 921600
#define CONFIG_INT_WDT_CHECK_CPU1 1 #define CONFIG_INT_WDT_CHECK_CPU1 1
...@@ -173,7 +172,6 @@ ...@@ -173,7 +172,6 @@
#define CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED 1 #define CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED 1
#define CONFIG_MBEDTLS_KEY_EXCHANGE_PSK 1 #define CONFIG_MBEDTLS_KEY_EXCHANGE_PSK 1
#define CONFIG_TCP_SYNMAXRTX 6 #define CONFIG_TCP_SYNMAXRTX 6
#define CONFIG_MB_UART_RTS 32
#define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA 1 #define CONFIG_MBEDTLS_KEY_EXCHANGE_ECDHE_ECDSA 1
#define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF 0 #define CONFIG_BTDM_CONTROLLER_BR_EDR_MAX_SYNC_CONN_EFF 0
#define CONFIG_HEAP_POISONING_LIGHT 1 #define CONFIG_HEAP_POISONING_LIGHT 1
...@@ -266,7 +264,6 @@ ...@@ -266,7 +264,6 @@
#define CONFIG_FREERTOS_INTERRUPT_BACKTRACE 1 #define CONFIG_FREERTOS_INTERRUPT_BACKTRACE 1
#define CONFIG_WL_SECTOR_SIZE 4096 #define CONFIG_WL_SECTOR_SIZE 4096
#define CONFIG_ESP32_DEBUG_OCDAWARE 1 #define CONFIG_ESP32_DEBUG_OCDAWARE 1
#define CONFIG_MB_UART_TXD 33
#define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1 #define CONFIG_MQTT_TRANSPORT_WEBSOCKET 1
#define CONFIG_TIMER_TASK_PRIORITY 1 #define CONFIG_TIMER_TASK_PRIORITY 1
#define CONFIG_PPP_PAP_SUPPORT 1 #define CONFIG_PPP_PAP_SUPPORT 1
...@@ -274,6 +271,7 @@ ...@@ -274,6 +271,7 @@
#define CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI 1 #define CONFIG_BTDM_CONTROLLER_HCI_MODE_VHCI 1
#define CONFIG_BT_ENABLED 1 #define CONFIG_BT_ENABLED 1
#define CONFIG_ESP32_DEFAULT_PTHREAD_CORE_NO_AFFINITY 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_MBEDTLS_ECP_DP_SECP256R1_ENABLED 1
#define CONFIG_MONITOR_BAUD 115200 #define CONFIG_MONITOR_BAUD 115200
#define CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT -1 #define CONFIG_ESP32_PTHREAD_TASK_CORE_DEFAULT -1
...@@ -335,6 +333,7 @@ ...@@ -335,6 +333,7 @@
#define CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF 1 #define CONFIG_NEWLIB_STDOUT_LINE_ENDING_CRLF 1
#define CONFIG_ESPTOOLPY_PORT "/dev/cu.usbserial-DO00EAB0" #define CONFIG_ESPTOOLPY_PORT "/dev/cu.usbserial-DO00EAB0"
#define CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS 1 #define CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ABORTS 1
#define CONFIG_TASK_WDT_PANIC 1
#define CONFIG_UNITY_ENABLE_DOUBLE 1 #define CONFIG_UNITY_ENABLE_DOUBLE 1
#define CONFIG_BLUEDROID_PINNED_TO_CORE 0 #define CONFIG_BLUEDROID_PINNED_TO_CORE 0
#define CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG 1 #define CONFIG_BTDM_MODEM_SLEEP_MODE_ORIG 1
......
...@@ -20,11 +20,11 @@ ...@@ -20,11 +20,11 @@
//and all variables in shared RAM. These macros can be used to redirect //and all variables in shared RAM. These macros can be used to redirect
//particular functions/variables to other memory regions. //particular functions/variables to other memory regions.
// Forces code into IRAM instead of flash. // Forces code into IRAM instead of flash
#define IRAM_ATTR __attribute__((section(".iram1"))) #define IRAM_ATTR _SECTION_ATTR_IMPL(".iram1", __COUNTER__)
// Forces data into DRAM instead of flash // 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 // Forces data to be 4 bytes aligned
#define WORD_ALIGNED_ATTR __attribute__((aligned(4))) #define WORD_ALIGNED_ATTR __attribute__((aligned(4)))
...@@ -37,11 +37,11 @@ ...@@ -37,11 +37,11 @@
#define DRAM_STR(str) (__extension__({static const DRAM_ATTR char __c[] = (str); (const char *)&__c;})) #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" // 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 #if CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY
// Forces bss variable into 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 #else
#define EXT_RAM_ATTR #define EXT_RAM_ATTR
#endif #endif
...@@ -49,26 +49,37 @@ ...@@ -49,26 +49,37 @@
// Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst" // Forces data into RTC slow memory. See "docs/deep-sleep-stub.rst"
// Any variable marked with this attribute will keep its value // Any variable marked with this attribute will keep its value
// during a deep sleep / wake cycle. // 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" // 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. // 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. // 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. // 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. // Forces data into RTC slow memory of .noinit section.
// Any variable marked with this attribute will keep its value // Any variable marked with this attribute will keep its value
// after restart or during a deep sleep / wake cycle. // 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 // Forces to not inline function
#define NOINLINE_ATTR __attribute__((noinline)) #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__ */ #endif /* __ESP_ATTR_H__ */
...@@ -24,11 +24,22 @@ extern "C" ...@@ -24,11 +24,22 @@ extern "C"
#define ESP_PARTITION_MAGIC 0x50AA #define ESP_PARTITION_MAGIC 0x50AA
#define ESP_PARTITION_MAGIC_MD5 0xEBEB #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.) /* OTA selection structure (two copies in the OTA data partition.)
Size of 32 bytes is friendly to flash encryption */ Size of 32 bytes is friendly to flash encryption */
typedef struct { typedef struct {
uint32_t ota_seq; 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 */ uint32_t crc; /* CRC32 of ota_seq field only */
} esp_ota_select_entry_t; } esp_ota_select_entry_t;
......
...@@ -624,6 +624,7 @@ esp_err_t esp_mesh_stop(void); ...@@ -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. * - 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. * 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 * @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 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). * - 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 * @param[in] flag bitmap for data sent
...@@ -1440,6 +1441,14 @@ esp_err_t esp_mesh_disconnect(void); ...@@ -1440,6 +1441,14 @@ esp_err_t esp_mesh_disconnect(void);
*/ */
esp_err_t esp_mesh_connect(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 * @brief Cause the root device to add Channel Switch Announcement Element (CSA IE) to beacon
* - Set the new channel * - Set the new channel
...@@ -1457,6 +1466,18 @@ esp_err_t esp_mesh_connect(void); ...@@ -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); 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 #ifdef __cplusplus
} }
#endif #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 ...@@ -14,7 +14,7 @@ SECTIONS
{ {
. = ALIGN(4); . = ALIGN(4);
*( .rtc.literal .rtc.text) *( .rtc.literal .rtc.text .rtc.text.*)
*rtc_wake_stub*.*(.literal .text .literal.* .text.*) *rtc_wake_stub*.*(.literal .text .literal.* .text.*)
_rtc_text_end = ABSOLUTE(.); _rtc_text_end = ABSOLUTE(.);
...@@ -56,7 +56,7 @@ SECTIONS ...@@ -56,7 +56,7 @@ SECTIONS
{ {
_rtc_data_start = ABSOLUTE(.); _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_wake_stub*.*(.data .rodata .data.* .rodata.* .bss .bss.*)
_rtc_data_end = ABSOLUTE(.); _rtc_data_end = ABSOLUTE(.);
......
...@@ -12,6 +12,7 @@ SECTIONS ...@@ -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) *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) *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) *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(.); _ext_ram_bss_end = ABSOLUTE(.);
} > extern_ram_seg } > extern_ram_seg
} }
无法预览此类型文件
...@@ -15,6 +15,8 @@ CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y ...@@ -15,6 +15,8 @@ CONFIG_MAKE_WARN_UNDEFINED_VARIABLES=y
# Application manager # Application manager
# #
CONFIG_APP_COMPILE_TIME_DATE=y CONFIG_APP_COMPILE_TIME_DATE=y
CONFIG_APP_EXCLUDE_PROJECT_VER_VAR=
CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR=
# #
# Arduino Configuration # Arduino Configuration
...@@ -60,6 +62,7 @@ CONFIG_BOOTLOADER_APP_TEST= ...@@ -60,6 +62,7 @@ CONFIG_BOOTLOADER_APP_TEST=
CONFIG_BOOTLOADER_WDT_ENABLE=y CONFIG_BOOTLOADER_WDT_ENABLE=y
CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE= CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE=
CONFIG_BOOTLOADER_WDT_TIME_MS=9000 CONFIG_BOOTLOADER_WDT_TIME_MS=9000
CONFIG_APP_ROLLBACK_ENABLE=
# #
# Security features # Security features
...@@ -207,6 +210,7 @@ CONFIG_HFP_ENABLE=y ...@@ -207,6 +210,7 @@ CONFIG_HFP_ENABLE=y
CONFIG_HFP_CLIENT_ENABLE=y CONFIG_HFP_CLIENT_ENABLE=y
CONFIG_HFP_AUDIO_DATA_PATH_PCM=y CONFIG_HFP_AUDIO_DATA_PATH_PCM=y
CONFIG_HFP_AUDIO_DATA_PATH_HCI= CONFIG_HFP_AUDIO_DATA_PATH_HCI=
CONFIG_BT_SSP_ENABLED=y
CONFIG_GATTS_ENABLE=y CONFIG_GATTS_ENABLE=y
CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL= CONFIG_GATTS_SEND_SERVICE_CHANGE_MANUAL=
CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y CONFIG_GATTS_SEND_SERVICE_CHANGE_AUTO=y
...@@ -311,7 +315,7 @@ CONFIG_INT_WDT=y ...@@ -311,7 +315,7 @@ CONFIG_INT_WDT=y
CONFIG_INT_WDT_TIMEOUT_MS=300 CONFIG_INT_WDT_TIMEOUT_MS=300
CONFIG_INT_WDT_CHECK_CPU1=y CONFIG_INT_WDT_CHECK_CPU1=y
CONFIG_TASK_WDT=y CONFIG_TASK_WDT=y
CONFIG_TASK_WDT_PANIC= CONFIG_TASK_WDT_PANIC=y
CONFIG_TASK_WDT_TIMEOUT_S=5 CONFIG_TASK_WDT_TIMEOUT_S=5
CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU0=y
CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1= CONFIG_TASK_WDT_CHECK_IDLE_TASK_CPU1=
...@@ -463,9 +467,6 @@ CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y ...@@ -463,9 +467,6 @@ CONFIG_FATFS_ALLOC_PREFER_EXTRAM=y
# #
# Modbus configuration # Modbus configuration
# #
CONFIG_MB_UART_RXD=34
CONFIG_MB_UART_TXD=33
CONFIG_MB_UART_RTS=32
CONFIG_MB_QUEUE_LENGTH=20 CONFIG_MB_QUEUE_LENGTH=20
CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048 CONFIG_MB_SERIAL_TASK_STACK_SIZE=2048
CONFIG_MB_SERIAL_BUF_SIZE=256 CONFIG_MB_SERIAL_BUF_SIZE=256
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册