8000 esp8266: Add support for firmware update from a file on LFS2 filesystem. · micropython/micropython@d75afb8 · GitHub
[go: up one dir, main page]

Skip to content

Commit d75afb8

Browse files
committed
esp8266: Add support for firmware update from a file on LFS2 filesystem.
lib/littlefs/lfs2.c: installed a hook in LFS2 to dig sectors for DFU. ports/esp8266/modesp.c: core functions for DFU. ports/esp8266/modules/inisetup.py: user functions for DFU. ports/esp8266/main.c: more heap memory (tested working). ports/esp8266/esppwm.c: higher PWM frequency limit for IR control. ports/.../esp8266_common.ld: migrated 3 functions for more IRAM space. ports/.../mpconfigboard.h: this DFU is only for ESP8266 2MB+ Signed-off-by: Wang Xuancong <xuancong84@gmail.com>
1 parent dc99840 commit d75afb8

File tree

9 files changed

+970
-769
lines changed

9 files changed

+970
-769
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,4 @@ user.props
2323

2424
# MacOS desktop metadata files
2525
.DS_Store
26+
ports/esp8266/modules/*.py

lib/littlefs/lfs2.c

Lines changed: 782 additions & 766 deletions
Large diffs are not rendered by default.

ports/esp8266/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ CFLAGS_XTENSA = -fsingle-precision-constant -Wdouble-promotion \
7171
-Wl,-EL -mlongcalls -mtext-section-literals -mforce-l32 \
7272
-DLWIP_OPEN_SRC
7373

74-
CFLAGS += $(INC) -Wall -Wpointer-arith -Werror -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \
74+
CFLAGS += $(INC) -Wall -Wpointer-arith -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \
7575
$(CFLAGS_XTENSA) $(COPT) $(CFLAGS_EXTRA) -I$(BOARD_DIR)
7676

7777
LD_FILES ?= boards/esp8266_2m.ld

ports/esp8266/boards/ESP8266_GENERIC/mpconfigboard.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define MICROPY_VFS (1)
1515

1616
#define MICROPY_PY_CRYPTOLIB (1)
17+
#define MICROPY_DFU (1)
1718

1819
#elif defined(MICROPY_ESP8266_1M)
1920

ports/esp8266/boards/esp8266_common.ld

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@ SECTIONS
182182

183183
/* for -mforce-l32 */
184184
*/*.o(.rodata*)
185+
*modespnow.o(.text.espnow_del_peer .text.espnow_add_peer .text.espnow_config)
185186

186187
_irom0_text_end = ABSOLUTE(.);
187188
} >irom0_0_seg :irom0_0_phdr

ports/esp8266/esppwm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727
#define PWM_CHANNEL 8
2828
#define PWM_DEPTH 1023
29-
#define PWM_FREQ_MAX 1000
29+
#define PWM_FREQ_MAX 60000
3030
#define PWM_1S 1000000
3131

3232
struct pwm_single_param {

ports/esp8266/main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
#include "modespnow.h"
5050
#endif
5151

52-
STATIC char heap[38 * 1024];
52+
STATIC char heap[45 * 1024];
5353

5454
STATIC void mp_reset(void) {
5555
mp_stack_set_top((void *)0x40000000);

ports/esp8266/modesp.c

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,147 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_set_native_code_location_obj, esp_set_nativ
339339

340340
#endif
341341

342+
/*
343+
#include <stdarg.h>
344+
int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args);
345+
STATIC void _strncat(char *data, const char *str, size_t len){
346+
int len_data = strlen(data);
347+
memcpy(&data[len_data], str, len);
348+
data[len_data+len] = 0;
349+
}
350+
351+
STATIC int _sprintf(char *_buf, const char *fmt, ...) {
352+
mp_print_t buf = {(void*)_buf, _strncat};
353+
va_list ap;
354+
va_start(ap, fmt);
355+
int ret = mp_vprintf(&buf, fmt, ap);
356+
va_end(ap);
357+
return ret;
358+
}
359+
360+
STATIC void showMemory(char *ptr, size_t size){
361+
char buf[16];
362+
for(int x=0; x<size;){
363+
buf[0] = 0;
364+
_sprintf(&buf[0], "%02x ", ptr[x++]);
365+
if(x%32==0)_sprintf(&buf[0], "\r\n");
366+
else if(x%16==0)_sprintf(&buf[0], " ");
367+
else if(x%8==0)_sprintf(&buf[0], " ");
368+
mp_hal_stdout_tx_str(&buf[0]);
369+
ets_loop_iter();
370+
}
371+
mp_hal_stdout_tx_str("\r\n");
372+
}
373+
STATIC mp_obj_t esp_showMemory(mp_obj_t _start, mp_obj_t _size) {
374+
showMemory((char*)mp_obj_get_int(_start), mp_obj_get_int(_size));
375+
return mp_const_none;
376+
}
377+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_showMemory_obj, esp_showMemory);
378+
*/
379+
#ifdef MICROPY_DFU
380+
uint16_t dfu_blks[256];
381+
uint16_t dfu_offs[256];
382+
int dfu_nblks = -1;
383+
uint32_t dfu_fwsize = 0;
384+
385+
/* Firmware update codes must be put into IRAM, or will crash while flashing halfway! */
386+
void MP_FASTCODE(erase_sector)(int sector) {
387+
char *ptr = FLASH_START + sector * FLASH_SEC_SIZE;
388+
for (char *PTR = ptr + FLASH_SEC_SIZE; ptr < PTR; ptr++) {
389+
if (*ptr != 0xff) {
390+
SPIEraseSector(sector);
391+
break;
392+
}
393+
}
394+
}
395+
void MP_FASTCODE(DFU)(char *dfu_buf, int n_fwblks, int n_erase) {
396+
for (int x = 0; x < n_fwblks; x++) {
397+
erase_sector(x);
398+
// uart_tx_one_char(0, 'E');
399+
}
400+
401+
int cur_write_pos = 0;
402+
int cur_write_sz;
403+
int remaining_sz = dfu_fwsize;
404+
405+
for (int x = 0; x < dfu_nblks && remaining_sz > 0; x++) {
406+
cur_write_sz = FLASH_SEC_SIZE - dfu_offs[x];
407+
if (remaining_sz < cur_write_sz) {
408+
cur_write_sz = remaining_sz;
409+
}
410+
411+
Cache_Read_Disable_2();
412+
SPIRead(1048576 + FLASH_SEC_SIZE * dfu_blks[x] + dfu_offs[x], (uint32_t *)dfu_buf, cur_write_sz);
413+
Cache_Read_Enable_2();
414+
// uart_tx_one_char(0, 'R');
415+
if (x == 0) {
416+
dfu_buf[3] = 64;
417+
}
418+
SPIWrite(cur_write_pos, (uint32_t *)dfu_buf, cur_write_sz);
419+
// uart_tx_one_char(0, 'W');
420+
421+
cur_write_pos += cur_write_sz;
422+
remaining_sz -= cur_write_sz;
423+
wdt_feed();
424+
}
425+
426+
for (int x = n_fwblks; x < n_erase; x++) {
427+
erase_sector(x);
428+
// uart_tx_one_char(0, 'E');
429+
}
430+
431+
asm ("memw");
432+
asm ("isync");
433+
// rom_phy_reset_req();
434+
system_restart_core();
435+
// return cur_write_pos;
436+
}
437+
STATIC mp_obj_t esp_DFU(mp_obj_t erase_all) {
438+
extern char flashchip;
439+
SpiFlashChip *flash = (SpiFlashChip *)(&flashchip + 4);
440+
char *buf = malloc(FLASH_SEC_SIZE);
441+
if (buf == NULL) {
442+
mp_raise_OSError(MP_ENOMEM);
443+
return mp_const_none;
444+
}
445+
446+
ets_wdt_disable();
447+
disable_irq();
448+
DFU(buf, dfu_fwsize / FLASH_SEC_SIZE + (dfu_fwsize % FLASH_SEC_SIZE?1:0), mp_obj_is_true(erase_all)?(flash->chip_size / FLASH_SEC_SIZE):0);
449+
450+
// It will NEVER reach here even if flash failed
451+
// enable_irq(state);
452+
// ets_wdt_enable();
453+
454+
return mp_const_none;
455+
}
456+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_DFU_obj, esp_DFU);
457+
458+
STATIC mp_obj_t esp_set_dfu(mp_obj_t counter, mp_obj_t fsize) {
459+
dfu_nblks = mp_obj_get_int(counter);
460+
dfu_fwsize = mp_obj_get_int(fsize);
461+
return mp_const_none;
462+
}
463+
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_set_dfu_obj, esp_set_dfu);
464+
465+
STATIC mp_obj_t esp_get_blks() {
466+
if (dfu_nblks <= 0) {
467+
return mp_obj_new_list(0, NULL), mp_obj_new_list(0, NULL);
468+
}
469+
mp_obj_t ret1 = mp_obj_new_list(0, NULL);
470+
mp_obj_t ret2 = mp_obj_new_list(0, NULL);
471+
for (int x = 0; x < dfu_nblks; x++) {
472+
mp_obj_list_append(ret1, mp_obj_new_int(dfu_blks[x]));
473+
mp_obj_list_append(ret2, mp_obj_new_int(dfu_offs[x]));
474+
}
475+
mp_obj_t ret = mp_obj_new_list(0, NULL);
476+
mp_obj_list_append(ret, ret1);
477+
mp_obj_list_append(ret, ret2);
478+
return ret;
479+
}
480+
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_get_blks_obj, esp_get_blks);
481+
#endif
482+
342483
STATIC const mp_rom_map_elem_t esp_module_globals_table[] = {
343484
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp) },
344485

@@ -351,6 +492,14 @@ STATIC const mp_rom_map_elem_t esp_module_globals_table[] = {
351492
{ MP_ROM_QSTR(MP_QSTR_flash_erase), MP_ROM_PTR(&esp_flash_erase_obj) },
352493
{ MP_ROM_QSTR(MP_QSTR_flash_size), MP_ROM_PTR(&esp_flash_size_obj) },
353494
{ MP_ROM_QSTR(MP_QSTR_flash_user_start), MP_ROM_PTR(&esp_flash_user_start_obj) },
495+
496+
#ifdef MICROPY_DFU
497+
{ MP_ROM_QSTR(MP_QSTR_DFU), MP_ROM_PTR(&esp_DFU_obj) },
498+
// { MP_ROM_QSTR(MP_QSTR_showMemory), MP_ROM_PTR(&esp_showMemory_obj) },
499+
{ MP_ROM_QSTR(MP_QSTR_set_dfu), MP_ROM_PTR(&esp_set_dfu_obj) },
500+
{ MP_ROM_QSTR(MP_QSTR_get_blks), MP_ROM_PTR(&esp_get_blks_obj) },
501+
#endif
502+
354503
#if MICROPY_ESP8266_APA102
355504
{ MP_ROM_QSTR(MP_QSTR_apa102_write), MP_ROM_PTR(&esp_apa102_write_obj) },
356505
#endif

ports/esp8266/modules/inisetup.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,39 @@
33
from flashbdev import bdev
44

55

6+
def fwupdate(fn, erase_all=False, safe_check=True, verbose=True):
7+
import esp
8+
9+
fw_size = rem_fs = os.stat(fn)[6]
10+
esp.set_dfu(0, fw_size)
11+
with open(fn, "rb") as fp:
12+
while fp.read(4096):
13+
pass
14+
15+
if safe_check:
16+
blks, offs = esp.get_blks()
17+
esp.set_dfu(-1, fw_size)
18+
if verbose:
19+
print(f"Verifying sector data:{blks} {offs}")
20+
with open(fn, "rb") as fp:
21+
for ii, blkid in enumerate(blks):
22+
sz = min(rem_fs, 4096 - offs[ii])
23+
L2 = esp.flash_read(esp.flash_user_start() + blkid * 4096 + offs[ii], sz)
24+
L1 = fp.read(sz)
25+
if L1 != L2:
26+
raise Exception("Data is different at N={ii} blkid={blkid}")
27+
del L1, L2
28+
rem_fs -= sz
29+
if verbose:
30+
print(f"{ii}/{len(blks)}", end="\r")
31+
esp.set_dfu(len(blks), fw_size)
32+
del blks, offs
33+
if verbose:
34+
print("Success, starting firmware update ...")
35+
36+
esp.DFU(erase_all)
37+
38+
639
def wifi():
740
import binascii
841

0 commit comments

Comments
 (0)
0