diff --git a/lib/libesp32/berry/generate/be_const_strtab.h b/lib/libesp32/berry/generate/be_const_strtab.h index 5ae3888e6..825b5b69c 100644 --- a/lib/libesp32/berry/generate/be_const_strtab.h +++ b/lib/libesp32/berry/generate/be_const_strtab.h @@ -913,6 +913,7 @@ extern const bcstring be_const_str_subscribe; extern const bcstring be_const_str_subtype; extern const bcstring be_const_str_success; extern const bcstring be_const_str_super; +extern const bcstring be_const_str_switch_safeboot; extern const bcstring be_const_str_sys; extern const bcstring be_const_str_tag; extern const bcstring be_const_str_tan; diff --git a/lib/libesp32/berry/generate/be_const_strtab_def.h b/lib/libesp32/berry/generate/be_const_strtab_def.h index 382db86bf..52248982d 100644 --- a/lib/libesp32/berry/generate/be_const_strtab_def.h +++ b/lib/libesp32/berry/generate/be_const_strtab_def.h @@ -276,7 +276,7 @@ be_define_const_str(adv_block, "adv_block", 4243837184u, 0, 9, NULL); be_define_const_str(adv_cb, "adv_cb", 1957890034u, 0, 6, &be_const_str_dirty); be_define_const_str(adv_watch, "adv_watch", 3871786950u, 0, 9, &be_const_str_connection_error); be_define_const_str(allocated, "allocated", 429986098u, 0, 9, &be_const_str_check_privileged_access); -be_define_const_str(alternate, "alternate", 1140253277u, 0, 9, NULL); +be_define_const_str(alternate, "alternate", 1140253277u, 0, 9, &be_const_str_switch_safeboot); be_define_const_str(animate, "animate", 3885786800u, 0, 7, &be_const_str_gamma10); be_define_const_str(animators, "animators", 279858213u, 0, 9, &be_const_str_bus); be_define_const_str(app, "app", 527074092u, 0, 3, &be_const_str_refr_pos); @@ -905,6 +905,7 @@ be_define_const_str(subscribe, "subscribe", 2946386435u, 0, 9, NULL); be_define_const_str(subtype, "subtype", 2023873341u, 0, 7, NULL); be_define_const_str(success, "success", 979353360u, 0, 7, NULL); be_define_const_str(super, "super", 4152230356u, 0, 5, NULL); +be_define_const_str(switch_safeboot, "switch_safeboot", 1833415835u, 0, 15, NULL); be_define_const_str(sys, "sys", 3277365014u, 0, 3, NULL); be_define_const_str(tag, "tag", 2516003219u, 0, 3, NULL); be_define_const_str(tan, "tan", 2633446552u, 0, 3, &be_const_str_tcpclient); @@ -1530,6 +1531,6 @@ static const bstring* const m_string_table[] = { static const struct bconststrtab m_const_string_table = { .size = 501, - .count = 1025, + .count = 1026, .table = m_string_table }; diff --git a/lib/libesp32/berry_tasmota/src/be_partition_core_module.c b/lib/libesp32/berry_tasmota/src/be_partition_core_module.c index 6231e667f..cc5670952 100644 --- a/lib/libesp32/berry_tasmota/src/be_partition_core_module.c +++ b/lib/libesp32/berry_tasmota/src/be_partition_core_module.c @@ -7,46 +7,6 @@ *******************************************************************/ #include "be_constobj.h" -/******************************************************************** -** Solidified function: tostring -********************************************************************/ -be_local_closure(Partition_otadata_tostring, /* name */ - be_nested_proto( - 9, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_nested_str(string), - /* K1 */ be_nested_str(format), - /* K2 */ be_nested_str(_X3Cinstance_X3A_X20Partition_otadata_X28ota_active_X3A_X25d_X2C_X20ota_seq_X3D_X5B_X25d_X2C_X25d_X5D_X2C_X20ota_max_X3D_X25d_X29_X3E), - /* K3 */ be_nested_str(active_otadata), - /* K4 */ be_nested_str(seq0), - /* K5 */ be_nested_str(seq1), - /* K6 */ be_nested_str(maxota), - }), - &be_const_str_tostring, - &be_const_str_solidified, - ( &(const binstruction[ 9]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080301, // 0001 GETMET R2 R1 K1 - 0x58100002, // 0002 LDCONST R4 K2 - 0x88140103, // 0003 GETMBR R5 R0 K3 - 0x88180104, // 0004 GETMBR R6 R0 K4 - 0x881C0105, // 0005 GETMBR R7 R0 K5 - 0x88200106, // 0006 GETMBR R8 R0 K6 - 0x7C080C00, // 0007 CALL R2 6 - 0x80040400, // 0008 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: load ********************************************************************/ @@ -213,6 +173,106 @@ be_local_closure(Partition_otadata_save, /* name */ /*******************************************************************/ +/******************************************************************** +** Solidified function: tostring +********************************************************************/ +be_local_closure(Partition_otadata_tostring, /* name */ + be_nested_proto( + 9, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_nested_str(string), + /* K1 */ be_nested_str(format), + /* K2 */ be_nested_str(_X3Cinstance_X3A_X20Partition_otadata_X28ota_active_X3A_X25d_X2C_X20ota_seq_X3D_X5B_X25d_X2C_X25d_X5D_X2C_X20ota_max_X3D_X25d_X29_X3E), + /* K3 */ be_nested_str(active_otadata), + /* K4 */ be_nested_str(seq0), + /* K5 */ be_nested_str(seq1), + /* K6 */ be_nested_str(maxota), + }), + &be_const_str_tostring, + &be_const_str_solidified, + ( &(const binstruction[ 9]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080301, // 0001 GETMET R2 R1 K1 + 0x58100002, // 0002 LDCONST R4 K2 + 0x88140103, // 0003 GETMBR R5 R0 K3 + 0x88180104, // 0004 GETMBR R6 R0 K4 + 0x881C0105, // 0005 GETMBR R7 R0 K5 + 0x88200106, // 0006 GETMBR R8 R0 K6 + 0x7C080C00, // 0007 CALL R2 6 + 0x80040400, // 0008 RET 1 R2 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: _validate +********************************************************************/ +be_local_closure(Partition_otadata__validate, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str(active_otadata), + /* K1 */ be_const_int(0), + /* K2 */ be_nested_str(seq0), + /* K3 */ be_const_int(1), + /* K4 */ be_nested_str(maxota), + /* K5 */ be_nested_str(seq1), + }), + &be_const_str__validate, + &be_const_str_solidified, + ( &(const binstruction[30]) { /* code */ + 0x90020101, // 0000 SETMBR R0 K0 K1 + 0x88040102, // 0001 GETMBR R1 R0 K2 + 0x4C080000, // 0002 LDNIL R2 + 0x20040202, // 0003 NE R1 R1 R2 + 0x78060005, // 0004 JMPF R1 #000B + 0x88040102, // 0005 GETMBR R1 R0 K2 + 0x04040303, // 0006 SUB R1 R1 K3 + 0x88080104, // 0007 GETMBR R2 R0 K4 + 0x00080503, // 0008 ADD R2 R2 K3 + 0x10040202, // 0009 MOD R1 R1 R2 + 0x90020001, // 000A SETMBR R0 K0 R1 + 0x88040105, // 000B GETMBR R1 R0 K5 + 0x4C080000, // 000C LDNIL R2 + 0x20040202, // 000D NE R1 R1 R2 + 0x7806000D, // 000E JMPF R1 #001D + 0x88040102, // 000F GETMBR R1 R0 K2 + 0x4C080000, // 0010 LDNIL R2 + 0x1C040202, // 0011 EQ R1 R1 R2 + 0x74060003, // 0012 JMPT R1 #0017 + 0x88040105, // 0013 GETMBR R1 R0 K5 + 0x88080102, // 0014 GETMBR R2 R0 K2 + 0x24040202, // 0015 GT R1 R1 R2 + 0x78060005, // 0016 JMPF R1 #001D + 0x88040105, // 0017 GETMBR R1 R0 K5 + 0x04040303, // 0018 SUB R1 R1 K3 + 0x88080104, // 0019 GETMBR R2 R0 K4 + 0x00080503, // 001A ADD R2 R2 K3 + 0x10040202, // 001B MOD R1 R1 R2 + 0x90020001, // 001C SETMBR R0 K0 R1 + 0x80000000, // 001D RET 0 + }) + ) +); +/*******************************************************************/ + + /******************************************************************** ** Solidified function: init ********************************************************************/ @@ -331,33 +391,6 @@ be_local_closure(Partition_otadata_set_active, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: set_ota_max -********************************************************************/ -be_local_closure(Partition_otadata_set_ota_max, /* name */ - be_nested_proto( - 2, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 1]) { /* constants */ - /* K0 */ be_nested_str(maxota), - }), - &be_const_str_set_ota_max, - &be_const_str_solidified, - ( &(const binstruction[ 2]) { /* code */ - 0x90020001, // 0000 SETMBR R0 K0 R1 - 0x80000000, // 0001 RET 0 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: crc32_ota_seq ********************************************************************/ @@ -397,11 +430,11 @@ be_local_closure(Partition_otadata_crc32_ota_seq, /* name */ /******************************************************************** -** Solidified function: _validate +** Solidified function: clear ********************************************************************/ -be_local_closure(Partition_otadata__validate, /* name */ +be_local_closure(Partition_otadata_clear, /* name */ be_nested_proto( - 3, /* nstack */ + 6, /* nstack */ 1, /* argc */ 2, /* varg */ 0, /* has upvals */ @@ -409,47 +442,61 @@ be_local_closure(Partition_otadata__validate, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str(active_otadata), - /* K1 */ be_const_int(0), - /* K2 */ be_nested_str(seq0), - /* K3 */ be_const_int(1), - /* K4 */ be_nested_str(maxota), - /* K5 */ be_nested_str(seq1), + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_nested_str(flash), + /* K1 */ be_nested_str(b), + /* K2 */ be_nested_str(resize), + /* K3 */ be_nested_str(write), + /* K4 */ be_nested_str(offset), }), - &be_const_str__validate, + &be_const_str_clear, &be_const_str_solidified, - ( &(const binstruction[30]) { /* code */ - 0x90020101, // 0000 SETMBR R0 K0 K1 - 0x88040102, // 0001 GETMBR R1 R0 K2 - 0x4C080000, // 0002 LDNIL R2 - 0x20040202, // 0003 NE R1 R1 R2 - 0x78060005, // 0004 JMPF R1 #000B - 0x88040102, // 0005 GETMBR R1 R0 K2 - 0x04040303, // 0006 SUB R1 R1 K3 - 0x88080104, // 0007 GETMBR R2 R0 K4 - 0x00080503, // 0008 ADD R2 R2 K3 - 0x10040202, // 0009 MOD R1 R1 R2 - 0x90020001, // 000A SETMBR R0 K0 R1 - 0x88040105, // 000B GETMBR R1 R0 K5 - 0x4C080000, // 000C LDNIL R2 - 0x20040202, // 000D NE R1 R1 R2 - 0x7806000D, // 000E JMPF R1 #001D - 0x88040102, // 000F GETMBR R1 R0 K2 - 0x4C080000, // 0010 LDNIL R2 - 0x1C040202, // 0011 EQ R1 R1 R2 - 0x74060003, // 0012 JMPT R1 #0017 - 0x88040105, // 0013 GETMBR R1 R0 K5 - 0x88080102, // 0014 GETMBR R2 R0 K2 - 0x24040202, // 0015 GT R1 R1 R2 - 0x78060005, // 0016 JMPF R1 #001D - 0x88040105, // 0017 GETMBR R1 R0 K5 - 0x04040303, // 0018 SUB R1 R1 K3 - 0x88080104, // 0019 GETMBR R2 R0 K4 - 0x00080503, // 001A ADD R2 R2 K3 - 0x10040202, // 001B MOD R1 R1 R2 - 0x90020001, // 001C SETMBR R0 K0 R1 - 0x80000000, // 001D RET 0 + ( &(const binstruction[18]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x60080015, // 0001 GETGBL R2 G21 + 0x7C080000, // 0002 CALL R2 0 + 0x8C080502, // 0003 GETMET R2 R2 K2 + 0x5412001F, // 0004 LDINT R4 32 + 0x7C080400, // 0005 CALL R2 2 + 0xBC0A0200, // 0006 SETNGBL R2 K1 + 0x8C080303, // 0007 GETMET R2 R1 K3 + 0x88100104, // 0008 GETMBR R4 R0 K4 + 0xB8160200, // 0009 GETNGBL R5 K1 + 0x7C080600, // 000A CALL R2 3 + 0x8C080303, // 000B GETMET R2 R1 K3 + 0x88100104, // 000C GETMBR R4 R0 K4 + 0x54160FFF, // 000D LDINT R5 4096 + 0x00100805, // 000E ADD R4 R4 R5 + 0xB8160200, // 000F GETNGBL R5 K1 + 0x7C080600, // 0010 CALL R2 3 + 0x80000000, // 0011 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_ota_max +********************************************************************/ +be_local_closure(Partition_otadata_set_ota_max, /* name */ + be_nested_proto( + 2, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 1]) { /* constants */ + /* K0 */ be_nested_str(maxota), + }), + &be_const_str_set_ota_max, + &be_const_str_solidified, + ( &(const binstruction[ 2]) { /* code */ + 0x90020001, // 0000 SETMBR R0 K0 R1 + 0x80000000, // 0001 RET 0 }) ) ); @@ -462,21 +509,22 @@ be_local_closure(Partition_otadata__validate, /* name */ be_local_class(Partition_otadata, 5, NULL, - be_nested_map(13, + be_nested_map(14, ( (struct bmapnode*) &(const bmapnode[]) { - { be_const_key(tostring, 1), be_const_closure(Partition_otadata_tostring_closure) }, - { be_const_key(_validate, -1), be_const_closure(Partition_otadata__validate_closure) }, - { be_const_key(crc32_ota_seq, 12), be_const_static_closure(Partition_otadata_crc32_ota_seq_closure) }, - { be_const_key(active_otadata, -1), be_const_var(2) }, - { be_const_key(save, 8), be_const_closure(Partition_otadata_save_closure) }, - { be_const_key(seq1, -1), be_const_var(4) }, - { be_const_key(init, 7), be_const_closure(Partition_otadata_init_closure) }, { be_const_key(set_ota_max, -1), be_const_closure(Partition_otadata_set_ota_max_closure) }, - { be_const_key(seq0, 10), be_const_var(3) }, - { be_const_key(set_active, -1), be_const_closure(Partition_otadata_set_active_closure) }, - { be_const_key(offset, -1), be_const_var(1) }, - { be_const_key(load, 2), be_const_closure(Partition_otadata_load_closure) }, + { be_const_key(seq1, 8), be_const_var(4) }, + { be_const_key(save, -1), be_const_closure(Partition_otadata_save_closure) }, + { be_const_key(tostring, -1), be_const_closure(Partition_otadata_tostring_closure) }, + { be_const_key(_validate, -1), be_const_closure(Partition_otadata__validate_closure) }, + { be_const_key(init, 0), be_const_closure(Partition_otadata_init_closure) }, + { be_const_key(clear, -1), be_const_closure(Partition_otadata_clear_closure) }, + { be_const_key(load, 13), be_const_closure(Partition_otadata_load_closure) }, { be_const_key(maxota, -1), be_const_var(0) }, + { be_const_key(active_otadata, 11), be_const_var(2) }, + { be_const_key(offset, 9), be_const_var(1) }, + { be_const_key(seq0, -1), be_const_var(3) }, + { be_const_key(set_active, 6), be_const_closure(Partition_otadata_set_active_closure) }, + { be_const_key(crc32_ota_seq, -1), be_const_static_closure(Partition_otadata_crc32_ota_seq_closure) }, })), (bstring*) &be_const_str_Partition_otadata ); @@ -543,174 +591,6 @@ be_local_closure(Partition_load_otadata, /* name */ /*******************************************************************/ -/******************************************************************** -** Solidified function: get_active -********************************************************************/ -be_local_closure(Partition_get_active, /* name */ - be_nested_proto( - 2, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 2]) { /* constants */ - /* K0 */ be_nested_str(otadata), - /* K1 */ be_nested_str(active_otadata), - }), - &be_const_str_get_active, - &be_const_str_solidified, - ( &(const binstruction[ 3]) { /* code */ - 0x88040100, // 0000 GETMBR R1 R0 K0 - 0x88040301, // 0001 GETMBR R1 R1 K1 - 0x80040200, // 0002 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: init -********************************************************************/ -be_local_closure(Partition_init, /* name */ - be_nested_proto( - 3, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 4]) { /* constants */ - /* K0 */ be_nested_str(slots), - /* K1 */ be_nested_str(load), - /* K2 */ be_nested_str(parse), - /* K3 */ be_nested_str(load_otadata), - }), - &be_const_str_init, - &be_const_str_solidified, - ( &(const binstruction[10]) { /* code */ - 0x60040012, // 0000 GETGBL R1 G18 - 0x7C040000, // 0001 CALL R1 0 - 0x90020001, // 0002 SETMBR R0 K0 R1 - 0x8C040101, // 0003 GETMET R1 R0 K1 - 0x7C040200, // 0004 CALL R1 1 - 0x8C040102, // 0005 GETMET R1 R0 K2 - 0x7C040200, // 0006 CALL R1 1 - 0x8C040103, // 0007 GETMET R1 R0 K3 - 0x7C040200, // 0008 CALL R1 1 - 0x80000000, // 0009 RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: get_ota_slot -********************************************************************/ -be_local_closure(Partition_get_ota_slot, /* name */ - be_nested_proto( - 6, /* nstack */ - 2, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str(slots), - /* K1 */ be_nested_str(is_ota), - /* K2 */ be_nested_str(stop_iteration), - }), - &be_const_str_get_ota_slot, - &be_const_str_solidified, - ( &(const binstruction[18]) { /* code */ - 0x60080010, // 0000 GETGBL R2 G16 - 0x880C0100, // 0001 GETMBR R3 R0 K0 - 0x7C080200, // 0002 CALL R2 1 - 0xA8020008, // 0003 EXBLK 0 #000D - 0x5C0C0400, // 0004 MOVE R3 R2 - 0x7C0C0000, // 0005 CALL R3 0 - 0x8C100701, // 0006 GETMET R4 R3 K1 - 0x7C100200, // 0007 CALL R4 1 - 0x1C100801, // 0008 EQ R4 R4 R1 - 0x78120001, // 0009 JMPF R4 #000C - 0xA8040001, // 000A EXBLK 1 1 - 0x80040600, // 000B RET 1 R3 - 0x7001FFF6, // 000C JMP #0004 - 0x58080002, // 000D LDCONST R2 K2 - 0xAC080200, // 000E CATCH R2 1 0 - 0xB0080000, // 000F RAISE 2 R0 R0 - 0x4C080000, // 0010 LDNIL R2 - 0x80040400, // 0011 RET 1 R2 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: tostring -********************************************************************/ -be_local_closure(Partition_tostring, /* name */ - be_nested_proto( - 6, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 9]) { /* constants */ - /* K0 */ be_nested_str(_X3Cinstance_X3A_X20Partition_X28_X5B_X0A), - /* K1 */ be_nested_str(slots), - /* K2 */ be_nested_str(_X20_X20), - /* K3 */ be_nested_str(tostring), - /* K4 */ be_nested_str(_X0A), - /* K5 */ be_nested_str(stop_iteration), - /* K6 */ be_nested_str(_X5D_X2C_X0A_X20_X20), - /* K7 */ be_nested_str(otadata), - /* K8 */ be_nested_str(_X0A_X29_X3E), - }), - &be_const_str_tostring, - &be_const_str_solidified, - ( &(const binstruction[23]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x60080010, // 0001 GETGBL R2 G16 - 0x880C0101, // 0002 GETMBR R3 R0 K1 - 0x7C080200, // 0003 CALL R2 1 - 0xA8020007, // 0004 EXBLK 0 #000D - 0x5C0C0400, // 0005 MOVE R3 R2 - 0x7C0C0000, // 0006 CALL R3 0 - 0x00040302, // 0007 ADD R1 R1 K2 - 0x8C100703, // 0008 GETMET R4 R3 K3 - 0x7C100200, // 0009 CALL R4 1 - 0x00040204, // 000A ADD R1 R1 R4 - 0x00040304, // 000B ADD R1 R1 K4 - 0x7001FFF7, // 000C JMP #0005 - 0x58080005, // 000D LDCONST R2 K5 - 0xAC080200, // 000E CATCH R2 1 0 - 0xB0080000, // 000F RAISE 2 R0 R0 - 0x00040306, // 0010 ADD R1 R1 K6 - 0x88080107, // 0011 GETMBR R2 R0 K7 - 0x8C080503, // 0012 GETMET R2 R2 K3 - 0x7C080200, // 0013 CALL R2 1 - 0x00040202, // 0014 ADD R1 R1 R2 - 0x00040308, // 0015 ADD R1 R1 K8 - 0x80040200, // 0016 RET 1 R1 - }) - ) -); -/*******************************************************************/ - - /******************************************************************** ** Solidified function: tobytes ********************************************************************/ @@ -780,54 +660,9 @@ be_local_closure(Partition_tobytes, /* name */ /******************************************************************** -** Solidified function: save +** Solidified function: tostring ********************************************************************/ -be_local_closure(Partition_save, /* name */ - be_nested_proto( - 7, /* nstack */ - 1, /* argc */ - 2, /* varg */ - 0, /* has upvals */ - NULL, /* no upvals */ - 0, /* has sup protos */ - NULL, /* no sub protos */ - 1, /* has constants */ - ( &(const bvalue[ 6]) { /* constants */ - /* K0 */ be_nested_str(flash), - /* K1 */ be_nested_str(tobytes), - /* K2 */ be_nested_str(erase), - /* K3 */ be_nested_str(write), - /* K4 */ be_nested_str(otadata), - /* K5 */ be_nested_str(save), - }), - &be_const_str_save, - &be_const_str_solidified, - ( &(const binstruction[15]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080101, // 0001 GETMET R2 R0 K1 - 0x7C080200, // 0002 CALL R2 1 - 0x8C0C0302, // 0003 GETMET R3 R1 K2 - 0x54167FFF, // 0004 LDINT R5 32768 - 0x541A0FFF, // 0005 LDINT R6 4096 - 0x7C0C0600, // 0006 CALL R3 3 - 0x8C0C0303, // 0007 GETMET R3 R1 K3 - 0x54167FFF, // 0008 LDINT R5 32768 - 0x5C180400, // 0009 MOVE R6 R2 - 0x7C0C0600, // 000A CALL R3 3 - 0x880C0104, // 000B GETMBR R3 R0 K4 - 0x8C0C0705, // 000C GETMET R3 R3 K5 - 0x7C0C0200, // 000D CALL R3 1 - 0x80000000, // 000E RET 0 - }) - ) -); -/*******************************************************************/ - - -/******************************************************************** -** Solidified function: load -********************************************************************/ -be_local_closure(Partition_load, /* name */ +be_local_closure(Partition_tostring, /* name */ be_nested_proto( 6, /* nstack */ 1, /* argc */ @@ -837,21 +672,198 @@ be_local_closure(Partition_load, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 3]) { /* constants */ - /* K0 */ be_nested_str(flash), - /* K1 */ be_nested_str(raw), - /* K2 */ be_nested_str(read), + ( &(const bvalue[ 9]) { /* constants */ + /* K0 */ be_nested_str(_X3Cinstance_X3A_X20Partition_X28_X5B_X0A), + /* K1 */ be_nested_str(slots), + /* K2 */ be_nested_str(_X20_X20), + /* K3 */ be_nested_str(tostring), + /* K4 */ be_nested_str(_X0A), + /* K5 */ be_nested_str(stop_iteration), + /* K6 */ be_nested_str(_X5D_X2C_X0A_X20_X20), + /* K7 */ be_nested_str(otadata), + /* K8 */ be_nested_str(_X0A_X29_X3E), }), - &be_const_str_load, + &be_const_str_tostring, &be_const_str_solidified, - ( &(const binstruction[ 7]) { /* code */ - 0xA4060000, // 0000 IMPORT R1 K0 - 0x8C080302, // 0001 GETMET R2 R1 K2 - 0x54127FFF, // 0002 LDINT R4 32768 - 0x54160FFF, // 0003 LDINT R5 4096 - 0x7C080600, // 0004 CALL R2 3 - 0x90020202, // 0005 SETMBR R0 K1 R2 - 0x80000000, // 0006 RET 0 + ( &(const binstruction[23]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x60080010, // 0001 GETGBL R2 G16 + 0x880C0101, // 0002 GETMBR R3 R0 K1 + 0x7C080200, // 0003 CALL R2 1 + 0xA8020007, // 0004 EXBLK 0 #000D + 0x5C0C0400, // 0005 MOVE R3 R2 + 0x7C0C0000, // 0006 CALL R3 0 + 0x00040302, // 0007 ADD R1 R1 K2 + 0x8C100703, // 0008 GETMET R4 R3 K3 + 0x7C100200, // 0009 CALL R4 1 + 0x00040204, // 000A ADD R1 R1 R4 + 0x00040304, // 000B ADD R1 R1 K4 + 0x7001FFF7, // 000C JMP #0005 + 0x58080005, // 000D LDCONST R2 K5 + 0xAC080200, // 000E CATCH R2 1 0 + 0xB0080000, // 000F RAISE 2 R0 R0 + 0x00040306, // 0010 ADD R1 R1 K6 + 0x88080107, // 0011 GETMBR R2 R0 K7 + 0x8C080503, // 0012 GETMET R2 R2 K3 + 0x7C080200, // 0013 CALL R2 1 + 0x00040202, // 0014 ADD R1 R1 R2 + 0x00040308, // 0015 ADD R1 R1 K8 + 0x80040200, // 0016 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_active +********************************************************************/ +be_local_closure(Partition_get_active, /* name */ + be_nested_proto( + 2, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str(otadata), + /* K1 */ be_nested_str(active_otadata), + }), + &be_const_str_get_active, + &be_const_str_solidified, + ( &(const binstruction[ 3]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x88040301, // 0001 GETMBR R1 R1 K1 + 0x80040200, // 0002 RET 1 R1 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: switch_safeboot +********************************************************************/ +be_local_closure(Partition_switch_safeboot, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 2]) { /* constants */ + /* K0 */ be_nested_str(otadata), + /* K1 */ be_nested_str(clear), + }), + &be_const_str_switch_safeboot, + &be_const_str_solidified, + ( &(const binstruction[ 4]) { /* code */ + 0x88040100, // 0000 GETMBR R1 R0 K0 + 0x8C040301, // 0001 GETMET R1 R1 K1 + 0x7C040200, // 0002 CALL R1 1 + 0x80000000, // 0003 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: init +********************************************************************/ +be_local_closure(Partition_init, /* name */ + be_nested_proto( + 3, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 4]) { /* constants */ + /* K0 */ be_nested_str(slots), + /* K1 */ be_nested_str(load), + /* K2 */ be_nested_str(parse), + /* K3 */ be_nested_str(load_otadata), + }), + &be_const_str_init, + &be_const_str_solidified, + ( &(const binstruction[10]) { /* code */ + 0x60040012, // 0000 GETGBL R1 G18 + 0x7C040000, // 0001 CALL R1 0 + 0x90020001, // 0002 SETMBR R0 K0 R1 + 0x8C040101, // 0003 GETMET R1 R0 K1 + 0x7C040200, // 0004 CALL R1 1 + 0x8C040102, // 0005 GETMET R1 R0 K2 + 0x7C040200, // 0006 CALL R1 1 + 0x8C040103, // 0007 GETMET R1 R0 K3 + 0x7C040200, // 0008 CALL R1 1 + 0x80000000, // 0009 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: ota_max +********************************************************************/ +be_local_closure(Partition_ota_max, /* name */ + be_nested_proto( + 6, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 5]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str(slots), + /* K2 */ be_nested_str(type), + /* K3 */ be_nested_str(subtype), + /* K4 */ be_nested_str(stop_iteration), + }), + &be_const_str_ota_max, + &be_const_str_solidified, + ( &(const binstruction[29]) { /* code */ + 0x58040000, // 0000 LDCONST R1 K0 + 0x60080010, // 0001 GETGBL R2 G16 + 0x880C0101, // 0002 GETMBR R3 R0 K1 + 0x7C080200, // 0003 CALL R2 1 + 0xA8020013, // 0004 EXBLK 0 #0019 + 0x5C0C0400, // 0005 MOVE R3 R2 + 0x7C0C0000, // 0006 CALL R3 0 + 0x88100702, // 0007 GETMBR R4 R3 K2 + 0x1C100900, // 0008 EQ R4 R4 K0 + 0x7812000D, // 0009 JMPF R4 #0018 + 0x88100703, // 000A GETMBR R4 R3 K3 + 0x5416000F, // 000B LDINT R5 16 + 0x28100805, // 000C GE R4 R4 R5 + 0x78120009, // 000D JMPF R4 #0018 + 0x88100703, // 000E GETMBR R4 R3 K3 + 0x5416001F, // 000F LDINT R5 32 + 0x14100805, // 0010 LT R4 R4 R5 + 0x78120005, // 0011 JMPF R4 #0018 + 0x88100703, // 0012 GETMBR R4 R3 K3 + 0x5416000F, // 0013 LDINT R5 16 + 0x04100805, // 0014 SUB R4 R4 R5 + 0x24140801, // 0015 GT R5 R4 R1 + 0x78160000, // 0016 JMPF R5 #0018 + 0x5C040800, // 0017 MOVE R1 R4 + 0x7001FFEB, // 0018 JMP #0005 + 0x58080004, // 0019 LDCONST R2 K4 + 0xAC080200, // 001A CATCH R2 1 0 + 0xB0080000, // 001B RAISE 2 R0 R0 + 0x80040200, // 001C RET 1 R1 }) ) ); @@ -913,9 +925,54 @@ be_local_closure(Partition_invalidate_spiffs, /* name */ /******************************************************************** -** Solidified function: set_active +** Solidified function: save ********************************************************************/ -be_local_closure(Partition_set_active, /* name */ +be_local_closure(Partition_save, /* name */ + be_nested_proto( + 7, /* nstack */ + 1, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 6]) { /* constants */ + /* K0 */ be_nested_str(flash), + /* K1 */ be_nested_str(tobytes), + /* K2 */ be_nested_str(erase), + /* K3 */ be_nested_str(write), + /* K4 */ be_nested_str(otadata), + /* K5 */ be_nested_str(save), + }), + &be_const_str_save, + &be_const_str_solidified, + ( &(const binstruction[15]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080101, // 0001 GETMET R2 R0 K1 + 0x7C080200, // 0002 CALL R2 1 + 0x8C0C0302, // 0003 GETMET R3 R1 K2 + 0x54167FFF, // 0004 LDINT R5 32768 + 0x541A0FFF, // 0005 LDINT R6 4096 + 0x7C0C0600, // 0006 CALL R3 3 + 0x8C0C0303, // 0007 GETMET R3 R1 K3 + 0x54167FFF, // 0008 LDINT R5 32768 + 0x5C180400, // 0009 MOVE R6 R2 + 0x7C0C0600, // 000A CALL R3 3 + 0x880C0104, // 000B GETMBR R3 R0 K4 + 0x8C0C0705, // 000C GETMET R3 R3 K5 + 0x7C0C0200, // 000D CALL R3 1 + 0x80000000, // 000E RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: get_ota_slot +********************************************************************/ +be_local_closure(Partition_get_ota_slot, /* name */ be_nested_proto( 6, /* nstack */ 2, /* argc */ @@ -925,35 +982,32 @@ be_local_closure(Partition_set_active, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 7]) { /* constants */ - /* K0 */ be_const_int(0), - /* K1 */ be_nested_str(ota_max), - /* K2 */ be_nested_str(value_error), - /* K3 */ be_nested_str(Invalid_X20ota_X20partition_X20number), - /* K4 */ be_nested_str(otadata), - /* K5 */ be_nested_str(set_ota_max), - /* K6 */ be_nested_str(set_active), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str(slots), + /* K1 */ be_nested_str(is_ota), + /* K2 */ be_nested_str(stop_iteration), }), - &be_const_str_set_active, + &be_const_str_get_ota_slot, &be_const_str_solidified, - ( &(const binstruction[17]) { /* code */ - 0x14080300, // 0000 LT R2 R1 K0 - 0x740A0003, // 0001 JMPT R2 #0006 - 0x8C080101, // 0002 GETMET R2 R0 K1 - 0x7C080200, // 0003 CALL R2 1 - 0x24080202, // 0004 GT R2 R1 R2 - 0x780A0000, // 0005 JMPF R2 #0007 - 0xB0060503, // 0006 RAISE 1 K2 K3 - 0x88080104, // 0007 GETMBR R2 R0 K4 - 0x8C080505, // 0008 GETMET R2 R2 K5 - 0x8C100101, // 0009 GETMET R4 R0 K1 - 0x7C100200, // 000A CALL R4 1 - 0x7C080400, // 000B CALL R2 2 - 0x88080104, // 000C GETMBR R2 R0 K4 - 0x8C080506, // 000D GETMET R2 R2 K6 - 0x5C100200, // 000E MOVE R4 R1 - 0x7C080400, // 000F CALL R2 2 - 0x80000000, // 0010 RET 0 + ( &(const binstruction[18]) { /* code */ + 0x60080010, // 0000 GETGBL R2 G16 + 0x880C0100, // 0001 GETMBR R3 R0 K0 + 0x7C080200, // 0002 CALL R2 1 + 0xA8020008, // 0003 EXBLK 0 #000D + 0x5C0C0400, // 0004 MOVE R3 R2 + 0x7C0C0000, // 0005 CALL R3 0 + 0x8C100701, // 0006 GETMET R4 R3 K1 + 0x7C100200, // 0007 CALL R4 1 + 0x1C100801, // 0008 EQ R4 R4 R1 + 0x78120001, // 0009 JMPF R4 #000C + 0xA8040001, // 000A EXBLK 1 1 + 0x80040600, // 000B RET 1 R3 + 0x7001FFF6, // 000C JMP #0004 + 0x58080002, // 000D LDCONST R2 K2 + 0xAC080200, // 000E CATCH R2 1 0 + 0xB0080000, // 000F RAISE 2 R0 R0 + 0x4C080000, // 0010 LDNIL R2 + 0x80040400, // 0011 RET 1 R2 }) ) ); @@ -1053,9 +1107,9 @@ be_local_closure(Partition_parse, /* name */ /******************************************************************** -** Solidified function: ota_max +** Solidified function: load ********************************************************************/ -be_local_closure(Partition_ota_max, /* name */ +be_local_closure(Partition_load, /* name */ be_nested_proto( 6, /* nstack */ 1, /* argc */ @@ -1065,45 +1119,69 @@ be_local_closure(Partition_ota_max, /* name */ 0, /* has sup protos */ NULL, /* no sub protos */ 1, /* has constants */ - ( &(const bvalue[ 5]) { /* constants */ - /* K0 */ be_const_int(0), - /* K1 */ be_nested_str(slots), - /* K2 */ be_nested_str(type), - /* K3 */ be_nested_str(subtype), - /* K4 */ be_nested_str(stop_iteration), + ( &(const bvalue[ 3]) { /* constants */ + /* K0 */ be_nested_str(flash), + /* K1 */ be_nested_str(raw), + /* K2 */ be_nested_str(read), }), - &be_const_str_ota_max, + &be_const_str_load, &be_const_str_solidified, - ( &(const binstruction[29]) { /* code */ - 0x58040000, // 0000 LDCONST R1 K0 - 0x60080010, // 0001 GETGBL R2 G16 - 0x880C0101, // 0002 GETMBR R3 R0 K1 + ( &(const binstruction[ 7]) { /* code */ + 0xA4060000, // 0000 IMPORT R1 K0 + 0x8C080302, // 0001 GETMET R2 R1 K2 + 0x54127FFF, // 0002 LDINT R4 32768 + 0x54160FFF, // 0003 LDINT R5 4096 + 0x7C080600, // 0004 CALL R2 3 + 0x90020202, // 0005 SETMBR R0 K1 R2 + 0x80000000, // 0006 RET 0 + }) + ) +); +/*******************************************************************/ + + +/******************************************************************** +** Solidified function: set_active +********************************************************************/ +be_local_closure(Partition_set_active, /* name */ + be_nested_proto( + 6, /* nstack */ + 2, /* argc */ + 2, /* varg */ + 0, /* has upvals */ + NULL, /* no upvals */ + 0, /* has sup protos */ + NULL, /* no sub protos */ + 1, /* has constants */ + ( &(const bvalue[ 7]) { /* constants */ + /* K0 */ be_const_int(0), + /* K1 */ be_nested_str(ota_max), + /* K2 */ be_nested_str(value_error), + /* K3 */ be_nested_str(Invalid_X20ota_X20partition_X20number), + /* K4 */ be_nested_str(otadata), + /* K5 */ be_nested_str(set_ota_max), + /* K6 */ be_nested_str(set_active), + }), + &be_const_str_set_active, + &be_const_str_solidified, + ( &(const binstruction[17]) { /* code */ + 0x14080300, // 0000 LT R2 R1 K0 + 0x740A0003, // 0001 JMPT R2 #0006 + 0x8C080101, // 0002 GETMET R2 R0 K1 0x7C080200, // 0003 CALL R2 1 - 0xA8020013, // 0004 EXBLK 0 #0019 - 0x5C0C0400, // 0005 MOVE R3 R2 - 0x7C0C0000, // 0006 CALL R3 0 - 0x88100702, // 0007 GETMBR R4 R3 K2 - 0x1C100900, // 0008 EQ R4 R4 K0 - 0x7812000D, // 0009 JMPF R4 #0018 - 0x88100703, // 000A GETMBR R4 R3 K3 - 0x5416000F, // 000B LDINT R5 16 - 0x28100805, // 000C GE R4 R4 R5 - 0x78120009, // 000D JMPF R4 #0018 - 0x88100703, // 000E GETMBR R4 R3 K3 - 0x5416001F, // 000F LDINT R5 32 - 0x14100805, // 0010 LT R4 R4 R5 - 0x78120005, // 0011 JMPF R4 #0018 - 0x88100703, // 0012 GETMBR R4 R3 K3 - 0x5416000F, // 0013 LDINT R5 16 - 0x04100805, // 0014 SUB R4 R4 R5 - 0x24140801, // 0015 GT R5 R4 R1 - 0x78160000, // 0016 JMPF R5 #0018 - 0x5C040800, // 0017 MOVE R1 R4 - 0x7001FFEB, // 0018 JMP #0005 - 0x58080004, // 0019 LDCONST R2 K4 - 0xAC080200, // 001A CATCH R2 1 0 - 0xB0080000, // 001B RAISE 2 R0 R0 - 0x80040200, // 001C RET 1 R1 + 0x24080202, // 0004 GT R2 R1 R2 + 0x780A0000, // 0005 JMPF R2 #0007 + 0xB0060503, // 0006 RAISE 1 K2 K3 + 0x88080104, // 0007 GETMBR R2 R0 K4 + 0x8C080505, // 0008 GETMET R2 R2 K5 + 0x8C100101, // 0009 GETMET R4 R0 K1 + 0x7C100200, // 000A CALL R4 1 + 0x7C080400, // 000B CALL R2 2 + 0x88080104, // 000C GETMBR R2 R0 K4 + 0x8C080506, // 000D GETMET R2 R2 K6 + 0x5C100200, // 000E MOVE R4 R1 + 0x7C080400, // 000F CALL R2 2 + 0x80000000, // 0010 RET 0 }) ) ); @@ -1116,24 +1194,25 @@ be_local_closure(Partition_ota_max, /* name */ be_local_class(Partition, 4, NULL, - be_nested_map(16, + be_nested_map(17, ( (struct bmapnode*) &(const bmapnode[]) { { be_const_key(load_otadata, -1), be_const_closure(Partition_load_otadata_closure) }, - { be_const_key(raw, -1), be_const_var(0) }, - { be_const_key(get_active, -1), be_const_closure(Partition_get_active_closure) }, - { be_const_key(init, 11), be_const_closure(Partition_init_closure) }, - { be_const_key(ota_max, -1), be_const_closure(Partition_ota_max_closure) }, - { be_const_key(tostring, -1), be_const_closure(Partition_tostring_closure) }, - { be_const_key(slots, 14), be_const_var(2) }, - { be_const_key(get_ota_slot, 15), be_const_closure(Partition_get_ota_slot_closure) }, - { be_const_key(save, 4), be_const_closure(Partition_save_closure) }, - { be_const_key(load, -1), be_const_closure(Partition_load_closure) }, - { be_const_key(invalidate_spiffs, -1), be_const_closure(Partition_invalidate_spiffs_closure) }, - { be_const_key(md5, -1), be_const_var(1) }, - { be_const_key(parse, -1), be_const_closure(Partition_parse_closure) }, - { be_const_key(otadata, -1), be_const_var(3) }, { be_const_key(set_active, -1), be_const_closure(Partition_set_active_closure) }, - { be_const_key(tobytes, -1), be_const_closure(Partition_tobytes_closure) }, + { be_const_key(tostring, 12), be_const_closure(Partition_tostring_closure) }, + { be_const_key(raw, -1), be_const_var(0) }, + { be_const_key(get_active, 16), be_const_closure(Partition_get_active_closure) }, + { be_const_key(switch_safeboot, -1), be_const_closure(Partition_switch_safeboot_closure) }, + { be_const_key(load, -1), be_const_closure(Partition_load_closure) }, + { be_const_key(ota_max, 1), be_const_closure(Partition_ota_max_closure) }, + { be_const_key(slots, -1), be_const_var(2) }, + { be_const_key(save, -1), be_const_closure(Partition_save_closure) }, + { be_const_key(invalidate_spiffs, -1), be_const_closure(Partition_invalidate_spiffs_closure) }, + { be_const_key(tobytes, 9), be_const_closure(Partition_tobytes_closure) }, + { be_const_key(parse, 13), be_const_closure(Partition_parse_closure) }, + { be_const_key(get_ota_slot, -1), be_const_closure(Partition_get_ota_slot_closure) }, + { be_const_key(md5, -1), be_const_var(1) }, + { be_const_key(init, 6), be_const_closure(Partition_init_closure) }, + { be_const_key(otadata, -1), be_const_var(3) }, })), (bstring*) &be_const_str_Partition ); diff --git a/lib/libesp32/berry_tasmota/src/embedded/partition_core.be b/lib/libesp32/berry_tasmota/src/embedded/partition_core.be index 5b04c8058..8a8e18996 100644 --- a/lib/libesp32/berry_tasmota/src/embedded/partition_core.be +++ b/lib/libesp32/berry_tasmota/src/embedded/partition_core.be @@ -336,6 +336,14 @@ class Partition_otadata flash.write(offset_to_save, bytes_to_save) end + # clear otadata information, which forces a boot on the safeboot partition + def clear() + import flash + b=bytes().resize(32) + flash.write(self.offset,b) + flash.write(self.offset + 0x1000,b) + end + # Produce a human-readable representation of the object with relevant information def tostring() import string @@ -483,7 +491,12 @@ class Partition var b = bytes("00") #- flash memory: we can turn bits from '1' to '0' -# flash.write(spiffs.start , b) #- block #0 -# flash.write(spiffs.start + 0x1000, b) #- block #1 -# - end + end + + # switch to safeboot `factory` partition + def switch_safeboot() + self.otadata.clear() + end end partition_core.Partition = Partition diff --git a/lib/libesp32/berry_tasmota/src/embedded/partition_core2.be b/lib/libesp32/berry_tasmota/src/embedded/partition_core2.be deleted file mode 100644 index 2e9ede007..000000000 --- a/lib/libesp32/berry_tasmota/src/embedded/partition_core2.be +++ /dev/null @@ -1,510 +0,0 @@ -####################################################################### -# Partition manager for ESP32 - ESP32C3 - ESP32S2 -# -# use : `import partition_core` -# -# To solidify: -#- - import solidify load("partition_core.be") solidify.dump(partition_core) --# -# Provides low-level objects and a Web UI -####################################################################### - -var partition_core2 = module('partition_core2') - -####################################################################### -# Class for a partition table entry -# -# typedef struct { -# uint16_t magic; -# uint8_t type; -# uint8_t subtype; -# uint32_t offset; -# uint32_t size; -# uint8_t label[16]; -# uint32_t flags; -# } esp_partition_info_t_simplified; -# -####################################################################### -class Partition_info - var type - var subtype - var start - var size - var label - var flags - - #- remove trailing NULL chars from a bytes buffer before converting to string -# - #- Berry strings can contain NULL, but this messes up C-Berry interface -# - static def remove_trailing_zeroes(b) - var sz = size(b) - var i = 0 - while i < sz - if b[-1-i] != 0 break end - i += 1 - end - if i > 0 - b.resize(size(b)-i) - end - return b - end - - # Init the Parition information structure, either from a bytes() buffer or an empty if no buffer is provided - def init(raw) - self.type = 0 - self.subtype = 0 - self.start = 0 - self.size = 0 - self.label = '' - self.flags = 0 - - if !issubclass(bytes, raw) # no payload, empty partition information - return - end - - #- we have a payload, parse it -# - var magic = raw.get(0,2) - if magic == 0x50AA #- partition entry -# - - self.type = raw.get(2,1) - self.subtype = raw.get(3,1) - self.start = raw.get(4,4) - self.size = raw.get(8,4) - print("size", self.size) - self.label = self.remove_trailing_zeroes(raw[12..27]).asstring() - self.flags = raw.get(28,4) - - # elif magic == 0xEBEB #- MD5 -# - else - import string - raise "internal_error", string.format("invalid magic number %02X", magic) - end - - end - - # check if the parition is an OTA partition - # if yes, return OTA number (starting at 0) - # if no, return nil - def is_ota() - var sub_type = self.subtype - if self.type == 0 && (sub_type >= 0x10 && sub_type < 0x20) - return sub_type - 0x10 - end - end - - # check if the parition is a SPIFFS partition - # returns bool - def is_spiffs() - return self.type == 1 && self.subtype == 130 - end - - # get the actual image size give of the partition - # returns -1 if the partition is not an app ota partition - def get_image_size() - import flash - if self.is_ota() == nil return -1 end - try - var addr = self.start - var magic_byte = flash.read(addr, 1).get(0, 1) - if magic_byte != 0xE9 return -1 end - - var seg_count = flash.read(addr+1, 1).get(0, 1) - # print("Segment count", seg_count) - - var seg_offset = addr + 0x20 # sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t) = 24 + 8 - - var seg_num = 0 - while seg_num < seg_count - # print(string.format("Reading 0x%08X", seg_offset)) - var segment_header = flash.read(seg_offset - 8, 8) - var seg_start_addr = segment_header.get(0, 4) - var seg_size = segment_header.get(4,4) - # print(string.format("Segment %i: flash_offset=0x%08X start_addr=0x%08X size=0x%08X", seg_num, seg_offset, seg_start_addr, seg_size)) - - seg_offset += seg_size + 8 # add segment_length + sizeof(esp_image_segment_header_t) - - seg_num += 1 - end - var total_size = seg_offset - addr + 1 # add 1KB for safety - - # print(string.format("Total size = %i KB", total_size/1024)) - - return total_size - except .. as e, m - tasmota.log("BRY: Exception> '" + e + "' - " + m, 2) - return -1 - end - end - - # Human readable version of Partition information - # this method is not included in the solidified version to save space, - # it is included only in the optional application `tapp` version - def tostring() - import string - var type_s = "" - var subtype_s = "" - if self.type == 0 type_s = "app" - if self.subtype == 0 subtype_s = "factory" - elif self.subtype >= 0x10 && self.subtype < 0x20 subtype_s = "ota" + str(self.subtype - 0x10) - elif self.subtype == 0x20 subtype_s = "test" - end - elif self.type == 1 type_s = "data" - if self.subtype == 0x00 subtype_s = "otadata" - elif self.subtype == 0x01 subtype_s = "phy" - elif self.subtype == 0x02 subtype_s = "nvs" - elif self.subtype == 0x03 subtype_s = "coredump" - elif self.subtype == 0x04 subtype_s = "nvskeys" - elif self.subtype == 0x05 subtype_s = "efuse_em" - elif self.subtype == 0x80 subtype_s = "esphttpd" - elif self.subtype == 0x81 subtype_s = "fat" - elif self.subtype == 0x82 subtype_s = "spiffs" - end - end - - # reformat strings - if type_s != "" type_s = " (" + type_s + ")" end - if subtype_s != "" subtype_s = " (" + subtype_s + ")" end - return string.format("", - self.type, type_s, - self.subtype, subtype_s, - self.start, self.size, - self.label, self.flags) - end - - def tobytes() - #- convert to raw bytes -# - var b = bytes('AA50') #- set magic number -# - b.resize(32).resize(2) #- pre-reserve 32 bytes -# - b.add(self.type, 1) - b.add(self.subtype, 1) - b.add(self.start, 4) - b.add(self.size, 4) - var label = bytes().fromstring(self.label) - label.resize(16) - b = b + label - b.add(self.flags, 4) - return b - end - -end -partition_core2.Partition_info = Partition_info - -#------------------------------------------------------------- - - OTA Data - - - - Selection of the active OTA partition - - - typedef struct { - uint32_t ota_seq; - uint8_t seq_label[20]; - uint32_t ota_state; - uint32_t crc; /* CRC32 of ota_seq field only */ - } esp_ota_select_entry_t; - - - Excerp from esp_ota_ops.c - esp32_idf use two sector for store information about which partition is running - it defined the two sector as ota data partition,two structure esp_ota_select_entry_t is saved in the two sector - named data in first sector as otadata[0], second sector data as otadata[1] - e.g. - if otadata[0].ota_seq == otadata[1].ota_seq == 0xFFFFFFFF,means ota info partition is in init status - so it will boot factory application(if there is),if there's no factory application,it will boot ota[0] application - if otadata[0].ota_seq != 0 and otadata[1].ota_seq != 0,it will choose a max seq ,and get value of max_seq%max_ota_app_number - and boot a subtype (mask 0x0F) value is (max_seq - 1)%max_ota_app_number,so if want switch to run ota[x],can use next formulas. - for example, if otadata[0].ota_seq = 4, otadata[1].ota_seq = 5, and there are 8 ota application, - current running is (5-1)%8 = 4,running ota[4],so if we want to switch to run ota[7], - we should add otadata[0].ota_seq (is 4) to 4 ,(8-1)%8=7,then it will boot ota[7] - if A=(B - C)%D - then B=(A + C)%D + D*n ,n= (0,1,2...) - so current ota app sub type id is x , dest bin subtype is y,total ota app count is n - seq will add (x + n*1 + 1 - seq)%n - -------------------------------------------------------------# -class Partition_otadata - var maxota #- number of highest OTA partition, default 1 (double ota0/ota1) -# - var offset #- offset of the otadata partition (0x2000 in length), default 0xE000 -# - var active_otadata #- which otadata block is active, 0 or 1, i.e. 0xE000 or 0xF000 -# - var seq0 #- ota_seq of first block -# - var seq1 #- ota_seq of second block -# - - #- crc32 for ota_seq as 32 bits unsigned, with init vector -1 -# - static def crc32_ota_seq(seq) - import crc - return crc.crc32(0xFFFFFFFF, bytes().add(seq, 4)) - end - - #---------------------------------------------------------------------# - # Rest of the class - #---------------------------------------------------------------------# - def init(maxota, offset) - self.maxota = maxota - if self.maxota == nil self.maxota = 1 end - self.offset = offset - if self.offset == nil self.offset = 0xE000 end - self.active_otadata = 0 - self.load() - end - - #- update ota_max, needs to recompute everything -# - def set_ota_max(n) - self.maxota = n - end - - # change the active OTA partition - def set_active(n) - var seq_max = 0 #- current highest seq number -# - var block_act = 0 #- block number containing the highest seq number -# - - if self.seq0 != nil - seq_max = self.seq0 - block_act = 0 - end - if self.seq1 != nil && self.seq1 > seq_max - seq_max = self.seq1 - block_act = 1 - end - - #- compute the next sequence number -# - var actual_ota = (seq_max - 1) % (self.maxota + 1) - if actual_ota != n #- change only if different -# - if n > actual_ota seq_max += n - actual_ota - else seq_max += (self.maxota + 1) - actual_ota + n - end - - #- update internal structure -# - if block_act == 1 #- current block is 1, so update block 0 -# - self.seq0 = seq_max - else #- or write to block 1 -# - self.seq1 = seq_max - end - self._validate() - end - end - - #- load otadata from SPI Flash -# - def load() - import flash - var otadata0 = flash.read(0xE000, 32) - var otadata1 = flash.read(0xF000, 32) - self.seq0 = otadata0.get(0, 4) #- ota_seq for block 1 -# - self.seq1 = otadata1.get(0, 4) #- ota_seq for block 2 -# - var valid0 = otadata0.get(28, 4) == self.crc32_ota_seq(self.seq0) #- is CRC32 valid? -# - var valid1 = otadata1.get(28, 4) == self.crc32_ota_seq(self.seq1) #- is CRC32 valid? -# - if !valid0 self.seq0 = nil end - if !valid1 self.seq1 = nil end - - self._validate() - end - - #- internally used, validate data -# - def _validate() - self.active_otadata = 0 #- if none is valid, default to OTA0 -# - if self.seq0 != nil - self.active_otadata = (self.seq0 - 1) % (self.maxota + 1) - end - if self.seq1 != nil && (self.seq0 == nil || self.seq1 > self.seq0) - self.active_otadata = (self.seq1 - 1) % (self.maxota + 1) - end - end - - # Save partition information to SPI Flash - def save() - import flash - #- check the block number to save, 0 or 1. Choose the highest ota_seq -# - var block_to_save = -1 #- invalid -# - var seq_to_save = -1 #- invalid value -# - - # check seq0 - if self.seq0 != nil - seq_to_save = self.seq0 - block_to_save = 0 - end - if (self.seq1 != nil) && (self.seq1 > seq_to_save) - seq_to_save = self.seq1 - block_to_save = 1 - end - # if none was good - if block_to_save < 0 block_to_save = 0 end - if seq_to_save < 0 seq_to_save = 1 end - - var offset_to_save = self.offset + 0x1000 * block_to_save #- default 0xE000 or 0xF000 -# - - var bytes_to_save = bytes() - bytes_to_save.add(seq_to_save, 4) - bytes_to_save += bytes("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF") - bytes_to_save.add(self.crc32_ota_seq(seq_to_save), 4) - - #- erase flash area and write -# - flash.erase(offset_to_save, 0x1000) - flash.write(offset_to_save, bytes_to_save) - end - - # Produce a human-readable representation of the object with relevant information - def tostring() - import string - return string.format("", - self.active_otadata, self.seq0, self.seq1, self.maxota) - end -end -partition_core2.Partition_otadata = Partition_otadata - -#------------------------------------------------------------- - - Class for a partition table entry - -------------------------------------------------------------# -class Partition - var raw #- raw bytes of the partition table in flash -# - var md5 #- md5 hash of partition list -# - var slots - var otadata #- instance of Partition_otadata() -# - - def init() - self.slots = [] - self.load() - self.parse() - self.load_otadata() - end - - # Load partition information from SPI Flash - def load() - import flash - self.raw = flash.read(0x8000,0x1000) - end - - #- parse the raw bytes to a structured list of partition items -# - def parse() - for i:0..94 # there are maximum 95 slots + md5 (0xC00) - var item_raw = self.raw[i*32..(i+1)*32-1] - print(item_raw) - var magic = item_raw.get(0,2) - if magic == 0x50AA #- partition entry -# - var slot = partition_core2.Partition_info(item_raw) - self.slots.push(slot) - elif magic == 0xEBEB #- MD5 -# - self.md5 = self.raw[i*32+16..i*33-1] - break - else - break - end - end - end - - def get_ota_slot(n) - for slot: self.slots - if slot.is_ota() == n return slot end - end - return nil - end - - #- compute the highest ota partition -# - def ota_max() - var ota_max = 0 - for slot:self.slots - if slot.type == 0 && (slot.subtype >= 0x10 && slot.subtype < 0x20) - var ota_num = slot.subtype - 0x10 - if ota_num > ota_max ota_max = ota_num end - end - end - return ota_max - end - - def load_otadata() - #- look for otadata partition offset, and max_ota -# - var otadata_offset = 0xE000 #- default value -# - var ota_max = self.ota_max() - for slot:self.slots - if slot.type == 1 && slot.subtype == 0 #- otadata -# - otadata_offset = slot.start - end - end - - self.otadata = partition_core2.Partition_otadata(ota_max, otadata_offset) - end - - # get the active OTA app partition number - def get_active() - return self.otadata.active_otadata - end - - #- change the active partition -# - def set_active(n) - if n < 0 || n > self.ota_max() raise "value_error", "Invalid ota partition number" end - self.otadata.set_ota_max(self.ota_max()) #- update ota_max if it changed -# - self.otadata.set_active(n) - end - - # Human readable version of Partition information - # this method is not included in the solidified version to save space, - # it is included only in the optional application `tapp` version - #- convert to human readble -# - def tostring() - var ret = " 95 raise "value_error", "Too many partiition slots" end - var b = bytes() - for slot: self.slots - b += slot.tobytes() - end - #- compute MD5 -# - var md5 = MD5() - md5.update(b) - #- add the last segment -# - b += bytes("EBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFF") - b += md5.finish() - #- complete -# - return b - end - - #- write back to flash -# - def save() - import flash - var b = self.tobytes() - #- erase flash area and write -# - flash.erase(0x8000, 0x1000) - flash.write(0x8000, b) - self.otadata.save() - end - - #- invalidate SPIFFS partition to force format at next boot -# - #- we simply erase the first byte of the first 2 blocks in the SPIFFS partition -# - def invalidate_spiffs() - import flash - #- we expect the SPIFFS partition to be the last one -# - var spiffs = self.slots[-1] - if !spiffs.is_spiffs() raise 'value_error', 'No SPIFFS partition found' end - - var b = bytes("00") #- flash memory: we can turn bits from '1' to '0' -# - flash.write(spiffs.start , b) #- block #0 -# - flash.write(spiffs.start + 0x1000, b) #- block #1 -# - end -end -partition_core2.Partition = Partition - -# init method to force the global `partition_core` is defined even if the import is done within a function -def init(m) - import global - global.partition_core2 = m - return m -end -partition_core2.init = init - -return partition_core2 - -#- Example - -import partition_core2 - -# read -p = partition_core2.Partition() -print(p) - --# diff --git a/tasmota/berry/modules/partition.be b/tasmota/berry/modules/partition.be index 1c6d54d6d..02dc44792 100644 --- a/tasmota/berry/modules/partition.be +++ b/tasmota/berry/modules/partition.be @@ -165,7 +165,7 @@ class Partition_manager_UI #- ---------------------------------------------------------------------- -# # Show a single OTA Partition #- ---------------------------------------------------------------------- -# - def page_show_partition(slot, active, ota_num) + def page_show_partition(slot, active, ota_num, maxota) import webserver import string #- define `bdis` style for gray disabled buttons -# @@ -183,21 +183,23 @@ class Partition_manager_UI webserver.content_send("

Used: unknown

") webserver.content_send("

Free: unknown

") end - if !active && used > 0 - webserver.content_send("

") - webserver.content_send("") - webserver.content_send(string.format("", ota_num)) - webserver.content_send("

") - else - # put a fake disabled button - webserver.content_send("

") - if used >= 0 - webserver.content_send("") + if maxota > 0 + if !active && used > 0 + webserver.content_send("

") + webserver.content_send("") + webserver.content_send(string.format("", ota_num)) + webserver.content_send("

") else - webserver.content_send("") + # put a fake disabled button + webserver.content_send("

") + if used >= 0 + webserver.content_send("") + else + webserver.content_send("") + end + webserver.content_send("

") end - webserver.content_send("

") end webserver.content_send("

") @@ -239,7 +241,7 @@ class Partition_manager_UI var ota_num = slot.is_ota() if ota_num != nil # we have an OTA partition - self.page_show_partition(slot, ota_num == p.otadata.active_otadata, ota_num) + self.page_show_partition(slot, ota_num == p.otadata.active_otadata, ota_num, p.otadata.maxota) elif slot.is_spiffs() var flash_size = tasmota.memory()['flash'] * 1024 var used_size = (slot.start + slot.size) @@ -308,9 +310,11 @@ class Partition_manager_UI self.page_show_partitions(p) webserver.content_send("

") - webserver.content_send("
 Re-partition

") - self.page_show_repartition_asym(p) - webserver.content_send("

") + if p.otadata.maxota > 0 + webserver.content_send("
 Re-partition

") + self.page_show_repartition_asym(p) + webserver.content_send("

") + end webserver.content_button(webserver.BUTTON_MANAGEMENT) #- button back to management page -# webserver.content_stop() #- end of web page -#