10000 esp32: added Dynamic filesystem funcionality and new Bootmgr function… · pycom/pycom-micropython-sigfox@0cebd58 · GitHub
[go: up one dir, main page]

Skip to content
This repository was archived by the owner on Sep 16, 2024. It is now read-only.

Commit 0cebd58

Browse files
author
iwahdan88
committed
esp32: added Dynamic filesystem funcionality and new Bootmgr function in Pycom mod
* Re-enable Fatfs on /flash (#1) * Dynamic choice of file system type (WIP) * Dynamic choice of file system type (WIP) * Dynamic choice of file system type (WIP) Fix Sigfox initialization * Fix crash in modsigfox.c Based on husigeza/pycom-micropython-sigfox@277275a * Improved pycom.bootmgr() function, add more #ifndef FS_USE_LITTLEFS based on Geza's recommendation. * esp32/mods: updated bootmgr API in Pycom module to return tuple + raise exeptions in case of value errors
1 parent 37d2a5a commit 0cebd58

File tree

5 files changed

+293
-9
lines changed

5 files changed

+293
-9
lines changed

esp32/application.mk

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,11 @@ CFLAGS += $(APP_INC) -DMICROPY_NLR_SETJMP=1 -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_
333333
CFLAGS_SIGFOX += $(APP_INC) -DMICROPY_NLR_SETJMP=1 -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_config.h"' -DHAVE_CONFIG_H -DESP_PLATFORM
334334
CFLAGS += -DREGION_AS923 -DREGION_AU915 -DREGION_EU868 -DREGION_US915
335335

336+
# Give the possibility to use LittleFs on /flash, otherwise FatFs is used
337+
FS ?= ""
338+
ifeq ($(FS), LFS)
339+
CFLAGS += -DFS_USE_LITTLEFS
340+
endif
336341
# add the application archive, this order is very important
337342
APP_LIBS = -Wl,--start-group $(LIBS) $(BUILD)/application.a -Wl,--end-group -Wl,-EL
338343

esp32/mods/modpycom.c

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,12 @@
3030
#include "antenna.h"
3131
#include "py/mphal.h"
3232

33+
#include "bootmgr.h"
34+
#include "updater.h"
35+
36+
#include "modmachine.h"
37+
38+
3339
#include <string.h>
3440

3541
extern led_info_t led_info;
@@ -40,17 +46,60 @@ extern led_info_t led_info;
4046
#define WDT_ON_BOOT_MIN_TIMEOUT_MS (5000)
4147

4248
static nvs_handle pycom_nvs_handle;
49+
boot_info_t boot_info;
50+
uint32_t boot_info_offset;
51+
52+
static void modpycom_bootmgr(uint8_t boot_partition, uint8_t fs_type, uint8_t safeboot);
4353

4454
void modpycom_init0(void) {
4555
if (nvs_open(NVS_NAMESPACE, NVS_READWRITE, &pycom_nvs_handle) != ESP_OK) {
4656
mp_printf(&mp_plat_print, "Error while opening Pycom NVS name space\n");
4757
}
4858
rmt_driver_install(RMT_CHANNEL_0, 1000, 0);
59+
if (updater_read_boot_info (&boot_info, &boot_info_offset) == false) {
60+
mp_printf(&mp_plat_print, "Error reading bootloader information!\n");
61+
}
62+
}
63+
64+
static void modpycom_bootmgr(uint8_t boot_partition, uint8_t fs_type, uint8_t safeboot) {
65+
bool update_boot = false;
66+
67+
if (boot_partition < 255) {
68+
if (boot_partition <= 1) {
69+
boot_info.ActiveImg = (uint32_t)boot_partition;
70+
boot_info.Status = 0;
71+
update_boot = true;
72+
} else {
73+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Error invalid boot partition!"));
74+
}
75+
}
76+
if (safeboot < 255) {
77+
if (safeboot <= 1) {
78+
boot_info.safeboot = (uint32_t)safeboot;
79+
update_boot = true;
80+
} else {
81+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Error safeboot must be True or False!"));
82+
}
83+
}
84+
if (fs_type < 255) {
85+
if (fs_type <= 1) {
86+
config_set_boot_fs_type(fs_type);
87+
}
88+
else {
89+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Error invalid filesystem type!"));
90+
}
91+
}
92+
if (update_boot) {
93+
if (updater_write_boot_info (&boot_info, boot_info_offset) == false) {
94+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Error writing bootloader information!"));
95+
}
96+
}
4997
}
5098

5199
/******************************************************************************/
52100
// Micro Python bindings
53101

102+
54103
STATIC mp_obj_t mod_pycom_heartbeat (mp_uint_t n_args, const mp_obj_t *args) {
55104
if (n_args) {
56105
mperror_enable_heartbeat (mp_obj_is_true(args[0]));
@@ -74,7 +123,7 @@ STATIC mp_obj_t mod_pycom_rgb_led (mp_obj_t o_color) {
74123

75124
uint32_t color = mp_obj_get_int(o_color);
76125
led_info.color.value = color;
77-
led_set_color(&led_info, true);
126+
led_set_color(&led_info, true, false);
78127

79128
return mp_const_none;
80129
}
@@ -287,6 +336,64 @@ STATIC mp_obj_t mod_pycom_lte_modem_on_boot (mp_uint_t n_args, const mp_obj_t *a
287336
return mp_const_none;
288337
}
289338
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mod_pycom_lte_modem_on_boot_obj, 0, 1, mod_pycom_lte_modem_on_boot);
339+
340+
STATIC mp_obj_t mod_pycom_bootmgr (size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
341+
enum { ARG_boot_partition, ARG_fs_type, ARG_safeboot, ARG_reset };
342+
STATIC const mp_arg_t allowed_args[] = {
343+
{ MP_QSTR_boot_partition, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} },
344+
{ MP_QSTR_fs_type, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} },
345+
{ MP_QSTR_safeboot, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 255} },
346+
{ MP_QSTR_reset, MP_ARG_KW_ONLY | MP_ARG_BOOL, {.u_bool = false} },
347+
};
348+
349+
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
350+
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
351+
352+
if (args[ARG_boot_partition].u_int == 255 && args[ARG_fs_type].u_int == 255 && args[ARG_safeboot].u_int == 255) {
353+
mp_obj_tuple_t *t = MP_OBJ_TO_PTR(mp_obj_new_tuple(3, NULL));
354+
355+
if(boot_info.ActiveImg == 0x00)
356+
{
357+
t->items[ARG_boot_partition] = mp_obj_new_str("Factory", strlen("Factory"));
358+
}
359+
else
360+
{
361+
t->items[ARG_boot_partition] = mp_obj_new_str("ota_0", strlen("ota_0"));
362+
}
363+
364+
if(config_get_boot_fs_type() == 0x00)
365+
{
366+
t->items[ARG_fs_type] = mp_obj_new_str("FAT", strlen("FAT"));
367+
}
368+
else
369+
{
370+
t->items[ARG_fs_type] = mp_obj_new_str("LittleFS", strlen("LittleFS"));
371+
}
372+
373+
if(boot_info.safeboot == 0x00)
374+
{
375+
t->items[ARG_safeboot] = mp_obj_new_str("False", strlen("False"));
376+
}
377+
else
378+
{
379+
t->items[ARG_safeboot] = mp_obj_new_str("True", strlen("True"));
380+
}
381+
382+
return MP_OBJ_FROM_PTR(t);
383+
384+
} else {
385+
modpycom_bootmgr(args[ARG_boot_partition].u_int, args[ARG_fs_type].u_int, args[ARG_safeboot].u_int);
386+
387+
if (args[ARG_reset].u_bool == true) {
388+
machine_reset();
389+
}
390+
}
391+
392+
return mp_const_none;
393+
}
394+
395+
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(mod_pycom_bootmgr_obj, 0, mod_pycom_bootmgr);
396+
290397
STATIC const mp_map_elem_t pycom_module_globals_table[] = {
291398
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_pycom) },
292399
{ MP_OBJ_NEW_QSTR(MP_QSTR_heartbeat), (mp_obj_t)&mod_pycom_heartbeat_obj },
@@ -308,6 +415,14 @@ STATIC const mp_map_elem_t pycom_module_globals_table[] = {
308415
{ MP_OBJ_NEW_QSTR(MP_QSTR_wifi_pwd), (mp_obj_t)&mod_pycom_wifi_pwd_obj },
309416
{ MP_OBJ_NEW_QSTR(MP_QSTR_heartbeat_on_boot), (mp_obj_t)&mod_pycom_heartbeat_on_boot_obj },
310417
{ MP_OBJ_NEW_QSTR(MP_QSTR_lte_modem_en_on_boot), (mp_obj_t)&mod_pycom_lte_modem_on_boot_obj },
418+
{ MP_OBJ_NEW_QSTR(MP_QSTR_bootmgr), (mp_obj_t)&mod_pycom_bootmgr_obj },
419+
420+
// class constants
421+
{ MP_OBJ_NEW_QSTR(MP_QSTR_FACTORY), MP_OBJ_NEW_SMALL_INT(0) },
422+
{ MP_OBJ_NEW_QSTR(MP_QSTR_OTA_0), MP_OBJ_NEW_SMALL_INT(1) },
423+
{ MP_OBJ_NEW_QSTR(MP_QSTR_FAT), MP_OBJ_NEW_SMALL_INT(0) },
424+
{ MP_OBJ_NEW_QSTR(MP_QSTR_LittleFS), MP_OBJ_NEW_SMALL_INT(1) },
425+
311426
};
312427

313428
STATIC MP_DEFINE_CONST_DICT(pycom_module_globals, pycom_module_globals_table);

esp32/mptask.c

Lines changed: 132 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,19 +68,22 @@
6868
#include "machtimer_alarm.h"
6969
#include "mptask.h"
7070

71-
#include "extmod/vfs_fat.h"
72-
#include "diskio.h"
73-
#include "sflash_diskio.h"
74-
7571
#include "freertos/FreeRTOS.h"
7672
#include "freertos/task.h"
7773
#include "freertos/semphr.h"
7874
#include "freertos/queue.h"
7975

76+
#include "extmod/vfs_fat.h"
77+
78+
#include "ff.h"
79+
#include "diskio.h"
80+
#include "sflash_diskio.h"
8081

8182
#include "lfs.h"
8283
#include "sflash_diskio_littlefs.h"
8384
#include "lteppp.h"
85+
86+
8487
/******************************************************************************
8588
DECLARE EXTERNAL FUNCTIONS
8689
******************************************************************************/
@@ -103,6 +106,9 @@ extern TaskHandle_t svTaskHandle;
103106
******************************************************************************/
104107
STATIC void mptask_preinit (void);
105108
STATIC void mptask_init_sflash_filesystem (void);
109+
STATIC void mptask_init_sflash_filesystem_fatfs(void);
110+
STATIC void mptask_create_main_py (void);
111+
STATIC void mptask_init_sflash_filesystem_littlefs(void);
106112
#if defined (LOPY) || defined (SIPY) || defined (LOPY4) || defined (FIPY)
107113
STATIC void mptask_update_lpwan_mac_address (void);
108114
#endif
@@ -345,6 +351,20 @@ void TASK_Micropython (void *pvParameters) {
345351
goto soft_reset;
346352
}
347353

354+
bool isLittleFs(const TCHAR *path){
355+
#ifndef FS_USE_LITTLEFS
356+
if (config_get_boot_fs_type() == 0x01) {
357+
#endif
358+
const char *flash = "/flash";
359+
if(strncmp(flash, path, sizeof(flash)-1) == 0) {
360+
return true;
361+
}
362+
#ifndef FS_USE_LITTLEFS
363+
}
364+
#endif
365+
return false;
366+
}
367+
348368
/******************************************************************************
349369
DEFINE PRIVATE FUNCTIONS
350370
******************************************************************************/
@@ -446,6 +466,106 @@ STATIC void mptask_init_sflash_filesystem_fatfs(void) {
446466
}
447467
}
448468

469+
STATIC void mptask_init_sflash_filesystem_littlefs(void) {
470+
471+
fs_user_mount_t* vfs_littlefs = &sflash_vfs_flash;
472+
lfs_t *littlefsptr = &(vfs_littlefs->fs.littlefs.lfs);
473+
474+
//Initialize the block device
475+
sflash_disk_init();
476+
//Initialize the VFS object with the block device's functions
477+
pyb_flash_init_vfs_littlefs(vfs_littlefs);
478+
479+
if(spi_flash_get_chip_size() > (4* 1024 * 1024))
480+
{
481+
lfscfg.block_count = SFLASH_BLOCK_COUNT_8MB;
482+
lfscfg.lookahead = SFLASH_BLOCK_COUNT_8MB;
483+
}
484+
else
485+
{
486+
lfscfg.block_count = SFLASH_BLOCK_COUNT_4MB;
487+
lfscfg.lookahead = SFLASH_BLOCK_COUNT_4MB;
488+
}
489+
490+
// Mount the file system if exists
491+
if(LFS_ERR_OK != lfs_mount(littlefsptr, &lfscfg))
492+
{
493+
// File system does not exist, create it and mount
494+
if(LFS_ERR_OK == lfs_format(littlefsptr, &lfscfg))
495+
{
496+
if(LFS_ERR_OK != lfs_mount(littlefsptr, &lfscfg))
497+
{
498+
__fatal_error("failed to create /flash");
499+
}
500+
}
501+
else
502+
{
503+
__fatal_error("failed to create /flash");
504+
}
505+
}
506+
507+
// mount the flash device (there should be no other devices mounted at this point)
508+
// we allocate this structure on the heap because vfs->next is a root pointer
509+
mp_vfs_mount_t *vfs = m_new_obj_maybe(mp_vfs_mount_t);
510+
if (vfs == NULL) {
511+
__fatal_error("failed to create /flash");
512+
}
513+
vfs->str = "/flash";
514+
vfs->len = 6;
515+
vfs->obj = MP_OBJ_FROM_PTR(vfs_littlefs);
516+
vfs->next = NULL;
517+
MP_STATE_VM(vfs_mount_table) = vfs;
518+
519+
// The current directory is used as the boot up directory.
520+
// It is set to the internal flash filesystem by default.
521+
MP_STATE_PORT(vfs_cur) = vfs;
522+
523+
//Initialize the current working directory (cwd)
524+
vfs_littlefs->fs.littlefs.cwd = (char*)m_malloc(2);
525+
vfs_littlefs->fs.littlefs.cwd[0] = '/';
526+
vfs_littlefs->fs.littlefs.cwd[1] = '\0';
527+
528+
MP_STATE_PORT(lfs_cwd) = vfs_littlefs->fs.littlefs.cwd;
529+
vfs_littlefs->fs.littlefs.mutex = xSemaphoreCreateMutex();
530+
531+
xSemaphoreTake(vfs_littlefs->fs.littlefs.mutex, portMAX_DELAY);
532+
533+
// create empty main.py if does not exist
534+
lfs_file_t fp;
535+
lfs_ssize_t n = 0;
536+
537+
if(LFS_ERR_OK == lfs_file_open(littlefsptr, &fp, "/main.py", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL))
538+
{
539+
//Create empty main.py if does not exist
540+
n = lfs_file_write(littlefsptr, &fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */);
541+
lfs_file_close(littlefsptr, &fp);
542+
if(n != sizeof(fresh_main_py) - 1)
543+
{
544+
__fatal_error("failed to create main.py");
545+
}
546+
}
547+
548+
// create empty boot.py if does not exist
549+
if(LFS_ERR_OK == lfs_file_open(littlefsptr, &fp, "/boot.py", LFS_O_WRONLY | LFS_O_CREAT | LFS_O_EXCL))
550+
{
551+
//Create empty boot.py if does not exist
552+
n = lfs_file_write(littlefsptr, &fp, fresh_boot_py, sizeof(fresh_boot_py) - 1 /* don't count null terminator */);
553+
lfs_file_close(littlefsptr, &fp);
554+
if(n != sizeof(fresh_boot_py) - 1)
555+
{
556+
__fatal_error("failed to create boot.py");
557+
}
558+
}
559+
560+
// create /flash/sys, /flash/lib and /flash/cert if they don't exist
561+
lfs_mkdir(littlefsptr,"/sys");
562+
lfs_mkdir(littlefsptr,"/lib");
563+
lfs_mkdir(littlefsptr,"/cert");
564+
565+
xSemaphoreGive(vfs_littlefs->fs.littlefs.mutex);
566+
}
567+
568+
449569
#if defined(LOPY) || defined(SIPY) || defined (LOPY4) || defined(FIPY)
450570
STATIC void mptask_update_lpwan_mac_address (void) {
451571
#define LPWAN_MAC_ADDR_PATH "/sys/lpwan.mac"
@@ -517,6 +637,14 @@ STATIC void mptask_enable_wifi_ap (void) {
517637
mod_network_register_nic(&wlan_obj);
518638
}
519639

640+
STATIC void mptask_create_main_py (void) {
641+
// create empty main.py
642+
FIL fp;
643+
f_open(&sflash_vfs_flash.fs.fatfs, &fp, "/main.py", FA_WRITE | FA_CREATE_ALWAYS);
644+
UINT n;
645+
f_write(&fp, fresh_main_py, sizeof(fresh_main_py) - 1 /* don't count null terminator */, &n);
646+
f_close(&fp);
647+
}
520648

521649
void stoupper (char *str) {
522650
while (str && *str != '\0') {

esp32/pycom_config.c

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ static pycom_config_block_t pycom_config_block;
2626
void config_init0 (void) {
2727
// read the config struct from flash
2828
spi_flash_read(CONFIG_DATA_FLASH_ADDR, (void *)&pycom_config_block, sizeof(pycom_config_block));
29-
// printf("Config block has size: %d\n", sizeof(pycom_config_block));
3029
}
3130

3231
bool config_set_lpwan_mac (const uint8_t *mac) {
@@ -168,8 +167,34 @@ void config_get_wifi_pwd (uint8_t *wifi_pwd) {
168167
}
169168
}
170169

170+
uint8_t config_get_boot_partition (void) {
171+
if (pycom_config_block.pycom_config.boot_partition==0xff) {
172+
return 0x00;
173+
}
174+
return pycom_config_block.pycom_config.boot_partition;
175+
}
176+
177+
bool config_set_boot_partition (const uint8_t boot_partition) {
178+
pycom_config_block.pycom_config.boot_partition=boot_partition;
179+
return config_write();
180+
}
181+
182+
uint8_t config_get_boot_fs_type (void) {
183+
#ifdef FS_USE_LITTLEFS
184+
return 0x01;
185+
#endif
186+
if (pycom_config_block.pycom_config.boot_fs_type==0xff) {
187+
return 0x00;
188+
}
189+
return pycom_config_block.pycom_config.boot_fs_type;
190+
}
191+
192+
bool config_set_boot_fs_type (const uint8_t boot_fs_type) {
193+
pycom_config_block.pycom_config.boot_fs_type=boot_fs_type;
194+
return config_write();
195+
}
196+
171197
static bool config_write (void) {
172-
// printf("Config block has size: %d\n", sizeof(pycom_config_block));
173198
// erase the block first
174199
if (ESP_OK == spi_flash_erase_sector(CONFIG_DATA_FLASH_BLOCK)) {
175200
// then write it

0 commit comments

Comments
 (0)
0