Merge branch 'dev' into rabbitnew100mw

This commit is contained in:
Sil
2023-07-21 23:58:03 +02:00
258 changed files with 10741 additions and 3542 deletions

View File

@@ -1,12 +1,10 @@
#include <furi.h>
#include <furi_hal.h>
#include <stm32wbxx_ll_tim.h>
#include <storage/storage.h>
#include <lib/flipper_format/flipper_format.h>
#include <lib/nfc/protocols/nfca.h>
#include <lib/nfc/helpers/mf_classic_dict.h>
#include <lib/digital_signal/digital_signal.h>
#include <lib/pulse_reader/pulse_reader.h>
#include <lib/nfc/nfc_device.h>
#include <lib/nfc/helpers/nfc_generators.h>
@@ -224,153 +222,6 @@ MU_TEST(nfc_digital_signal_test) {
"NFC long digital signal test failed\r\n");
}
static bool nfc_test_pulse_reader_toggle(
uint32_t usec_low,
uint32_t usec_high,
uint32_t period_count,
uint32_t tolerance) {
furi_assert(nfc_test);
bool success = false;
uint32_t pulses = 0;
const GpioPin* gpio_in = &gpio_ext_pa6;
const GpioPin* gpio_out = &gpio_ext_pa7;
PulseReader* reader = NULL;
do {
reader = pulse_reader_alloc(gpio_in, 512);
if(!reader) {
FURI_LOG_E(TAG, "failed to allocate pulse reader");
break;
}
/* use TIM1 to create a specific number of pulses with defined duty cycle
but first set the IO to high, so the low/high pulse can get detected */
furi_hal_gpio_init(gpio_out, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh);
furi_hal_gpio_write(gpio_out, true);
LL_TIM_DeInit(TIM1);
LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP);
LL_TIM_SetRepetitionCounter(TIM1, 0);
LL_TIM_SetClockDivision(TIM1, LL_TIM_CLOCKDIVISION_DIV1);
LL_TIM_SetClockSource(TIM1, LL_TIM_CLOCKSOURCE_INTERNAL);
LL_TIM_DisableARRPreload(TIM1);
LL_TIM_OC_DisablePreload(TIM1, LL_TIM_CHANNEL_CH1);
LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_PWM2);
LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH);
LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1);
LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1N);
LL_TIM_EnableAllOutputs(TIM1);
/* now calculate the TIM1 period and compare values */
uint32_t freq_div = 64 * (usec_low + usec_high);
uint32_t prescaler = freq_div / 0x10000LU;
uint32_t period = freq_div / (prescaler + 1);
uint32_t compare = 64 * usec_low / (prescaler + 1);
LL_TIM_SetPrescaler(TIM1, prescaler);
LL_TIM_SetAutoReload(TIM1, period - 1);
LL_TIM_SetCounter(TIM1, period - 1);
LL_TIM_OC_SetCompareCH1(TIM1, compare);
/* timer is ready to launch, now start the pulse reader */
pulse_reader_set_timebase(reader, PulseReaderUnitMicrosecond);
pulse_reader_start(reader);
/* and quickly enable and switch over the GPIO to the generated signal */
LL_TIM_EnableCounter(TIM1);
furi_hal_gpio_init_ex(
gpio_out, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedVeryHigh, GpioAltFn1TIM1);
/* now it's time to parse the pulses received by the reader */
uint32_t timer_pulses = period_count;
uint32_t prev_cnt = 0;
while(timer_pulses > 0) {
/* whenever the counter gets reset, we went through a full period */
uint32_t cur_cnt = LL_TIM_GetCounter(TIM1);
if(cur_cnt < prev_cnt) {
timer_pulses--;
}
prev_cnt = cur_cnt;
}
/* quickly halt the counter to keep a static signal */
LL_TIM_DisableCounter(TIM1);
do {
/* as all edges were sampled asynchronously, the timeout can be zero */
uint32_t length = pulse_reader_receive(reader, 0);
/* in the last pulse, we expect a "no edge" return value. if seen that, test succeeded. */
if(pulses > period_count * 2) {
if(length != PULSE_READER_NO_EDGE) {
FURI_LOG_E(
TAG,
"last pulse expected to be PULSE_READER_NO_EDGE, but was %lu.",
length);
break;
}
success = true;
break;
}
/* else we shall never see "no edge" or "lost edge" */
if(length == PULSE_READER_NO_EDGE) {
FURI_LOG_E(TAG, "%lu. pulse not expected to be PULSE_READER_NO_EDGE", pulses);
break;
}
if(length == PULSE_READER_LOST_EDGE) {
FURI_LOG_E(TAG, "%lu. pulse not expected to be PULSE_READER_LOST_EDGE", pulses);
break;
}
if(pulses > 0) {
/* throw away the first pulse, which is the 1->0 from the first start and will be irrelevant for our test */
bool phase = ((pulses - 1) % 2) == 1;
uint32_t expected = phase ? usec_high : usec_low;
uint32_t deviation = abs((int32_t)length - (int32_t)expected);
if(deviation > tolerance) {
FURI_LOG_E(
TAG,
"%lu. pulse expected %lu, but pulse was %lu.",
pulses,
expected,
length);
break;
}
}
pulses++;
} while(true);
} while(false);
if(reader != NULL) {
pulse_reader_stop(reader);
pulse_reader_free(reader);
}
LL_TIM_DeInit(TIM1);
furi_hal_gpio_init_simple(gpio_in, GpioModeAnalog);
furi_hal_gpio_init_simple(gpio_out, GpioModeAnalog);
return success;
}
MU_TEST(nfc_pulse_reader_test) {
mu_assert(nfc_test_pulse_reader_toggle(1500, 2500, 50, 10), "1 ms signal failed\r\n");
mu_assert(nfc_test_pulse_reader_toggle(10000, 10000, 10, 10), "10 ms signal failed\r\n");
mu_assert(nfc_test_pulse_reader_toggle(100000, 100000, 5, 50), "100 ms signal failed\r\n");
mu_assert(nfc_test_pulse_reader_toggle(100, 900, 50, 10), "1 ms asymmetric signal failed\r\n");
mu_assert(
nfc_test_pulse_reader_toggle(3333, 6666, 10, 10), "10 ms asymmetric signal failed\r\n");
mu_assert(
nfc_test_pulse_reader_toggle(25000, 75000, 5, 10), "100 ms asymmetric signal failed\r\n");
}
MU_TEST(mf_classic_dict_test) {
MfClassicDict* instance = NULL;
uint64_t key = 0;
@@ -705,7 +556,6 @@ MU_TEST(mf_classic_4k_7b_file_test) {
MU_TEST_SUITE(nfc) {
nfc_test_alloc();
MU_RUN_TEST(nfc_pulse_reader_test);
MU_RUN_TEST(nfca_file_test);
MU_RUN_TEST(mf_mini_file_test);
MU_RUN_TEST(mf_classic_1k_4b_file_test);

View File

@@ -4,5 +4,6 @@ App(
targets=["f7"],
entry_point="subghz_device_cc1101_ext_ep",
requires=["subghz"],
sdk_headers=["cc1101_ext/cc1101_ext_interconnect.h"],
fap_libs=["hwdrivers"],
)

View File

@@ -18,7 +18,7 @@ Before launching the application, connect the sensor to Flipper's external GPIO
In order to launch this demo, follow the steps below:
1. Make sure your Flipper has an SD card installed.
2. Connect your Flipper to the computer via a USB cable.
3. Run `./fbt launch_app APPSRC=example_thermo` in your terminal emulator of choice.
3. Run `./fbt launch APPSRC=example_thermo` in your terminal emulator of choice.
## Changing the data pin
It is possible to use other GPIO pin as a 1-Wire data pin. In order to change it, set the `THERMO_GPIO_PIN` macro to any of the options listed below:

View File

@@ -28,9 +28,7 @@
#define MAXPOWERUPS 3 /* Max powerups allowed on screen */
#define POWERUPSTTL 400 /* Max powerup time to live, in ticks. */
#define SHIP_HIT_ANIMATION_LEN 15
// Tick runs in thread, cant use APP_DATA_PATH()
#define SAVING_DIRECTORY EXT_PATH("apps_data/asteroids")
#define SAVING_FILENAME SAVING_DIRECTORY "/game_asteroids.save"
#define SAVING_FILENAME APP_DATA_PATH("game_asteroids.save")
#ifndef PI
#define PI 3.14159265358979f
#endif
@@ -1147,7 +1145,6 @@ void game_tick(void* ctx) {
bool load_game(AsteroidsApp* app) {
Storage* storage = furi_record_open(RECORD_STORAGE);
storage_common_mkdir(storage, SAVING_DIRECTORY);
storage_common_migrate(storage, EXT_PATH("apps/Games/game_asteroids.save"), SAVING_FILENAME);
File* file = storage_file_alloc(storage);

View File

@@ -8,9 +8,9 @@ App(
fap_category="Tools",
fap_icon="images/barcode_10.png",
fap_icon_assets="images",
fap_icon_assets_symbol="barcode_app",
fap_file_assets="barcode_encoding_files",
fap_author="@Kingal1337",
fap_weburl="https://github.com/Kingal1337/flipper-barcode-generator",
fap_version="1.0",
fap_version="1.1",
fap_description="App allows you to display various barcodes on flipper screen",
)

View File

@@ -23,20 +23,17 @@
#define BARCODE_HEIGHT 50
#define BARCODE_Y_START 3
//the folder where the encodings are located
#define BARCODE_DATA_FILE_DIR_PATH EXT_PATH("apps_data/barcode_data")
//the folder where the codabar encoding table is located
#define CODABAR_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/codabar_encodings.txt"
#define CODABAR_DICT_FILE_PATH APP_ASSETS_PATH("codabar_encodings.txt")
//the folder where the code 39 encoding table is located
#define CODE39_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/code39_encodings.txt"
#define CODE39_DICT_FILE_PATH APP_ASSETS_PATH("code39_encodings.txt")
//the folder where the code 128 encoding table is located
#define CODE128_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/code128_encodings.txt"
#define CODE128_DICT_FILE_PATH APP_ASSETS_PATH("code128_encodings.txt")
//the folder where the code 128 C encoding table is located
#define CODE128C_DICT_FILE_PATH BARCODE_DATA_FILE_DIR_PATH "/code128c_encodings.txt"
#define CODE128C_DICT_FILE_PATH APP_ASSETS_PATH("code128c_encodings.txt")
//the folder where the user stores their barcodes
#define DEFAULT_USER_BARCODES EXT_PATH("apps_data/barcodes")

View File

@@ -0,0 +1,22 @@
# alternates between bars and spaces, always begins with bar
# 0 for narrow, 1 for wide
0: 0000011
1: 0000110
2: 0001001
3: 1100000
4: 0010010
5: 1000010
6: 0100001
7: 0100100
8: 0110000
9: 1001000
-: 0001100
$: 0011000
:: 1000101
/: 1010001
.: 1010100
+: 0010101
A: 0011010
B: 0101001
C: 0001011
D: 0001110

View File

@@ -0,0 +1,202 @@
: 00
!: 01
": 02
#: 03
$: 04
%: 05
&: 06
': 07
(: 08
): 09
*: 10
+: 11
,: 12
-: 13
.: 14
/: 15
0: 16
1: 17
2: 18
3: 19
4: 20
5: 21
6: 22
7: 23
8: 24
9: 25
:: 26
;: 27
<: 28
=: 29
>: 30
?: 31
@: 32
A: 33
B: 34
C: 35
D: 36
E: 37
F: 38
G: 39
H: 40
I: 41
J: 42
K: 43
L: 44
M: 45
N: 46
O: 47
P: 48
Q: 49
R: 50
S: 51
T: 52
U: 53
V: 54
W: 55
X: 56
Y: 57
Z: 58
[: 59
\: 60
]: 61
^: 62
_: 63
`: 64
a: 65
b: 66
c: 67
d: 68
e: 69
f: 70
g: 71
h: 72
i: 73
j: 74
k: 75
l: 76
m: 77
n: 78
o: 79
p: 80
q: 81
r: 82
s: 83
t: 84
u: 85
v: 86
w: 87
x: 88
y: 89
z: 90
{: 91
|: 92
}: 93
~: 94
00: 11011001100
01: 11001101100
02: 11001100110
03: 10010011000
04: 10010001100
05: 10001001100
06: 10011001000
07: 10011000100
08: 10001100100
09: 11001001000
10: 11001000100
11: 11000100100
12: 10110011100
13: 10011011100
14: 10011001110
15: 10111001100
16: 10011101100
17: 10011100110
18: 11001110010
19: 11001011100
20: 11001001110
21: 11011100100
22: 11001110100
23: 11101101110
24: 11101001100
25: 11100101100
26: 11100100110
27: 11101100100
28: 11100110100
29: 11100110010
30: 11011011000
31: 11011000110
32: 11000110110
33: 10100011000
34: 10001011000
35: 10001000110
36: 10110001000
37: 10001101000
38: 10001100010
39: 11010001000
40: 11000101000
41: 11000100010
42: 10110111000
43: 10110001110
44: 10001101110
45: 10111011000
46: 10111000110
47: 10001110110
48: 11101110110
49: 11010001110
50: 11000101110
51: 11011101000
52: 11011100010
53: 11011101110
54: 11101011000
55: 11101000110
56: 11100010110
57: 11101101000
58: 11101100010
59: 11100011010
60: 11101111010
61: 11001000010
62: 11110001010
63: 10100110000
64: 10100001100
65: 10010110000
66: 10010000110
67: 10000101100
68: 10000100110
69: 10110010000
70: 10110000100
71: 10011010000
72: 10011000010
73: 10000110100
74: 10000110010
75: 11000010010
76: 11001010000
77: 11110111010
78: 11000010100
79: 10001111010
80: 10100111100
81: 10010111100
82: 10010011110
83: 10111100100
84: 10011110100
85: 10011110010
86: 11110100100
87: 11110010100
88: 11110010010
89: 11011011110
90: 11011110110
91: 11110110110
92: 10101111000
93: 10100011110
94: 10001011110
95: 10111101000
96: 10111100010
97: 11110101000
98: 11110100010
99: 10111011110
100: 10111101110
101: 11101011110
102: 11110101110
103: 11010000100
104: 11010010000
105: 11010011100

View File

@@ -0,0 +1,106 @@
00: 11011001100
01: 11001101100
02: 11001100110
03: 10010011000
04: 10010001100
05: 10001001100
06: 10011001000
07: 10011000100
08: 10001100100
09: 11001001000
10: 11001000100
11: 11000100100
12: 10110011100
13: 10011011100
14: 10011001110
15: 10111001100
16: 10011101100
17: 10011100110
18: 11001110010
19: 11001011100
20: 11001001110
21: 11011100100
22: 11001110100
23: 11101101110
24: 11101001100
25: 11100101100
26: 11100100110
27: 11101100100
28: 11100110100
29: 11100110010
30: 11011011000
31: 11011000110
32: 11000110110
33: 10100011000
34: 10001011000
35: 10001000110
36: 10110001000
37: 10001101000
38: 10001100010
39: 11010001000
40: 11000101000
41: 11000100010
42: 10110111000
43: 10110001110
44: 10001101110
45: 10111011000
46: 10111000110
47: 10001110110
48: 11101110110
49: 11010001110
50: 11000101110
51: 11011101000
52: 11011100010
53: 11011101110
54: 11101011000
55: 11101000110
56: 11100010110
57: 11101101000
58: 11101100010
59: 11100011010
60: 11101111010
61: 11001000010
62: 11110001010
63: 10100110000
64: 10100001100
65: 10010110000
66: 10010000110
67: 10000101100
68: 10000100110
69: 10110010000
70: 10110000100
71: 10011010000
72: 10011000010
73: 10000110100
74: 10000110010
75: 11000010010
76: 11001010000
77: 11110111010
78: 11000010100
79: 10001111010
80: 10100111100
81: 10010111100
82: 10010011110
83: 10111100100
84: 10011110100
85: 10011110010
86: 11110100100
87: 11110010100
88: 11110010010
89: 11011011110
90: 11011110110
91: 11110110110
92: 10101111000
93: 10100011110
94: 10001011110
95: 10111101000
96: 10111100010
97: 11110101000
98: 11110100010
99: 10111011110
100: 10111101110
101: 11101011110
102: 11110101110
103: 11010000100
104: 11010010000
105: 11010011100

View File

@@ -0,0 +1,44 @@
0: 000110100
1: 100100001
2: 001100001
3: 101100000
4: 000110001
5: 100110000
6: 001110000
7: 000100101
8: 100100100
9: 001100100
A: 100001001
B: 001001001
C: 101001000
D: 000011001
E: 100011000
F: 001011000
G: 000001101
H: 100001100
I: 001001100
J: 000011100
K: 100000011
L: 001000011
M: 101000010
N: 000010011
O: 100010010
P: 001010010
Q: 000000111
R: 100000110
S: 001000110
T: 000010110
U: 110000001
V: 011000001
W: 111000000
X: 010010001
Y: 110010000
Z: 011010000
-: 010000101
.: 110000100
: 011000100
*: 010010100
$: 010101000
/: 010100010
+: 010001010
%: 000101010

View File

@@ -0,0 +1,29 @@
App(
appid="esp_flasher",
name="[GPIO] ESP Flasher",
apptype=FlipperAppType.EXTERNAL,
entry_point="esp_flasher_app",
requires=["gui"],
stack_size=4 * 1024,
order=90,
fap_icon="wifi_10px.png",
fap_category="GPIO",
fap_private_libs=[
Lib(
name="esp-serial-flasher",
fap_include_paths=["include"],
sources=[
"src/esp_loader.c",
"src/esp_targets.c",
"src/md5_hash.c",
"src/protocol_common.c",
"src/protocol_uart.c",
"src/slip.c",
],
cincludes=["lib/esp-serial-flasher/private_include"],
cdefines=["SERIAL_FLASHER_INTERFACE_UART=1", "MD5_ENABLED=1"],
),
],
cdefines=["SERIAL_FLASHER_INTERFACE_UART=1"],
fap_icon_assets="assets",
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 158 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,135 @@
#include "esp_flasher_app_i.h"
#include <furi.h>
#include <furi_hal.h>
static bool esp_flasher_app_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
EspFlasherApp* app = context;
return scene_manager_handle_custom_event(app->scene_manager, event);
}
static bool esp_flasher_app_back_event_callback(void* context) {
furi_assert(context);
EspFlasherApp* app = context;
return scene_manager_handle_back_event(app->scene_manager);
}
static void esp_flasher_app_tick_event_callback(void* context) {
furi_assert(context);
EspFlasherApp* app = context;
scene_manager_handle_tick_event(app->scene_manager);
}
EspFlasherApp* esp_flasher_app_alloc() {
EspFlasherApp* app = malloc(sizeof(EspFlasherApp));
app->gui = furi_record_open(RECORD_GUI);
app->dialogs = furi_record_open(RECORD_DIALOGS);
app->storage = furi_record_open(RECORD_STORAGE);
app->view_dispatcher = view_dispatcher_alloc();
app->scene_manager = scene_manager_alloc(&esp_flasher_scene_handlers, app);
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
view_dispatcher_set_custom_event_callback(
app->view_dispatcher, esp_flasher_app_custom_event_callback);
view_dispatcher_set_navigation_event_callback(
app->view_dispatcher, esp_flasher_app_back_event_callback);
view_dispatcher_set_tick_event_callback(
app->view_dispatcher, esp_flasher_app_tick_event_callback, 100);
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
app->var_item_list = variable_item_list_alloc();
view_dispatcher_add_view(
app->view_dispatcher,
EspFlasherAppViewVarItemList,
variable_item_list_get_view(app->var_item_list));
app->text_box = text_box_alloc();
view_dispatcher_add_view(
app->view_dispatcher, EspFlasherAppViewConsoleOutput, text_box_get_view(app->text_box));
app->text_box_store = furi_string_alloc();
furi_string_reserve(app->text_box_store, ESP_FLASHER_TEXT_BOX_STORE_SIZE);
app->widget = widget_alloc();
view_dispatcher_add_view(
app->view_dispatcher, EspFlasherAppViewWidget, widget_get_view(app->widget));
// Submenu
app->submenu = submenu_alloc();
view_dispatcher_add_view(
app->view_dispatcher, EspFlasherAppViewSubmenu, submenu_get_view(app->submenu));
app->flash_worker_busy = false;
scene_manager_next_scene(app->scene_manager, EspFlasherSceneStart);
return app;
}
void esp_flasher_make_app_folder(EspFlasherApp* app) {
furi_assert(app);
if(!storage_simply_mkdir(app->storage, ESP_APP_FOLDER)) {
dialog_message_show_storage_error(app->dialogs, "Cannot create\napp folder");
}
}
void esp_flasher_app_free(EspFlasherApp* app) {
furi_assert(app);
// Views
view_dispatcher_remove_view(app->view_dispatcher, EspFlasherAppViewVarItemList);
view_dispatcher_remove_view(app->view_dispatcher, EspFlasherAppViewConsoleOutput);
view_dispatcher_remove_view(app->view_dispatcher, EspFlasherAppViewWidget);
view_dispatcher_remove_view(app->view_dispatcher, EspFlasherAppViewSubmenu);
widget_free(app->widget);
text_box_free(app->text_box);
furi_string_free(app->text_box_store);
submenu_free(app->submenu);
variable_item_list_free(app->var_item_list);
// View dispatcher
view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager);
esp_flasher_uart_free(app->uart);
// Close records
furi_record_close(RECORD_GUI);
furi_record_close(RECORD_STORAGE);
furi_record_close(RECORD_DIALOGS);
free(app);
}
int32_t esp_flasher_app(void* p) {
UNUSED(p);
uint8_t attempts = 0;
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
furi_hal_power_enable_otg();
furi_delay_ms(10);
}
furi_delay_ms(200);
EspFlasherApp* esp_flasher_app = esp_flasher_app_alloc();
esp_flasher_make_app_folder(esp_flasher_app);
esp_flasher_app->uart = esp_flasher_usart_init(esp_flasher_app);
view_dispatcher_run(esp_flasher_app->view_dispatcher);
esp_flasher_app_free(esp_flasher_app);
if(furi_hal_power_is_otg_enabled()) {
furi_hal_power_disable_otg();
}
return 0;
}

View File

@@ -0,0 +1,13 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
#define ESP_FLASHER_APP_VERSION "v1.0"
typedef struct EspFlasherApp EspFlasherApp;
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,75 @@
//** Includes sniffbt and sniffskim for compatible ESP32-WROOM hardware.
// esp_flasher_scene_start.c also changed **//
#pragma once
#include "esp_flasher_app.h"
#include "scenes/esp_flasher_scene.h"
#include "esp_flasher_custom_event.h"
#include "esp_flasher_uart.h"
#include "file/sequential_file.h"
#include <gui/gui.h>
#include <gui/view_dispatcher.h>
#include <gui/scene_manager.h>
#include <gui/modules/text_box.h>
#include <gui/modules/submenu.h>
#include <gui/modules/variable_item_list.h>
#include <gui/modules/widget.h>
#include <esp_flasher_icons.h>
#include <storage/storage.h>
#include <lib/toolbox/path.h>
#include <dialogs/dialogs.h>
#define ESP_FLASHER_TEXT_BOX_STORE_SIZE (4096)
#define ESP_APP_FOLDER_USER "apps_data/esp_flasher"
#define ESP_APP_FOLDER EXT_PATH(ESP_APP_FOLDER_USER)
typedef enum SelectedFlashOptions {
SelectedFlashS3Mode,
SelectedFlashBoot,
SelectedFlashPart,
SelectedFlashNvs,
SelectedFlashBootApp0,
SelectedFlashApp,
SelectedFlashCustom,
NUM_FLASH_OPTIONS
} SelectedFlashOptions;
struct EspFlasherApp {
Gui* gui;
ViewDispatcher* view_dispatcher;
SceneManager* scene_manager;
FuriString* text_box_store;
size_t text_box_store_strlen;
TextBox* text_box;
Storage* storage;
DialogsApp* dialogs;
VariableItemList* var_item_list;
Widget* widget;
Submenu* submenu;
EspFlasherUart* uart;
bool selected_flash_options[NUM_FLASH_OPTIONS];
int num_selected_flash_options;
char bin_file_path_boot[100];
char bin_file_path_part[100];
char bin_file_path_nvs[100];
char bin_file_path_boot_app0[100];
char bin_file_path_app[100];
char bin_file_path_custom[100];
FuriThread* flash_worker;
bool flash_worker_busy;
};
typedef enum {
EspFlasherAppViewVarItemList,
EspFlasherAppViewConsoleOutput,
EspFlasherAppViewTextInput,
EspFlasherAppViewWidget,
EspFlasherAppViewSubmenu,
} EspFlasherAppView;

View File

@@ -0,0 +1,9 @@
#pragma once
typedef enum {
EspFlasherEventRefreshConsoleOutput = 0,
EspFlasherEventStartConsole,
EspFlasherEventStartKeyboard,
EspFlasherEventStartFlasher,
EspFlasherEventRefreshSubmenu
} EspFlasherCustomEvent;

View File

@@ -0,0 +1,106 @@
#include "esp_flasher_app_i.h"
#include "esp_flasher_uart.h"
#define UART_CH (FuriHalUartIdUSART1)
#define BAUDRATE (115200)
struct EspFlasherUart {
EspFlasherApp* app;
FuriHalUartId channel;
FuriThread* rx_thread;
FuriStreamBuffer* rx_stream;
uint8_t rx_buf[RX_BUF_SIZE + 1];
void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context);
};
typedef enum {
WorkerEvtStop = (1 << 0),
WorkerEvtRxDone = (1 << 1),
} WorkerEvtFlags;
void esp_flasher_uart_set_handle_rx_data_cb(
EspFlasherUart* uart,
void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)) {
furi_assert(uart);
uart->handle_rx_data_cb = handle_rx_data_cb;
}
#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
void esp_flasher_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
EspFlasherUart* uart = (EspFlasherUart*)context;
if(ev == UartIrqEventRXNE) {
furi_stream_buffer_send(uart->rx_stream, &data, 1, 0);
furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
}
}
static int32_t uart_worker(void* context) {
EspFlasherUart* uart = (void*)context;
while(1) {
uint32_t events =
furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
furi_check((events & FuriFlagError) == 0);
if(events & WorkerEvtStop) break;
if(events & WorkerEvtRxDone) {
size_t len = furi_stream_buffer_receive(uart->rx_stream, uart->rx_buf, RX_BUF_SIZE, 0);
if(len > 0) {
if(uart->handle_rx_data_cb) uart->handle_rx_data_cb(uart->rx_buf, len, uart->app);
}
}
}
furi_stream_buffer_free(uart->rx_stream);
return 0;
}
void esp_flasher_uart_tx(uint8_t* data, size_t len) {
furi_hal_uart_tx(UART_CH, data, len);
}
EspFlasherUart*
esp_flasher_uart_init(EspFlasherApp* app, FuriHalUartId channel, const char* thread_name) {
EspFlasherUart* uart = malloc(sizeof(EspFlasherUart));
uart->app = app;
uart->channel = channel;
uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
uart->rx_thread = furi_thread_alloc();
furi_thread_set_name(uart->rx_thread, thread_name);
furi_thread_set_stack_size(uart->rx_thread, 1024);
furi_thread_set_context(uart->rx_thread, uart);
furi_thread_set_callback(uart->rx_thread, uart_worker);
furi_thread_start(uart->rx_thread);
if(channel == FuriHalUartIdUSART1) {
furi_hal_console_disable();
} else if(channel == FuriHalUartIdLPUART1) {
furi_hal_uart_init(channel, BAUDRATE);
}
furi_hal_uart_set_br(channel, BAUDRATE);
furi_hal_uart_set_irq_cb(channel, esp_flasher_uart_on_irq_cb, uart);
return uart;
}
EspFlasherUart* esp_flasher_usart_init(EspFlasherApp* app) {
return esp_flasher_uart_init(app, UART_CH, "EspFlasherUartRxThread");
}
void esp_flasher_uart_free(EspFlasherUart* uart) {
furi_assert(uart);
furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop);
furi_thread_join(uart->rx_thread);
furi_thread_free(uart->rx_thread);
furi_hal_uart_set_irq_cb(uart->channel, NULL, NULL);
if(uart->channel == FuriHalUartIdLPUART1) {
furi_hal_uart_deinit(uart->channel);
}
furi_hal_console_enable();
free(uart);
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include "furi_hal.h"
#define RX_BUF_SIZE (2048)
typedef struct EspFlasherUart EspFlasherUart;
void esp_flasher_uart_set_handle_rx_data_cb(
EspFlasherUart* uart,
void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context));
void esp_flasher_uart_tx(uint8_t* data, size_t len);
EspFlasherUart* esp_flasher_usart_init(EspFlasherApp* app);
void esp_flasher_uart_free(EspFlasherUart* uart);

View File

@@ -0,0 +1,255 @@
#include "esp_flasher_worker.h"
FuriStreamBuffer* flash_rx_stream; // TODO make safe
EspFlasherApp* global_app; // TODO make safe
FuriTimer* timer; // TODO make
static uint32_t _remaining_time = 0;
static void _timer_callback(void* context) {
UNUSED(context);
if(_remaining_time > 0) {
_remaining_time--;
}
}
static esp_loader_error_t _flash_file(EspFlasherApp* app, char* filepath, uint32_t addr) {
// TODO cleanup
esp_loader_error_t err;
static uint8_t payload[1024];
File* bin_file = storage_file_alloc(app->storage);
char user_msg[256];
// open file
if(!storage_file_open(bin_file, filepath, FSAM_READ, FSOM_OPEN_EXISTING)) {
storage_file_close(bin_file);
storage_file_free(bin_file);
dialog_message_show_storage_error(app->dialogs, "Cannot open file");
return ESP_LOADER_ERROR_FAIL;
}
uint64_t size = storage_file_size(bin_file);
loader_port_debug_print("Erasing flash...this may take a while\n");
err = esp_loader_flash_start(addr, size, sizeof(payload));
if(err != ESP_LOADER_SUCCESS) {
storage_file_close(bin_file);
storage_file_free(bin_file);
snprintf(user_msg, sizeof(user_msg), "Erasing flash failed with error %d\n", err);
loader_port_debug_print(user_msg);
return err;
}
loader_port_debug_print("Start programming\n");
uint64_t last_updated = size;
while(size > 0) {
if((last_updated - size) > 50000) {
// inform user every 50k bytes
// TODO: draw a progress bar next update
snprintf(user_msg, sizeof(user_msg), "%llu bytes left.\n", size);
loader_port_debug_print(user_msg);
last_updated = size;
}
size_t to_read = MIN(size, sizeof(payload));
uint16_t num_bytes = storage_file_read(bin_file, payload, to_read);
err = esp_loader_flash_write(payload, num_bytes);
if(err != ESP_LOADER_SUCCESS) {
snprintf(user_msg, sizeof(user_msg), "Packet could not be written! Error: %u\n", err);
storage_file_close(bin_file);
storage_file_free(bin_file);
loader_port_debug_print(user_msg);
return err;
}
size -= num_bytes;
}
loader_port_debug_print("Finished programming\n");
// TODO verify
storage_file_close(bin_file);
storage_file_free(bin_file);
return ESP_LOADER_SUCCESS;
}
typedef struct {
SelectedFlashOptions selected;
const char* description;
char* path;
uint32_t addr;
} FlashItem;
static void _flash_all_files(EspFlasherApp* app) {
esp_loader_error_t err;
const int num_steps = app->num_selected_flash_options;
#define NUM_FLASH_ITEMS 6
FlashItem items[NUM_FLASH_ITEMS] = {
{SelectedFlashBoot,
"bootloader",
app->bin_file_path_boot,
app->selected_flash_options[SelectedFlashS3Mode] ? ESP_ADDR_BOOT_S3 : ESP_ADDR_BOOT},
{SelectedFlashPart, "partition table", app->bin_file_path_part, ESP_ADDR_PART},
{SelectedFlashNvs, "NVS", app->bin_file_path_nvs, ESP_ADDR_NVS},
{SelectedFlashBootApp0, "boot_app0", app->bin_file_path_boot_app0, ESP_ADDR_BOOT_APP0},
{SelectedFlashApp, "firmware", app->bin_file_path_app, ESP_ADDR_APP},
{SelectedFlashCustom, "custom data", app->bin_file_path_custom, 0x0},
/* if you add more entries, update NUM_FLASH_ITEMS above! */
};
char user_msg[256];
int current_step = 1;
for(FlashItem* item = &items[0]; item < &items[NUM_FLASH_ITEMS]; ++item) {
if(app->selected_flash_options[item->selected]) {
snprintf(
user_msg,
sizeof(user_msg),
"Flashing %s (%d/%d) to address 0x%lx\n",
item->description,
current_step++,
num_steps,
item->addr);
loader_port_debug_print(user_msg);
err = _flash_file(app, item->path, item->addr);
if(err) {
break;
}
}
}
}
static int32_t esp_flasher_flash_bin(void* context) {
EspFlasherApp* app = (void*)context;
esp_loader_error_t err;
app->flash_worker_busy = true;
// alloc global objects
flash_rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
timer = furi_timer_alloc(_timer_callback, FuriTimerTypePeriodic, app);
loader_port_debug_print("Connecting\n");
esp_loader_connect_args_t connect_config = ESP_LOADER_CONNECT_DEFAULT();
err = esp_loader_connect(&connect_config);
if(err != ESP_LOADER_SUCCESS) {
char err_msg[256];
snprintf(
err_msg,
sizeof(err_msg),
"Cannot connect to target. Error: %u\nMake sure the device is in bootloader/reflash mode, then try again.\n",
err);
loader_port_debug_print(err_msg);
}
#if 0 // still getting packet drops with this
// higher BR
if(!err) {
loader_port_debug_print("Increasing speed for faster flash\n");
err = esp_loader_change_transmission_rate(230400);
if (err != ESP_LOADER_SUCCESS) {
char err_msg[256];
snprintf(
err_msg,
sizeof(err_msg),
"Cannot change transmission rate. Error: %u\n",
err);
loader_port_debug_print(err_msg);
}
furi_hal_uart_set_br(FuriHalUartIdUSART1, 230400);
}
#endif
if(!err) {
loader_port_debug_print("Connected\n");
_flash_all_files(app);
#if 0
loader_port_debug_print("Restoring transmission rate\n");
furi_hal_uart_set_br(FuriHalUartIdUSART1, 115200);
#endif
loader_port_debug_print("Done flashing. Please reset the board manually.\n");
}
// done
app->flash_worker_busy = false;
// cleanup
furi_stream_buffer_free(flash_rx_stream);
flash_rx_stream = NULL;
furi_timer_free(timer);
return 0;
}
void esp_flasher_worker_start_thread(EspFlasherApp* app) {
global_app = app;
app->flash_worker = furi_thread_alloc();
furi_thread_set_name(app->flash_worker, "EspFlasherFlashWorker");
furi_thread_set_stack_size(app->flash_worker, 2048);
furi_thread_set_context(app->flash_worker, app);
furi_thread_set_callback(app->flash_worker, esp_flasher_flash_bin);
furi_thread_start(app->flash_worker);
}
void esp_flasher_worker_stop_thread(EspFlasherApp* app) {
furi_thread_join(app->flash_worker);
furi_thread_free(app->flash_worker);
}
esp_loader_error_t loader_port_read(uint8_t* data, uint16_t size, uint32_t timeout) {
size_t read = furi_stream_buffer_receive(flash_rx_stream, data, size, pdMS_TO_TICKS(timeout));
if(read < size) {
return ESP_LOADER_ERROR_TIMEOUT;
} else {
return ESP_LOADER_SUCCESS;
}
}
esp_loader_error_t loader_port_write(const uint8_t* data, uint16_t size, uint32_t timeout) {
UNUSED(timeout);
esp_flasher_uart_tx((uint8_t*)data, size);
return ESP_LOADER_SUCCESS;
}
void loader_port_enter_bootloader(void) {
// unimplemented
}
void loader_port_delay_ms(uint32_t ms) {
furi_delay_ms(ms);
}
void loader_port_start_timer(uint32_t ms) {
_remaining_time = ms;
furi_timer_start(timer, pdMS_TO_TICKS(1));
}
uint32_t loader_port_remaining_time(void) {
return _remaining_time;
}
extern void esp_flasher_console_output_handle_rx_data_cb(
uint8_t* buf,
size_t len,
void* context); // TODO cleanup
void loader_port_debug_print(const char* str) {
if(global_app)
esp_flasher_console_output_handle_rx_data_cb((uint8_t*)str, strlen(str), global_app);
}
void loader_port_spi_set_cs(uint32_t level) {
UNUSED(level);
// unimplemented
}
void esp_flasher_worker_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
UNUSED(context);
if(flash_rx_stream) {
furi_stream_buffer_send(flash_rx_stream, buf, len, 0);
} else {
// done flashing
if(global_app) esp_flasher_console_output_handle_rx_data_cb(buf, len, global_app);
}
}

View File

@@ -0,0 +1,17 @@
#pragma once
#include "esp_flasher_app_i.h"
#include "esp_flasher_uart.h"
#define SERIAL_FLASHER_INTERFACE_UART /* TODO why is application.fam not passing this via cdefines */
#include "esp_loader_io.h"
#define ESP_ADDR_BOOT_S3 0x0
#define ESP_ADDR_BOOT 0x1000
#define ESP_ADDR_PART 0x8000
#define ESP_ADDR_NVS 0x9000
#define ESP_ADDR_BOOT_APP0 0xE000
#define ESP_ADDR_APP 0x10000
void esp_flasher_worker_start_thread(EspFlasherApp* app);
void esp_flasher_worker_stop_thread(EspFlasherApp* app);
void esp_flasher_worker_handle_rx_data_cb(uint8_t* buf, size_t len, void* context);

View File

@@ -0,0 +1,46 @@
#include "sequential_file.h"
char* sequential_file_resolve_path(
Storage* storage,
const char* dir,
const char* prefix,
const char* extension) {
if(storage == NULL || dir == NULL || prefix == NULL || extension == NULL) {
return NULL;
}
char file_path[256];
int file_index = 0;
do {
if(snprintf(
file_path, sizeof(file_path), "%s/%s_%d.%s", dir, prefix, file_index, extension) <
0) {
return NULL;
}
file_index++;
} while(storage_file_exists(storage, file_path));
return strdup(file_path);
}
bool sequential_file_open(
Storage* storage,
File* file,
const char* dir,
const char* prefix,
const char* extension) {
if(storage == NULL || file == NULL || dir == NULL || prefix == NULL || extension == NULL) {
return false;
}
char* file_path = sequential_file_resolve_path(storage, dir, prefix, extension);
if(file_path == NULL) {
return false;
}
bool success = storage_file_open(file, file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS);
free(file_path);
return success;
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include <storage/storage.h>
char* sequential_file_resolve_path(
Storage* storage,
const char* dir,
const char* prefix,
const char* extension);
bool sequential_file_open(
Storage* storage,
File* file,
const char* dir,
const char* prefix,
const char* extension);

View File

@@ -0,0 +1,366 @@
# This is the CMakeCache file.
# For build in directory: /home/cococode/flipperzero-firmware/lib/esp-serial-flasher
# It was generated by CMake: /usr/bin/cmake
# You can edit this file to change values found and used by cmake.
# If you do not want to change any of the values, simply exit the editor.
# If you do want to change a value, simply edit, save, and exit the editor.
# The syntax for the file is as follows:
# KEY:TYPE=VALUE
# KEY is the name of a variable in the cache.
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
# VALUE is the current value for the KEY.
########################
# EXTERNAL cache entries
########################
//Path to a program.
CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line
//Path to a program.
CMAKE_AR:FILEPATH=/usr/bin/ar
//Choose the type of build, options are: None Debug Release RelWithDebInfo
// MinSizeRel ...
CMAKE_BUILD_TYPE:STRING=
//Enable/Disable color output during build.
CMAKE_COLOR_MAKEFILE:BOOL=ON
//CXX compiler
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-9
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-9
//Flags used by the CXX compiler during all build types.
CMAKE_CXX_FLAGS:STRING=
//Flags used by the CXX compiler during DEBUG builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
//Flags used by the CXX compiler during MINSIZEREL builds.
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the CXX compiler during RELEASE builds.
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the CXX compiler during RELWITHDEBINFO builds.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//C compiler
CMAKE_C_COMPILER:FILEPATH=/usr/bin/cc
//A wrapper around 'ar' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-9
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
// for the GCC compiler
CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-9
//Flags used by the C compiler during all build types.
CMAKE_C_FLAGS:STRING=
//Flags used by the C compiler during DEBUG builds.
CMAKE_C_FLAGS_DEBUG:STRING=-g
//Flags used by the C compiler during MINSIZEREL builds.
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
//Flags used by the C compiler during RELEASE builds.
CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
//Flags used by the C compiler during RELWITHDEBINFO builds.
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
//Path to a program.
CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND
//Flags used by the linker during all build types.
CMAKE_EXE_LINKER_FLAGS:STRING=
//Flags used by the linker during DEBUG builds.
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during MINSIZEREL builds.
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during RELEASE builds.
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during RELWITHDEBINFO builds.
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Enable/Disable output of compile commands during generation.
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=OFF
//Install path prefix, prepended onto install directories.
CMAKE_INSTALL_PREFIX:PATH=/usr/local
//Path to a program.
CMAKE_LINKER:FILEPATH=/usr/bin/ld
//Path to a program.
CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make
//Flags used by the linker during the creation of modules during
// all build types.
CMAKE_MODULE_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of modules during
// DEBUG builds.
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of modules during
// MINSIZEREL builds.
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of modules during
// RELEASE builds.
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of modules during
// RELWITHDEBINFO builds.
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_NM:FILEPATH=/usr/bin/nm
//Path to a program.
CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy
//Path to a program.
CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump
//Value Computed by CMake
CMAKE_PROJECT_DESCRIPTION:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
//Value Computed by CMake
CMAKE_PROJECT_NAME:STATIC=Project
//Path to a program.
CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib
//Path to a program.
CMAKE_READELF:FILEPATH=/usr/bin/readelf
//Flags used by the linker during the creation of shared libraries
// during all build types.
CMAKE_SHARED_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of shared libraries
// during DEBUG builds.
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of shared libraries
// during MINSIZEREL builds.
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of shared libraries
// during RELEASE builds.
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of shared libraries
// during RELWITHDEBINFO builds.
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//If set, runtime paths are not added when installing shared libraries,
// but are added when building.
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
//If set, runtime paths are not added when using shared libraries.
CMAKE_SKIP_RPATH:BOOL=NO
//Flags used by the linker during the creation of static libraries
// during all build types.
CMAKE_STATIC_LINKER_FLAGS:STRING=
//Flags used by the linker during the creation of static libraries
// during DEBUG builds.
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
//Flags used by the linker during the creation of static libraries
// during MINSIZEREL builds.
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
//Flags used by the linker during the creation of static libraries
// during RELEASE builds.
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
//Flags used by the linker during the creation of static libraries
// during RELWITHDEBINFO builds.
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
//Path to a program.
CMAKE_STRIP:FILEPATH=/usr/bin/strip
//If this value is on, makefiles will be generated without the
// .SILENT directive, and all commands will be echoed to the console
// during the make. This is useful for debugging only. With Visual
// Studio IDE projects all commands are done without /nologo.
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
//Value Computed by CMake
Project_BINARY_DIR:STATIC=/home/cococode/flipperzero-firmware/lib/esp-serial-flasher
//Value Computed by CMake
Project_SOURCE_DIR:STATIC=/home/cococode/flipperzero-firmware/lib/esp-serial-flasher
########################
# INTERNAL cache entries
########################
//ADVANCED property for variable: CMAKE_ADDR2LINE
CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_AR
CMAKE_AR-ADVANCED:INTERNAL=1
//This is the directory where this CMakeCache.txt was created
CMAKE_CACHEFILE_DIR:INTERNAL=/home/cococode/flipperzero-firmware/lib/esp-serial-flasher
//Major version of cmake used to create the current loaded cache
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
//Minor version of cmake used to create the current loaded cache
CMAKE_CACHE_MINOR_VERSION:INTERNAL=16
//Patch version of cmake used to create the current loaded cache
CMAKE_CACHE_PATCH_VERSION:INTERNAL=3
//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE
CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1
//Path to CMake executable.
CMAKE_COMMAND:INTERNAL=/usr/bin/cmake
//Path to cpack program executable.
CMAKE_CPACK_COMMAND:INTERNAL=/usr/bin/cpack
//Path to ctest program executable.
CMAKE_CTEST_COMMAND:INTERNAL=/usr/bin/ctest
//ADVANCED property for variable: CMAKE_CXX_COMPILER
CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR
CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB
CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER
CMAKE_C_COMPILER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_AR
CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB
CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_DLLTOOL
CMAKE_DLLTOOL-ADVANCED:INTERNAL=1
//Executable file format
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
//Name of external makefile project generator.
CMAKE_EXTRA_GENERATOR:INTERNAL=
//Name of generator.
CMAKE_GENERATOR:INTERNAL=Unix Makefiles
//Generator instance identifier.
CMAKE_GENERATOR_INSTANCE:INTERNAL=
//Name of generator platform.
CMAKE_GENERATOR_PLATFORM:INTERNAL=
//Name of generator toolset.
CMAKE_GENERATOR_TOOLSET:INTERNAL=
//Source directory with the top level CMakeLists.txt file for this
// project
CMAKE_HOME_DIRECTORY:INTERNAL=/home/cococode/flipperzero-firmware/lib/esp-serial-flasher
//Install .so files without execute permission.
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1
//ADVANCED property for variable: CMAKE_LINKER
CMAKE_LINKER-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MAKE_PROGRAM
CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_NM
CMAKE_NM-ADVANCED:INTERNAL=1
//number of local generators
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJCOPY
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_OBJDUMP
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
//Platform information initialized
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
//ADVANCED property for variable: CMAKE_RANLIB
CMAKE_RANLIB-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_READELF
CMAKE_READELF-ADVANCED:INTERNAL=1
//Path to CMake installation.
CMAKE_ROOT:INTERNAL=/usr/share/cmake-3.16
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_SKIP_RPATH
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
//ADVANCED property for variable: CMAKE_STRIP
CMAKE_STRIP-ADVANCED:INTERNAL=1
//uname command
CMAKE_UNAME:INTERNAL=/usr/bin/uname
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1

View File

@@ -0,0 +1,76 @@
set(CMAKE_C_COMPILER "/usr/bin/cc")
set(CMAKE_C_COMPILER_ARG1 "")
set(CMAKE_C_COMPILER_ID "GNU")
set(CMAKE_C_COMPILER_VERSION "9.4.0")
set(CMAKE_C_COMPILER_VERSION_INTERNAL "")
set(CMAKE_C_COMPILER_WRAPPER "")
set(CMAKE_C_STANDARD_COMPUTED_DEFAULT "11")
set(CMAKE_C_COMPILE_FEATURES "c_std_90;c_function_prototypes;c_std_99;c_restrict;c_variadic_macros;c_std_11;c_static_assert")
set(CMAKE_C90_COMPILE_FEATURES "c_std_90;c_function_prototypes")
set(CMAKE_C99_COMPILE_FEATURES "c_std_99;c_restrict;c_variadic_macros")
set(CMAKE_C11_COMPILE_FEATURES "c_std_11;c_static_assert")
set(CMAKE_C_PLATFORM_ID "Linux")
set(CMAKE_C_SIMULATE_ID "")
set(CMAKE_C_COMPILER_FRONTEND_VARIANT "")
set(CMAKE_C_SIMULATE_VERSION "")
set(CMAKE_AR "/usr/bin/ar")
set(CMAKE_C_COMPILER_AR "/usr/bin/gcc-ar-9")
set(CMAKE_RANLIB "/usr/bin/ranlib")
set(CMAKE_C_COMPILER_RANLIB "/usr/bin/gcc-ranlib-9")
set(CMAKE_LINKER "/usr/bin/ld")
set(CMAKE_MT "")
set(CMAKE_COMPILER_IS_GNUCC 1)
set(CMAKE_C_COMPILER_LOADED 1)
set(CMAKE_C_COMPILER_WORKS TRUE)
set(CMAKE_C_ABI_COMPILED TRUE)
set(CMAKE_COMPILER_IS_MINGW )
set(CMAKE_COMPILER_IS_CYGWIN )
if(CMAKE_COMPILER_IS_CYGWIN)
set(CYGWIN 1)
set(UNIX 1)
endif()
set(CMAKE_C_COMPILER_ENV_VAR "CC")
if(CMAKE_COMPILER_IS_MINGW)
set(MINGW 1)
endif()
set(CMAKE_C_COMPILER_ID_RUN 1)
set(CMAKE_C_SOURCE_FILE_EXTENSIONS c;m)
set(CMAKE_C_IGNORE_EXTENSIONS h;H;o;O;obj;OBJ;def;DEF;rc;RC)
set(CMAKE_C_LINKER_PREFERENCE 10)
# Save compiler ABI information.
set(CMAKE_C_SIZEOF_DATA_PTR "8")
set(CMAKE_C_COMPILER_ABI "ELF")
set(CMAKE_C_LIBRARY_ARCHITECTURE "x86_64-linux-gnu")
if(CMAKE_C_SIZEOF_DATA_PTR)
set(CMAKE_SIZEOF_VOID_P "${CMAKE_C_SIZEOF_DATA_PTR}")
endif()
if(CMAKE_C_COMPILER_ABI)
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_C_COMPILER_ABI}")
endif()
if(CMAKE_C_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu")
endif()
set(CMAKE_C_CL_SHOWINCLUDES_PREFIX "")
if(CMAKE_C_CL_SHOWINCLUDES_PREFIX)
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_C_CL_SHOWINCLUDES_PREFIX}")
endif()
set(CMAKE_C_IMPLICIT_INCLUDE_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/9/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include")
set(CMAKE_C_IMPLICIT_LINK_LIBRARIES "gcc;gcc_s;c;gcc;gcc_s")
set(CMAKE_C_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/9;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib")
set(CMAKE_C_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")

View File

@@ -0,0 +1,88 @@
set(CMAKE_CXX_COMPILER "/usr/bin/c++")
set(CMAKE_CXX_COMPILER_ARG1 "")
set(CMAKE_CXX_COMPILER_ID "GNU")
set(CMAKE_CXX_COMPILER_VERSION "9.4.0")
set(CMAKE_CXX_COMPILER_VERSION_INTERNAL "")
set(CMAKE_CXX_COMPILER_WRAPPER "")
set(CMAKE_CXX_STANDARD_COMPUTED_DEFAULT "14")
set(CMAKE_CXX_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters;cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates;cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates;cxx_std_17;cxx_std_20")
set(CMAKE_CXX98_COMPILE_FEATURES "cxx_std_98;cxx_template_template_parameters")
set(CMAKE_CXX11_COMPILE_FEATURES "cxx_std_11;cxx_alias_templates;cxx_alignas;cxx_alignof;cxx_attributes;cxx_auto_type;cxx_constexpr;cxx_decltype;cxx_decltype_incomplete_return_types;cxx_default_function_template_args;cxx_defaulted_functions;cxx_defaulted_move_initializers;cxx_delegating_constructors;cxx_deleted_functions;cxx_enum_forward_declarations;cxx_explicit_conversions;cxx_extended_friend_declarations;cxx_extern_templates;cxx_final;cxx_func_identifier;cxx_generalized_initializers;cxx_inheriting_constructors;cxx_inline_namespaces;cxx_lambdas;cxx_local_type_template_args;cxx_long_long_type;cxx_noexcept;cxx_nonstatic_member_init;cxx_nullptr;cxx_override;cxx_range_for;cxx_raw_string_literals;cxx_reference_qualified_functions;cxx_right_angle_brackets;cxx_rvalue_references;cxx_sizeof_member;cxx_static_assert;cxx_strong_enums;cxx_thread_local;cxx_trailing_return_types;cxx_unicode_literals;cxx_uniform_initialization;cxx_unrestricted_unions;cxx_user_literals;cxx_variadic_macros;cxx_variadic_templates")
set(CMAKE_CXX14_COMPILE_FEATURES "cxx_std_14;cxx_aggregate_default_initializers;cxx_attribute_deprecated;cxx_binary_literals;cxx_contextual_conversions;cxx_decltype_auto;cxx_digit_separators;cxx_generic_lambdas;cxx_lambda_init_captures;cxx_relaxed_constexpr;cxx_return_type_deduction;cxx_variable_templates")
set(CMAKE_CXX17_COMPILE_FEATURES "cxx_std_17")
set(CMAKE_CXX20_COMPILE_FEATURES "cxx_std_20")
set(CMAKE_CXX_PLATFORM_ID "Linux")
set(CMAKE_CXX_SIMULATE_ID "")
set(CMAKE_CXX_COMPILER_FRONTEND_VARIANT "")
set(CMAKE_CXX_SIMULATE_VERSION "")
set(CMAKE_AR "/usr/bin/ar")
set(CMAKE_CXX_COMPILER_AR "/usr/bin/gcc-ar-9")
set(CMAKE_RANLIB "/usr/bin/ranlib")
set(CMAKE_CXX_COMPILER_RANLIB "/usr/bin/gcc-ranlib-9")
set(CMAKE_LINKER "/usr/bin/ld")
set(CMAKE_MT "")
set(CMAKE_COMPILER_IS_GNUCXX 1)
set(CMAKE_CXX_COMPILER_LOADED 1)
set(CMAKE_CXX_COMPILER_WORKS TRUE)
set(CMAKE_CXX_ABI_COMPILED TRUE)
set(CMAKE_COMPILER_IS_MINGW )
set(CMAKE_COMPILER_IS_CYGWIN )
if(CMAKE_COMPILER_IS_CYGWIN)
set(CYGWIN 1)
set(UNIX 1)
endif()
set(CMAKE_CXX_COMPILER_ENV_VAR "CXX")
if(CMAKE_COMPILER_IS_MINGW)
set(MINGW 1)
endif()
set(CMAKE_CXX_COMPILER_ID_RUN 1)
set(CMAKE_CXX_SOURCE_FILE_EXTENSIONS C;M;c++;cc;cpp;cxx;m;mm;CPP)
set(CMAKE_CXX_IGNORE_EXTENSIONS inl;h;hpp;HPP;H;o;O;obj;OBJ;def;DEF;rc;RC)
foreach (lang C OBJC OBJCXX)
if (CMAKE_${lang}_COMPILER_ID_RUN)
foreach(extension IN LISTS CMAKE_${lang}_SOURCE_FILE_EXTENSIONS)
list(REMOVE_ITEM CMAKE_CXX_SOURCE_FILE_EXTENSIONS ${extension})
endforeach()
endif()
endforeach()
set(CMAKE_CXX_LINKER_PREFERENCE 30)
set(CMAKE_CXX_LINKER_PREFERENCE_PROPAGATES 1)
# Save compiler ABI information.
set(CMAKE_CXX_SIZEOF_DATA_PTR "8")
set(CMAKE_CXX_COMPILER_ABI "ELF")
set(CMAKE_CXX_LIBRARY_ARCHITECTURE "x86_64-linux-gnu")
if(CMAKE_CXX_SIZEOF_DATA_PTR)
set(CMAKE_SIZEOF_VOID_P "${CMAKE_CXX_SIZEOF_DATA_PTR}")
endif()
if(CMAKE_CXX_COMPILER_ABI)
set(CMAKE_INTERNAL_PLATFORM_ABI "${CMAKE_CXX_COMPILER_ABI}")
endif()
if(CMAKE_CXX_LIBRARY_ARCHITECTURE)
set(CMAKE_LIBRARY_ARCHITECTURE "x86_64-linux-gnu")
endif()
set(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX "")
if(CMAKE_CXX_CL_SHOWINCLUDES_PREFIX)
set(CMAKE_CL_SHOWINCLUDES_PREFIX "${CMAKE_CXX_CL_SHOWINCLUDES_PREFIX}")
endif()
set(CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES "/usr/include/c++/9;/usr/include/x86_64-linux-gnu/c++/9;/usr/include/c++/9/backward;/usr/lib/gcc/x86_64-linux-gnu/9/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include")
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "stdc++;m;gcc_s;gcc;c;gcc_s;gcc")
set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "/usr/lib/gcc/x86_64-linux-gnu/9;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib")
set(CMAKE_CXX_IMPLICIT_LINK_FRAMEWORK_DIRECTORIES "")

View File

@@ -0,0 +1,15 @@
set(CMAKE_HOST_SYSTEM "Linux-5.10.16.3-microsoft-standard-WSL2")
set(CMAKE_HOST_SYSTEM_NAME "Linux")
set(CMAKE_HOST_SYSTEM_VERSION "5.10.16.3-microsoft-standard-WSL2")
set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64")
set(CMAKE_SYSTEM "Linux-5.10.16.3-microsoft-standard-WSL2")
set(CMAKE_SYSTEM_NAME "Linux")
set(CMAKE_SYSTEM_VERSION "5.10.16.3-microsoft-standard-WSL2")
set(CMAKE_SYSTEM_PROCESSOR "x86_64")
set(CMAKE_CROSSCOMPILING "FALSE")
set(CMAKE_SYSTEM_LOADED 1)

View File

@@ -0,0 +1,671 @@
#ifdef __cplusplus
# error "A C++ compiler has been selected for C."
#endif
#if defined(__18CXX)
# define ID_VOID_MAIN
#endif
#if defined(__CLASSIC_C__)
/* cv-qualifiers did not exist in K&R C */
# define const
# define volatile
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP */
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_C)
# define COMPILER_ID "SunPro"
# if __SUNPRO_C >= 0x5100
/* __SUNPRO_C = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_C>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_C>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_C & 0xF)
# endif
#elif defined(__HP_cc)
# define COMPILER_ID "HP"
/* __HP_cc = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_cc/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_cc/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_cc % 100)
#elif defined(__DECC)
# define COMPILER_ID "Compaq"
/* __DECC_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECC_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECC_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECC_VER % 10000)
#elif defined(__IBMC__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ >= 800
# define COMPILER_ID "XL"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__IBMC__) && !defined(__COMPILER_VER__) && __IBMC__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMC__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMC__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMC__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMC__ % 10)
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__FUJITSU) || defined(__FCC_VERSION) || defined(__fcc_version)
# define COMPILER_ID "Fujitsu"
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__TINYC__)
# define COMPILER_ID "TinyCC"
#elif defined(__BCC__)
# define COMPILER_ID "Bruce"
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__GNUC__)
# define COMPILER_ID "GNU"
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
# define COMPILER_ID "ADSP"
#if defined(__VISUALDSPVERSION__)
/* __VISUALDSPVERSION__ = 0xVVRRPP00 */
# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
#elif defined(__SDCC_VERSION_MAJOR) || defined(SDCC)
# define COMPILER_ID "SDCC"
# if defined(__SDCC_VERSION_MAJOR)
# define COMPILER_VERSION_MAJOR DEC(__SDCC_VERSION_MAJOR)
# define COMPILER_VERSION_MINOR DEC(__SDCC_VERSION_MINOR)
# define COMPILER_VERSION_PATCH DEC(__SDCC_VERSION_PATCH)
# else
/* SDCC = VRP */
# define COMPILER_VERSION_MAJOR DEC(SDCC/100)
# define COMPILER_VERSION_MINOR DEC(SDCC/10 % 10)
# define COMPILER_VERSION_PATCH DEC(SDCC % 10)
# endif
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXE) || defined(__CRAYXC)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number components. */
#ifdef COMPILER_VERSION_MAJOR
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#if !defined(__STDC__)
# if (defined(_MSC_VER) && !defined(__clang__)) \
|| (defined(__ibmxl__) || defined(__IBMC__))
# define C_DIALECT "90"
# else
# define C_DIALECT
# endif
#elif __STDC_VERSION__ >= 201000L
# define C_DIALECT "11"
#elif __STDC_VERSION__ >= 199901L
# define C_DIALECT "99"
#else
# define C_DIALECT "90"
#endif
const char* info_language_dialect_default =
"INFO" ":" "dialect_default[" C_DIALECT "]";
/*--------------------------------------------------------------------------*/
#ifdef ID_VOID_MAIN
void main() {}
#else
# if defined(__CLASSIC_C__)
int main(argc, argv) int argc; char *argv[];
# else
int main(int argc, char* argv[])
# endif
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
require += info_arch[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#ifdef COMPILER_VERSION_INTERNAL
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXE) || defined(__CRAYXC)
require += info_cray[argc];
#endif
require += info_language_dialect_default[argc];
(void)argv;
return require;
}
#endif

View File

@@ -0,0 +1,660 @@
/* This source file must have a .cpp extension so that all C++ compilers
recognize the extension without flags. Borland does not know .cxx for
example. */
#ifndef __cplusplus
# error "A C compiler has been selected for C++."
#endif
/* Version number components: V=Version, R=Revision, P=Patch
Version date components: YYYY=Year, MM=Month, DD=Day */
#if defined(__COMO__)
# define COMPILER_ID "Comeau"
/* __COMO_VERSION__ = VRR */
# define COMPILER_VERSION_MAJOR DEC(__COMO_VERSION__ / 100)
# define COMPILER_VERSION_MINOR DEC(__COMO_VERSION__ % 100)
#elif defined(__INTEL_COMPILER) || defined(__ICC)
# define COMPILER_ID "Intel"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# if defined(__GNUC__)
# define SIMULATE_ID "GNU"
# endif
/* __INTEL_COMPILER = VRP */
# define COMPILER_VERSION_MAJOR DEC(__INTEL_COMPILER/100)
# define COMPILER_VERSION_MINOR DEC(__INTEL_COMPILER/10 % 10)
# if defined(__INTEL_COMPILER_UPDATE)
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER_UPDATE)
# else
# define COMPILER_VERSION_PATCH DEC(__INTEL_COMPILER % 10)
# endif
# if defined(__INTEL_COMPILER_BUILD_DATE)
/* __INTEL_COMPILER_BUILD_DATE = YYYYMMDD */
# define COMPILER_VERSION_TWEAK DEC(__INTEL_COMPILER_BUILD_DATE)
# endif
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# if defined(__GNUC__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUC__)
# elif defined(__GNUG__)
# define SIMULATE_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define SIMULATE_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define SIMULATE_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(__PATHCC__)
# define COMPILER_ID "PathScale"
# define COMPILER_VERSION_MAJOR DEC(__PATHCC__)
# define COMPILER_VERSION_MINOR DEC(__PATHCC_MINOR__)
# if defined(__PATHCC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PATHCC_PATCHLEVEL__)
# endif
#elif defined(__BORLANDC__) && defined(__CODEGEARC_VERSION__)
# define COMPILER_ID "Embarcadero"
# define COMPILER_VERSION_MAJOR HEX(__CODEGEARC_VERSION__>>24 & 0x00FF)
# define COMPILER_VERSION_MINOR HEX(__CODEGEARC_VERSION__>>16 & 0x00FF)
# define COMPILER_VERSION_PATCH DEC(__CODEGEARC_VERSION__ & 0xFFFF)
#elif defined(__BORLANDC__)
# define COMPILER_ID "Borland"
/* __BORLANDC__ = 0xVRR */
# define COMPILER_VERSION_MAJOR HEX(__BORLANDC__>>8)
# define COMPILER_VERSION_MINOR HEX(__BORLANDC__ & 0xFF)
#elif defined(__WATCOMC__) && __WATCOMC__ < 1200
# define COMPILER_ID "Watcom"
/* __WATCOMC__ = VVRR */
# define COMPILER_VERSION_MAJOR DEC(__WATCOMC__ / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__WATCOMC__)
# define COMPILER_ID "OpenWatcom"
/* __WATCOMC__ = VVRP + 1100 */
# define COMPILER_VERSION_MAJOR DEC((__WATCOMC__ - 1100) / 100)
# define COMPILER_VERSION_MINOR DEC((__WATCOMC__ / 10) % 10)
# if (__WATCOMC__ % 10) > 0
# define COMPILER_VERSION_PATCH DEC(__WATCOMC__ % 10)
# endif
#elif defined(__SUNPRO_CC)
# define COMPILER_ID "SunPro"
# if __SUNPRO_CC >= 0x5100
/* __SUNPRO_CC = 0xVRRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>12)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# else
/* __SUNPRO_CC = 0xVRP */
# define COMPILER_VERSION_MAJOR HEX(__SUNPRO_CC>>8)
# define COMPILER_VERSION_MINOR HEX(__SUNPRO_CC>>4 & 0xF)
# define COMPILER_VERSION_PATCH HEX(__SUNPRO_CC & 0xF)
# endif
#elif defined(__HP_aCC)
# define COMPILER_ID "HP"
/* __HP_aCC = VVRRPP */
# define COMPILER_VERSION_MAJOR DEC(__HP_aCC/10000)
# define COMPILER_VERSION_MINOR DEC(__HP_aCC/100 % 100)
# define COMPILER_VERSION_PATCH DEC(__HP_aCC % 100)
#elif defined(__DECCXX)
# define COMPILER_ID "Compaq"
/* __DECCXX_VER = VVRRTPPPP */
# define COMPILER_VERSION_MAJOR DEC(__DECCXX_VER/10000000)
# define COMPILER_VERSION_MINOR DEC(__DECCXX_VER/100000 % 100)
# define COMPILER_VERSION_PATCH DEC(__DECCXX_VER % 10000)
#elif defined(__IBMCPP__) && defined(__COMPILER_VER__)
# define COMPILER_ID "zOS"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__ibmxl__) && defined(__clang__)
# define COMPILER_ID "XLClang"
# define COMPILER_VERSION_MAJOR DEC(__ibmxl_version__)
# define COMPILER_VERSION_MINOR DEC(__ibmxl_release__)
# define COMPILER_VERSION_PATCH DEC(__ibmxl_modification__)
# define COMPILER_VERSION_TWEAK DEC(__ibmxl_ptf_fix_level__)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ >= 800
# define COMPILER_ID "XL"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__IBMCPP__) && !defined(__COMPILER_VER__) && __IBMCPP__ < 800
# define COMPILER_ID "VisualAge"
/* __IBMCPP__ = VRP */
# define COMPILER_VERSION_MAJOR DEC(__IBMCPP__/100)
# define COMPILER_VERSION_MINOR DEC(__IBMCPP__/10 % 10)
# define COMPILER_VERSION_PATCH DEC(__IBMCPP__ % 10)
#elif defined(__PGI)
# define COMPILER_ID "PGI"
# define COMPILER_VERSION_MAJOR DEC(__PGIC__)
# define COMPILER_VERSION_MINOR DEC(__PGIC_MINOR__)
# if defined(__PGIC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__PGIC_PATCHLEVEL__)
# endif
#elif defined(_CRAYC)
# define COMPILER_ID "Cray"
# define COMPILER_VERSION_MAJOR DEC(_RELEASE_MAJOR)
# define COMPILER_VERSION_MINOR DEC(_RELEASE_MINOR)
#elif defined(__TI_COMPILER_VERSION__)
# define COMPILER_ID "TI"
/* __TI_COMPILER_VERSION__ = VVVRRRPPP */
# define COMPILER_VERSION_MAJOR DEC(__TI_COMPILER_VERSION__/1000000)
# define COMPILER_VERSION_MINOR DEC(__TI_COMPILER_VERSION__/1000 % 1000)
# define COMPILER_VERSION_PATCH DEC(__TI_COMPILER_VERSION__ % 1000)
#elif defined(__FUJITSU) || defined(__FCC_VERSION) || defined(__fcc_version)
# define COMPILER_ID "Fujitsu"
#elif defined(__ghs__)
# define COMPILER_ID "GHS"
/* __GHS_VERSION_NUMBER = VVVVRP */
# ifdef __GHS_VERSION_NUMBER
# define COMPILER_VERSION_MAJOR DEC(__GHS_VERSION_NUMBER / 100)
# define COMPILER_VERSION_MINOR DEC(__GHS_VERSION_NUMBER / 10 % 10)
# define COMPILER_VERSION_PATCH DEC(__GHS_VERSION_NUMBER % 10)
# endif
#elif defined(__SCO_VERSION__)
# define COMPILER_ID "SCO"
#elif defined(__ARMCC_VERSION) && !defined(__clang__)
# define COMPILER_ID "ARMCC"
#if __ARMCC_VERSION >= 1000000
/* __ARMCC_VERSION = VRRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#else
/* __ARMCC_VERSION = VRPPPP */
# define COMPILER_VERSION_MAJOR DEC(__ARMCC_VERSION/100000)
# define COMPILER_VERSION_MINOR DEC(__ARMCC_VERSION/10000 % 10)
# define COMPILER_VERSION_PATCH DEC(__ARMCC_VERSION % 10000)
#endif
#elif defined(__clang__) && defined(__apple_build_version__)
# define COMPILER_ID "AppleClang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
# define COMPILER_VERSION_TWEAK DEC(__apple_build_version__)
#elif defined(__clang__) && defined(__ARMCOMPILER_VERSION)
# define COMPILER_ID "ARMClang"
# define COMPILER_VERSION_MAJOR DEC(__ARMCOMPILER_VERSION/1000000)
# define COMPILER_VERSION_MINOR DEC(__ARMCOMPILER_VERSION/10000 % 100)
# define COMPILER_VERSION_PATCH DEC(__ARMCOMPILER_VERSION % 10000)
# define COMPILER_VERSION_INTERNAL DEC(__ARMCOMPILER_VERSION)
#elif defined(__clang__)
# define COMPILER_ID "Clang"
# if defined(_MSC_VER)
# define SIMULATE_ID "MSVC"
# endif
# define COMPILER_VERSION_MAJOR DEC(__clang_major__)
# define COMPILER_VERSION_MINOR DEC(__clang_minor__)
# define COMPILER_VERSION_PATCH DEC(__clang_patchlevel__)
# if defined(_MSC_VER)
/* _MSC_VER = VVRR */
# define SIMULATE_VERSION_MAJOR DEC(_MSC_VER / 100)
# define SIMULATE_VERSION_MINOR DEC(_MSC_VER % 100)
# endif
#elif defined(__GNUC__) || defined(__GNUG__)
# define COMPILER_ID "GNU"
# if defined(__GNUC__)
# define COMPILER_VERSION_MAJOR DEC(__GNUC__)
# else
# define COMPILER_VERSION_MAJOR DEC(__GNUG__)
# endif
# if defined(__GNUC_MINOR__)
# define COMPILER_VERSION_MINOR DEC(__GNUC_MINOR__)
# endif
# if defined(__GNUC_PATCHLEVEL__)
# define COMPILER_VERSION_PATCH DEC(__GNUC_PATCHLEVEL__)
# endif
#elif defined(_MSC_VER)
# define COMPILER_ID "MSVC"
/* _MSC_VER = VVRR */
# define COMPILER_VERSION_MAJOR DEC(_MSC_VER / 100)
# define COMPILER_VERSION_MINOR DEC(_MSC_VER % 100)
# if defined(_MSC_FULL_VER)
# if _MSC_VER >= 1400
/* _MSC_FULL_VER = VVRRPPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 100000)
# else
/* _MSC_FULL_VER = VVRRPPPP */
# define COMPILER_VERSION_PATCH DEC(_MSC_FULL_VER % 10000)
# endif
# endif
# if defined(_MSC_BUILD)
# define COMPILER_VERSION_TWEAK DEC(_MSC_BUILD)
# endif
#elif defined(__VISUALDSPVERSION__) || defined(__ADSPBLACKFIN__) || defined(__ADSPTS__) || defined(__ADSP21000__)
# define COMPILER_ID "ADSP"
#if defined(__VISUALDSPVERSION__)
/* __VISUALDSPVERSION__ = 0xVVRRPP00 */
# define COMPILER_VERSION_MAJOR HEX(__VISUALDSPVERSION__>>24)
# define COMPILER_VERSION_MINOR HEX(__VISUALDSPVERSION__>>16 & 0xFF)
# define COMPILER_VERSION_PATCH HEX(__VISUALDSPVERSION__>>8 & 0xFF)
#endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# define COMPILER_ID "IAR"
# if defined(__VER__) && defined(__ICCARM__)
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 1000000)
# define COMPILER_VERSION_MINOR DEC(((__VER__) / 1000) % 1000)
# define COMPILER_VERSION_PATCH DEC((__VER__) % 1000)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# elif defined(__VER__) && (defined(__ICCAVR__) || defined(__ICCRX__) || defined(__ICCRH850__) || defined(__ICCRL78__) || defined(__ICC430__) || defined(__ICCRISCV__) || defined(__ICCV850__) || defined(__ICC8051__))
# define COMPILER_VERSION_MAJOR DEC((__VER__) / 100)
# define COMPILER_VERSION_MINOR DEC((__VER__) - (((__VER__) / 100)*100))
# define COMPILER_VERSION_PATCH DEC(__SUBVERSION__)
# define COMPILER_VERSION_INTERNAL DEC(__IAR_SYSTEMS_ICC__)
# endif
/* These compilers are either not known or too old to define an
identification macro. Try to identify the platform and guess that
it is the native compiler. */
#elif defined(__hpux) || defined(__hpua)
# define COMPILER_ID "HP"
#else /* unknown compiler */
# define COMPILER_ID ""
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_compiler = "INFO" ":" "compiler[" COMPILER_ID "]";
#ifdef SIMULATE_ID
char const* info_simulate = "INFO" ":" "simulate[" SIMULATE_ID "]";
#endif
#ifdef __QNXNTO__
char const* qnxnto = "INFO" ":" "qnxnto[]";
#endif
#if defined(__CRAYXE) || defined(__CRAYXC)
char const *info_cray = "INFO" ":" "compiler_wrapper[CrayPrgEnv]";
#endif
#define STRINGIFY_HELPER(X) #X
#define STRINGIFY(X) STRINGIFY_HELPER(X)
/* Identify known platforms by name. */
#if defined(__linux) || defined(__linux__) || defined(linux)
# define PLATFORM_ID "Linux"
#elif defined(__CYGWIN__)
# define PLATFORM_ID "Cygwin"
#elif defined(__MINGW32__)
# define PLATFORM_ID "MinGW"
#elif defined(__APPLE__)
# define PLATFORM_ID "Darwin"
#elif defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
# define PLATFORM_ID "Windows"
#elif defined(__FreeBSD__) || defined(__FreeBSD)
# define PLATFORM_ID "FreeBSD"
#elif defined(__NetBSD__) || defined(__NetBSD)
# define PLATFORM_ID "NetBSD"
#elif defined(__OpenBSD__) || defined(__OPENBSD)
# define PLATFORM_ID "OpenBSD"
#elif defined(__sun) || defined(sun)
# define PLATFORM_ID "SunOS"
#elif defined(_AIX) || defined(__AIX) || defined(__AIX__) || defined(__aix) || defined(__aix__)
# define PLATFORM_ID "AIX"
#elif defined(__hpux) || defined(__hpux__)
# define PLATFORM_ID "HP-UX"
#elif defined(__HAIKU__)
# define PLATFORM_ID "Haiku"
#elif defined(__BeOS) || defined(__BEOS__) || defined(_BEOS)
# define PLATFORM_ID "BeOS"
#elif defined(__QNX__) || defined(__QNXNTO__)
# define PLATFORM_ID "QNX"
#elif defined(__tru64) || defined(_tru64) || defined(__TRU64__)
# define PLATFORM_ID "Tru64"
#elif defined(__riscos) || defined(__riscos__)
# define PLATFORM_ID "RISCos"
#elif defined(__sinix) || defined(__sinix__) || defined(__SINIX__)
# define PLATFORM_ID "SINIX"
#elif defined(__UNIX_SV__)
# define PLATFORM_ID "UNIX_SV"
#elif defined(__bsdos__)
# define PLATFORM_ID "BSDOS"
#elif defined(_MPRAS) || defined(MPRAS)
# define PLATFORM_ID "MP-RAS"
#elif defined(__osf) || defined(__osf__)
# define PLATFORM_ID "OSF1"
#elif defined(_SCO_SV) || defined(SCO_SV) || defined(sco_sv)
# define PLATFORM_ID "SCO_SV"
#elif defined(__ultrix) || defined(__ultrix__) || defined(_ULTRIX)
# define PLATFORM_ID "ULTRIX"
#elif defined(__XENIX__) || defined(_XENIX) || defined(XENIX)
# define PLATFORM_ID "Xenix"
#elif defined(__WATCOMC__)
# if defined(__LINUX__)
# define PLATFORM_ID "Linux"
# elif defined(__DOS__)
# define PLATFORM_ID "DOS"
# elif defined(__OS2__)
# define PLATFORM_ID "OS2"
# elif defined(__WINDOWS__)
# define PLATFORM_ID "Windows3x"
# else /* unknown platform */
# define PLATFORM_ID
# endif
#elif defined(__INTEGRITY)
# if defined(INT_178B)
# define PLATFORM_ID "Integrity178"
# else /* regular Integrity */
# define PLATFORM_ID "Integrity"
# endif
#else /* unknown platform */
# define PLATFORM_ID
#endif
/* For windows compilers MSVC and Intel we can determine
the architecture of the compiler being used. This is because
the compilers do not have flags that can change the architecture,
but rather depend on which compiler is being used
*/
#if defined(_WIN32) && defined(_MSC_VER)
# if defined(_M_IA64)
# define ARCHITECTURE_ID "IA64"
# elif defined(_M_X64) || defined(_M_AMD64)
# define ARCHITECTURE_ID "x64"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# elif defined(_M_ARM64)
# define ARCHITECTURE_ID "ARM64"
# elif defined(_M_ARM)
# if _M_ARM == 4
# define ARCHITECTURE_ID "ARMV4I"
# elif _M_ARM == 5
# define ARCHITECTURE_ID "ARMV5I"
# else
# define ARCHITECTURE_ID "ARMV" STRINGIFY(_M_ARM)
# endif
# elif defined(_M_MIPS)
# define ARCHITECTURE_ID "MIPS"
# elif defined(_M_SH)
# define ARCHITECTURE_ID "SHx"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__WATCOMC__)
# if defined(_M_I86)
# define ARCHITECTURE_ID "I86"
# elif defined(_M_IX86)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__IAR_SYSTEMS_ICC__) || defined(__IAR_SYSTEMS_ICC)
# if defined(__ICCARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__ICCRX__)
# define ARCHITECTURE_ID "RX"
# elif defined(__ICCRH850__)
# define ARCHITECTURE_ID "RH850"
# elif defined(__ICCRL78__)
# define ARCHITECTURE_ID "RL78"
# elif defined(__ICCRISCV__)
# define ARCHITECTURE_ID "RISCV"
# elif defined(__ICCAVR__)
# define ARCHITECTURE_ID "AVR"
# elif defined(__ICC430__)
# define ARCHITECTURE_ID "MSP430"
# elif defined(__ICCV850__)
# define ARCHITECTURE_ID "V850"
# elif defined(__ICC8051__)
# define ARCHITECTURE_ID "8051"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#elif defined(__ghs__)
# if defined(__PPC64__)
# define ARCHITECTURE_ID "PPC64"
# elif defined(__ppc__)
# define ARCHITECTURE_ID "PPC"
# elif defined(__ARM__)
# define ARCHITECTURE_ID "ARM"
# elif defined(__x86_64__)
# define ARCHITECTURE_ID "x64"
# elif defined(__i386__)
# define ARCHITECTURE_ID "X86"
# else /* unknown architecture */
# define ARCHITECTURE_ID ""
# endif
#else
# define ARCHITECTURE_ID
#endif
/* Convert integer to decimal digit literals. */
#define DEC(n) \
('0' + (((n) / 10000000)%10)), \
('0' + (((n) / 1000000)%10)), \
('0' + (((n) / 100000)%10)), \
('0' + (((n) / 10000)%10)), \
('0' + (((n) / 1000)%10)), \
('0' + (((n) / 100)%10)), \
('0' + (((n) / 10)%10)), \
('0' + ((n) % 10))
/* Convert integer to hex digit literals. */
#define HEX(n) \
('0' + ((n)>>28 & 0xF)), \
('0' + ((n)>>24 & 0xF)), \
('0' + ((n)>>20 & 0xF)), \
('0' + ((n)>>16 & 0xF)), \
('0' + ((n)>>12 & 0xF)), \
('0' + ((n)>>8 & 0xF)), \
('0' + ((n)>>4 & 0xF)), \
('0' + ((n) & 0xF))
/* Construct a string literal encoding the version number components. */
#ifdef COMPILER_VERSION_MAJOR
char const info_version[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','[',
COMPILER_VERSION_MAJOR,
# ifdef COMPILER_VERSION_MINOR
'.', COMPILER_VERSION_MINOR,
# ifdef COMPILER_VERSION_PATCH
'.', COMPILER_VERSION_PATCH,
# ifdef COMPILER_VERSION_TWEAK
'.', COMPILER_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct a string literal encoding the internal version number. */
#ifdef COMPILER_VERSION_INTERNAL
char const info_version_internal[] = {
'I', 'N', 'F', 'O', ':',
'c','o','m','p','i','l','e','r','_','v','e','r','s','i','o','n','_',
'i','n','t','e','r','n','a','l','[',
COMPILER_VERSION_INTERNAL,']','\0'};
#endif
/* Construct a string literal encoding the version number components. */
#ifdef SIMULATE_VERSION_MAJOR
char const info_simulate_version[] = {
'I', 'N', 'F', 'O', ':',
's','i','m','u','l','a','t','e','_','v','e','r','s','i','o','n','[',
SIMULATE_VERSION_MAJOR,
# ifdef SIMULATE_VERSION_MINOR
'.', SIMULATE_VERSION_MINOR,
# ifdef SIMULATE_VERSION_PATCH
'.', SIMULATE_VERSION_PATCH,
# ifdef SIMULATE_VERSION_TWEAK
'.', SIMULATE_VERSION_TWEAK,
# endif
# endif
# endif
']','\0'};
#endif
/* Construct the string literal in pieces to prevent the source from
getting matched. Store it in a pointer rather than an array
because some compilers will just produce instructions to fill the
array rather than assigning a pointer to a static array. */
char const* info_platform = "INFO" ":" "platform[" PLATFORM_ID "]";
char const* info_arch = "INFO" ":" "arch[" ARCHITECTURE_ID "]";
#if defined(__INTEL_COMPILER) && defined(_MSVC_LANG) && _MSVC_LANG < 201403L
# if defined(__INTEL_CXX11_MODE__)
# if defined(__cpp_aggregate_nsdmi)
# define CXX_STD 201402L
# else
# define CXX_STD 201103L
# endif
# else
# define CXX_STD 199711L
# endif
#elif defined(_MSC_VER) && defined(_MSVC_LANG)
# define CXX_STD _MSVC_LANG
#else
# define CXX_STD __cplusplus
#endif
const char* info_language_dialect_default = "INFO" ":" "dialect_default["
#if CXX_STD > 201703L
"20"
#elif CXX_STD >= 201703L
"17"
#elif CXX_STD >= 201402L
"14"
#elif CXX_STD >= 201103L
"11"
#else
"98"
#endif
"]";
/*--------------------------------------------------------------------------*/
int main(int argc, char* argv[])
{
int require = 0;
require += info_compiler[argc];
require += info_platform[argc];
#ifdef COMPILER_VERSION_MAJOR
require += info_version[argc];
#endif
#ifdef COMPILER_VERSION_INTERNAL
require += info_version_internal[argc];
#endif
#ifdef SIMULATE_ID
require += info_simulate[argc];
#endif
#ifdef SIMULATE_VERSION_MAJOR
require += info_simulate_version[argc];
#endif
#if defined(__CRAYXE) || defined(__CRAYXC)
require += info_cray[argc];
#endif
require += info_language_dialect_default[argc];
(void)argv;
return require;
}

View File

@@ -0,0 +1,463 @@
The system is: Linux - 5.10.16.3-microsoft-standard-WSL2 - x86_64
Compiling the C compiler identification source file "CMakeCCompilerId.c" succeeded.
Compiler: /usr/bin/cc
Build flags:
Id flags:
The output was:
0
Compilation of the C compiler identification source "CMakeCCompilerId.c" produced "a.out"
The C compiler identification is GNU, found in "/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/3.16.3/CompilerIdC/a.out"
Compiling the CXX compiler identification source file "CMakeCXXCompilerId.cpp" succeeded.
Compiler: /usr/bin/c++
Build flags:
Id flags:
The output was:
0
Compilation of the CXX compiler identification source "CMakeCXXCompilerId.cpp" produced "a.out"
The CXX compiler identification is GNU, found in "/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/3.16.3/CompilerIdCXX/a.out"
Determining if the C compiler works passed with the following output:
Change Dir: /home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp
Run Build Command(s):/usr/bin/make cmTC_8695b/fast && /usr/bin/make -f CMakeFiles/cmTC_8695b.dir/build.make CMakeFiles/cmTC_8695b.dir/build
make[1]: Entering directory '/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_8695b.dir/testCCompiler.c.o
/usr/bin/cc -o CMakeFiles/cmTC_8695b.dir/testCCompiler.c.o -c /home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp/testCCompiler.c
Linking C executable cmTC_8695b
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_8695b.dir/link.txt --verbose=1
/usr/bin/cc -rdynamic CMakeFiles/cmTC_8695b.dir/testCCompiler.c.o -o cmTC_8695b
make[1]: Leaving directory '/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp'
Detecting C compiler ABI info compiled with the following output:
Change Dir: /home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp
Run Build Command(s):/usr/bin/make cmTC_8c7d9/fast && /usr/bin/make -f CMakeFiles/cmTC_8c7d9.dir/build.make CMakeFiles/cmTC_8c7d9.dir/build
make[1]: Entering directory '/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp'
Building C object CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o
/usr/bin/cc -v -o CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake-3.16/Modules/CMakeCCompilerABI.c
Using built-in specs.
COLLECT_GCC=/usr/bin/cc
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/9/cc1 -quiet -v -imultiarch x86_64-linux-gnu /usr/share/cmake-3.16/Modules/CMakeCCompilerABI.c -quiet -dumpbase CMakeCCompilerABI.c -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccBr8JWY.s
GNU C17 (Ubuntu 9.4.0-1ubuntu1~20.04.1) version 9.4.0 (x86_64-linux-gnu)
compiled by GNU C version 9.4.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/9/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
GNU C17 (Ubuntu 9.4.0-1ubuntu1~20.04.1) version 9.4.0 (x86_64-linux-gnu)
compiled by GNU C version 9.4.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: c0c95c0b4209efec1c1892d5ff24030b
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'
as -v --64 -o CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o /tmp/ccBr8JWY.s
GNU assembler version 2.34 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.34
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64'
Linking C executable cmTC_8c7d9
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_8c7d9.dir/link.txt --verbose=1
/usr/bin/cc -v -rdynamic CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o -o cmTC_8c7d9
Using built-in specs.
COLLECT_GCC=/usr/bin/cc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_8c7d9' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/9/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper -plugin-opt=-fresolution=/tmp/cc78SKyq.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_8c7d9 /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/9 -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/9/../../.. CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o
COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_8c7d9' '-mtune=generic' '-march=x86-64'
make[1]: Leaving directory '/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp'
Parsed C implicit include dir info from above output: rv=done
found start of include info
found start of implicit include info
add: [/usr/lib/gcc/x86_64-linux-gnu/9/include]
add: [/usr/local/include]
add: [/usr/include/x86_64-linux-gnu]
add: [/usr/include]
end of search list found
collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/9/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/9/include]
collapse include dir [/usr/local/include] ==> [/usr/local/include]
collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu]
collapse include dir [/usr/include] ==> [/usr/include]
implicit include dirs: [/usr/lib/gcc/x86_64-linux-gnu/9/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include]
Parsed C implicit link information from above output:
link line regex: [^( *|.*[/\])(ld|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)]
ignore line: [Change Dir: /home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp]
ignore line: []
ignore line: [Run Build Command(s):/usr/bin/make cmTC_8c7d9/fast && /usr/bin/make -f CMakeFiles/cmTC_8c7d9.dir/build.make CMakeFiles/cmTC_8c7d9.dir/build]
ignore line: [make[1]: Entering directory '/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp']
ignore line: [Building C object CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o]
ignore line: [/usr/bin/cc -v -o CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o -c /usr/share/cmake-3.16/Modules/CMakeCCompilerABI.c]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/cc]
ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:hsa]
ignore line: [OFFLOAD_TARGET_DEFAULT=1]
ignore line: [Target: x86_64-linux-gnu]
ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu]
ignore line: [Thread model: posix]
ignore line: [gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) ]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64']
ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/9/cc1 -quiet -v -imultiarch x86_64-linux-gnu /usr/share/cmake-3.16/Modules/CMakeCCompilerABI.c -quiet -dumpbase CMakeCCompilerABI.c -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccBr8JWY.s]
ignore line: [GNU C17 (Ubuntu 9.4.0-1ubuntu1~20.04.1) version 9.4.0 (x86_64-linux-gnu)]
ignore line: [ compiled by GNU C version 9.4.0 GMP version 6.2.0 MPFR version 4.0.2 MPC version 1.1.0 isl version isl-0.22.1-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/include-fixed"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/../../../../x86_64-linux-gnu/include"]
ignore line: [#include "..." search starts here:]
ignore line: [#include <...> search starts here:]
ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/9/include]
ignore line: [ /usr/local/include]
ignore line: [ /usr/include/x86_64-linux-gnu]
ignore line: [ /usr/include]
ignore line: [End of search list.]
ignore line: [GNU C17 (Ubuntu 9.4.0-1ubuntu1~20.04.1) version 9.4.0 (x86_64-linux-gnu)]
ignore line: [ compiled by GNU C version 9.4.0 GMP version 6.2.0 MPFR version 4.0.2 MPC version 1.1.0 isl version isl-0.22.1-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [Compiler executable checksum: c0c95c0b4209efec1c1892d5ff24030b]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64']
ignore line: [ as -v --64 -o CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o /tmp/ccBr8JWY.s]
ignore line: [GNU assembler version 2.34 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.34]
ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o' '-c' '-mtune=generic' '-march=x86-64']
ignore line: [Linking C executable cmTC_8c7d9]
ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_8c7d9.dir/link.txt --verbose=1]
ignore line: [/usr/bin/cc -v -rdynamic CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o -o cmTC_8c7d9 ]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/cc]
ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper]
ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:hsa]
ignore line: [OFFLOAD_TARGET_DEFAULT=1]
ignore line: [Target: x86_64-linux-gnu]
ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu]
ignore line: [Thread model: posix]
ignore line: [gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) ]
ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_8c7d9' '-mtune=generic' '-march=x86-64']
link line: [ /usr/lib/gcc/x86_64-linux-gnu/9/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper -plugin-opt=-fresolution=/tmp/cc78SKyq.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_8c7d9 /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/9 -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/9/../../.. CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o -lgcc --push-state --as-needed -lgcc_s --pop-state -lc -lgcc --push-state --as-needed -lgcc_s --pop-state /usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/9/collect2] ==> ignore
arg [-plugin] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/liblto_plugin.so] ==> ignore
arg [-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper] ==> ignore
arg [-plugin-opt=-fresolution=/tmp/cc78SKyq.res] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [--build-id] ==> ignore
arg [--eh-frame-hdr] ==> ignore
arg [-m] ==> ignore
arg [elf_x86_64] ==> ignore
arg [--hash-style=gnu] ==> ignore
arg [--as-needed] ==> ignore
arg [-export-dynamic] ==> ignore
arg [-dynamic-linker] ==> ignore
arg [/lib64/ld-linux-x86-64.so.2] ==> ignore
arg [-pie] ==> ignore
arg [-znow] ==> ignore
arg [-zrelro] ==> ignore
arg [-o] ==> ignore
arg [cmTC_8c7d9] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o] ==> ignore
arg [-L/usr/lib/gcc/x86_64-linux-gnu/9] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/9]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib]
arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu]
arg [-L/lib/../lib] ==> dir [/lib/../lib]
arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu]
arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/9/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../..]
arg [CMakeFiles/cmTC_8c7d9.dir/CMakeCCompilerABI.c.o] ==> ignore
arg [-lgcc] ==> lib [gcc]
arg [--push-state] ==> ignore
arg [--as-needed] ==> ignore
arg [-lgcc_s] ==> lib [gcc_s]
arg [--pop-state] ==> ignore
arg [-lc] ==> lib [c]
arg [-lgcc] ==> lib [gcc]
arg [--push-state] ==> ignore
arg [--as-needed] ==> ignore
arg [-lgcc_s] ==> lib [gcc_s]
arg [--pop-state] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o] ==> ignore
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/9] ==> [/usr/lib/gcc/x86_64-linux-gnu/9]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib] ==> [/usr/lib]
collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu]
collapse library dir [/lib/../lib] ==> [/lib]
collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu]
collapse library dir [/usr/lib/../lib] ==> [/usr/lib]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../..] ==> [/usr/lib]
implicit libs: [gcc;gcc_s;c;gcc;gcc_s]
implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/9;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib]
implicit fwks: []
Determining if the CXX compiler works passed with the following output:
Change Dir: /home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp
Run Build Command(s):/usr/bin/make cmTC_9b51d/fast && /usr/bin/make -f CMakeFiles/cmTC_9b51d.dir/build.make CMakeFiles/cmTC_9b51d.dir/build
make[1]: Entering directory '/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp'
Building CXX object CMakeFiles/cmTC_9b51d.dir/testCXXCompiler.cxx.o
/usr/bin/c++ -o CMakeFiles/cmTC_9b51d.dir/testCXXCompiler.cxx.o -c /home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp/testCXXCompiler.cxx
Linking CXX executable cmTC_9b51d
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_9b51d.dir/link.txt --verbose=1
/usr/bin/c++ -rdynamic CMakeFiles/cmTC_9b51d.dir/testCXXCompiler.cxx.o -o cmTC_9b51d
make[1]: Leaving directory '/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp'
Detecting CXX compiler ABI info compiled with the following output:
Change Dir: /home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp
Run Build Command(s):/usr/bin/make cmTC_b76ad/fast && /usr/bin/make -f CMakeFiles/cmTC_b76ad.dir/build.make CMakeFiles/cmTC_b76ad.dir/build
make[1]: Entering directory '/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp'
Building CXX object CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o
/usr/bin/c++ -v -o CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-3.16/Modules/CMakeCXXCompilerABI.cpp
Using built-in specs.
COLLECT_GCC=/usr/bin/c++
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/9/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /usr/share/cmake-3.16/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpbase CMakeCXXCompilerABI.cpp -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccTEwRoV.s
GNU C++14 (Ubuntu 9.4.0-1ubuntu1~20.04.1) version 9.4.0 (x86_64-linux-gnu)
compiled by GNU C version 9.4.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/9"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/9
/usr/include/x86_64-linux-gnu/c++/9
/usr/include/c++/9/backward
/usr/lib/gcc/x86_64-linux-gnu/9/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
GNU C++14 (Ubuntu 9.4.0-1ubuntu1~20.04.1) version 9.4.0 (x86_64-linux-gnu)
compiled by GNU C version 9.4.0, GMP version 6.2.0, MPFR version 4.0.2, MPC version 1.1.0, isl version isl-0.22.1-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 65fe925b83d3956b533de4aaba7dace0
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
as -v --64 -o CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccTEwRoV.s
GNU assembler version 2.34 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.34
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
Linking CXX executable cmTC_b76ad
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_b76ad.dir/link.txt --verbose=1
/usr/bin/c++ -v -rdynamic CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_b76ad
Using built-in specs.
COLLECT_GCC=/usr/bin/c++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1)
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_b76ad' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/9/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccnXxdBn.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_b76ad /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/9 -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/9/../../.. CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o
COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_b76ad' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
make[1]: Leaving directory '/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp'
Parsed CXX implicit include dir info from above output: rv=done
found start of include info
found start of implicit include info
add: [/usr/include/c++/9]
add: [/usr/include/x86_64-linux-gnu/c++/9]
add: [/usr/include/c++/9/backward]
add: [/usr/lib/gcc/x86_64-linux-gnu/9/include]
add: [/usr/local/include]
add: [/usr/include/x86_64-linux-gnu]
add: [/usr/include]
end of search list found
collapse include dir [/usr/include/c++/9] ==> [/usr/include/c++/9]
collapse include dir [/usr/include/x86_64-linux-gnu/c++/9] ==> [/usr/include/x86_64-linux-gnu/c++/9]
collapse include dir [/usr/include/c++/9/backward] ==> [/usr/include/c++/9/backward]
collapse include dir [/usr/lib/gcc/x86_64-linux-gnu/9/include] ==> [/usr/lib/gcc/x86_64-linux-gnu/9/include]
collapse include dir [/usr/local/include] ==> [/usr/local/include]
collapse include dir [/usr/include/x86_64-linux-gnu] ==> [/usr/include/x86_64-linux-gnu]
collapse include dir [/usr/include] ==> [/usr/include]
implicit include dirs: [/usr/include/c++/9;/usr/include/x86_64-linux-gnu/c++/9;/usr/include/c++/9/backward;/usr/lib/gcc/x86_64-linux-gnu/9/include;/usr/local/include;/usr/include/x86_64-linux-gnu;/usr/include]
Parsed CXX implicit link information from above output:
link line regex: [^( *|.*[/\])(ld|CMAKE_LINK_STARTFILE-NOTFOUND|([^/\]+-)?ld|collect2)[^/\]*( |$)]
ignore line: [Change Dir: /home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp]
ignore line: []
ignore line: [Run Build Command(s):/usr/bin/make cmTC_b76ad/fast && /usr/bin/make -f CMakeFiles/cmTC_b76ad.dir/build.make CMakeFiles/cmTC_b76ad.dir/build]
ignore line: [make[1]: Entering directory '/home/cococode/flipperzero-firmware/lib/esp-serial-flasher/CMakeFiles/CMakeTmp']
ignore line: [Building CXX object CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o]
ignore line: [/usr/bin/c++ -v -o CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o -c /usr/share/cmake-3.16/Modules/CMakeCXXCompilerABI.cpp]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/c++]
ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:hsa]
ignore line: [OFFLOAD_TARGET_DEFAULT=1]
ignore line: [Target: x86_64-linux-gnu]
ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu]
ignore line: [Thread model: posix]
ignore line: [gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) ]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64']
ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/9/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE /usr/share/cmake-3.16/Modules/CMakeCXXCompilerABI.cpp -quiet -dumpbase CMakeCXXCompilerABI.cpp -mtune=generic -march=x86-64 -auxbase-strip CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o -version -fasynchronous-unwind-tables -fstack-protector-strong -Wformat -Wformat-security -fstack-clash-protection -fcf-protection -o /tmp/ccTEwRoV.s]
ignore line: [GNU C++14 (Ubuntu 9.4.0-1ubuntu1~20.04.1) version 9.4.0 (x86_64-linux-gnu)]
ignore line: [ compiled by GNU C version 9.4.0 GMP version 6.2.0 MPFR version 4.0.2 MPC version 1.1.0 isl version isl-0.22.1-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/9"]
ignore line: [ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/include-fixed"]
ignore line: [ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/9/../../../../x86_64-linux-gnu/include"]
ignore line: [#include "..." search starts here:]
ignore line: [#include <...> search starts here:]
ignore line: [ /usr/include/c++/9]
ignore line: [ /usr/include/x86_64-linux-gnu/c++/9]
ignore line: [ /usr/include/c++/9/backward]
ignore line: [ /usr/lib/gcc/x86_64-linux-gnu/9/include]
ignore line: [ /usr/local/include]
ignore line: [ /usr/include/x86_64-linux-gnu]
ignore line: [ /usr/include]
ignore line: [End of search list.]
ignore line: [GNU C++14 (Ubuntu 9.4.0-1ubuntu1~20.04.1) version 9.4.0 (x86_64-linux-gnu)]
ignore line: [ compiled by GNU C version 9.4.0 GMP version 6.2.0 MPFR version 4.0.2 MPC version 1.1.0 isl version isl-0.22.1-GMP]
ignore line: []
ignore line: [GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072]
ignore line: [Compiler executable checksum: 65fe925b83d3956b533de4aaba7dace0]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64']
ignore line: [ as -v --64 -o CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o /tmp/ccTEwRoV.s]
ignore line: [GNU assembler version 2.34 (x86_64-linux-gnu) using BFD version (GNU Binutils for Ubuntu) 2.34]
ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-o' 'CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o' '-c' '-shared-libgcc' '-mtune=generic' '-march=x86-64']
ignore line: [Linking CXX executable cmTC_b76ad]
ignore line: [/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_b76ad.dir/link.txt --verbose=1]
ignore line: [/usr/bin/c++ -v -rdynamic CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o -o cmTC_b76ad ]
ignore line: [Using built-in specs.]
ignore line: [COLLECT_GCC=/usr/bin/c++]
ignore line: [COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper]
ignore line: [OFFLOAD_TARGET_NAMES=nvptx-none:hsa]
ignore line: [OFFLOAD_TARGET_DEFAULT=1]
ignore line: [Target: x86_64-linux-gnu]
ignore line: [Configured with: ../src/configure -v --with-pkgversion='Ubuntu 9.4.0-1ubuntu1~20.04.1' --with-bugurl=file:///usr/share/doc/gcc-9/README.Bugs --enable-languages=c ada c++ go brig d fortran objc obj-c++ gm2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-9 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32 m64 mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-9-Av3uEd/gcc-9-9.4.0/debian/tmp-nvptx/usr hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu]
ignore line: [Thread model: posix]
ignore line: [gcc version 9.4.0 (Ubuntu 9.4.0-1ubuntu1~20.04.1) ]
ignore line: [COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/]
ignore line: [LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/9/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/9/../../../:/lib/:/usr/lib/]
ignore line: [COLLECT_GCC_OPTIONS='-v' '-rdynamic' '-o' 'cmTC_b76ad' '-shared-libgcc' '-mtune=generic' '-march=x86-64']
link line: [ /usr/lib/gcc/x86_64-linux-gnu/9/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccnXxdBn.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu --as-needed -export-dynamic -dynamic-linker /lib64/ld-linux-x86-64.so.2 -pie -z now -z relro -o cmTC_b76ad /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o -L/usr/lib/gcc/x86_64-linux-gnu/9 -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/9/../../.. CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o]
arg [/usr/lib/gcc/x86_64-linux-gnu/9/collect2] ==> ignore
arg [-plugin] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/liblto_plugin.so] ==> ignore
arg [-plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/9/lto-wrapper] ==> ignore
arg [-plugin-opt=-fresolution=/tmp/ccnXxdBn.res] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [-plugin-opt=-pass-through=-lc] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc_s] ==> ignore
arg [-plugin-opt=-pass-through=-lgcc] ==> ignore
arg [--build-id] ==> ignore
arg [--eh-frame-hdr] ==> ignore
arg [-m] ==> ignore
arg [elf_x86_64] ==> ignore
arg [--hash-style=gnu] ==> ignore
arg [--as-needed] ==> ignore
arg [-export-dynamic] ==> ignore
arg [-dynamic-linker] ==> ignore
arg [/lib64/ld-linux-x86-64.so.2] ==> ignore
arg [-pie] ==> ignore
arg [-znow] ==> ignore
arg [-zrelro] ==> ignore
arg [-o] ==> ignore
arg [cmTC_b76ad] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crti.o] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/crtbeginS.o] ==> ignore
arg [-L/usr/lib/gcc/x86_64-linux-gnu/9] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/9]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib]
arg [-L/lib/x86_64-linux-gnu] ==> dir [/lib/x86_64-linux-gnu]
arg [-L/lib/../lib] ==> dir [/lib/../lib]
arg [-L/usr/lib/x86_64-linux-gnu] ==> dir [/usr/lib/x86_64-linux-gnu]
arg [-L/usr/lib/../lib] ==> dir [/usr/lib/../lib]
arg [-L/usr/lib/gcc/x86_64-linux-gnu/9/../../..] ==> dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../..]
arg [CMakeFiles/cmTC_b76ad.dir/CMakeCXXCompilerABI.cpp.o] ==> ignore
arg [-lstdc++] ==> lib [stdc++]
arg [-lm] ==> lib [m]
arg [-lgcc_s] ==> lib [gcc_s]
arg [-lgcc] ==> lib [gcc]
arg [-lc] ==> lib [c]
arg [-lgcc_s] ==> lib [gcc_s]
arg [-lgcc] ==> lib [gcc]
arg [/usr/lib/gcc/x86_64-linux-gnu/9/crtendS.o] ==> ignore
arg [/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/crtn.o] ==> ignore
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/9] ==> [/usr/lib/gcc/x86_64-linux-gnu/9]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../../../lib] ==> [/usr/lib]
collapse library dir [/lib/x86_64-linux-gnu] ==> [/lib/x86_64-linux-gnu]
collapse library dir [/lib/../lib] ==> [/lib]
collapse library dir [/usr/lib/x86_64-linux-gnu] ==> [/usr/lib/x86_64-linux-gnu]
collapse library dir [/usr/lib/../lib] ==> [/usr/lib]
collapse library dir [/usr/lib/gcc/x86_64-linux-gnu/9/../../..] ==> [/usr/lib]
implicit libs: [stdc++;m;gcc_s;gcc;c;gcc_s;gcc]
implicit dirs: [/usr/lib/gcc/x86_64-linux-gnu/9;/usr/lib/x86_64-linux-gnu;/usr/lib;/lib/x86_64-linux-gnu;/lib]
implicit fwks: []

View File

@@ -0,0 +1 @@
# This file is generated by cmake for dependency checking of the CMakeCache.txt file

View File

@@ -0,0 +1,119 @@
cmake_minimum_required(VERSION 3.5)
set(srcs
src/esp_targets.c
src/md5_hash.c
src/esp_loader.c
src/protocol_common.c
)
if (DEFINED ESP_PLATFORM)
if (${CONFIG_SERIAL_FLASHER_INTERFACE_UART})
list(APPEND srcs
src/protocol_uart.c
src/slip.c
port/esp32_port.c
)
elseif (${CONFIG_SERIAL_FLASHER_INTERFACE_SPI})
list(APPEND srcs
src/protocol_spi.c
port/esp32_spi_port.c
)
endif()
# Register component to esp-idf build system
if ("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER "4.0")
# esp_timer component was introduced in v4.2
set(priv_requires driver)
if("${IDF_VERSION_MAJOR}.${IDF_VERSION_MINOR}" VERSION_GREATER "4.1")
list(APPEND priv_requires esp_timer)
endif()
idf_component_register(SRCS ${srcs}
INCLUDE_DIRS include port
PRIV_INCLUDE_DIRS private_include
PRIV_REQUIRES ${priv_requires})
set(target ${COMPONENT_LIB})
component_compile_options(-Wstrict-prototypes)
else()
# Remove when dropping support for IDF 3.3
set(COMPONENT_SRCS ${srcs})
set(COMPONENT_ADD_INCLUDEDIRS include port)
set(COMPONENT_PRIV_INCLUDEDIRS private_include)
register_component()
set(target ${COMPONENT_TARGET})
endif()
else()
if (NOT DEFINED SERIAL_FLASHER_INTERFACE_UART AND NOT DEFINED SERIAL_FLASHER_INTERFACE_SPI)
set(SERIAL_FLASHER_INTERFACE_UART true)
endif()
if (DEFINED SERIAL_FLASHER_INTERFACE_UART)
list(APPEND srcs
src/protocol_uart.c
src/slip.c
)
elseif (DEFINED SERIAL_FLASHER_INTERFACE_SPI)
list(APPEND srcs src/protocol_spi.c)
endif()
# Create traditional CMake target
add_library(flasher ${srcs})
target_include_directories(flasher PUBLIC include port PRIVATE private_include)
if(PORT STREQUAL "STM32")
target_link_libraries(flasher PUBLIC stm_cube)
target_sources(flasher PRIVATE port/stm32_port.c)
elseif(PORT STREQUAL "RASPBERRY_PI")
find_library(pigpio_LIB pigpio)
target_link_libraries(flasher PUBLIC ${pigpio_LIB})
target_sources(flasher PRIVATE port/raspberry_port.c)
else()
message(FATAL_ERROR "Selected port is not supported")
endif()
set(target flasher)
endif()
if (DEFINED SERIAL_FLASHER_INTERFACE_UART OR CONFIG_SERIAL_FLASHER_INTERFACE_UART STREQUAL "y")
target_compile_definitions(${target}
PUBLIC
SERIAL_FLASHER_INTERFACE_UART
)
if (DEFINED MD5_ENABLED OR CONFIG_SERIAL_FLASHER_MD5_ENABLED)
target_compile_definitions(${target} PUBLIC MD5_ENABLED=1)
endif()
elseif (DEFINED SERIAL_FLASHER_INTERFACE_SPI OR CONFIG_SERIAL_FLASHER_INTERFACE_SPI STREQUAL "y")
target_compile_definitions(${target}
PUBLIC
SERIAL_FLASHER_INTERFACE_SPI
)
endif()
if(DEFINED SERIAL_FLASHER_DEBUG_TRACE OR CONFIG_SERIAL_FLASHER_DEBUG_TRACE)
target_compile_definitions(${target} PUBLIC SERIAL_FLASHER_DEBUG_TRACE)
endif()
if(DEFINED CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS AND DEFINED CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS)
target_compile_definitions(${target}
PUBLIC
SERIAL_FLASHER_RESET_HOLD_TIME_MS=${CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS}
SERIAL_FLASHER_BOOT_HOLD_TIME_MS=${CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS}
)
else()
if(NOT DEFINED SERIAL_FLASHER_RESET_HOLD_TIME_MS)
target_compile_definitions(${target}
PUBLIC
SERIAL_FLASHER_RESET_HOLD_TIME_MS=100
)
endif()
if(NOT DEFINED SERIAL_FLASHER_BOOT_HOLD_TIME_MS)
target_compile_definitions(${target}
PUBLIC
SERIAL_FLASHER_BOOT_HOLD_TIME_MS=50
)
endif()
endif()

View File

@@ -0,0 +1,34 @@
menu "ESP serial flasher"
config SERIAL_FLASHER_MD5_ENABLED
bool "Enable MD5 check"
default y
help
Select this option to enable MD5 hashsum check after flashing.
choice SERIAL_FLASHER_INTERFACE
prompt "Hardware interface to use for firmware download"
default SERIAL_FLASHER_INTERFACE_UART
help
esp-serial-flasher can work with UART and SPI interfaces.
config SERIAL_FLASHER_INTERFACE_UART
bool "UART"
config SERIAL_FLASHER_INTERFACE_SPI
bool "SPI (Only supports downloading to RAM, experimental)"
endchoice
config SERIAL_FLASHER_RESET_HOLD_TIME_MS
int "Time for which the reset pin is asserted when doing a hard reset"
default 100
config SERIAL_FLASHER_BOOT_HOLD_TIME_MS
int "Time for which the boot pin is asserted when doing a hard reset"
default 50
config SERIAL_FLASHER_DEBUG_TRACE
bool "Enable debug tracing output (only transfer data tracing is supported at the time)"
default n
endmenu

View File

@@ -0,0 +1,3 @@
version: "0.2.0"
description: Serial flasher component provides portable library for flashing or loading ram loadble app to Espressif SoCs from other host microcontroller
url: https://github.com/espressif/esp-serial-flasher

View File

@@ -0,0 +1,313 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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 <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/* Used for backwards compatibility with the previous API */
#define esp_loader_change_baudrate esp_loader_change_transmission_rate
/**
* Macro which can be used to check the error code,
* and return in case the code is not ESP_LOADER_SUCCESS.
*/
#define RETURN_ON_ERROR(x) do { \
esp_loader_error_t _err_ = (x); \
if (_err_ != ESP_LOADER_SUCCESS) { \
return _err_; \
} \
} while(0)
/**
* @brief Error codes
*/
typedef enum {
ESP_LOADER_SUCCESS, /*!< Success */
ESP_LOADER_ERROR_FAIL, /*!< Unspecified error */
ESP_LOADER_ERROR_TIMEOUT, /*!< Timeout elapsed */
ESP_LOADER_ERROR_IMAGE_SIZE, /*!< Image size to flash is larger than flash size */
ESP_LOADER_ERROR_INVALID_MD5, /*!< Computed and received MD5 does not match */
ESP_LOADER_ERROR_INVALID_PARAM, /*!< Invalid parameter passed to function */
ESP_LOADER_ERROR_INVALID_TARGET, /*!< Connected target is invalid */
ESP_LOADER_ERROR_UNSUPPORTED_CHIP, /*!< Attached chip is not supported */
ESP_LOADER_ERROR_UNSUPPORTED_FUNC, /*!< Function is not supported on attached target */
ESP_LOADER_ERROR_INVALID_RESPONSE /*!< Internal error */
} esp_loader_error_t;
/**
* @brief Supported targets
*/
typedef enum {
ESP8266_CHIP = 0,
ESP32_CHIP = 1,
ESP32S2_CHIP = 2,
ESP32C3_CHIP = 3,
ESP32S3_CHIP = 4,
ESP32C2_CHIP = 5,
ESP32H4_CHIP = 6,
ESP32H2_CHIP = 7,
ESP_MAX_CHIP = 8,
ESP_UNKNOWN_CHIP = 8
} target_chip_t;
/**
* @brief Application binary header
*/
typedef struct {
uint8_t magic;
uint8_t segments;
uint8_t flash_mode;
uint8_t flash_size_freq;
uint32_t entrypoint;
} esp_loader_bin_header_t;
/**
* @brief Segment binary header
*/
typedef struct {
uint32_t addr;
uint32_t size;
uint8_t *data;
} esp_loader_bin_segment_t;
/**
* @brief SPI pin configuration arguments
*/
typedef union {
struct {
uint32_t pin_clk: 6;
uint32_t pin_q: 6;
uint32_t pin_d: 6;
uint32_t pin_cs: 6;
uint32_t pin_hd: 6;
uint32_t zero: 2;
};
uint32_t val;
} esp_loader_spi_config_t;
/**
* @brief Connection arguments
*/
typedef struct {
uint32_t sync_timeout; /*!< Maximum time to wait for response from serial interface. */
int32_t trials; /*!< Number of trials to connect to target. If greater than 1,
100 millisecond delay is inserted after each try. */
} esp_loader_connect_args_t;
#define ESP_LOADER_CONNECT_DEFAULT() { \
.sync_timeout = 100, \
.trials = 10, \
}
/**
* @brief Connects to the target
*
* @param connect_args[in] Timing parameters to be used for connecting to target.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
*/
esp_loader_error_t esp_loader_connect(esp_loader_connect_args_t *connect_args);
/**
* @brief Returns attached target chip.
*
* @warning This function can only be called after connection with target
* has been successfully established by calling esp_loader_connect().
*
* @return One of target_chip_t
*/
target_chip_t esp_loader_get_target(void);
#ifdef SERIAL_FLASHER_INTERFACE_UART
/**
* @brief Initiates flash operation
*
* @param offset[in] Address from which flash operation will be performed.
* @param image_size[in] Size of the whole binary to be loaded into flash.
* @param block_size[in] Size of buffer used in subsequent calls to esp_loader_flash_write.
*
* @note image_size is size of the whole image, whereas, block_size is chunk of data sent
* to the target, each time esp_loader_flash_write function is called.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
*/
esp_loader_error_t esp_loader_flash_start(uint32_t offset, uint32_t image_size, uint32_t block_size);
/**
* @brief Writes supplied data to target's flash memory.
*
* @param payload[in] Data to be flashed into target's memory.
* @param size[in] Size of payload in bytes.
*
* @note size must not be greater that block_size supplied to previously called
* esp_loader_flash_start function. If size is less than block_size,
* remaining bytes of payload buffer will be padded with 0xff.
* Therefore, size of payload buffer has to be equal or greater than block_size.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
*/
esp_loader_error_t esp_loader_flash_write(void *payload, uint32_t size);
/**
* @brief Ends flash operation.
*
* @param reboot[in] reboot the target if true.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
*/
esp_loader_error_t esp_loader_flash_finish(bool reboot);
#endif /* SERIAL_FLASHER_INTERFACE_UART */
/**
* @brief Initiates mem operation, initiates loading for program into target RAM
*
* @param offset[in] Address from which mem operation will be performed.
* @param size[in] Size of the whole binary to be loaded into mem.
* @param block_size[in] Size of buffer used in subsequent calls to esp_loader_mem_write.
*
* @note image_size is size of the whole image, whereas, block_size is chunk of data sent
* to the target, each time esp_mem_flash_write function is called.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
*/
esp_loader_error_t esp_loader_mem_start(uint32_t offset, uint32_t size, uint32_t block_size);
/**
* @brief Writes supplied data to target's mem memory.
*
* @param payload[in] Data to be loaded into target's memory.
* @param size[in] Size of data in bytes.
*
* @note size must not be greater that block_size supplied to previously called
* esp_loader_mem_start function.
* Therefore, size of data buffer has to be equal or greater than block_size.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
*/
esp_loader_error_t esp_loader_mem_write(const void *payload, uint32_t size);
/**
* @brief Ends mem operation, finish loading for program into target RAM
* and send the entrypoint of ram_loadable app
*
* @param entrypoint[in] entrypoint of ram program.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
*/
esp_loader_error_t esp_loader_mem_finish(uint32_t entrypoint);
/**
* @brief Writes register.
*
* @param address[in] Address of register.
* @param reg_value[in] New register value.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
*/
esp_loader_error_t esp_loader_write_register(uint32_t address, uint32_t reg_value);
/**
* @brief Reads register.
*
* @param address[in] Address of register.
* @param reg_value[out] Register value.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
*/
esp_loader_error_t esp_loader_read_register(uint32_t address, uint32_t *reg_value);
/**
* @brief Change baud rate.
*
* @note Baud rate has to be also adjusted accordingly on host MCU, as
* target's baud rate is changed upon return from this function.
*
* @param transmission_rate[in] new baud rate to be set.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
* - ESP_LOADER_ERROR_UNSUPPORTED_FUNC Unsupported on the target
*/
esp_loader_error_t esp_loader_change_transmission_rate(uint32_t transmission_rate);
/**
* @brief Verify target's flash integrity by checking MD5.
* MD5 checksum is computed from data pushed to target's memory by calling
* esp_loader_flash_write() function and compared against target's MD5.
* Target computes checksum based on offset and image_size passed to
* esp_loader_flash_start() function.
*
* @note This function is only available if MD5_ENABLED is set.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_INVALID_MD5 MD5 does not match
* - ESP_LOADER_ERROR_TIMEOUT Timeout
* - ESP_LOADER_ERROR_INVALID_RESPONSE Internal error
* - ESP_LOADER_ERROR_UNSUPPORTED_FUNC Unsupported on the target
*/
#if MD5_ENABLED
esp_loader_error_t esp_loader_flash_verify(void);
#endif
/**
* @brief Toggles reset pin.
*/
void esp_loader_reset_target(void);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,112 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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 <stdint.h>
#include "esp_loader.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Changes the transmission rate of the used peripheral.
*/
esp_loader_error_t loader_port_change_transmission_rate(uint32_t transmission_rate);
/**
* @brief Writes data over the io interface.
*
* @param data[in] Buffer with data to be written.
* @param size[in] Size of data in bytes.
* @param timeout[in] Timeout in milliseconds.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout elapsed
*/
esp_loader_error_t loader_port_write(const uint8_t *data, uint16_t size, uint32_t timeout);
/**
* @brief Reads data from the io interface.
*
* @param data[out] Buffer into which received data will be written.
* @param size[in] Number of bytes to read.
* @param timeout[in] Timeout in milliseconds.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_TIMEOUT Timeout elapsed
*/
esp_loader_error_t loader_port_read(uint8_t *data, uint16_t size, uint32_t timeout);
/**
* @brief Delay in milliseconds.
*
* @param ms[in] Number of milliseconds.
*
*/
void loader_port_delay_ms(uint32_t ms);
/**
* @brief Starts timeout timer.
*
* @param ms[in] Number of milliseconds.
*
*/
void loader_port_start_timer(uint32_t ms);
/**
* @brief Returns remaining time since timer was started by calling esp_loader_start_timer.
* 0 if timer has elapsed.
*
* @return Number of milliseconds.
*
*/
uint32_t loader_port_remaining_time(void);
/**
* @brief Asserts bootstrap pins to enter boot mode and toggles reset pin.
*
* @note Reset pin should stay asserted for at least 20 milliseconds.
*/
void loader_port_enter_bootloader(void);
/**
* @brief Toggles reset pin.
*
* @note Reset pin should stay asserted for at least 20 milliseconds.
*/
void loader_port_reset_target(void);
/**
* @brief Function can be defined by user to print debug message.
*
* @note Empty weak function is used, otherwise.
*
*/
void loader_port_debug_print(const char *str);
#ifdef SERIAL_FLASHER_INTERFACE_SPI
/**
* @brief Sets the chip select to a defined level
*/
void loader_port_spi_set_cs(uint32_t level);
#endif /* SERIAL_FLASHER_INTERFACE_SPI */
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,24 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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.
*/
#warning Please replace serial_io.h with esp_loader_io.h and change the function names \
to match the new API
/* Defines used to avoid breaking existing ports */
#define loader_port_change_baudrate loader_port_change_transmission_rate
#define loader_port_serial_write loader_port_write
#define loader_port_serial_read loader_port_read
#include "esp_loader_io.h"

View File

@@ -0,0 +1,181 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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.
*/
#include "esp32_port.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#include "esp_log.h"
#include "esp_idf_version.h"
#include <unistd.h>
#ifdef SERIAL_FLASHER_DEBUG_TRACE
static void transfer_debug_print(const uint8_t *data, uint16_t size, bool write)
{
static bool write_prev = false;
if (write_prev != write) {
write_prev = write;
printf("\n--- %s ---\n", write ? "WRITE" : "READ");
}
for (uint32_t i = 0; i < size; i++) {
printf("%02x ", data[i]);
}
}
#endif
static int64_t s_time_end;
static int32_t s_uart_port;
static int32_t s_reset_trigger_pin;
static int32_t s_gpio0_trigger_pin;
esp_loader_error_t loader_port_esp32_init(const loader_esp32_config_t *config)
{
s_uart_port = config->uart_port;
s_reset_trigger_pin = config->reset_trigger_pin;
s_gpio0_trigger_pin = config->gpio0_trigger_pin;
// Initialize UART
uart_config_t uart_config = {
.baud_rate = config->baud_rate,
.data_bits = UART_DATA_8_BITS,
.parity = UART_PARITY_DISABLE,
.stop_bits = UART_STOP_BITS_1,
.flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
.source_clk = UART_SCLK_DEFAULT,
#endif
};
int rx_buffer_size = config->rx_buffer_size ? config->rx_buffer_size : 400;
int tx_buffer_size = config->tx_buffer_size ? config->tx_buffer_size : 400;
QueueHandle_t *uart_queue = config->uart_queue ? config->uart_queue : NULL;
int queue_size = config->queue_size ? config->queue_size : 0;
if ( uart_param_config(s_uart_port, &uart_config) != ESP_OK ) {
return ESP_LOADER_ERROR_FAIL;
}
if ( uart_set_pin(s_uart_port, config->uart_tx_pin, config->uart_rx_pin, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE) != ESP_OK ) {
return ESP_LOADER_ERROR_FAIL;
}
if ( uart_driver_install(s_uart_port, rx_buffer_size, tx_buffer_size, queue_size, uart_queue, 0) != ESP_OK ) {
return ESP_LOADER_ERROR_FAIL;
}
// Initialize boot pin selection pins
gpio_reset_pin(s_reset_trigger_pin);
gpio_set_pull_mode(s_reset_trigger_pin, GPIO_PULLUP_ONLY);
gpio_set_direction(s_reset_trigger_pin, GPIO_MODE_OUTPUT);
gpio_reset_pin(s_gpio0_trigger_pin);
gpio_set_pull_mode(s_gpio0_trigger_pin, GPIO_PULLUP_ONLY);
gpio_set_direction(s_gpio0_trigger_pin, GPIO_MODE_OUTPUT);
return ESP_LOADER_SUCCESS;
}
void loader_port_esp32_deinit(void)
{
uart_driver_delete(s_uart_port);
}
esp_loader_error_t loader_port_write(const uint8_t *data, uint16_t size, uint32_t timeout)
{
uart_write_bytes(s_uart_port, (const char *)data, size);
esp_err_t err = uart_wait_tx_done(s_uart_port, pdMS_TO_TICKS(timeout));
if (err == ESP_OK) {
#ifdef SERIAL_FLASHER_DEBUG_TRACE
transfer_debug_print(data, size, true);
#endif
return ESP_LOADER_SUCCESS;
} else if (err == ESP_ERR_TIMEOUT) {
return ESP_LOADER_ERROR_TIMEOUT;
} else {
return ESP_LOADER_ERROR_FAIL;
}
}
esp_loader_error_t loader_port_read(uint8_t *data, uint16_t size, uint32_t timeout)
{
int read = uart_read_bytes(s_uart_port, data, size, pdMS_TO_TICKS(timeout));
if (read < 0) {
return ESP_LOADER_ERROR_FAIL;
} else if (read < size) {
#ifdef SERIAL_FLASHER_DEBUG_TRACE
transfer_debug_print(data, read, false);
#endif
return ESP_LOADER_ERROR_TIMEOUT;
} else {
#ifdef SERIAL_FLASHER_DEBUG_TRACE
transfer_debug_print(data, read, false);
#endif
return ESP_LOADER_SUCCESS;
}
}
// Set GPIO0 LOW, then
// assert reset pin for 50 milliseconds.
void loader_port_enter_bootloader(void)
{
gpio_set_level(s_gpio0_trigger_pin, 0);
loader_port_reset_target();
loader_port_delay_ms(SERIAL_FLASHER_BOOT_HOLD_TIME_MS);
gpio_set_level(s_gpio0_trigger_pin, 1);
}
void loader_port_reset_target(void)
{
gpio_set_level(s_reset_trigger_pin, 0);
loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
gpio_set_level(s_reset_trigger_pin, 1);
}
void loader_port_delay_ms(uint32_t ms)
{
usleep(ms * 1000);
}
void loader_port_start_timer(uint32_t ms)
{
s_time_end = esp_timer_get_time() + ms * 1000;
}
uint32_t loader_port_remaining_time(void)
{
int64_t remaining = (s_time_end - esp_timer_get_time()) / 1000;
return (remaining > 0) ? (uint32_t)remaining : 0;
}
void loader_port_debug_print(const char *str)
{
printf("DEBUG: %s\n", str);
}
esp_loader_error_t loader_port_change_transmission_rate(uint32_t baudrate)
{
esp_err_t err = uart_set_baudrate(s_uart_port, baudrate);
return (err == ESP_OK) ? ESP_LOADER_SUCCESS : ESP_LOADER_ERROR_FAIL;
}

View File

@@ -0,0 +1,59 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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 "esp_loader_io.h"
#include "freertos/FreeRTOS.h"
#include "freertos/queue.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
uint32_t baud_rate; /*!< Initial baud rate, can be changed later */
uint32_t uart_port; /*!< UART port */
uint32_t uart_rx_pin; /*!< This pin will be configured as UART Rx pin */
uint32_t uart_tx_pin; /*!< This pin will be configured as UART Tx pin */
uint32_t reset_trigger_pin; /*!< This pin will be used to reset target chip */
uint32_t gpio0_trigger_pin; /*!< This pin will be used to toggle set IO0 of target chip */
uint32_t rx_buffer_size; /*!< Set to zero for default RX buffer size */
uint32_t tx_buffer_size; /*!< Set to zero for default TX buffer size */
uint32_t queue_size; /*!< Set to zero for default UART queue size */
QueueHandle_t *uart_queue; /*!< Set to NULL, if UART queue handle is not
necessary. Otherwise, it will be assigned here */
} loader_esp32_config_t;
/**
* @brief Initializes serial interface.
*
* @param baud_rate[in] Communication speed.
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_FAIL Initialization failure
*/
esp_loader_error_t loader_port_esp32_init(const loader_esp32_config_t *config);
/**
* @brief Deinitialize serial interface.
*/
void loader_port_esp32_deinit(void);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,298 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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.
*/
#include "esp32_spi_port.h"
#include "esp_log.h"
#include "driver/gpio.h"
#include "esp_timer.h"
#include "esp_log.h"
#include "esp_idf_version.h"
#include <unistd.h>
// #define SERIAL_DEBUG_ENABLE
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 3, 0)
#define DMA_CHAN SPI_DMA_CH_AUTO
#else
#define DMA_CHAN 1
#endif
#define WORD_ALIGNED(ptr) ((size_t)ptr % sizeof(size_t) == 0)
#ifdef SERIAL_DEBUG_ENABLE
static void dec_to_hex_str(const uint8_t dec, uint8_t hex_str[3])
{
static const uint8_t dec_to_hex[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
hex_str[0] = dec_to_hex[dec >> 4];
hex_str[1] = dec_to_hex[dec & 0xF];
hex_str[2] = '\0';
}
static void serial_debug_print(const uint8_t *data, uint16_t size, bool write)
{
static bool write_prev = false;
uint8_t hex_str[3];
if(write_prev != write) {
write_prev = write;
printf("\n--- %s ---\n", write ? "WRITE" : "READ");
}
for(uint32_t i = 0; i < size; i++) {
dec_to_hex_str(data[i], hex_str);
printf("%s ", hex_str);
}
}
#else
static void serial_debug_print(const uint8_t *data, uint16_t size, bool write) { }
#endif
static spi_host_device_t s_spi_bus;
static spi_bus_config_t s_spi_config;
static spi_device_handle_t s_device_h;
static spi_device_interface_config_t s_device_config;
static int64_t s_time_end;
static uint32_t s_reset_trigger_pin;
static uint32_t s_strap_bit0_pin;
static uint32_t s_strap_bit1_pin;
static uint32_t s_strap_bit2_pin;
static uint32_t s_strap_bit3_pin;
static uint32_t s_spi_cs_pin;
esp_loader_error_t loader_port_esp32_spi_init(const loader_esp32_spi_config_t *config)
{
/* Initialize the global static variables*/
s_spi_bus = config->spi_bus;
s_reset_trigger_pin = config->reset_trigger_pin;
s_strap_bit0_pin = config->strap_bit0_pin;
s_strap_bit1_pin = config->strap_bit1_pin;
s_strap_bit2_pin = config->strap_bit2_pin;
s_strap_bit3_pin = config->strap_bit3_pin;
s_spi_cs_pin = config->spi_cs_pin;
/* Configure and initialize the SPI bus*/
s_spi_config.mosi_io_num = config->spi_mosi_pin;
s_spi_config.miso_io_num = config->spi_miso_pin;
s_spi_config.sclk_io_num = config->spi_clk_pin;
s_spi_config.quadwp_io_num = config->spi_quadwp_pin;
s_spi_config.quadhd_io_num = config->spi_quadhd_pin;
s_spi_config.max_transfer_sz = 4096 * 4;
if (spi_bus_initialize(s_spi_bus, &s_spi_config, DMA_CHAN) != ESP_OK) {
return ESP_LOADER_ERROR_FAIL;
}
/* Configure and add the device */
s_device_config.clock_speed_hz = config->frequency;
s_device_config.spics_io_num = -1; /* We're using the chip select pin as GPIO as we need to
chain multiple transactions with CS pulled down */
s_device_config.flags = SPI_DEVICE_HALFDUPLEX;
s_device_config.queue_size = 16;
if (spi_bus_add_device(s_spi_bus, &s_device_config, &s_device_h) != ESP_OK) {
return ESP_LOADER_ERROR_FAIL;
}
/* Initialize the pins except for the strapping ones */
gpio_reset_pin(s_reset_trigger_pin);
gpio_set_pull_mode(s_reset_trigger_pin, GPIO_PULLUP_ONLY);
gpio_set_direction(s_reset_trigger_pin, GPIO_MODE_OUTPUT);
gpio_set_level(s_reset_trigger_pin, 1);
gpio_reset_pin(s_spi_cs_pin);
gpio_set_pull_mode(s_spi_cs_pin, GPIO_PULLUP_ONLY);
gpio_set_direction(s_spi_cs_pin, GPIO_MODE_OUTPUT);
gpio_set_level(s_spi_cs_pin, 1);
return ESP_LOADER_SUCCESS;
}
void loader_port_esp32_spi_deinit(void)
{
gpio_reset_pin(s_reset_trigger_pin);
gpio_reset_pin(s_spi_cs_pin);
spi_bus_remove_device(s_device_h);
spi_bus_free(s_spi_bus);
}
void loader_port_spi_set_cs(const uint32_t level) {
gpio_set_level(s_spi_cs_pin, level);
}
esp_loader_error_t loader_port_write(const uint8_t *data, const uint16_t size, const uint32_t timeout)
{
/* Due to the fact that the SPI driver uses DMA for larger transfers,
and the DMA requirements, the buffer must be word aligned */
if (data == NULL || !WORD_ALIGNED(data)) {
return ESP_LOADER_ERROR_INVALID_PARAM;
}
serial_debug_print(data, size, true);
spi_transaction_t transaction = {
.tx_buffer = data,
.rx_buffer = NULL,
.length = size * 8U,
.rxlength = 0,
};
esp_err_t err = spi_device_transmit(s_device_h, &transaction);
if (err == ESP_OK) {
serial_debug_print(data, size, false);
return ESP_LOADER_SUCCESS;
} else if (err == ESP_ERR_TIMEOUT) {
return ESP_LOADER_ERROR_TIMEOUT;
} else {
return ESP_LOADER_ERROR_FAIL;
}
}
esp_loader_error_t loader_port_read(uint8_t *data, const uint16_t size, const uint32_t timeout)
{
/* Due to the fact that the SPI driver uses DMA for larger transfers,
and the DMA requirements, the buffer must be word aligned */
if (data == NULL || !WORD_ALIGNED(data)) {
return ESP_LOADER_ERROR_INVALID_PARAM;
}
serial_debug_print(data, size, true);
spi_transaction_t transaction = {
.tx_buffer = NULL,
.rx_buffer = data,
.rxlength = size * 8,
};
esp_err_t err = spi_device_transmit(s_device_h, &transaction);
if (err == ESP_OK) {
serial_debug_print(data, size, false);
return ESP_LOADER_SUCCESS;
} else if (err == ESP_ERR_TIMEOUT) {
return ESP_LOADER_ERROR_TIMEOUT;
} else {
return ESP_LOADER_ERROR_FAIL;
}
}
void loader_port_enter_bootloader(void)
{
/*
We have to initialize the GPIO pins for the target strapping pins here,
as they may overlap with target SPI pins.
For instance in the case of ESP32C3 MISO and strapping bit 0 pins overlap.
*/
spi_bus_remove_device(s_device_h);
spi_bus_free(s_spi_bus);
gpio_reset_pin(s_strap_bit0_pin);
gpio_set_pull_mode(s_strap_bit0_pin, GPIO_PULLUP_ONLY);
gpio_set_direction(s_strap_bit0_pin, GPIO_MODE_OUTPUT);
gpio_reset_pin(s_strap_bit1_pin);
gpio_set_pull_mode(s_strap_bit1_pin, GPIO_PULLUP_ONLY);
gpio_set_direction(s_strap_bit1_pin, GPIO_MODE_OUTPUT);
gpio_reset_pin(s_strap_bit2_pin);
gpio_set_pull_mode(s_strap_bit2_pin, GPIO_PULLUP_ONLY);
gpio_set_direction(s_strap_bit2_pin, GPIO_MODE_OUTPUT);
gpio_reset_pin(s_strap_bit3_pin);
gpio_set_pull_mode(s_strap_bit3_pin, GPIO_PULLUP_ONLY);
gpio_set_direction(s_strap_bit3_pin, GPIO_MODE_OUTPUT);
/* Set the strapping pins and perform the reset sequence */
gpio_set_level(s_strap_bit0_pin, 1);
gpio_set_level(s_strap_bit1_pin, 0);
gpio_set_level(s_strap_bit2_pin, 0);
gpio_set_level(s_strap_bit3_pin, 0);
loader_port_reset_target();
loader_port_delay_ms(SERIAL_FLASHER_BOOT_HOLD_TIME_MS);
gpio_set_level(s_strap_bit3_pin, 1);
gpio_set_level(s_strap_bit0_pin, 0);
/* Disable the strapping pins so they can be used by the slave later */
gpio_reset_pin(s_strap_bit0_pin);
gpio_reset_pin(s_strap_bit1_pin);
gpio_reset_pin(s_strap_bit2_pin);
gpio_reset_pin(s_strap_bit3_pin);
/* Restore the SPI bus pins */
spi_bus_initialize(s_spi_bus, &s_spi_config, DMA_CHAN);
spi_bus_add_device(s_spi_bus, &s_device_config, &s_device_h);
}
void loader_port_reset_target(void)
{
gpio_set_level(s_reset_trigger_pin, 0);
loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
gpio_set_level(s_reset_trigger_pin, 1);
}
void loader_port_delay_ms(const uint32_t ms)
{
usleep(ms * 1000);
}
void loader_port_start_timer(const uint32_t ms)
{
s_time_end = esp_timer_get_time() + ms * 1000;
}
uint32_t loader_port_remaining_time(void)
{
int64_t remaining = (s_time_end - esp_timer_get_time()) / 1000;
return (remaining > 0) ? (uint32_t)remaining : 0;
}
void loader_port_debug_print(const char *str)
{
printf("DEBUG: %s\n", str);
}
esp_loader_error_t loader_port_change_transmission_rate(const uint32_t frequency)
{
if (spi_bus_remove_device(s_device_h) != ESP_OK) {
return ESP_LOADER_ERROR_FAIL;
}
uint32_t old_frequency = s_device_config.clock_speed_hz;
s_device_config.clock_speed_hz = frequency;
if (spi_bus_add_device(s_spi_bus, &s_device_config, &s_device_h) != ESP_OK) {
s_device_config.clock_speed_hz = old_frequency;
return ESP_LOADER_ERROR_FAIL;
}
return ESP_LOADER_SUCCESS;
}

View File

@@ -0,0 +1,60 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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 "esp_loader_io.h"
#include "driver/spi_master.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
spi_host_device_t spi_bus;
uint32_t frequency;
uint32_t spi_clk_pin;
uint32_t spi_miso_pin;
uint32_t spi_mosi_pin;
uint32_t spi_cs_pin;
uint32_t spi_quadwp_pin;
uint32_t spi_quadhd_pin;
uint32_t reset_trigger_pin;
uint32_t strap_bit0_pin;
uint32_t strap_bit1_pin;
uint32_t strap_bit2_pin;
uint32_t strap_bit3_pin;
} loader_esp32_spi_config_t;
/**
* @brief Initializes the SPI interface.
*
* @param config[in] Configuration structure
*
* @return
* - ESP_LOADER_SUCCESS Success
* - ESP_LOADER_ERROR_FAIL Initialization failure
*/
esp_loader_error_t loader_port_esp32_spi_init(const loader_esp32_spi_config_t *config);
/**
* @brief Deinitializes the SPI interface.
*/
void loader_port_esp32_spi_deinit(void);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,302 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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.
*/
#include "esp_loader_io.h"
#include "protocol.h"
#include <pigpio.h>
#include "raspberry_port.h"
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <termios.h>
#include <time.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#ifdef SERIAL_FLASHER_DEBUG_TRACE
static void transfer_debug_print(const uint8_t *data, uint16_t size, bool write)
{
static bool write_prev = false;
if (write_prev != write) {
write_prev = write;
printf("\n--- %s ---\n", write ? "WRITE" : "READ");
}
for (uint32_t i = 0; i < size; i++) {
printf("%02x ", data[i]);
}
}
#endif
static int serial;
static int64_t s_time_end;
static int32_t s_reset_trigger_pin;
static int32_t s_gpio0_trigger_pin;
static speed_t convert_baudrate(int baud)
{
switch (baud) {
case 50: return B50;
case 75: return B75;
case 110: return B110;
case 134: return B134;
case 150: return B150;
case 200: return B200;
case 300: return B300;
case 600: return B600;
case 1200: return B1200;
case 1800: return B1800;
case 2400: return B2400;
case 4800: return B4800;
case 9600: return B9600;
case 19200: return B19200;
case 38400: return B38400;
case 57600: return B57600;
case 115200: return B115200;
case 230400: return B230400;
case 460800: return B460800;
case 500000: return B500000;
case 576000: return B576000;
case 921600: return B921600;
case 1000000: return B1000000;
case 1152000: return B1152000;
case 1500000: return B1500000;
case 2000000: return B2000000;
case 2500000: return B2500000;
case 3000000: return B3000000;
case 3500000: return B3500000;
case 4000000: return B4000000;
default: return -1;
}
}
static int serialOpen (const char *device, uint32_t baudrate)
{
struct termios options;
int status, fd;
if ((fd = open (device, O_RDWR | O_NOCTTY | O_NDELAY | O_NONBLOCK)) == -1) {
printf("Error occured while opening serial port !\n");
return -1 ;
}
fcntl (fd, F_SETFL, O_RDWR) ;
// Get and modify current options:
tcgetattr (fd, &options);
speed_t baud = convert_baudrate(baudrate);
if(baud < 0) {
printf("Invalid baudrate!\n");
return -1;
}
cfmakeraw (&options) ;
cfsetispeed (&options, baud) ;
cfsetospeed (&options, baud) ;
options.c_cflag |= (CLOCAL | CREAD) ;
options.c_cflag &= ~(PARENB | CSTOPB | CSIZE) ;
options.c_cflag |= CS8 ;
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG) ;
options.c_oflag &= ~OPOST ;
options.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL); // Disable any special handling of received bytes
options.c_cc [VMIN] = 0 ;
options.c_cc [VTIME] = 10 ; // 1 Second
tcsetattr (fd, TCSANOW, &options) ;
ioctl (fd, TIOCMGET, &status);
status |= TIOCM_DTR ;
status |= TIOCM_RTS ;
ioctl (fd, TIOCMSET, &status);
usleep (10000) ; // 10mS
return fd ;
}
static esp_loader_error_t change_baudrate(int file_desc, int baudrate)
{
struct termios options;
speed_t baud = convert_baudrate(baudrate);
if(baud < 0) {
return ESP_LOADER_ERROR_INVALID_PARAM;
}
tcgetattr (file_desc, &options);
cfmakeraw (&options) ;
cfsetispeed (&options, baud);
cfsetospeed (&options, baud);
tcsetattr (file_desc, TCSANOW, &options);
return ESP_LOADER_SUCCESS;
}
static void set_timeout(uint32_t timeout)
{
struct termios options;
timeout /= 100;
timeout = MAX(timeout, 1);
tcgetattr(serial, &options);
options.c_cc[VTIME] = timeout;
tcsetattr(serial, TCSANOW, &options);
}
static esp_loader_error_t read_char(char *c, uint32_t timeout)
{
set_timeout(timeout);
int read_bytes = read(serial, c, 1);
if (read_bytes == 1) {
return ESP_LOADER_SUCCESS;
} else if (read_bytes == 0) {
return ESP_LOADER_ERROR_TIMEOUT;
} else {
return ESP_LOADER_ERROR_FAIL;
}
}
static esp_loader_error_t read_data(char *buffer, uint32_t size)
{
for (int i = 0; i < size; i++) {
uint32_t remaining_time = loader_port_remaining_time();
RETURN_ON_ERROR( read_char(&buffer[i], remaining_time) );
}
return ESP_LOADER_SUCCESS;
}
esp_loader_error_t loader_port_raspberry_init(const loader_raspberry_config_t *config)
{
s_reset_trigger_pin = config->reset_trigger_pin;
s_gpio0_trigger_pin = config->gpio0_trigger_pin;
serial = serialOpen(config->device, config->baudrate);
if (serial < 0) {
printf("Serial port could not be opened!\n");
return ESP_LOADER_ERROR_FAIL;
}
if (gpioInitialise() < 0) {
printf("pigpio initialisation failed\n");
return ESP_LOADER_ERROR_FAIL;
}
gpioSetMode(config->reset_trigger_pin, PI_OUTPUT);
gpioSetMode(config->gpio0_trigger_pin, PI_OUTPUT);
return ESP_LOADER_SUCCESS;
}
esp_loader_error_t loader_port_write(const uint8_t *data, uint16_t size, uint32_t timeout)
{
int written = write(serial, data, size);
if (written < 0) {
return ESP_LOADER_ERROR_FAIL;
} else if (written < size) {
#ifdef SERIAL_FLASHER_DEBUG_TRACE
transfer_debug_print(data, written, true);
#endif
return ESP_LOADER_ERROR_TIMEOUT;
} else {
#ifdef SERIAL_FLASHER_DEBUG_TRACE
transfer_debug_print(data, written, true);
#endif
return ESP_LOADER_SUCCESS;
}
}
esp_loader_error_t loader_port_read(uint8_t *data, uint16_t size, uint32_t timeout)
{
RETURN_ON_ERROR( read_data(data, size) );
#ifdef SERIAL_FLASHER_DEBUG_TRACE
transfer_debug_print(data, size, false);
#endif
return ESP_LOADER_SUCCESS;
}
// Set GPIO0 LOW, then assert reset pin for 50 milliseconds.
void loader_port_enter_bootloader(void)
{
gpioWrite(s_gpio0_trigger_pin, 0);
loader_port_reset_target();
loader_port_delay_ms(SERIAL_FLASHER_BOOT_HOLD_TIME_MS);
gpioWrite(s_gpio0_trigger_pin, 1);
}
void loader_port_reset_target(void)
{
gpioWrite(s_reset_trigger_pin, 0);
loader_port_delay_ms(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
gpioWrite(s_reset_trigger_pin, 1);
}
void loader_port_delay_ms(uint32_t ms)
{
usleep(ms * 1000);
}
void loader_port_start_timer(uint32_t ms)
{
s_time_end = clock() + (ms * (CLOCKS_PER_SEC / 1000));
}
uint32_t loader_port_remaining_time(void)
{
int64_t remaining = (s_time_end - clock()) / 1000;
return (remaining > 0) ? (uint32_t)remaining : 0;
}
void loader_port_debug_print(const char *str)
{
printf("DEBUG: %s\n", str);
}
esp_loader_error_t loader_port_change_transmission_rate(uint32_t baudrate)
{
return change_baudrate(serial, baudrate);
}

View File

@@ -0,0 +1,36 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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 <stdint.h>
#include "esp_loader_io.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
const char *device;
uint32_t baudrate;
uint32_t reset_trigger_pin;
uint32_t gpio0_trigger_pin;
} loader_raspberry_config_t;
esp_loader_error_t loader_port_raspberry_init(const loader_raspberry_config_t *config);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,140 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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.
*/
#include <string.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/param.h>
#include <stdio.h>
#include "stm32_port.h"
static UART_HandleTypeDef *uart;
static GPIO_TypeDef* gpio_port_io0, *gpio_port_rst;
static uint16_t gpio_num_io0, gpio_num_rst;
#ifdef SERIAL_FLASHER_DEBUG_TRACE
static void transfer_debug_print(const uint8_t *data, uint16_t size, bool write)
{
static bool write_prev = false;
if (write_prev != write) {
write_prev = write;
printf("\n--- %s ---\n", write ? "WRITE" : "READ");
}
for (uint32_t i = 0; i < size; i++) {
printf("%02x ", data[i]);
}
}
#endif
static uint32_t s_time_end;
esp_loader_error_t loader_port_write(const uint8_t *data, uint16_t size, uint32_t timeout)
{
HAL_StatusTypeDef err = HAL_UART_Transmit(uart, (uint8_t *)data, size, timeout);
if (err == HAL_OK) {
#ifdef SERIAL_FLASHER_DEBUG_TRACE
transfer_debug_print(data, size, true);
#endif
return ESP_LOADER_SUCCESS;
} else if (err == HAL_TIMEOUT) {
return ESP_LOADER_ERROR_TIMEOUT;
} else {
return ESP_LOADER_ERROR_FAIL;
}
}
esp_loader_error_t loader_port_read(uint8_t *data, uint16_t size, uint32_t timeout)
{
HAL_StatusTypeDef err = HAL_UART_Receive(uart, data, size, timeout);
if (err == HAL_OK) {
#ifdef SERIAL_FLASHER_DEBUG_TRACE
transfer_debug_print(data, size, false);
#endif
return ESP_LOADER_SUCCESS;
} else if (err == HAL_TIMEOUT) {
return ESP_LOADER_ERROR_TIMEOUT;
} else {
return ESP_LOADER_ERROR_FAIL;
}
}
void loader_port_stm32_init(loader_stm32_config_t *config)
{
uart = config->huart;
gpio_port_io0 = config->port_io0;
gpio_port_rst = config->port_rst;
gpio_num_io0 = config->pin_num_io0;
gpio_num_rst = config->pin_num_rst;
}
// Set GPIO0 LOW, then
// assert reset pin for 100 milliseconds.
void loader_port_enter_bootloader(void)
{
HAL_GPIO_WritePin(gpio_port_io0, gpio_num_io0, GPIO_PIN_RESET);
loader_port_reset_target();
HAL_Delay(SERIAL_FLASHER_BOOT_HOLD_TIME_MS);
HAL_GPIO_WritePin(gpio_port_io0, gpio_num_io0, GPIO_PIN_SET);
}
void loader_port_reset_target(void)
{
HAL_GPIO_WritePin(gpio_port_rst, gpio_num_rst, GPIO_PIN_RESET);
HAL_Delay(SERIAL_FLASHER_RESET_HOLD_TIME_MS);
HAL_GPIO_WritePin(gpio_port_rst, gpio_num_rst, GPIO_PIN_SET);
}
void loader_port_delay_ms(uint32_t ms)
{
HAL_Delay(ms);
}
void loader_port_start_timer(uint32_t ms)
{
s_time_end = HAL_GetTick() + ms;
}
uint32_t loader_port_remaining_time(void)
{
int32_t remaining = s_time_end - HAL_GetTick();
return (remaining > 0) ? (uint32_t)remaining : 0;
}
void loader_port_debug_print(const char *str)
{
printf("DEBUG: %s", str);
}
esp_loader_error_t loader_port_change_transmission_rate(uint32_t baudrate)
{
uart->Init.BaudRate = baudrate;
if( HAL_UART_Init(uart) != HAL_OK ) {
return ESP_LOADER_ERROR_FAIL;
}
return ESP_LOADER_SUCCESS;
}

View File

@@ -0,0 +1,38 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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 <stdint.h>
#include "esp_loader_io.h"
#include "stm32f4xx_hal.h"
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
UART_HandleTypeDef *huart;
GPIO_TypeDef *port_io0;
uint16_t pin_num_io0;
GPIO_TypeDef *port_rst;
uint16_t pin_num_rst;
} loader_stm32_config_t;
void loader_port_stm32_init(loader_stm32_config_t *config);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,170 @@
/*
* Copyright (c) 2022 KT-Elektronik, Klaucke und Partner GmbH
*
* 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.
*/
#include "zephyr_port.h"
#include <zephyr/drivers/uart.h>
#include <zephyr/console/tty.h>
static const struct device *uart_dev;
static struct gpio_dt_spec enable_spec;
static struct gpio_dt_spec boot_spec;
static struct tty_serial tty;
static char tty_rx_buf[CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE];
static char tty_tx_buf[CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE];
#ifdef SERIAL_FLASHER_DEBUG_TRACE
static void transfer_debug_print(const uint8_t *data, uint16_t size, bool write)
{
static bool write_prev = false;
if (write_prev != write) {
write_prev = write;
printk("\n--- %s ---\n", write ? "WRITE" : "READ");
}
for (uint32_t i = 0; i < size; i++) {
printk("%02x ", data[i]);
}
}
#endif
esp_loader_error_t configure_tty()
{
if (tty_init(&tty, uart_dev) < 0 ||
tty_set_rx_buf(&tty, tty_rx_buf, sizeof(tty_rx_buf)) < 0 ||
tty_set_tx_buf(&tty, tty_tx_buf, sizeof(tty_tx_buf)) < 0) {
return ESP_LOADER_ERROR_FAIL;
}
return ESP_LOADER_SUCCESS;
}
esp_loader_error_t loader_port_read(uint8_t *data, const uint16_t size, const uint32_t timeout)
{
if (!device_is_ready(uart_dev) || data == NULL || size == 0) {
return ESP_LOADER_ERROR_FAIL;
}
ssize_t total_read = 0;
ssize_t remaining = size;
tty_set_rx_timeout(&tty, timeout);
while (remaining > 0) {
const uint16_t chunk_size = remaining < CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE ?
remaining : CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE;
ssize_t read = tty_read(&tty, &data[total_read], chunk_size);
if (read < 0) {
return ESP_LOADER_ERROR_TIMEOUT;
}
#ifdef SERIAL_FLASHER_DEBUG_TRACE
transfer_debug_print(data, read, false);
#endif
total_read += read;
remaining -= read;
}
return ESP_LOADER_SUCCESS;
}
esp_loader_error_t loader_port_write(const uint8_t *data, const uint16_t size, const uint32_t timeout)
{
if (!device_is_ready(uart_dev) || data == NULL || size == 0) {
return ESP_LOADER_ERROR_FAIL;
}
ssize_t total_written = 0;
ssize_t remaining = size;
tty_set_tx_timeout(&tty, timeout);
while (remaining > 0) {
const uint16_t chunk_size = remaining < CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE ?
remaining : CONFIG_ESP_SERIAL_FLASHER_UART_BUFSIZE;
ssize_t written = tty_write(&tty, &data[total_written], chunk_size);
if (written < 0) {
return ESP_LOADER_ERROR_TIMEOUT;
}
#ifdef SERIAL_FLASHER_DEBUG_TRACE
transfer_debug_print(data, written, true);
#endif
total_written += written;
remaining -= written;
}
return ESP_LOADER_SUCCESS;
}
esp_loader_error_t loader_port_zephyr_init(const loader_zephyr_config_t *config)
{
uart_dev = config->uart_dev;
enable_spec = config->enable_spec;
boot_spec = config->boot_spec;
return configure_tty();
}
void loader_port_reset_target(void)
{
gpio_pin_set_dt(&enable_spec, false);
loader_port_delay_ms(CONFIG_SERIAL_FLASHER_RESET_HOLD_TIME_MS);
gpio_pin_set_dt(&enable_spec, true);
}
void loader_port_enter_bootloader(void)
{
gpio_pin_set_dt(&boot_spec, false);
loader_port_reset_target();
loader_port_delay_ms(CONFIG_SERIAL_FLASHER_BOOT_HOLD_TIME_MS);
gpio_pin_set_dt(&boot_spec, true);
}
void loader_port_delay_ms(uint32_t ms)
{
k_msleep(ms);
}
static uint64_t s_time_end;
void loader_port_start_timer(uint32_t ms)
{
s_time_end = sys_clock_timeout_end_calc(Z_TIMEOUT_MS(ms));
}
uint32_t loader_port_remaining_time(void)
{
int64_t remaining = k_ticks_to_ms_floor64(s_time_end - k_uptime_ticks());
return (remaining > 0) ? (uint32_t)remaining : 0;
}
esp_loader_error_t loader_port_change_transmission_rate(uint32_t baudrate)
{
struct uart_config uart_config;
if (!device_is_ready(uart_dev)) {
return ESP_LOADER_ERROR_FAIL;
}
if (uart_config_get(uart_dev, &uart_config) != 0) {
return ESP_LOADER_ERROR_FAIL;
}
uart_config.baudrate = baudrate;
if (uart_configure(uart_dev, &uart_config) != 0) {
return ESP_LOADER_ERROR_FAIL;
}
/* bitrate-change can require tty re-configuration */
return configure_tty();
}

View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2022 KT-Elektronik, Klaucke und Partner GmbH
*
* 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 "esp_loader_io.h"
#include <zephyr/kernel.h>
#include <zephyr/drivers/gpio.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
const struct device *uart_dev;
const struct gpio_dt_spec enable_spec;
const struct gpio_dt_spec boot_spec;
} loader_zephyr_config_t;
esp_loader_error_t loader_port_zephyr_init(const loader_zephyr_config_t *config);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,33 @@
/* Copyright 2020 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 <stdint.h>
#include "esp_loader.h"
typedef struct {
uint32_t cmd;
uint32_t usr;
uint32_t usr1;
uint32_t usr2;
uint32_t w0;
uint32_t mosi_dlen;
uint32_t miso_dlen;
} target_registers_t;
esp_loader_error_t loader_detect_chip(target_chip_t *target, const target_registers_t **regs);
esp_loader_error_t loader_read_spi_config(target_chip_t target_chip, uint32_t *spi_config);
bool encryption_in_begin_flash_cmd(target_chip_t target);

View File

@@ -0,0 +1,28 @@
/*
* MD5 hash implementation and interface functions
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#pragma once
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
struct MD5Context {
uint32_t buf[4];
uint32_t bits[2];
uint8_t in[64];
};
void MD5Init(struct MD5Context *context);
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len);
void MD5Final(unsigned char digest[16], struct MD5Context *context);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,230 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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 <stdint.h>
#include <stdbool.h>
#include "esp_loader.h"
#ifdef __cplusplus
extern "C" {
#endif
#define STATUS_FAILURE 1
#define STATUS_SUCCESS 0
#define READ_DIRECTION 1
#define WRITE_DIRECTION 0
#define MD5_SIZE 32
typedef enum __attribute__((packed))
{
FLASH_BEGIN = 0x02,
FLASH_DATA = 0x03,
FLASH_END = 0x04,
MEM_BEGIN = 0x05,
MEM_END = 0x06,
MEM_DATA = 0x07,
SYNC = 0x08,
WRITE_REG = 0x09,
READ_REG = 0x0a,
SPI_SET_PARAMS = 0x0b,
SPI_ATTACH = 0x0d,
CHANGE_BAUDRATE = 0x0f,
FLASH_DEFL_BEGIN = 0x10,
FLASH_DEFL_DATA = 0x11,
FLASH_DEFL_END = 0x12,
SPI_FLASH_MD5 = 0x13,
} command_t;
typedef enum __attribute__((packed))
{
RESPONSE_OK = 0x00,
INVALID_COMMAND = 0x05, // parameters or length field is invalid
COMMAND_FAILED = 0x06, // Failed to act on received message
INVALID_CRC = 0x07, // Invalid CRC in message
FLASH_WRITE_ERR = 0x08, // After writing a block of data to flash, the ROM loader reads the value back and the 8-bit CRC is compared to the data read from flash. If they don't match, this error is returned.
FLASH_READ_ERR = 0x09, // SPI read failed
READ_LENGTH_ERR = 0x0a, // SPI read request length is too long
DEFLATE_ERROR = 0x0b, // ESP32 compressed uploads only
} error_code_t;
typedef struct __attribute__((packed))
{
uint8_t direction;
uint8_t command; // One of command_t
uint16_t size;
uint32_t checksum;
} command_common_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t erase_size;
uint32_t packet_count;
uint32_t packet_size;
uint32_t offset;
uint32_t encrypted;
} flash_begin_command_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t data_size;
uint32_t sequence_number;
uint32_t zero_0;
uint32_t zero_1;
} data_command_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t stay_in_loader;
} flash_end_command_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t total_size;
uint32_t blocks;
uint32_t block_size;
uint32_t offset;
} mem_begin_command_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t stay_in_loader;
uint32_t entry_point_address;
} mem_end_command_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint8_t sync_sequence[36];
} sync_command_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t address;
uint32_t value;
uint32_t mask;
uint32_t delay_us;
} write_reg_command_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t address;
} read_reg_command_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t configuration;
uint32_t zero; // ESP32 ROM only
} spi_attach_command_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t new_baudrate;
uint32_t old_baudrate;
} change_baudrate_command_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t address;
uint32_t size;
uint32_t reserved_0;
uint32_t reserved_1;
} spi_flash_md5_command_t;
typedef struct __attribute__((packed))
{
uint8_t direction;
uint8_t command; // One of command_t
uint16_t size;
uint32_t value;
} common_response_t;
typedef struct __attribute__((packed))
{
uint8_t failed;
uint8_t error;
} response_status_t;
typedef struct __attribute__((packed))
{
common_response_t common;
response_status_t status;
} response_t;
typedef struct __attribute__((packed))
{
common_response_t common;
uint8_t md5[MD5_SIZE]; // ROM only
response_status_t status;
} rom_md5_response_t;
typedef struct __attribute__((packed))
{
command_common_t common;
uint32_t id;
uint32_t total_size;
uint32_t block_size;
uint32_t sector_size;
uint32_t page_size;
uint32_t status_mask;
} write_spi_command_t;
esp_loader_error_t loader_initialize_conn(esp_loader_connect_args_t *connect_args);
#ifdef SERIAL_FLASHER_INTERFACE_UART
esp_loader_error_t loader_flash_begin_cmd(uint32_t offset, uint32_t erase_size, uint32_t block_size, uint32_t blocks_to_write, bool encryption);
esp_loader_error_t loader_flash_data_cmd(const uint8_t *data, uint32_t size);
esp_loader_error_t loader_flash_end_cmd(bool stay_in_loader);
esp_loader_error_t loader_sync_cmd(void);
esp_loader_error_t loader_spi_attach_cmd(uint32_t config);
esp_loader_error_t loader_md5_cmd(uint32_t address, uint32_t size, uint8_t *md5_out);
esp_loader_error_t loader_spi_parameters(uint32_t total_size);
#endif /* SERIAL_FLASHER_INTERFACE_UART */
esp_loader_error_t loader_mem_begin_cmd(uint32_t offset, uint32_t size, uint32_t blocks_to_write, uint32_t block_size);
esp_loader_error_t loader_mem_data_cmd(const uint8_t *data, uint32_t size);
esp_loader_error_t loader_mem_end_cmd(uint32_t entrypoint);
esp_loader_error_t loader_write_reg_cmd(uint32_t address, uint32_t value, uint32_t mask, uint32_t delay_us);
esp_loader_error_t loader_read_reg_cmd(uint32_t address, uint32_t *reg);
esp_loader_error_t loader_change_baudrate_cmd(uint32_t baudrate);
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,31 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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 <stdint.h>
#include <stdbool.h>
#include <stddef.h>
#include "esp_loader.h"
#include "protocol.h"
void log_loader_internal_error(error_code_t error);
esp_loader_error_t send_cmd(const void *cmd_data, uint32_t size, uint32_t *reg_value);
esp_loader_error_t send_cmd_with_data(const void *cmd_data, size_t cmd_size,
const void *data, size_t data_size);
esp_loader_error_t send_cmd_md5(const void *cmd_data, size_t cmd_size, uint8_t md5_out[MD5_SIZE]);

View File

@@ -0,0 +1,28 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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 "esp_loader.h"
#include <stdint.h>
#include <stdlib.h>
esp_loader_error_t SLIP_receive_data(uint8_t *buff, size_t size);
esp_loader_error_t SLIP_receive_packet(uint8_t *buff, size_t size);
esp_loader_error_t SLIP_send(const uint8_t *data, size_t size);
esp_loader_error_t SLIP_send_delimiter(void);

View File

@@ -0,0 +1,415 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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.
*/
#include "protocol.h"
#include "esp_loader_io.h"
#include "esp_loader.h"
#include "esp_targets.h"
#include "md5_hash.h"
#include <string.h>
#include <assert.h>
#ifndef MAX
#define MAX(a, b) ((a) > (b)) ? (a) : (b)
#endif
#ifndef MIN
#define MIN(a, b) ((a) < (b)) ? (a) : (b)
#endif
#ifndef ROUNDUP
#define ROUNDUP(a, b) (((int)a + (int)b - 1) / (int)b)
#endif
static const uint32_t DEFAULT_TIMEOUT = 1000;
static const uint32_t DEFAULT_FLASH_TIMEOUT = 3000; // timeout for most flash operations
static const uint32_t LOAD_RAM_TIMEOUT_PER_MB = 2000000; // timeout (per megabyte) for erasing a region
typedef enum {
SPI_FLASH_READ_ID = 0x9F
} spi_flash_cmd_t;
static const target_registers_t *s_reg = NULL;
static target_chip_t s_target = ESP_UNKNOWN_CHIP;
#if MD5_ENABLED
static const uint32_t MD5_TIMEOUT_PER_MB = 800;
static struct MD5Context s_md5_context;
static uint32_t s_start_address;
static uint32_t s_image_size;
static inline void init_md5(uint32_t address, uint32_t size)
{
s_start_address = address;
s_image_size = size;
MD5Init(&s_md5_context);
}
static inline void md5_update(const uint8_t *data, uint32_t size)
{
MD5Update(&s_md5_context, data, size);
}
static inline void md5_final(uint8_t digets[16])
{
MD5Final(digets, &s_md5_context);
}
#else
static inline void init_md5(uint32_t address, uint32_t size) { }
static inline void md5_update(const uint8_t *data, uint32_t size) { }
static inline void md5_final(uint8_t digets[16]) { }
#endif
static uint32_t timeout_per_mb(uint32_t size_bytes, uint32_t time_per_mb)
{
uint32_t timeout = time_per_mb * (size_bytes / 1e6);
return MAX(timeout, DEFAULT_FLASH_TIMEOUT);
}
esp_loader_error_t esp_loader_connect(esp_loader_connect_args_t *connect_args)
{
loader_port_enter_bootloader();
RETURN_ON_ERROR(loader_initialize_conn(connect_args));
RETURN_ON_ERROR(loader_detect_chip(&s_target, &s_reg));
#ifdef SERIAL_FLASHER_INTERFACE_UART
esp_loader_error_t err;
uint32_t spi_config;
if (s_target == ESP8266_CHIP) {
err = loader_flash_begin_cmd(0, 0, 0, 0, s_target);
} else {
RETURN_ON_ERROR( loader_read_spi_config(s_target, &spi_config) );
loader_port_start_timer(DEFAULT_TIMEOUT);
err = loader_spi_attach_cmd(spi_config);
}
return err;
#endif /* SERIAL_FLASHER_INTERFACE_UART */
return ESP_LOADER_SUCCESS;
}
target_chip_t esp_loader_get_target(void)
{
return s_target;
}
#ifdef SERIAL_FLASHER_INTERFACE_UART
static uint32_t s_flash_write_size = 0;
static esp_loader_error_t spi_set_data_lengths(size_t mosi_bits, size_t miso_bits)
{
if (mosi_bits > 0) {
RETURN_ON_ERROR( esp_loader_write_register(s_reg->mosi_dlen, mosi_bits - 1) );
}
if (miso_bits > 0) {
RETURN_ON_ERROR( esp_loader_write_register(s_reg->miso_dlen, miso_bits - 1) );
}
return ESP_LOADER_SUCCESS;
}
static esp_loader_error_t spi_set_data_lengths_8266(size_t mosi_bits, size_t miso_bits)
{
uint32_t mosi_mask = (mosi_bits == 0) ? 0 : mosi_bits - 1;
uint32_t miso_mask = (miso_bits == 0) ? 0 : miso_bits - 1;
return esp_loader_write_register(s_reg->usr1, (miso_mask << 8) | (mosi_mask << 17));
}
static esp_loader_error_t spi_flash_command(spi_flash_cmd_t cmd, void *data_tx, size_t tx_size, void *data_rx, size_t rx_size)
{
assert(rx_size <= 32); // Reading more than 32 bits back from a SPI flash operation is unsupported
assert(tx_size <= 64); // Writing more than 64 bytes of data with one SPI command is unsupported
uint32_t SPI_USR_CMD = (1 << 31);
uint32_t SPI_USR_MISO = (1 << 28);
uint32_t SPI_USR_MOSI = (1 << 27);
uint32_t SPI_CMD_USR = (1 << 18);
uint32_t CMD_LEN_SHIFT = 28;
// Save SPI configuration
uint32_t old_spi_usr;
uint32_t old_spi_usr2;
RETURN_ON_ERROR( esp_loader_read_register(s_reg->usr, &old_spi_usr) );
RETURN_ON_ERROR( esp_loader_read_register(s_reg->usr2, &old_spi_usr2) );
if (s_target == ESP8266_CHIP) {
RETURN_ON_ERROR( spi_set_data_lengths_8266(tx_size, rx_size) );
} else {
RETURN_ON_ERROR( spi_set_data_lengths(tx_size, rx_size) );
}
uint32_t usr_reg_2 = (7 << CMD_LEN_SHIFT) | cmd;
uint32_t usr_reg = SPI_USR_CMD;
if (rx_size > 0) {
usr_reg |= SPI_USR_MISO;
}
if (tx_size > 0) {
usr_reg |= SPI_USR_MOSI;
}
RETURN_ON_ERROR( esp_loader_write_register(s_reg->usr, usr_reg) );
RETURN_ON_ERROR( esp_loader_write_register(s_reg->usr2, usr_reg_2 ) );
if (tx_size == 0) {
// clear data register before we read it
RETURN_ON_ERROR( esp_loader_write_register(s_reg->w0, 0) );
} else {
uint32_t *data = (uint32_t *)data_tx;
uint32_t words_to_write = (tx_size + 31) / (8 * 4);
uint32_t data_reg_addr = s_reg->w0;
while (words_to_write--) {
uint32_t word = *data++;
RETURN_ON_ERROR( esp_loader_write_register(data_reg_addr, word) );
data_reg_addr += 4;
}
}
RETURN_ON_ERROR( esp_loader_write_register(s_reg->cmd, SPI_CMD_USR) );
uint32_t trials = 10;
while (trials--) {
uint32_t cmd_reg;
RETURN_ON_ERROR( esp_loader_read_register(s_reg->cmd, &cmd_reg) );
if ((cmd_reg & SPI_CMD_USR) == 0) {
break;
}
}
if (trials == 0) {
return ESP_LOADER_ERROR_TIMEOUT;
}
RETURN_ON_ERROR( esp_loader_read_register(s_reg->w0, data_rx) );
// Restore SPI configuration
RETURN_ON_ERROR( esp_loader_write_register(s_reg->usr, old_spi_usr) );
RETURN_ON_ERROR( esp_loader_write_register(s_reg->usr2, old_spi_usr2) );
return ESP_LOADER_SUCCESS;
}
static esp_loader_error_t detect_flash_size(size_t *flash_size)
{
uint32_t flash_id = 0;
RETURN_ON_ERROR( spi_flash_command(SPI_FLASH_READ_ID, NULL, 0, &flash_id, 24) );
uint32_t size_id = flash_id >> 16;
if (size_id < 0x12 || size_id > 0x18) {
return ESP_LOADER_ERROR_UNSUPPORTED_CHIP;
}
*flash_size = 1 << size_id;
return ESP_LOADER_SUCCESS;
}
static uint32_t calc_erase_size(const target_chip_t target, const uint32_t offset,
const uint32_t image_size)
{
if (target != ESP8266_CHIP) {
return image_size;
} else {
/* Needed to fix a bug in the ESP8266 ROM */
const uint32_t sectors_per_block = 16U;
const uint32_t sector_size = 4096U;
const uint32_t num_sectors = (image_size + sector_size - 1) / sector_size;
const uint32_t start_sector = offset / sector_size;
uint32_t head_sectors = sectors_per_block - (start_sector % sectors_per_block);
/* The ROM bug deletes extra num_sectors if we don't cross the block boundary
and extra head_sectors if we do */
if (num_sectors <= head_sectors) {
return ((num_sectors + 1) / 2) * sector_size;
} else {
return (num_sectors - head_sectors) * sector_size;
}
}
}
esp_loader_error_t esp_loader_flash_start(uint32_t offset, uint32_t image_size, uint32_t block_size)
{
s_flash_write_size = block_size;
size_t flash_size = 0;
if (detect_flash_size(&flash_size) == ESP_LOADER_SUCCESS) {
if (image_size > flash_size) {
return ESP_LOADER_ERROR_IMAGE_SIZE;
}
loader_port_start_timer(DEFAULT_TIMEOUT);
RETURN_ON_ERROR( loader_spi_parameters(flash_size) );
} else {
loader_port_debug_print("Flash size detection failed, falling back to default");
}
init_md5(offset, image_size);
bool encryption_in_cmd = encryption_in_begin_flash_cmd(s_target);
const uint32_t erase_size = calc_erase_size(esp_loader_get_target(), offset, image_size);
const uint32_t blocks_to_write = (image_size + block_size - 1) / block_size;
const uint32_t erase_region_timeout_per_mb = 10000;
loader_port_start_timer(timeout_per_mb(erase_size, erase_region_timeout_per_mb));
return loader_flash_begin_cmd(offset, erase_size, block_size, blocks_to_write, encryption_in_cmd);
}
esp_loader_error_t esp_loader_flash_write(void *payload, uint32_t size)
{
uint32_t padding_bytes = s_flash_write_size - size;
uint8_t *data = (uint8_t *)payload;
uint32_t padding_index = size;
if (size > s_flash_write_size) {
return ESP_LOADER_ERROR_INVALID_PARAM;
}
const uint8_t padding_pattern = 0xFF;
while (padding_bytes--) {
data[padding_index++] = padding_pattern;
}
md5_update(payload, (size + 3) & ~3);
loader_port_start_timer(DEFAULT_TIMEOUT);
return loader_flash_data_cmd(data, s_flash_write_size);
}
esp_loader_error_t esp_loader_flash_finish(bool reboot)
{
loader_port_start_timer(DEFAULT_TIMEOUT);
return loader_flash_end_cmd(!reboot);
}
#endif /* SERIAL_FLASHER_INTERFACE_UART */
esp_loader_error_t esp_loader_mem_start(uint32_t offset, uint32_t size, uint32_t block_size)
{
uint32_t blocks_to_write = ROUNDUP(size, block_size);
loader_port_start_timer(timeout_per_mb(size, LOAD_RAM_TIMEOUT_PER_MB));
return loader_mem_begin_cmd(offset, size, blocks_to_write, block_size);
}
esp_loader_error_t esp_loader_mem_write(const void *payload, uint32_t size)
{
const uint8_t *data = (const uint8_t *)payload;
loader_port_start_timer(timeout_per_mb(size, LOAD_RAM_TIMEOUT_PER_MB));
return loader_mem_data_cmd(data, size);
}
esp_loader_error_t esp_loader_mem_finish(uint32_t entrypoint)
{
loader_port_start_timer(DEFAULT_TIMEOUT);
return loader_mem_end_cmd(entrypoint);
}
esp_loader_error_t esp_loader_read_register(uint32_t address, uint32_t *reg_value)
{
loader_port_start_timer(DEFAULT_TIMEOUT);
return loader_read_reg_cmd(address, reg_value);
}
esp_loader_error_t esp_loader_write_register(uint32_t address, uint32_t reg_value)
{
loader_port_start_timer(DEFAULT_TIMEOUT);
return loader_write_reg_cmd(address, reg_value, 0xFFFFFFFF, 0);
}
esp_loader_error_t esp_loader_change_transmission_rate(uint32_t transmission_rate)
{
if (s_target == ESP8266_CHIP) {
return ESP_LOADER_ERROR_UNSUPPORTED_FUNC;
}
loader_port_start_timer(DEFAULT_TIMEOUT);
return loader_change_baudrate_cmd(transmission_rate);
}
#if MD5_ENABLED
static void hexify(const uint8_t raw_md5[16], uint8_t hex_md5_out[32])
{
static const uint8_t dec_to_hex[] = {
'0', '1', '2', '3', '4', '5', '6', '7',
'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
};
for (int i = 0; i < 16; i++) {
*hex_md5_out++ = dec_to_hex[raw_md5[i] >> 4];
*hex_md5_out++ = dec_to_hex[raw_md5[i] & 0xF];
}
}
esp_loader_error_t esp_loader_flash_verify(void)
{
if (s_target == ESP8266_CHIP) {
return ESP_LOADER_ERROR_UNSUPPORTED_FUNC;
}
uint8_t raw_md5[16] = {0};
/* Zero termination and new line character require 2 bytes */
uint8_t hex_md5[MD5_SIZE + 2] = {0};
uint8_t received_md5[MD5_SIZE + 2] = {0};
md5_final(raw_md5);
hexify(raw_md5, hex_md5);
loader_port_start_timer(timeout_per_mb(s_image_size, MD5_TIMEOUT_PER_MB));
RETURN_ON_ERROR( loader_md5_cmd(s_start_address, s_image_size, received_md5) );
bool md5_match = memcmp(hex_md5, received_md5, MD5_SIZE) == 0;
if (!md5_match) {
hex_md5[MD5_SIZE] = '\n';
received_md5[MD5_SIZE] = '\n';
loader_port_debug_print("Error: MD5 checksum does not match:\n");
loader_port_debug_print("Expected:\n");
loader_port_debug_print((char *)received_md5);
loader_port_debug_print("Actual:\n");
loader_port_debug_print((char *)hex_md5);
return ESP_LOADER_ERROR_INVALID_MD5;
}
return ESP_LOADER_SUCCESS;
}
#endif
void esp_loader_reset_target(void)
{
loader_port_reset_target();
}

View File

@@ -0,0 +1,263 @@
/* Copyright 2020 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.
*/
#include "esp_targets.h"
#include <stddef.h>
#define MAX_MAGIC_VALUES 2
typedef esp_loader_error_t (*read_spi_config_t)(uint32_t efuse_base, uint32_t *spi_config);
typedef struct {
target_registers_t regs;
uint32_t efuse_base;
uint32_t chip_magic_value[MAX_MAGIC_VALUES];
read_spi_config_t read_spi_config;
bool encryption_in_begin_flash_cmd;
} esp_target_t;
// This ROM address has a different value on each chip model
#define CHIP_DETECT_MAGIC_REG_ADDR 0x40001000
#define ESP8266_SPI_REG_BASE 0x60000200
#define ESP32S2_SPI_REG_BASE 0x3f402000
#define ESP32xx_SPI_REG_BASE 0x60002000
#define ESP32_SPI_REG_BASE 0x3ff42000
static esp_loader_error_t spi_config_esp32(uint32_t efuse_base, uint32_t *spi_config);
static esp_loader_error_t spi_config_esp32xx(uint32_t efuse_base, uint32_t *spi_config);
static const esp_target_t esp_target[ESP_MAX_CHIP] = {
// ESP8266
{
.regs = {
.cmd = ESP8266_SPI_REG_BASE + 0x00,
.usr = ESP8266_SPI_REG_BASE + 0x1c,
.usr1 = ESP8266_SPI_REG_BASE + 0x20,
.usr2 = ESP8266_SPI_REG_BASE + 0x24,
.w0 = ESP8266_SPI_REG_BASE + 0x40,
.mosi_dlen = 0,
.miso_dlen = 0,
},
.efuse_base = 0, // Not used
.chip_magic_value = { 0xfff0c101, 0 },
.read_spi_config = NULL, // Not used
},
// ESP32
{
.regs = {
.cmd = ESP32_SPI_REG_BASE + 0x00,
.usr = ESP32_SPI_REG_BASE + 0x1c,
.usr1 = ESP32_SPI_REG_BASE + 0x20,
.usr2 = ESP32_SPI_REG_BASE + 0x24,
.w0 = ESP32_SPI_REG_BASE + 0x80,
.mosi_dlen = ESP32_SPI_REG_BASE + 0x28,
.miso_dlen = ESP32_SPI_REG_BASE + 0x2c,
},
.efuse_base = 0x3ff5A000,
.chip_magic_value = { 0x00f01d83, 0 },
.read_spi_config = spi_config_esp32,
},
// ESP32S2
{
.regs = {
.cmd = ESP32S2_SPI_REG_BASE + 0x00,
.usr = ESP32S2_SPI_REG_BASE + 0x18,
.usr1 = ESP32S2_SPI_REG_BASE + 0x1c,
.usr2 = ESP32S2_SPI_REG_BASE + 0x20,
.w0 = ESP32S2_SPI_REG_BASE + 0x58,
.mosi_dlen = ESP32S2_SPI_REG_BASE + 0x24,
.miso_dlen = ESP32S2_SPI_REG_BASE + 0x28,
},
.efuse_base = 0x3f41A000,
.chip_magic_value = { 0x000007c6, 0 },
.read_spi_config = spi_config_esp32xx,
},
// ESP32C3
{
.regs = {
.cmd = ESP32xx_SPI_REG_BASE + 0x00,
.usr = ESP32xx_SPI_REG_BASE + 0x18,
.usr1 = ESP32xx_SPI_REG_BASE + 0x1c,
.usr2 = ESP32xx_SPI_REG_BASE + 0x20,
.w0 = ESP32xx_SPI_REG_BASE + 0x58,
.mosi_dlen = ESP32xx_SPI_REG_BASE + 0x24,
.miso_dlen = ESP32xx_SPI_REG_BASE + 0x28,
},
.efuse_base = 0x60008800,
.chip_magic_value = { 0x6921506f, 0x1b31506f },
.read_spi_config = spi_config_esp32xx,
},
// ESP32S3
{
.regs = {
.cmd = ESP32xx_SPI_REG_BASE + 0x00,
.usr = ESP32xx_SPI_REG_BASE + 0x18,
.usr1 = ESP32xx_SPI_REG_BASE + 0x1c,
.usr2 = ESP32xx_SPI_REG_BASE + 0x20,
.w0 = ESP32xx_SPI_REG_BASE + 0x58,
.mosi_dlen = ESP32xx_SPI_REG_BASE + 0x24,
.miso_dlen = ESP32xx_SPI_REG_BASE + 0x28,
},
.efuse_base = 0x60007000,
.chip_magic_value = { 0x00000009, 0 },
.read_spi_config = spi_config_esp32xx,
},
// ESP32C2
{
.regs = {
.cmd = ESP32xx_SPI_REG_BASE + 0x00,
.usr = ESP32xx_SPI_REG_BASE + 0x18,
.usr1 = ESP32xx_SPI_REG_BASE + 0x1c,
.usr2 = ESP32xx_SPI_REG_BASE + 0x20,
.w0 = ESP32xx_SPI_REG_BASE + 0x58,
.mosi_dlen = ESP32xx_SPI_REG_BASE + 0x24,
.miso_dlen = ESP32xx_SPI_REG_BASE + 0x28,
},
.efuse_base = 0x60008800,
.chip_magic_value = { 0x6f51306f, 0x7c41a06f },
.read_spi_config = spi_config_esp32xx,
},
// ESP32H4
{
.regs = {
.cmd = ESP32xx_SPI_REG_BASE + 0x00,
.usr = ESP32xx_SPI_REG_BASE + 0x18,
.usr1 = ESP32xx_SPI_REG_BASE + 0x1c,
.usr2 = ESP32xx_SPI_REG_BASE + 0x20,
.w0 = ESP32xx_SPI_REG_BASE + 0x58,
.mosi_dlen = ESP32xx_SPI_REG_BASE + 0x24,
.miso_dlen = ESP32xx_SPI_REG_BASE + 0x28,
},
.efuse_base = 0x6001A000,
.chip_magic_value = {0xca26cc22, 0x6881b06f}, // ESP32H4-BETA1, ESP32H4-BETA2
.read_spi_config = spi_config_esp32xx,
},
// ESP32H2
{
.regs = {
.cmd = ESP32xx_SPI_REG_BASE + 0x00,
.usr = ESP32xx_SPI_REG_BASE + 0x18,
.usr1 = ESP32xx_SPI_REG_BASE + 0x1c,
.usr2 = ESP32xx_SPI_REG_BASE + 0x20,
.w0 = ESP32xx_SPI_REG_BASE + 0x58,
.mosi_dlen = ESP32xx_SPI_REG_BASE + 0x24,
.miso_dlen = ESP32xx_SPI_REG_BASE + 0x28,
},
.efuse_base = 0x6001A000,
.chip_magic_value = {0xd7b73e80, 0},
.read_spi_config = spi_config_esp32xx,
},
};
const target_registers_t *get_esp_target_data(target_chip_t chip)
{
return (const target_registers_t *)&esp_target[chip];
}
esp_loader_error_t loader_detect_chip(target_chip_t *target_chip, const target_registers_t **target_data)
{
uint32_t magic_value;
RETURN_ON_ERROR( esp_loader_read_register(CHIP_DETECT_MAGIC_REG_ADDR, &magic_value) );
for (int chip = 0; chip < ESP_MAX_CHIP; chip++) {
for(int index = 0; index < MAX_MAGIC_VALUES; index++) {
if (magic_value == esp_target[chip].chip_magic_value[index]) {
*target_chip = (target_chip_t)chip;
*target_data = (target_registers_t *)&esp_target[chip];
return ESP_LOADER_SUCCESS;
}
}
}
return ESP_LOADER_ERROR_INVALID_TARGET;
}
esp_loader_error_t loader_read_spi_config(target_chip_t target_chip, uint32_t *spi_config)
{
const esp_target_t *target = &esp_target[target_chip];
return target->read_spi_config(target->efuse_base, spi_config);
}
static inline uint32_t efuse_word_addr(uint32_t efuse_base, uint32_t n)
{
return efuse_base + (n * 4);
}
// 30->GPIO32 | 31->GPIO33
static inline uint8_t adjust_pin_number(uint8_t num)
{
return (num >= 30) ? num + 2 : num;
}
static esp_loader_error_t spi_config_esp32(uint32_t efuse_base, uint32_t *spi_config)
{
*spi_config = 0;
uint32_t reg5, reg3;
RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 5), &reg5) );
RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 3), &reg3) );
uint32_t pins = reg5 & 0xfffff;
if (pins == 0 || pins == 0xfffff) {
return ESP_LOADER_SUCCESS;
}
uint8_t clk = adjust_pin_number( (pins >> 0) & 0x1f );
uint8_t q = adjust_pin_number( (pins >> 5) & 0x1f );
uint8_t d = adjust_pin_number( (pins >> 10) & 0x1f );
uint8_t cs = adjust_pin_number( (pins >> 15) & 0x1f );
uint8_t hd = adjust_pin_number( (reg3 >> 4) & 0x1f );
if (clk == cs || clk == d || clk == q || q == cs || q == d || q == d) {
return ESP_LOADER_SUCCESS;
}
*spi_config = (hd << 24) | (cs << 18) | (d << 12) | (q << 6) | clk;
return ESP_LOADER_SUCCESS;
}
// Applies for esp32s2, esp32c3 and esp32c3
static esp_loader_error_t spi_config_esp32xx(uint32_t efuse_base, uint32_t *spi_config)
{
*spi_config = 0;
uint32_t reg1, reg2;
RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 18), &reg1) );
RETURN_ON_ERROR( esp_loader_read_register(efuse_word_addr(efuse_base, 19), &reg2) );
uint32_t pins = ((reg1 >> 16) | ((reg2 & 0xfffff) << 16)) & 0x3fffffff;
if (pins == 0 || pins == 0xffffffff) {
return ESP_LOADER_SUCCESS;
}
*spi_config = pins;
return ESP_LOADER_SUCCESS;
}
bool encryption_in_begin_flash_cmd(target_chip_t target)
{
return target == ESP32_CHIP || target == ESP8266_CHIP;
}

View File

@@ -0,0 +1,262 @@
/*
* MD5 hash implementation and interface functions
* Copyright (c) 2003-2005, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "md5_hash.h"
#include <stdlib.h>
#include <string.h>
static void MD5Transform(uint32_t buf[4], uint32_t const in[16]);
/* ===== start - public domain MD5 implementation ===== */
/*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
* written by Colin Plumb in 1993, no copyright is claimed.
* This code is in the public domain; do with it what you wish.
*
* Equivalent code is available from RSA Data Security, Inc.
* This code has been tested against that, and is equivalent,
* except that you don't need to include two pages of legalese
* with every copy.
*
* To compute the message digest of a chunk of bytes, declare an
* MD5Context structure, pass it to MD5Init, call MD5Update as
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*/
#ifndef WORDS_BIGENDIAN
#define byteReverse(buf, len) /* Nothing */
#else
/*
* Note: this code is harmless on little-endian machines.
*/
static void byteReverse(unsigned char *buf, unsigned longs)
{
uint32_t t;
do {
t = (uint32_t) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
((unsigned) buf[1] << 8 | buf[0]);
*(uint32_t *) buf = t;
buf += 4;
} while (--longs);
}
#endif
/*
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
void MD5Init(struct MD5Context *ctx)
{
ctx->buf[0] = 0x67452301;
ctx->buf[1] = 0xefcdab89;
ctx->buf[2] = 0x98badcfe;
ctx->buf[3] = 0x10325476;
ctx->bits[0] = 0;
ctx->bits[1] = 0;
}
/*
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
{
uint32_t t;
/* Update bitcount */
t = ctx->bits[0];
if ((ctx->bits[0] = t + ((uint32_t) len << 3)) < t) {
ctx->bits[1]++; /* Carry from low to high */
}
ctx->bits[1] += len >> 29;
t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
/* Handle any leading odd-sized chunks */
if (t) {
unsigned char *p = (unsigned char *) ctx->in + t;
t = 64 - t;
if (len < t) {
memcpy(p, buf, len);
return;
}
memcpy(p, buf, t);
byteReverse(ctx->in, 16);
MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in);
buf += t;
len -= t;
}
/* Process data in 64-byte chunks */
while (len >= 64) {
memcpy(ctx->in, buf, 64);
byteReverse(ctx->in, 16);
MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in);
buf += 64;
len -= 64;
}
/* Handle any remaining bytes of data. */
memcpy(ctx->in, buf, len);
}
/*
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
{
unsigned count;
unsigned char *p;
/* Compute number of bytes mod 64 */
count = (ctx->bits[0] >> 3) & 0x3F;
/* Set the first char of padding to 0x80. This is safe since there is
always at least one byte free */
p = ctx->in + count;
*p++ = 0x80;
/* Bytes of padding needed to make 64 bytes */
count = 64 - 1 - count;
/* Pad out to 56 mod 64 */
if (count < 8) {
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
byteReverse(ctx->in, 16);
MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in);
/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
} else {
/* Pad block to 56 bytes */
memset(p, 0, count - 8);
}
byteReverse(ctx->in, 14);
/* Append length in bits and transform */
((uint32_t *) ctx->in)[14] = ctx->bits[0];
((uint32_t *) ctx->in)[15] = ctx->bits[1];
MD5Transform((uint32_t *)ctx->buf, (uint32_t *) ctx->in);
byteReverse((unsigned char *) ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(struct MD5Context)); /* In case it's sensitive */
}
/* The four core functions - F1 is optimized somewhat */
/* #define F1(x, y, z) (x & y | ~x & z) */
#define F1(x, y, z) (z ^ (x & (y ^ z)))
#define F2(x, y, z) F1(z, x, y)
#define F3(x, y, z) (x ^ y ^ z)
#define F4(x, y, z) (y ^ (x | ~z))
/* This is the central step in the MD5 algorithm. */
#define MD5STEP(f, w, x, y, z, data, s) \
( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
/*
* The core of the MD5 algorithm, this alters an existing MD5 hash to
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
static void MD5Transform(uint32_t buf[4], uint32_t const in[16])
{
register uint32_t a, b, c, d;
a = buf[0];
b = buf[1];
c = buf[2];
d = buf[3];
MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
buf[0] += a;
buf[1] += b;
buf[2] += c;
buf[3] += d;
}
/* ===== end - public domain MD5 implementation ===== */

View File

@@ -0,0 +1,301 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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.
*/
#include "protocol.h"
#include "protocol_prv.h"
#include "esp_loader_io.h"
#include <stddef.h>
#include <string.h>
#define CMD_SIZE(cmd) ( sizeof(cmd) - sizeof(command_common_t) )
static uint32_t s_sequence_number = 0;
static uint8_t compute_checksum(const uint8_t *data, uint32_t size)
{
uint8_t checksum = 0xEF;
while (size--) {
checksum ^= *data++;
}
return checksum;
}
void log_loader_internal_error(error_code_t error)
{
loader_port_debug_print("Error: ");
switch (error) {
case INVALID_CRC: loader_port_debug_print("INVALID_CRC"); break;
case INVALID_COMMAND: loader_port_debug_print("INVALID_COMMAND"); break;
case COMMAND_FAILED: loader_port_debug_print("COMMAND_FAILED"); break;
case FLASH_WRITE_ERR: loader_port_debug_print("FLASH_WRITE_ERR"); break;
case FLASH_READ_ERR: loader_port_debug_print("FLASH_READ_ERR"); break;
case READ_LENGTH_ERR: loader_port_debug_print("READ_LENGTH_ERR"); break;
case DEFLATE_ERROR: loader_port_debug_print("DEFLATE_ERROR"); break;
default: loader_port_debug_print("UNKNOWN ERROR"); break;
}
loader_port_debug_print("\n");
}
esp_loader_error_t loader_flash_begin_cmd(uint32_t offset,
uint32_t erase_size,
uint32_t block_size,
uint32_t blocks_to_write,
bool encryption)
{
uint32_t encryption_size = encryption ? sizeof(uint32_t) : 0;
flash_begin_command_t flash_begin_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = FLASH_BEGIN,
.size = CMD_SIZE(flash_begin_cmd) - encryption_size,
.checksum = 0
},
.erase_size = erase_size,
.packet_count = blocks_to_write,
.packet_size = block_size,
.offset = offset,
.encrypted = 0
};
s_sequence_number = 0;
return send_cmd(&flash_begin_cmd, sizeof(flash_begin_cmd) - encryption_size, NULL);
}
esp_loader_error_t loader_flash_data_cmd(const uint8_t *data, uint32_t size)
{
data_command_t data_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = FLASH_DATA,
.size = CMD_SIZE(data_cmd) + size,
.checksum = compute_checksum(data, size)
},
.data_size = size,
.sequence_number = s_sequence_number++,
};
return send_cmd_with_data(&data_cmd, sizeof(data_cmd), data, size);
}
esp_loader_error_t loader_flash_end_cmd(bool stay_in_loader)
{
flash_end_command_t end_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = FLASH_END,
.size = CMD_SIZE(end_cmd),
.checksum = 0
},
.stay_in_loader = stay_in_loader
};
return send_cmd(&end_cmd, sizeof(end_cmd), NULL);
}
esp_loader_error_t loader_mem_begin_cmd(uint32_t offset, uint32_t size, uint32_t blocks_to_write, uint32_t block_size)
{
mem_begin_command_t mem_begin_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = MEM_BEGIN,
.size = CMD_SIZE(mem_begin_cmd),
.checksum = 0
},
.total_size = size,
.blocks = blocks_to_write,
.block_size = block_size,
.offset = offset
};
s_sequence_number = 0;
return send_cmd(&mem_begin_cmd, sizeof(mem_begin_cmd), NULL);
}
esp_loader_error_t loader_mem_data_cmd(const uint8_t *data, uint32_t size)
{
data_command_t data_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = MEM_DATA,
.size = CMD_SIZE(data_cmd) + size,
.checksum = compute_checksum(data, size)
},
.data_size = size,
.sequence_number = s_sequence_number++,
};
return send_cmd_with_data(&data_cmd, sizeof(data_cmd), data, size);
}
esp_loader_error_t loader_mem_end_cmd(uint32_t entrypoint)
{
mem_end_command_t end_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = MEM_END,
.size = CMD_SIZE(end_cmd),
},
.stay_in_loader = (entrypoint == 0),
.entry_point_address = entrypoint
};
return send_cmd(&end_cmd, sizeof(end_cmd), NULL);
}
esp_loader_error_t loader_sync_cmd(void)
{
sync_command_t sync_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = SYNC,
.size = CMD_SIZE(sync_cmd),
.checksum = 0
},
.sync_sequence = {
0x07, 0x07, 0x12, 0x20,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55,
}
};
return send_cmd(&sync_cmd, sizeof(sync_cmd), NULL);
}
esp_loader_error_t loader_write_reg_cmd(uint32_t address, uint32_t value,
uint32_t mask, uint32_t delay_us)
{
write_reg_command_t write_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = WRITE_REG,
.size = CMD_SIZE(write_cmd),
.checksum = 0
},
.address = address,
.value = value,
.mask = mask,
.delay_us = delay_us
};
return send_cmd(&write_cmd, sizeof(write_cmd), NULL);
}
esp_loader_error_t loader_read_reg_cmd(uint32_t address, uint32_t *reg)
{
read_reg_command_t read_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = READ_REG,
.size = CMD_SIZE(read_cmd),
.checksum = 0
},
.address = address,
};
return send_cmd(&read_cmd, sizeof(read_cmd), reg);
}
esp_loader_error_t loader_spi_attach_cmd(uint32_t config)
{
spi_attach_command_t attach_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = SPI_ATTACH,
.size = CMD_SIZE(attach_cmd),
.checksum = 0
},
.configuration = config,
.zero = 0
};
return send_cmd(&attach_cmd, sizeof(attach_cmd), NULL);
}
esp_loader_error_t loader_change_baudrate_cmd(uint32_t baudrate)
{
change_baudrate_command_t baudrate_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = CHANGE_BAUDRATE,
.size = CMD_SIZE(baudrate_cmd),
.checksum = 0
},
.new_baudrate = baudrate,
.old_baudrate = 0 // ESP32 ROM only
};
return send_cmd(&baudrate_cmd, sizeof(baudrate_cmd), NULL);
}
esp_loader_error_t loader_md5_cmd(uint32_t address, uint32_t size, uint8_t *md5_out)
{
spi_flash_md5_command_t md5_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = SPI_FLASH_MD5,
.size = CMD_SIZE(md5_cmd),
.checksum = 0
},
.address = address,
.size = size,
.reserved_0 = 0,
.reserved_1 = 0
};
return send_cmd_md5(&md5_cmd, sizeof(md5_cmd), md5_out);
}
esp_loader_error_t loader_spi_parameters(uint32_t total_size)
{
write_spi_command_t spi_cmd = {
.common = {
.direction = WRITE_DIRECTION,
.command = SPI_SET_PARAMS,
.size = 24,
.checksum = 0
},
.id = 0,
.total_size = total_size,
.block_size = 64 * 1024,
.sector_size = 4 * 1024,
.page_size = 0x100,
.status_mask = 0xFFFF,
};
return send_cmd(&spi_cmd, sizeof(spi_cmd), NULL);
}
__attribute__ ((weak)) void loader_port_debug_print(const char *str)
{
(void)(str);
}

View File

@@ -0,0 +1,312 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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.
*/
#include "protocol.h"
#include "protocol_prv.h"
#include "esp_loader_io.h"
#include <stddef.h>
#include <assert.h>
typedef struct __attribute__((packed)) {
uint8_t cmd;
uint8_t addr;
uint8_t dummy;
} transaction_preamble_t;
typedef enum {
TRANS_CMD_WRBUF = 0x01,
TRANS_CMD_RDBUF = 0x02,
TRANS_CMD_WRDMA = 0x03,
TRANS_CMD_RDDMA = 0x04,
TRANS_CMD_SEG_DONE = 0x05,
TRANS_CMD_ENQPI = 0x06,
TRANS_CMD_WR_DONE = 0x07,
TRANS_CMD_CMD8 = 0x08,
TRANS_CMD_CMD9 = 0x09,
TRANS_CMD_CMDA = 0x0A,
TRANS_CMD_EXQPI = 0xDD,
} transaction_cmd_t;
/* Slave protocol registers */
typedef enum {
SLAVE_REGISTER_VER = 0,
SLAVE_REGISTER_RXSTA = 4,
SLAVE_REGISTER_TXSTA = 8,
SLAVE_REGISTER_CMD = 12,
} slave_register_addr_t;
#define SLAVE_STA_TOGGLE_BIT (0x01U << 0)
#define SLAVE_STA_INIT_BIT (0x01U << 1)
#define SLAVE_STA_BUF_LENGTH_POS 2U
typedef enum {
SLAVE_STATE_INIT = SLAVE_STA_TOGGLE_BIT | SLAVE_STA_INIT_BIT,
SLAVE_STATE_FIRST_PACKET = SLAVE_STA_INIT_BIT,
} slave_state_t;
typedef enum {
/* Target to host */
SLAVE_CMD_IDLE = 0xAA,
SLAVE_CMD_READY = 0xA5,
/* Host to target */
SLAVE_CMD_REBOOT = 0xFE,
SLAVE_CMD_COMM_REINIT = 0x5A,
SLAVE_CMD_DONE = 0x55,
} slave_cmd_t;
static uint8_t s_slave_seq_tx;
static uint8_t s_slave_seq_rx;
static esp_loader_error_t write_slave_reg(const uint8_t *data, const uint32_t addr,
const uint8_t size);
static esp_loader_error_t read_slave_reg(uint8_t *out_data, const uint32_t addr,
const uint8_t size);
static esp_loader_error_t handle_slave_state(const uint32_t status_reg_addr, uint8_t *seq_state,
bool *slave_ready, uint32_t *buf_size);
static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value);
esp_loader_error_t loader_initialize_conn(esp_loader_connect_args_t *connect_args)
{
for (uint8_t trial = 0; trial < connect_args->trials; trial++) {
uint8_t slave_ready_flag;
RETURN_ON_ERROR(read_slave_reg(&slave_ready_flag, SLAVE_REGISTER_CMD,
sizeof(slave_ready_flag)));
if (slave_ready_flag != SLAVE_CMD_IDLE) {
loader_port_debug_print("Waiting for Slave to be idle...\n");
loader_port_delay_ms(100);
} else {
break;
}
}
const uint8_t reg_val = SLAVE_CMD_READY;
RETURN_ON_ERROR(write_slave_reg(&reg_val, SLAVE_REGISTER_CMD, sizeof(reg_val)));
for (uint8_t trial = 0; trial < connect_args->trials; trial++) {
uint8_t slave_ready_flag;
RETURN_ON_ERROR(read_slave_reg(&slave_ready_flag, SLAVE_REGISTER_CMD,
sizeof(slave_ready_flag)));
if (slave_ready_flag != SLAVE_CMD_READY) {
loader_port_debug_print("Waiting for Slave to be ready...\n");
loader_port_delay_ms(100);
} else {
break;
}
}
return ESP_LOADER_SUCCESS;
}
esp_loader_error_t send_cmd(const void *cmd_data, uint32_t size, uint32_t *reg_value)
{
command_t command = ((const command_common_t *)cmd_data)->command;
uint32_t buf_size;
bool slave_ready = false;
while (!slave_ready) {
RETURN_ON_ERROR(handle_slave_state(SLAVE_REGISTER_RXSTA, &s_slave_seq_rx, &slave_ready,
&buf_size));
}
if (size > buf_size) {
return ESP_LOADER_ERROR_INVALID_PARAM;
}
/* Start and write the command */
transaction_preamble_t preamble = {.cmd = TRANS_CMD_WRDMA};
loader_port_spi_set_cs(0);
RETURN_ON_ERROR(loader_port_write((const uint8_t *)&preamble, sizeof(preamble),
loader_port_remaining_time()));
RETURN_ON_ERROR(loader_port_write((const uint8_t *)cmd_data, size,
loader_port_remaining_time()));
loader_port_spi_set_cs(1);
/* Terminate the write */
loader_port_spi_set_cs(0);
preamble.cmd = TRANS_CMD_WR_DONE;
RETURN_ON_ERROR(loader_port_write((const uint8_t *)&preamble, sizeof(preamble),
loader_port_remaining_time()));
loader_port_spi_set_cs(1);
return check_response(command, reg_value);
}
esp_loader_error_t send_cmd_with_data(const void *cmd_data, size_t cmd_size,
const void *data, size_t data_size)
{
uint32_t buf_size;
bool slave_ready = false;
while (!slave_ready) {
RETURN_ON_ERROR(handle_slave_state(SLAVE_REGISTER_RXSTA, &s_slave_seq_rx, &slave_ready,
&buf_size));
}
if (cmd_size + data_size > buf_size) {
return ESP_LOADER_ERROR_INVALID_PARAM;
}
/* Start and write the command and the data */
transaction_preamble_t preamble = {.cmd = TRANS_CMD_WRDMA};
loader_port_spi_set_cs(0);
RETURN_ON_ERROR(loader_port_write((const uint8_t *)&preamble, sizeof(preamble),
loader_port_remaining_time()));
RETURN_ON_ERROR(loader_port_write((const uint8_t *)cmd_data, cmd_size,
loader_port_remaining_time()));
RETURN_ON_ERROR(loader_port_write((const uint8_t *)data, data_size,
loader_port_remaining_time()));
loader_port_spi_set_cs(1);
/* Terminate the write */
loader_port_spi_set_cs(0);
preamble.cmd = TRANS_CMD_WR_DONE;
RETURN_ON_ERROR(loader_port_write((const uint8_t *)&preamble, sizeof(preamble),
loader_port_remaining_time()));
loader_port_spi_set_cs(1);
command_t command = ((const command_common_t *)cmd_data)->command;
return check_response(command, NULL);
}
static esp_loader_error_t read_slave_reg(uint8_t *out_data, const uint32_t addr,
const uint8_t size)
{
transaction_preamble_t preamble = {
.cmd = TRANS_CMD_RDBUF,
.addr = addr,
};
loader_port_spi_set_cs(0);
RETURN_ON_ERROR(loader_port_write((const uint8_t *)&preamble, sizeof(preamble),
loader_port_remaining_time()));
RETURN_ON_ERROR(loader_port_read(out_data, size, loader_port_remaining_time()));
loader_port_spi_set_cs(1);
return ESP_LOADER_SUCCESS;
}
static esp_loader_error_t write_slave_reg(const uint8_t *data, const uint32_t addr,
const uint8_t size)
{
transaction_preamble_t preamble = {
.cmd = TRANS_CMD_WRBUF,
.addr = addr,
};
loader_port_spi_set_cs(0);
RETURN_ON_ERROR(loader_port_write((const uint8_t *)&preamble, sizeof(preamble),
loader_port_remaining_time()));
RETURN_ON_ERROR(loader_port_write(data, size, loader_port_remaining_time()));
loader_port_spi_set_cs(1);
return ESP_LOADER_SUCCESS;
}
static esp_loader_error_t handle_slave_state(const uint32_t status_reg_addr, uint8_t *seq_state,
bool *slave_ready, uint32_t *buf_size)
{
uint32_t status_reg;
RETURN_ON_ERROR(read_slave_reg((uint8_t *)&status_reg, status_reg_addr,
sizeof(status_reg)));
const slave_state_t state = status_reg & (SLAVE_STA_TOGGLE_BIT | SLAVE_STA_INIT_BIT);
switch(state) {
case SLAVE_STATE_INIT: {
const uint32_t initial = 0U;
RETURN_ON_ERROR(write_slave_reg((uint8_t *)&initial, status_reg_addr, sizeof(initial)));
break;
}
case SLAVE_STATE_FIRST_PACKET: {
*seq_state = state & SLAVE_STA_TOGGLE_BIT;
*buf_size = status_reg >> SLAVE_STA_BUF_LENGTH_POS;
*slave_ready = true;
break;
}
default: {
const uint8_t new_seq = state & SLAVE_STA_TOGGLE_BIT;
if (new_seq != *seq_state) {
*seq_state = new_seq;
*buf_size = status_reg >> SLAVE_STA_BUF_LENGTH_POS;
*slave_ready = true;
}
break;
}
}
return ESP_LOADER_SUCCESS;
}
static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value)
{
response_t resp;
uint32_t buf_size;
bool slave_ready = false;
while (!slave_ready) {
RETURN_ON_ERROR(handle_slave_state(SLAVE_REGISTER_TXSTA, &s_slave_seq_tx, &slave_ready,
&buf_size));
}
if (sizeof(resp) > buf_size) {
return ESP_LOADER_ERROR_INVALID_PARAM;
}
transaction_preamble_t preamble = {
.cmd = TRANS_CMD_RDDMA,
};
loader_port_spi_set_cs(0);
RETURN_ON_ERROR(loader_port_write((const uint8_t *)&preamble, sizeof(preamble),
loader_port_remaining_time()));
RETURN_ON_ERROR(loader_port_read((uint8_t *)&resp, sizeof(resp),
loader_port_remaining_time()));
loader_port_spi_set_cs(1);
/* Terminate the read */
loader_port_spi_set_cs(0);
preamble.cmd = TRANS_CMD_CMD8;
RETURN_ON_ERROR(loader_port_write((const uint8_t *)&preamble, sizeof(preamble),
loader_port_remaining_time()));
loader_port_spi_set_cs(1);
common_response_t *common = (common_response_t *)&resp;
if ((common->direction != READ_DIRECTION) || (common->command != cmd)) {
return ESP_LOADER_ERROR_INVALID_RESPONSE;
}
response_status_t *status =
(response_status_t *)((uint8_t *)&resp + sizeof(resp) - sizeof(response_status_t));
if (status->failed) {
log_loader_internal_error(status->error);
return ESP_LOADER_ERROR_INVALID_RESPONSE;
}
if (reg_value != NULL) {
*reg_value = common->value;
}
return ESP_LOADER_SUCCESS;
}

View File

@@ -0,0 +1,114 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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.
*/
#include "protocol.h"
#include "protocol_prv.h"
#include "esp_loader_io.h"
#include "slip.h"
#include <stddef.h>
#include <string.h>
static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value, void* resp, uint32_t resp_size);
esp_loader_error_t loader_initialize_conn(esp_loader_connect_args_t *connect_args) {
esp_loader_error_t err;
int32_t trials = connect_args->trials;
do {
loader_port_start_timer(connect_args->sync_timeout);
err = loader_sync_cmd();
if (err == ESP_LOADER_ERROR_TIMEOUT) {
if (--trials == 0) {
return ESP_LOADER_ERROR_TIMEOUT;
}
loader_port_delay_ms(100);
} else if (err != ESP_LOADER_SUCCESS) {
return err;
}
} while (err != ESP_LOADER_SUCCESS);
return err;
}
esp_loader_error_t send_cmd(const void *cmd_data, uint32_t size, uint32_t *reg_value)
{
response_t response;
command_t command = ((const command_common_t *)cmd_data)->command;
RETURN_ON_ERROR( SLIP_send_delimiter() );
RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, size) );
RETURN_ON_ERROR( SLIP_send_delimiter() );
return check_response(command, reg_value, &response, sizeof(response));
}
esp_loader_error_t send_cmd_with_data(const void *cmd_data, size_t cmd_size,
const void *data, size_t data_size)
{
response_t response;
command_t command = ((const command_common_t *)cmd_data)->command;
RETURN_ON_ERROR( SLIP_send_delimiter() );
RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, cmd_size) );
RETURN_ON_ERROR( SLIP_send(data, data_size) );
RETURN_ON_ERROR( SLIP_send_delimiter() );
return check_response(command, NULL, &response, sizeof(response));
}
esp_loader_error_t send_cmd_md5(const void *cmd_data, size_t cmd_size, uint8_t md5_out[MD5_SIZE])
{
rom_md5_response_t response;
command_t command = ((const command_common_t *)cmd_data)->command;
RETURN_ON_ERROR( SLIP_send_delimiter() );
RETURN_ON_ERROR( SLIP_send((const uint8_t *)cmd_data, cmd_size) );
RETURN_ON_ERROR( SLIP_send_delimiter() );
RETURN_ON_ERROR( check_response(command, NULL, &response, sizeof(response)) );
memcpy(md5_out, response.md5, MD5_SIZE);
return ESP_LOADER_SUCCESS;
}
static esp_loader_error_t check_response(command_t cmd, uint32_t *reg_value, void* resp, uint32_t resp_size)
{
esp_loader_error_t err;
common_response_t *response = (common_response_t *)resp;
do {
err = SLIP_receive_packet(resp, resp_size);
if (err != ESP_LOADER_SUCCESS) {
return err;
}
} while ((response->direction != READ_DIRECTION) || (response->command != cmd));
response_status_t *status = (response_status_t *)((uint8_t *)resp + resp_size - sizeof(response_status_t));
if (status->failed) {
log_loader_internal_error(status->error);
return ESP_LOADER_ERROR_INVALID_RESPONSE;
}
if (reg_value != NULL) {
*reg_value = response->value;
}
return ESP_LOADER_SUCCESS;
}

View File

@@ -0,0 +1,125 @@
/* Copyright 2020-2023 Espressif Systems (Shanghai) CO 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.
*/
#include "slip.h"
#include "esp_loader_io.h"
static const uint8_t DELIMITER = 0xC0;
static const uint8_t C0_REPLACEMENT[2] = {0xDB, 0xDC};
static const uint8_t DB_REPLACEMENT[2] = {0xDB, 0xDD};
static inline esp_loader_error_t peripheral_read(uint8_t *buff, const size_t size)
{
return loader_port_read(buff, size, loader_port_remaining_time());
}
static inline esp_loader_error_t peripheral_write(const uint8_t *buff, const size_t size)
{
return loader_port_write(buff, size, loader_port_remaining_time());
}
esp_loader_error_t SLIP_receive_data(uint8_t *buff, const size_t size)
{
uint8_t ch;
for (uint32_t i = 0; i < size; i++) {
RETURN_ON_ERROR( peripheral_read(&ch, 1) );
if (ch == 0xDB) {
RETURN_ON_ERROR( peripheral_read(&ch, 1) );
if (ch == 0xDC) {
buff[i] = 0xC0;
} else if (ch == 0xDD) {
buff[i] = 0xDB;
} else {
return ESP_LOADER_ERROR_INVALID_RESPONSE;
}
} else {
buff[i] = ch;
}
}
return ESP_LOADER_SUCCESS;
}
esp_loader_error_t SLIP_receive_packet(uint8_t *buff, const size_t size)
{
uint8_t ch;
// Wait for delimiter
do {
RETURN_ON_ERROR( peripheral_read(&ch, 1) );
} while (ch != DELIMITER);
// Workaround: bootloader sends two dummy(0xC0) bytes after response when baud rate is changed.
do {
RETURN_ON_ERROR( peripheral_read(&ch, 1) );
} while (ch == DELIMITER);
buff[0] = ch;
RETURN_ON_ERROR( SLIP_receive_data(&buff[1], size - 1) );
// Wait for delimiter
do {
RETURN_ON_ERROR( peripheral_read(&ch, 1) );
} while (ch != DELIMITER);
return ESP_LOADER_SUCCESS;
}
esp_loader_error_t SLIP_send(const uint8_t *data, const size_t size)
{
uint32_t to_write = 0; // Bytes ready to write as they are
uint32_t written = 0; // Bytes already written
for (uint32_t i = 0; i < size; i++) {
if (data[i] != 0xC0 && data[i] != 0xDB) {
to_write++; // Queue this byte for writing
continue;
}
// We have a byte that needs encoding, write the queue first
if (to_write > 0) {
RETURN_ON_ERROR( peripheral_write(&data[written], to_write) );
}
// Write the encoded byte
if (data[i] == 0xC0) {
RETURN_ON_ERROR( peripheral_write(C0_REPLACEMENT, 2) );
} else {
RETURN_ON_ERROR( peripheral_write(DB_REPLACEMENT, 2) );
}
// Update to start again after the encoded byte
written = i + 1;
to_write = 0;
}
// Write the rest of the bytes that didn't need encoding
if (to_write > 0) {
RETURN_ON_ERROR( peripheral_write(&data[written], to_write) );
}
return ESP_LOADER_SUCCESS;
}
esp_loader_error_t SLIP_send_delimiter(void)
{
return peripheral_write(&DELIMITER, 1);
}

View File

@@ -0,0 +1,20 @@
cmake_minimum_required(VERSION 3.13)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/stm32-cmake/cmake/gcc_stm32.cmake)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/stm32-cmake/cmake)
find_package(CMSIS REQUIRED)
find_package(STM32HAL COMPONENTS gpio tim uart REQUIRED)
add_library(stm_cube_impl ${CMSIS_SOURCES} ${STM32HAL_SOURCES})
target_include_directories(stm_cube_impl PUBLIC ${CMSIS_INCLUDE_DIRS} ${STM32HAL_INCLUDE_DIR})
stm32_set_target_properties(stm_cube_impl)
# stm_cube target is made to propagate properties of stm_cube_impl, as stm32_set_target_properties
# sets properties privately for given target. This eliminates need to call stm32_set_target_properties
# on every target that links against STM32HAL.
add_library(stm_cube INTERFACE)
target_link_libraries(stm_cube INTERFACE stm_cube_impl)
target_compile_definitions(stm_cube INTERFACE $<TARGET_PROPERTY:stm_cube_impl,COMPILE_DEFINITIONS>)
target_link_options(stm_cube INTERFACE -T${CMAKE_CURRENT_BINARY_DIR}/stm_cube_impl_flash.ld)

View File

@@ -0,0 +1,30 @@
cmake_minimum_required(VERSION 3.5)
if (CONFIG_ESP_SERIAL_FLASHER)
zephyr_include_directories(
"${ZEPHYR_CURRENT_MODULE_DIR}/include"
"${ZEPHYR_CURRENT_MODULE_DIR}/port"
"${ZEPHYR_CURRENT_MODULE_DIR}/private_include"
)
zephyr_interface_library_named(esp_flasher)
zephyr_library()
zephyr_library_sources(${ZEPHYR_CURRENT_MODULE_DIR}/src/esp_loader.c
${ZEPHYR_CURRENT_MODULE_DIR}/src/esp_targets.c
${ZEPHYR_CURRENT_MODULE_DIR}/src/protocol_common.c
${ZEPHYR_CURRENT_MODULE_DIR}/src/protocol_uart.c
${ZEPHYR_CURRENT_MODULE_DIR}/src/slip.c
${ZEPHYR_CURRENT_MODULE_DIR}/src/md5_hash.c
${ZEPHYR_CURRENT_MODULE_DIR}/port/zephyr_port.c
)
target_compile_definitions(esp_flasher INTERFACE SERIAL_FLASHER_INTERFACE_UART)
zephyr_library_link_libraries(esp_flasher)
if(DEFINED MD5_ENABLED OR CONFIG_SERIAL_FLASHER_MD5_ENABLED)
target_compile_definitions(esp_flasher INTERFACE -DMD5_ENABLED=1)
endif()
endif()

View File

@@ -0,0 +1,16 @@
config ESP_SERIAL_FLASHER
bool "Enable ESP serial flasher library"
default y
select CONSOLE_SUBSYS
help
Select this option to enable the ESP serial flasher library.
config ESP_SERIAL_FLASHER_UART_BUFSIZE
int "ESP Serial Flasher UART buffer size"
default 512
help
Buffer size for UART TX and RX packets
if ESP_SERIAL_FLASHER
rsource "../Kconfig"
endif

View File

@@ -0,0 +1,5 @@
name: esp-flasher
build:
cmake: zephyr
kconfig: zephyr/Kconfig

View File

@@ -0,0 +1,30 @@
#include "esp_flasher_scene.h"
// Generate scene on_enter handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
void (*const esp_flasher_scene_on_enter_handlers[])(void*) = {
#include "esp_flasher_scene_config.h"
};
#undef ADD_SCENE
// Generate scene on_event handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
bool (*const esp_flasher_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
#include "esp_flasher_scene_config.h"
};
#undef ADD_SCENE
// Generate scene on_exit handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
void (*const esp_flasher_scene_on_exit_handlers[])(void* context) = {
#include "esp_flasher_scene_config.h"
};
#undef ADD_SCENE
// Initialize scene handlers configuration structure
const SceneManagerHandlers esp_flasher_scene_handlers = {
.on_enter_handlers = esp_flasher_scene_on_enter_handlers,
.on_event_handlers = esp_flasher_scene_on_event_handlers,
.on_exit_handlers = esp_flasher_scene_on_exit_handlers,
.scene_num = EspFlasherSceneNum,
};

View File

@@ -0,0 +1,29 @@
#pragma once
#include <gui/scene_manager.h>
// Generate scene id and total number
#define ADD_SCENE(prefix, name, id) EspFlasherScene##id,
typedef enum {
#include "esp_flasher_scene_config.h"
EspFlasherSceneNum,
} EspFlasherScene;
#undef ADD_SCENE
extern const SceneManagerHandlers esp_flasher_scene_handlers;
// Generate scene on_enter handlers declaration
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
#include "esp_flasher_scene_config.h"
#undef ADD_SCENE
// Generate scene on_event handlers declaration
#define ADD_SCENE(prefix, name, id) \
bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
#include "esp_flasher_scene_config.h"
#undef ADD_SCENE
// Generate scene on_exit handlers declaration
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
#include "esp_flasher_scene_config.h"
#undef ADD_SCENE

View File

@@ -0,0 +1,56 @@
#include "../esp_flasher_app_i.h"
void esp_flasher_scene_about_widget_callback(GuiButtonType result, InputType type, void* context) {
EspFlasherApp* app = context;
if(type == InputTypeShort) {
view_dispatcher_send_custom_event(app->view_dispatcher, result);
}
}
#define ESP_FLASHER_APP_DESCRIPTION \
"\e#Information\nVersion: " ESP_FLASHER_APP_VERSION \
"\nDeveloped by: 0xchocolate\n(@cococode on discord) using espressif's esp-serial-flasher library\nGithub: https://github.com/0xchocolate/flipperzero-esp-flasher\n\n\e#Description\nApp to flash ESP chips from\nthe flipper (over UART) using\nbin files on the sd card.\nReset the chip into bootloader\nmode before flashing.\n\n Supported targets:\n- ESP32\n- ESP8266\n- ESP32-S2\n- ESP32-S3\n- ESP32-C3\n- ESP32-C2\n- ESP32-H2"
void esp_flasher_scene_about_on_enter(void* context) {
EspFlasherApp* app = context;
widget_add_text_box_element(
app->widget,
0,
0,
128,
14,
AlignCenter,
AlignBottom,
"\e#\e! \e!\n",
false);
widget_add_text_box_element(
app->widget,
0,
2,
128,
14,
AlignCenter,
AlignBottom,
"\e#\e! ESP Flasher \e!\n",
false);
widget_add_text_scroll_element(app->widget, 0, 16, 128, 50, ESP_FLASHER_APP_DESCRIPTION);
view_dispatcher_switch_to_view(app->view_dispatcher, EspFlasherAppViewWidget);
}
bool esp_flasher_scene_about_on_event(void* context, SceneManagerEvent event) {
EspFlasherApp* app = context;
bool consumed = false;
UNUSED(app);
UNUSED(event);
return consumed;
}
void esp_flasher_scene_about_on_exit(void* context) {
EspFlasherApp* app = context;
// Clear views
widget_reset(app->widget);
}

View File

@@ -0,0 +1,266 @@
#include "../esp_flasher_app_i.h"
#include "../esp_flasher_worker.h"
enum SubmenuIndex {
SubmenuIndexS3Mode,
SubmenuIndexBoot,
SubmenuIndexPart,
SubmenuIndexNvs,
SubmenuIndexBootApp0,
SubmenuIndexApp,
SubmenuIndexCustom,
SubmenuIndexFlash,
};
static void esp_flasher_scene_browse_callback(void* context, uint32_t index) {
EspFlasherApp* app = context;
scene_manager_set_scene_state(app->scene_manager, EspFlasherSceneBrowse, index);
// browse for files
FuriString* predefined_filepath = furi_string_alloc_set_str(ESP_APP_FOLDER);
FuriString* selected_filepath = furi_string_alloc();
DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(&browser_options, ".bin", &I_Text_10x10);
// TODO refactor
switch(index) {
case SubmenuIndexS3Mode:
// toggle S3 mode
app->selected_flash_options[SelectedFlashS3Mode] =
!app->selected_flash_options[SelectedFlashS3Mode];
view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu);
break;
case SubmenuIndexBoot:
app->selected_flash_options[SelectedFlashBoot] =
!app->selected_flash_options[SelectedFlashBoot];
if(app->selected_flash_options[SelectedFlashBoot]) {
if(dialog_file_browser_show(
app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
strncpy(
app->bin_file_path_boot,
furi_string_get_cstr(selected_filepath),
sizeof(app->bin_file_path_boot));
}
}
if(app->bin_file_path_boot[0] == '\0') {
// if user didn't select a file, leave unselected
app->selected_flash_options[SelectedFlashBoot] = false;
}
view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu);
break;
case SubmenuIndexPart:
app->selected_flash_options[SelectedFlashPart] =
!app->selected_flash_options[SelectedFlashPart];
if(dialog_file_browser_show(
app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
strncpy(
app->bin_file_path_part,
furi_string_get_cstr(selected_filepath),
sizeof(app->bin_file_path_part));
}
if(app->bin_file_path_part[0] == '\0') {
// if user didn't select a file, leave unselected
app->selected_flash_options[SelectedFlashPart] = false;
}
view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu);
break;
case SubmenuIndexNvs:
app->selected_flash_options[SelectedFlashNvs] =
!app->selected_flash_options[SelectedFlashNvs];
if(dialog_file_browser_show(
app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
strncpy(
app->bin_file_path_nvs,
furi_string_get_cstr(selected_filepath),
sizeof(app->bin_file_path_nvs));
}
if(app->bin_file_path_nvs[0] == '\0') {
// if user didn't select a file, leave unselected
app->selected_flash_options[SelectedFlashNvs] = false;
}
view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu);
break;
case SubmenuIndexBootApp0:
app->selected_flash_options[SelectedFlashBootApp0] =
!app->selected_flash_options[SelectedFlashBootApp0];
if(dialog_file_browser_show(
app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
strncpy(
app->bin_file_path_boot_app0,
furi_string_get_cstr(selected_filepath),
sizeof(app->bin_file_path_boot_app0));
}
if(app->bin_file_path_boot_app0[0] == '\0') {
// if user didn't select a file, leave unselected
app->selected_flash_options[SelectedFlashBootApp0] = false;
}
view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu);
break;
case SubmenuIndexApp:
app->selected_flash_options[SelectedFlashApp] =
!app->selected_flash_options[SelectedFlashApp];
if(dialog_file_browser_show(
app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
strncpy(
app->bin_file_path_app,
furi_string_get_cstr(selected_filepath),
sizeof(app->bin_file_path_app));
}
if(app->bin_file_path_app[0] == '\0') {
// if user didn't select a file, leave unselected
app->selected_flash_options[SelectedFlashApp] = false;
}
view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu);
break;
case SubmenuIndexCustom:
app->selected_flash_options[SelectedFlashCustom] =
!app->selected_flash_options[SelectedFlashCustom];
if(dialog_file_browser_show(
app->dialogs, selected_filepath, predefined_filepath, &browser_options)) {
strncpy(
app->bin_file_path_custom,
furi_string_get_cstr(selected_filepath),
sizeof(app->bin_file_path_custom));
}
if(app->bin_file_path_custom[0] == '\0') {
// if user didn't select a file, leave unselected
app->selected_flash_options[SelectedFlashCustom] = false;
}
view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshSubmenu);
break;
case SubmenuIndexFlash:
// count how many options are selected
app->num_selected_flash_options = 0;
for(bool* option = &app->selected_flash_options[SelectedFlashBoot];
option < &app->selected_flash_options[NUM_FLASH_OPTIONS];
++option) {
if(*option) {
++app->num_selected_flash_options;
}
}
if(app->num_selected_flash_options) {
// only start next scene if at least one option is selected
scene_manager_next_scene(app->scene_manager, EspFlasherSceneConsoleOutput);
}
break;
}
furi_string_free(selected_filepath);
furi_string_free(predefined_filepath);
}
#define STR_SELECT "[x]"
#define STR_UNSELECT "[ ]"
#define STR_BOOT "Bootloader (" TOSTRING(ESP_ADDR_BOOT) ")"
#define STR_BOOT_S3 "Bootloader (" TOSTRING(ESP_ADDR_BOOT_S3) ")"
#define STR_PART "Part Table (" TOSTRING(ESP_ADDR_PART) ")"
#define STR_NVS "NVS (" TOSTRING(ESP_ADDR_NVS) ")"
#define STR_BOOT_APP0 "boot_app0 (" TOSTRING(ESP_ADDR_BOOT_APP0) ")"
#define STR_APP "Firmware (" TOSTRING(ESP_ADDR_APP) ")"
#define STR_CUSTOM "Custom"
#define STR_FLASH_S3 "[>] FLASH (ESP32-S3)"
#define STR_FLASH "[>] FLASH"
static void _refresh_submenu(EspFlasherApp* app) {
Submenu* submenu = app->submenu;
submenu_reset(app->submenu);
submenu_set_header(submenu, "Browse for files to flash");
submenu_add_item(
submenu,
app->selected_flash_options[SelectedFlashS3Mode] ? "[x] Using ESP32-S3" :
"[ ] Select if using S3",
SubmenuIndexS3Mode,
esp_flasher_scene_browse_callback,
app);
const char* strSelectBootloader = STR_UNSELECT " " STR_BOOT;
if(app->selected_flash_options[SelectedFlashS3Mode]) {
if(app->selected_flash_options[SelectedFlashBoot]) {
strSelectBootloader = STR_SELECT " " STR_BOOT_S3;
} else {
strSelectBootloader = STR_UNSELECT " " STR_BOOT_S3;
}
} else {
if(app->selected_flash_options[SelectedFlashBoot]) {
strSelectBootloader = STR_SELECT " " STR_BOOT;
} else {
strSelectBootloader = STR_UNSELECT " " STR_BOOT;
}
}
submenu_add_item(
submenu, strSelectBootloader, SubmenuIndexBoot, esp_flasher_scene_browse_callback, app);
submenu_add_item(
submenu,
app->selected_flash_options[SelectedFlashPart] ? STR_SELECT " " STR_PART :
STR_UNSELECT " " STR_PART,
SubmenuIndexPart,
esp_flasher_scene_browse_callback,
app);
submenu_add_item(
submenu,
app->selected_flash_options[SelectedFlashNvs] ? STR_SELECT " " STR_NVS :
STR_UNSELECT " " STR_NVS,
SubmenuIndexNvs,
esp_flasher_scene_browse_callback,
app);
submenu_add_item(
submenu,
app->selected_flash_options[SelectedFlashBootApp0] ? STR_SELECT " " STR_BOOT_APP0 :
STR_UNSELECT " " STR_BOOT_APP0,
SubmenuIndexBootApp0,
esp_flasher_scene_browse_callback,
app);
submenu_add_item(
submenu,
app->selected_flash_options[SelectedFlashApp] ? STR_SELECT " " STR_APP :
STR_UNSELECT " " STR_APP,
SubmenuIndexApp,
esp_flasher_scene_browse_callback,
app);
// TODO: custom addr
//submenu_add_item(
// submenu, app->selected_flash_options[SelectedFlashCustom] ? STR_SELECT " " STR_CUSTOM : STR_UNSELECT " " STR_CUSTOM, SubmenuIndexCustom, esp_flasher_scene_browse_callback, app);
submenu_add_item(
submenu,
app->selected_flash_options[SelectedFlashS3Mode] ? STR_FLASH_S3 : STR_FLASH,
SubmenuIndexFlash,
esp_flasher_scene_browse_callback,
app);
submenu_set_selected_item(
submenu, scene_manager_get_scene_state(app->scene_manager, EspFlasherSceneBrowse));
view_dispatcher_switch_to_view(app->view_dispatcher, EspFlasherAppViewSubmenu);
}
void esp_flasher_scene_browse_on_enter(void* context) {
EspFlasherApp* app = context;
memset(app->selected_flash_options, 0, sizeof(app->selected_flash_options));
app->bin_file_path_boot[0] = '\0';
app->bin_file_path_part[0] = '\0';
app->bin_file_path_nvs[0] = '\0';
app->bin_file_path_boot_app0[0] = '\0';
app->bin_file_path_app[0] = '\0';
app->bin_file_path_custom[0] = '\0';
_refresh_submenu(app);
}
bool esp_flasher_scene_browse_on_event(void* context, SceneManagerEvent event) {
EspFlasherApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == EspFlasherEventRefreshSubmenu) {
_refresh_submenu(app);
consumed = true;
}
}
return consumed;
}
void esp_flasher_scene_browse_on_exit(void* context) {
EspFlasherApp* app = context;
submenu_reset(app->submenu);
}

View File

@@ -0,0 +1,5 @@
ADD_SCENE(esp_flasher, start, Start)
ADD_SCENE(esp_flasher, devboard, Devboard)
ADD_SCENE(esp_flasher, console_output, ConsoleOutput)
ADD_SCENE(esp_flasher, about, About)
ADD_SCENE(esp_flasher, browse, Browse)

View File

@@ -0,0 +1,77 @@
#include "../esp_flasher_app_i.h"
#include "../esp_flasher_worker.h"
void esp_flasher_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
furi_assert(context);
EspFlasherApp* app = context;
// If text box store gets too big, then truncate it
app->text_box_store_strlen += len;
if(app->text_box_store_strlen >= ESP_FLASHER_TEXT_BOX_STORE_SIZE - 1) {
furi_string_right(app->text_box_store, app->text_box_store_strlen / 2);
app->text_box_store_strlen = furi_string_size(app->text_box_store) + len;
}
// Null-terminate buf and append to text box store
buf[len] = '\0';
furi_string_cat_printf(app->text_box_store, "%s", buf);
view_dispatcher_send_custom_event(app->view_dispatcher, EspFlasherEventRefreshConsoleOutput);
}
void esp_flasher_scene_console_output_on_enter(void* context) {
EspFlasherApp* app = context;
// Reset text box and set font
TextBox* text_box = app->text_box;
text_box_reset(text_box);
text_box_set_font(text_box, TextBoxFontText);
// Set focus on end
text_box_set_focus(text_box, TextBoxFocusEnd);
// Set starting text
text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
// Set scene state and switch view
scene_manager_set_scene_state(app->scene_manager, EspFlasherSceneConsoleOutput, 0);
view_dispatcher_switch_to_view(app->view_dispatcher, EspFlasherAppViewConsoleOutput);
// Register callbacks to receive data
// setup callback for general log rx thread
esp_flasher_uart_set_handle_rx_data_cb(
app->uart,
esp_flasher_worker_handle_rx_data_cb); // setup callback for general log rx thread
// Start flash worker
esp_flasher_worker_start_thread(app);
}
bool esp_flasher_scene_console_output_on_event(void* context, SceneManagerEvent event) {
EspFlasherApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
consumed = true;
} else if(event.type == SceneManagerEventTypeTick) {
consumed = true;
} else {
if(app->flash_worker_busy) {
// ignore button presses while flashing
consumed = true;
}
}
return consumed;
}
void esp_flasher_scene_console_output_on_exit(void* context) {
EspFlasherApp* app = context;
esp_flasher_worker_stop_thread(app);
// Unregister rx callback
esp_flasher_uart_set_handle_rx_data_cb(app->uart, NULL);
}

View File

@@ -0,0 +1,86 @@
#include "../esp_flasher_app_i.h"
enum SubmenuIndex {
SubmenuIndexBlackMagic,
SubmenuIndexEvilPortal,
SubmenuIndexMarauder,
};
void esp_flasher_scene_devboard_submenu_callback(void* context, uint32_t index) {
furi_assert(context);
EspFlasherApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, index);
}
void esp_flasher_scene_devboard_on_enter(void* context) {
furi_assert(context);
EspFlasherApp* app = context;
Submenu* submenu = app->submenu;
submenu_set_header(submenu, "Select Firmware to flash");
submenu_add_item(
submenu,
"Black Magic",
SubmenuIndexBlackMagic,
esp_flasher_scene_devboard_submenu_callback,
app);
submenu_add_item(
submenu,
"Evil Portal",
SubmenuIndexEvilPortal,
esp_flasher_scene_devboard_submenu_callback,
app);
submenu_add_item(
submenu,
"Marauder",
SubmenuIndexMarauder,
esp_flasher_scene_devboard_submenu_callback,
app);
submenu_set_selected_item(
submenu, scene_manager_get_scene_state(app->scene_manager, EspFlasherSceneDevboard));
view_dispatcher_switch_to_view(app->view_dispatcher, EspFlasherAppViewSubmenu);
}
bool esp_flasher_scene_devboard_on_event(void* context, SceneManagerEvent event) {
furi_assert(context);
EspFlasherApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
const char* path = NULL;
consumed = true;
switch(event.event) {
case SubmenuIndexBlackMagic:
path = APP_DATA_PATH("Black_Magic.bin");
break;
case SubmenuIndexEvilPortal:
path = APP_DATA_PATH("Evil_Portal.bin");
break;
case SubmenuIndexMarauder:
path = APP_DATA_PATH("Marauder.bin");
break;
default:
consumed = false;
break;
}
if(consumed) {
app->selected_flash_options[SelectedFlashBoot] = true;
strncpy(app->bin_file_path_boot, path, sizeof(app->bin_file_path_boot));
scene_manager_next_scene(app->scene_manager, EspFlasherSceneConsoleOutput);
}
scene_manager_set_scene_state(app->scene_manager, EspFlasherSceneDevboard, event.event);
}
return consumed;
}
void esp_flasher_scene_devboard_on_exit(void* context) {
furi_assert(context);
EspFlasherApp* app = context;
submenu_reset(app->submenu);
}

View File

@@ -0,0 +1,73 @@
#include "../esp_flasher_app_i.h"
enum SubmenuIndex {
SubmenuIndexEspFlasherDevboardFlash,
SubmenuIndexEspFlasherFlash,
SubmenuIndexEspFlasherAbout,
};
void esp_flasher_scene_start_submenu_callback(void* context, uint32_t index) {
furi_assert(context);
EspFlasherApp* app = context;
view_dispatcher_send_custom_event(app->view_dispatcher, index);
}
void esp_flasher_scene_start_on_enter(void* context) {
furi_assert(context);
EspFlasherApp* app = context;
Submenu* submenu = app->submenu;
submenu_add_item(
submenu,
"Flash Wifi Devboard",
SubmenuIndexEspFlasherDevboardFlash,
esp_flasher_scene_start_submenu_callback,
app);
submenu_add_item(
submenu,
"Flash Generic ESP",
SubmenuIndexEspFlasherFlash,
esp_flasher_scene_start_submenu_callback,
app);
submenu_add_item(
submenu,
"About",
SubmenuIndexEspFlasherAbout,
esp_flasher_scene_start_submenu_callback,
app);
submenu_set_selected_item(
submenu, scene_manager_get_scene_state(app->scene_manager, EspFlasherSceneStart));
view_dispatcher_switch_to_view(app->view_dispatcher, EspFlasherAppViewSubmenu);
}
bool esp_flasher_scene_start_on_event(void* context, SceneManagerEvent event) {
furi_assert(context);
EspFlasherApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == SubmenuIndexEspFlasherDevboardFlash) {
scene_manager_next_scene(app->scene_manager, EspFlasherSceneDevboard);
consumed = true;
} else if(event.event == SubmenuIndexEspFlasherFlash) {
scene_manager_next_scene(app->scene_manager, EspFlasherSceneBrowse);
consumed = true;
} else if(event.event == SubmenuIndexEspFlasherAbout) {
scene_manager_next_scene(app->scene_manager, EspFlasherSceneAbout);
consumed = true;
}
scene_manager_set_scene_state(app->scene_manager, EspFlasherSceneStart, event.event);
}
return consumed;
}
void esp_flasher_scene_start_on_exit(void* context) {
furi_assert(context);
EspFlasherApp* app = context;
submenu_reset(app->submenu);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,12 @@
App(
appid="evil_portal",
name="[ESP32] Evil Portal",
apptype=FlipperAppType.EXTERNAL,
entry_point="evil_portal_app",
cdefines=["APP_EVIL_PORTAL"],
requires=["gui"],
stack_size=1 * 1024,
order=90,
fap_icon="icons/evil_portal_10px.png",
fap_category="WiFi",
)

View File

@@ -0,0 +1,117 @@
#include "evil_portal_app_i.h"
#include "helpers/evil_portal_storage.h"
#include <furi.h>
#include <furi_hal.h>
static bool evil_portal_app_custom_event_callback(void* context, uint32_t event) {
furi_assert(context);
Evil_PortalApp* app = context;
return scene_manager_handle_custom_event(app->scene_manager, event);
}
static bool evil_portal_app_back_event_callback(void* context) {
furi_assert(context);
Evil_PortalApp* app = context;
return scene_manager_handle_back_event(app->scene_manager);
}
static void evil_portal_app_tick_event_callback(void* context) {
furi_assert(context);
Evil_PortalApp* app = context;
scene_manager_handle_tick_event(app->scene_manager);
}
Evil_PortalApp* evil_portal_app_alloc() {
Evil_PortalApp* app = malloc(sizeof(Evil_PortalApp));
app->sent_html = false;
app->sent_ap = false;
app->sent_reset = false;
app->has_command_queue = false;
app->command_index = 0;
app->portal_logs = furi_string_alloc();
app->gui = furi_record_open(RECORD_GUI);
app->dialogs = furi_record_open(RECORD_DIALOGS);
app->view_dispatcher = view_dispatcher_alloc();
app->scene_manager = scene_manager_alloc(&evil_portal_scene_handlers, app);
view_dispatcher_enable_queue(app->view_dispatcher);
view_dispatcher_set_event_callback_context(app->view_dispatcher, app);
view_dispatcher_set_custom_event_callback(
app->view_dispatcher, evil_portal_app_custom_event_callback);
view_dispatcher_set_navigation_event_callback(
app->view_dispatcher, evil_portal_app_back_event_callback);
view_dispatcher_set_tick_event_callback(
app->view_dispatcher, evil_portal_app_tick_event_callback, 100);
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
app->var_item_list = variable_item_list_alloc();
view_dispatcher_add_view(
app->view_dispatcher,
Evil_PortalAppViewVarItemList,
variable_item_list_get_view(app->var_item_list));
for(int i = 0; i < NUM_MENU_ITEMS; ++i) {
app->selected_option_index[i] = 0;
}
app->text_box = text_box_alloc();
view_dispatcher_add_view(
app->view_dispatcher, Evil_PortalAppViewConsoleOutput, text_box_get_view(app->text_box));
app->text_box_store = furi_string_alloc();
furi_string_reserve(app->text_box_store, EVIL_PORTAL_TEXT_BOX_STORE_SIZE);
scene_manager_next_scene(app->scene_manager, Evil_PortalSceneStart);
return app;
}
void evil_portal_app_free(Evil_PortalApp* app) {
// save latest logs
if(furi_string_utf8_length(app->portal_logs) > 0) {
write_logs(app->portal_logs);
furi_string_free(app->portal_logs);
}
// Send reset event to dev board
evil_portal_uart_tx((uint8_t*)(RESET_CMD), strlen(RESET_CMD));
evil_portal_uart_tx((uint8_t*)("\n"), 1);
furi_assert(app);
// Views
view_dispatcher_remove_view(app->view_dispatcher, Evil_PortalAppViewVarItemList);
view_dispatcher_remove_view(app->view_dispatcher, Evil_PortalAppViewConsoleOutput);
text_box_free(app->text_box);
furi_string_free(app->text_box_store);
// View dispatcher
view_dispatcher_free(app->view_dispatcher);
scene_manager_free(app->scene_manager);
evil_portal_uart_free(app->uart);
// Close records
furi_record_close(RECORD_GUI);
furi_record_close(RECORD_DIALOGS);
free(app);
}
int32_t evil_portal_app(void* p) {
UNUSED(p);
Evil_PortalApp* evil_portal_app = evil_portal_app_alloc();
evil_portal_app->uart = evil_portal_uart_init(evil_portal_app);
view_dispatcher_run(evil_portal_app->view_dispatcher);
evil_portal_app_free(evil_portal_app);
return 0;
}

View File

@@ -0,0 +1,11 @@
#pragma once
#ifdef __cplusplus
extern "C" {
#endif
typedef struct Evil_PortalApp Evil_PortalApp;
#ifdef __cplusplus
}
#endif

View File

@@ -0,0 +1,67 @@
#pragma once
#include "evil_portal_app.h"
#include "evil_portal_custom_event.h"
#include "evil_portal_uart.h"
#include "scenes/evil_portal_scene.h"
#include <gui/gui.h>
#include <gui/modules/text_box.h>
#include <gui/modules/variable_item_list.h>
#include <gui/scene_manager.h>
#include <gui/view_dispatcher.h>
#include <assets_icons.h>
#include <dialogs/dialogs.h>
#define NUM_MENU_ITEMS (4)
#define EVIL_PORTAL_TEXT_BOX_STORE_SIZE (4096)
#define UART_CH (FuriHalUartIdUSART1)
#define SET_HTML_CMD "sethtml"
#define SET_AP_CMD "setap"
#define RESET_CMD "reset"
#define EVIL_PORTAL_INDEX_EXTENSION ".html"
#define EVIL_PORTAL_BASE_FOLDER STORAGE_APP_DATA_PATH_PREFIX
struct Evil_PortalApp {
Gui* gui;
ViewDispatcher* view_dispatcher;
SceneManager* scene_manager;
DialogsApp* dialogs;
FuriString* portal_logs;
const char* command_queue[1];
int command_index;
bool has_command_queue;
FuriString* text_box_store;
size_t text_box_store_strlen;
TextBox* text_box;
VariableItemList* var_item_list;
Evil_PortalUart* uart;
int selected_menu_index;
int selected_option_index[NUM_MENU_ITEMS];
const char* selected_tx_string;
bool is_command;
bool is_custom_tx_string;
bool focus_console_start;
bool show_stopscan_tip;
bool sent_ap;
bool sent_html;
bool sent_reset;
int BAUDRATE;
uint8_t* index_html;
uint8_t* ap_name;
};
typedef enum {
Evil_PortalAppViewVarItemList,
Evil_PortalAppViewConsoleOutput,
Evil_PortalAppViewStartPortal,
} Evil_PortalAppView;

View File

@@ -0,0 +1,8 @@
#pragma once
typedef enum {
Evil_PortalEventRefreshConsoleOutput = 0,
Evil_PortalEventStartConsole,
Evil_PortalEventStartKeyboard,
Evil_PortalEventStartPortal,
} Evil_PortalCustomEvent;

View File

@@ -0,0 +1,145 @@
#include "evil_portal_app_i.h"
#include "evil_portal_uart.h"
#include "helpers/evil_portal_storage.h"
struct Evil_PortalUart {
Evil_PortalApp* app;
FuriThread* rx_thread;
FuriStreamBuffer* rx_stream;
uint8_t rx_buf[RX_BUF_SIZE + 1];
void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context);
};
typedef enum {
WorkerEvtStop = (1 << 0),
WorkerEvtRxDone = (1 << 1),
} WorkerEvtFlags;
void evil_portal_uart_set_handle_rx_data_cb(
Evil_PortalUart* uart,
void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context)) {
furi_assert(uart);
uart->handle_rx_data_cb = handle_rx_data_cb;
}
#define WORKER_ALL_RX_EVENTS (WorkerEvtStop | WorkerEvtRxDone)
void evil_portal_uart_on_irq_cb(UartIrqEvent ev, uint8_t data, void* context) {
Evil_PortalUart* uart = (Evil_PortalUart*)context;
if(ev == UartIrqEventRXNE) {
furi_stream_buffer_send(uart->rx_stream, &data, 1, 0);
furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtRxDone);
}
}
static int32_t uart_worker(void* context) {
Evil_PortalUart* uart = (void*)context;
while(1) {
uint32_t events =
furi_thread_flags_wait(WORKER_ALL_RX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
furi_check((events & FuriFlagError) == 0);
if(events & WorkerEvtStop) break;
if(events & WorkerEvtRxDone) {
size_t len = furi_stream_buffer_receive(uart->rx_stream, uart->rx_buf, RX_BUF_SIZE, 0);
if(len > 0) {
if(uart->handle_rx_data_cb) {
uart->handle_rx_data_cb(uart->rx_buf, len, uart->app);
if(uart->app->has_command_queue) {
if(uart->app->command_index < 1) {
if(0 == strncmp(
SET_AP_CMD,
uart->app->command_queue[uart->app->command_index],
strlen(SET_AP_CMD))) {
FuriString* out_data = furi_string_alloc();
furi_string_cat(out_data, "setap=");
furi_string_cat(out_data, (char*)uart->app->ap_name);
evil_portal_uart_tx(
(uint8_t*)(furi_string_get_cstr(out_data)),
strlen(furi_string_get_cstr(out_data)));
evil_portal_uart_tx((uint8_t*)("\n"), 1);
uart->app->sent_ap = true;
free(out_data);
free(uart->app->ap_name);
}
uart->app->command_index = 0;
uart->app->has_command_queue = false;
uart->app->command_queue[0] = "";
}
}
if(uart->app->sent_reset == false) {
furi_string_cat(uart->app->portal_logs, (char*)uart->rx_buf);
}
if(furi_string_utf8_length(uart->app->portal_logs) > 4000) {
write_logs(uart->app->portal_logs);
furi_string_reset(uart->app->portal_logs);
}
} else {
uart->rx_buf[len] = '\0';
if(uart->app->sent_reset == false) {
furi_string_cat(uart->app->portal_logs, (char*)uart->rx_buf);
}
if(furi_string_utf8_length(uart->app->portal_logs) > 4000) {
write_logs(uart->app->portal_logs);
furi_string_reset(uart->app->portal_logs);
}
}
}
}
}
furi_stream_buffer_free(uart->rx_stream);
return 0;
}
void evil_portal_uart_tx(uint8_t* data, size_t len) {
furi_hal_uart_tx(UART_CH, data, len);
}
Evil_PortalUart* evil_portal_uart_init(Evil_PortalApp* app) {
Evil_PortalUart* uart = malloc(sizeof(Evil_PortalUart));
uart->app = app;
// Init all rx stream and thread early to avoid crashes
uart->rx_stream = furi_stream_buffer_alloc(RX_BUF_SIZE, 1);
uart->rx_thread = furi_thread_alloc();
furi_thread_set_name(uart->rx_thread, "Evil_PortalUartRxThread");
furi_thread_set_stack_size(uart->rx_thread, 1024);
furi_thread_set_context(uart->rx_thread, uart);
furi_thread_set_callback(uart->rx_thread, uart_worker);
furi_thread_start(uart->rx_thread);
furi_hal_console_disable();
if(app->BAUDRATE == 0) {
app->BAUDRATE = 115200;
}
furi_hal_uart_set_br(UART_CH, app->BAUDRATE);
furi_hal_uart_set_irq_cb(UART_CH, evil_portal_uart_on_irq_cb, uart);
return uart;
}
void evil_portal_uart_free(Evil_PortalUart* uart) {
furi_assert(uart);
furi_thread_flags_set(furi_thread_get_id(uart->rx_thread), WorkerEvtStop);
furi_thread_join(uart->rx_thread);
furi_thread_free(uart->rx_thread);
furi_hal_uart_set_irq_cb(UART_CH, NULL, NULL);
furi_hal_console_enable();
free(uart);
}

View File

@@ -0,0 +1,14 @@
#pragma once
#include "furi_hal.h"
#define RX_BUF_SIZE (320)
typedef struct Evil_PortalUart Evil_PortalUart;
void evil_portal_uart_set_handle_rx_data_cb(
Evil_PortalUart* uart,
void (*handle_rx_data_cb)(uint8_t* buf, size_t len, void* context));
void evil_portal_uart_tx(uint8_t* data, size_t len);
Evil_PortalUart* evil_portal_uart_init(Evil_PortalApp* app);
void evil_portal_uart_free(Evil_PortalUart* uart);

View File

@@ -0,0 +1,135 @@
#include "evil_portal_storage.h"
static Storage* evil_portal_open_storage() {
return furi_record_open(RECORD_STORAGE);
}
static void evil_portal_close_storage() {
furi_record_close(RECORD_STORAGE);
}
bool evil_portal_read_index_html(void* context) {
FuriString* file_path = furi_string_alloc_set(EVIL_PORTAL_BASE_FOLDER);
DialogsFileBrowserOptions browser_options;
dialog_file_browser_set_basic_options(
&browser_options,
EVIL_PORTAL_INDEX_EXTENSION,
NULL); // TODO configure icon
browser_options.base_path = EVIL_PORTAL_BASE_FOLDER;
Evil_PortalApp* app = context;
bool res = dialog_file_browser_show(app->dialogs, file_path, file_path, &browser_options);
if(!res) {
furi_string_free(file_path);
return false;
}
Storage* storage = evil_portal_open_storage();
FileInfo fi;
if(storage_common_stat(storage, furi_string_get_cstr(file_path), &fi) == FSE_OK) {
File* index_html = storage_file_alloc(storage);
if(storage_file_open(
index_html, furi_string_get_cstr(file_path), FSAM_READ, FSOM_OPEN_EXISTING)) {
app->index_html = malloc((size_t)fi.size);
uint8_t* buf_ptr = app->index_html;
size_t read = 0;
while(read < fi.size) {
size_t to_read = fi.size - read;
if(to_read > UINT16_MAX) to_read = UINT16_MAX;
uint16_t now_read = storage_file_read(index_html, buf_ptr, (uint16_t)to_read);
read += now_read;
buf_ptr += now_read;
}
free(buf_ptr);
}
furi_string_free(file_path);
storage_file_close(index_html);
storage_file_free(index_html);
} else {
char* html_error = "<b>Evil portal</b><br>Unable to read the html file.<br>"
"Is the SD Card set up correctly? <br>See instructions @ "
"github.com/bigbrodude6119/flipper-zero-evil-portal<br>"
"Under the 'Install pre-built app on the flipper' section.";
app->index_html = (uint8_t*)html_error;
}
evil_portal_close_storage();
return true;
}
void evil_portal_read_ap_name(void* context) {
Evil_PortalApp* app = context;
Storage* storage = evil_portal_open_storage();
FileInfo fi;
if(storage_common_stat(storage, EVIL_PORTAL_AP_SAVE_PATH, &fi) == FSE_OK) {
File* ap_name = storage_file_alloc(storage);
if(storage_file_open(ap_name, EVIL_PORTAL_AP_SAVE_PATH, FSAM_READ, FSOM_OPEN_EXISTING)) {
app->ap_name = malloc((size_t)fi.size);
uint8_t* buf_ptr = app->ap_name;
size_t read = 0;
while(read < fi.size) {
size_t to_read = fi.size - read;
if(to_read > UINT16_MAX) to_read = UINT16_MAX;
uint16_t now_read = storage_file_read(ap_name, buf_ptr, (uint16_t)to_read);
read += now_read;
buf_ptr += now_read;
}
free(buf_ptr);
}
storage_file_close(ap_name);
storage_file_free(ap_name);
} else {
char* app_default = "Evil Portal";
app->ap_name = (uint8_t*)app_default;
}
evil_portal_close_storage();
}
char* sequential_file_resolve_path(
Storage* storage,
const char* dir,
const char* prefix,
const char* extension) {
if(storage == NULL || dir == NULL || prefix == NULL || extension == NULL) {
return NULL;
}
char file_path[256];
int file_index = 0;
do {
if(snprintf(
file_path, sizeof(file_path), "%s/%s_%d.%s", dir, prefix, file_index, extension) <
0) {
return NULL;
}
file_index++;
} while(storage_file_exists(storage, file_path));
return strdup(file_path);
}
void write_logs(FuriString* portal_logs) {
Storage* storage = evil_portal_open_storage();
if(!storage_file_exists(storage, EVIL_PORTAL_LOG_SAVE_PATH)) {
storage_simply_mkdir(storage, EVIL_PORTAL_LOG_SAVE_PATH);
}
char* seq_file_path =
sequential_file_resolve_path(storage, EVIL_PORTAL_LOG_SAVE_PATH, "log", "txt");
File* file = storage_file_alloc(storage);
if(storage_file_open(file, seq_file_path, FSAM_WRITE, FSOM_CREATE_ALWAYS)) {
storage_file_write(
file, furi_string_get_cstr(portal_logs), furi_string_utf8_length(portal_logs));
}
storage_file_close(file);
storage_file_free(file);
evil_portal_close_storage();
}

View File

@@ -0,0 +1,21 @@
#include "../evil_portal_app_i.h"
#include <dialogs/dialogs.h>
#include <flipper_format/flipper_format_i.h>
#include <lib/toolbox/stream/file_stream.h>
#include <stdlib.h>
#include <storage/storage.h>
#include <string.h>
#define PORTAL_FILE_DIRECTORY_PATH EXT_PATH("apps_data/evil_portal")
#define EVIL_PORTAL_INDEX_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/index.html"
#define EVIL_PORTAL_AP_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/ap.config.txt"
#define EVIL_PORTAL_LOG_SAVE_PATH PORTAL_FILE_DIRECTORY_PATH "/logs"
bool evil_portal_read_index_html(void* context);
void evil_portal_read_ap_name(void* context);
void write_logs(FuriString* portal_logs);
char* sequential_file_resolve_path(
Storage* storage,
const char* dir,
const char* prefix,
const char* extension);

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1,30 @@
#include "evil_portal_scene.h"
// Generate scene on_enter handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_enter,
void (*const evil_portal_scene_on_enter_handlers[])(void*) = {
#include "evil_portal_scene_config.h"
};
#undef ADD_SCENE
// Generate scene on_event handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_event,
bool (*const evil_portal_scene_on_event_handlers[])(void* context, SceneManagerEvent event) = {
#include "evil_portal_scene_config.h"
};
#undef ADD_SCENE
// Generate scene on_exit handlers array
#define ADD_SCENE(prefix, name, id) prefix##_scene_##name##_on_exit,
void (*const evil_portal_scene_on_exit_handlers[])(void* context) = {
#include "evil_portal_scene_config.h"
};
#undef ADD_SCENE
// Initialize scene handlers configuration structure
const SceneManagerHandlers evil_portal_scene_handlers = {
.on_enter_handlers = evil_portal_scene_on_enter_handlers,
.on_event_handlers = evil_portal_scene_on_event_handlers,
.on_exit_handlers = evil_portal_scene_on_exit_handlers,
.scene_num = Evil_PortalSceneNum,
};

View File

@@ -0,0 +1,29 @@
#pragma once
#include <gui/scene_manager.h>
// Generate scene id and total number
#define ADD_SCENE(prefix, name, id) Evil_PortalScene##id,
typedef enum {
#include "evil_portal_scene_config.h"
Evil_PortalSceneNum,
} Evil_PortalScene;
#undef ADD_SCENE
extern const SceneManagerHandlers evil_portal_scene_handlers;
// Generate scene on_enter handlers declaration
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_enter(void*);
#include "evil_portal_scene_config.h"
#undef ADD_SCENE
// Generate scene on_event handlers declaration
#define ADD_SCENE(prefix, name, id) \
bool prefix##_scene_##name##_on_event(void* context, SceneManagerEvent event);
#include "evil_portal_scene_config.h"
#undef ADD_SCENE
// Generate scene on_exit handlers declaration
#define ADD_SCENE(prefix, name, id) void prefix##_scene_##name##_on_exit(void* context);
#include "evil_portal_scene_config.h"
#undef ADD_SCENE

View File

@@ -0,0 +1,2 @@
ADD_SCENE(evil_portal, start, Start)
ADD_SCENE(evil_portal, console_output, ConsoleOutput)

View File

@@ -0,0 +1,166 @@
#include "../evil_portal_app_i.h"
#include "../helpers/evil_portal_storage.h"
void evil_portal_console_output_handle_rx_data_cb(uint8_t* buf, size_t len, void* context) {
furi_assert(context);
Evil_PortalApp* app = context;
// If text box store gets too big, then truncate it
app->text_box_store_strlen += len;
if(app->text_box_store_strlen >= EVIL_PORTAL_TEXT_BOX_STORE_SIZE - 1) {
furi_string_right(app->text_box_store, app->text_box_store_strlen / 2);
app->text_box_store_strlen = furi_string_size(app->text_box_store) + len;
}
// Null-terminate buf and append to text box store
buf[len] = '\0';
furi_string_cat_printf(app->text_box_store, "%s", buf);
view_dispatcher_send_custom_event(app->view_dispatcher, Evil_PortalEventRefreshConsoleOutput);
}
void evil_portal_scene_console_output_on_enter(void* context) {
Evil_PortalApp* app = context;
bool portal_file_set = false;
TextBox* text_box = app->text_box;
text_box_reset(app->text_box);
text_box_set_font(text_box, TextBoxFontText);
if(app->focus_console_start) {
text_box_set_focus(text_box, TextBoxFocusStart);
} else {
text_box_set_focus(text_box, TextBoxFocusEnd);
}
if(app->is_command) {
furi_string_reset(app->text_box_store);
app->text_box_store_strlen = 0;
app->sent_reset = false;
if(0 == strncmp("help", app->selected_tx_string, strlen("help"))) {
const char* help_msg = "BLUE = Waiting\nGREEN = Good\nRED = Bad\n\nThis project is a "
"WIP.\ngithub.com/bigbrodude6119/flipper-zero-evil-portal\n\n"
"Version 0.0.2\n\n";
furi_string_cat_str(app->text_box_store, help_msg);
app->text_box_store_strlen += strlen(help_msg);
if(app->show_stopscan_tip) {
const char* msg = "Press BACK to return\n";
furi_string_cat_str(app->text_box_store, msg);
app->text_box_store_strlen += strlen(msg);
}
}
if(0 == strncmp("savelogs", app->selected_tx_string, strlen("savelogs"))) {
const char* help_msg = "Logs saved.\n\n";
furi_string_cat_str(app->text_box_store, help_msg);
app->text_box_store_strlen += strlen(help_msg);
write_logs(app->portal_logs);
furi_string_reset(app->portal_logs);
if(app->show_stopscan_tip) {
const char* msg = "Press BACK to return\n";
furi_string_cat_str(app->text_box_store, msg);
app->text_box_store_strlen += strlen(msg);
}
}
if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
portal_file_set = evil_portal_read_index_html(context);
if(portal_file_set) {
app->command_queue[0] = SET_AP_CMD;
app->has_command_queue = true;
app->command_index = 0;
if(app->show_stopscan_tip) {
const char* msg = "Starting portal\nIf no response press\nBACK to return\n";
furi_string_cat_str(app->text_box_store, msg);
app->text_box_store_strlen += strlen(msg);
}
} else {
if(app->show_stopscan_tip) {
const char* msg = "No portal selected\nShowing current logs\nPress "
"BACK to return\n";
furi_string_cat_str(app->text_box_store, msg);
app->text_box_store_strlen += strlen(msg);
}
}
}
if(0 == strncmp(RESET_CMD, app->selected_tx_string, strlen(RESET_CMD))) {
app->sent_reset = true;
if(app->show_stopscan_tip) {
const char* msg = "Reseting portal\nPress BACK to return\n\n\n\n";
furi_string_cat_str(app->text_box_store, msg);
app->text_box_store_strlen += strlen(msg);
}
}
}
text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
scene_manager_set_scene_state(app->scene_manager, Evil_PortalSceneConsoleOutput, 0);
view_dispatcher_switch_to_view(app->view_dispatcher, Evil_PortalAppViewConsoleOutput);
// Register callback to receive data
evil_portal_uart_set_handle_rx_data_cb(
app->uart, evil_portal_console_output_handle_rx_data_cb);
if(app->is_command && app->selected_tx_string) {
if(0 == strncmp(SET_HTML_CMD, app->selected_tx_string, strlen(SET_HTML_CMD))) {
if(!portal_file_set) {
scene_manager_set_scene_state(
app->scene_manager, Evil_PortalSceneConsoleOutput, 0);
view_dispatcher_switch_to_view(
app->view_dispatcher, Evil_PortalAppViewConsoleOutput);
return;
}
FuriString* data = furi_string_alloc();
furi_string_cat(data, "sethtml=");
furi_string_cat(data, (char*)app->index_html);
evil_portal_uart_tx(
(uint8_t*)(furi_string_get_cstr(data)), strlen(furi_string_get_cstr(data)));
evil_portal_uart_tx((uint8_t*)("\n"), 1);
app->sent_html = true;
free(data);
free(app->index_html);
evil_portal_read_ap_name(context);
} else if(0 == strncmp(RESET_CMD, app->selected_tx_string, strlen(RESET_CMD))) {
app->sent_html = false;
app->sent_ap = false;
evil_portal_uart_tx(
(uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
evil_portal_uart_tx((uint8_t*)("\n"), 1);
} else if(1 == strncmp("help", app->selected_tx_string, strlen("help"))) {
evil_portal_uart_tx(
(uint8_t*)(app->selected_tx_string), strlen(app->selected_tx_string));
evil_portal_uart_tx((uint8_t*)("\n"), 1);
}
}
}
bool evil_portal_scene_console_output_on_event(void* context, SceneManagerEvent event) {
Evil_PortalApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
text_box_set_text(app->text_box, furi_string_get_cstr(app->text_box_store));
consumed = true;
} else if(event.type == SceneManagerEventTypeTick) {
consumed = true;
}
return consumed;
}
void evil_portal_scene_console_output_on_exit(void* context) {
Evil_PortalApp* app = context;
// Unregister rx callback
evil_portal_uart_set_handle_rx_data_cb(app->uart, NULL);
}

View File

@@ -0,0 +1,130 @@
#include "../evil_portal_app_i.h"
// For each command, define whether additional arguments are needed
// (enabling text input to fill them out), and whether the console
// text box should focus at the start of the output or the end
typedef enum { NO_ARGS = 0, INPUT_ARGS, TOGGLE_ARGS } InputArgs;
typedef enum { FOCUS_CONSOLE_END = 0, FOCUS_CONSOLE_START, FOCUS_CONSOLE_TOGGLE } FocusConsole;
#define SHOW_STOPSCAN_TIP (true)
#define NO_TIP (false)
#define MAX_OPTIONS (9)
typedef struct {
const char* item_string;
const char* options_menu[MAX_OPTIONS];
int num_options_menu;
const char* actual_commands[MAX_OPTIONS];
InputArgs needs_keyboard;
FocusConsole focus_console;
bool show_stopscan_tip;
} Evil_PortalItem;
// NUM_MENU_ITEMS defined in evil_portal_app_i.h - if you add an entry here,
// increment it!
const Evil_PortalItem items[NUM_MENU_ITEMS] = {
// send command
{"Start portal", {""}, 1, {SET_HTML_CMD}, NO_ARGS, FOCUS_CONSOLE_END, SHOW_STOPSCAN_TIP},
// stop portal
{"Stop portal", {""}, 1, {RESET_CMD}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
// console
{"Save logs", {""}, 1, {"savelogs"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
// help
{"Help", {""}, 1, {"help"}, NO_ARGS, FOCUS_CONSOLE_START, SHOW_STOPSCAN_TIP},
};
static void evil_portal_scene_start_var_list_enter_callback(void* context, uint32_t index) {
furi_assert(context);
Evil_PortalApp* app = context;
furi_assert(index < NUM_MENU_ITEMS);
const Evil_PortalItem* item = &items[index];
const int selected_option_index = app->selected_option_index[index];
furi_assert(selected_option_index < item->num_options_menu);
app->selected_tx_string = item->actual_commands[selected_option_index];
app->is_command = true;
app->is_custom_tx_string = false;
app->selected_menu_index = index;
app->focus_console_start = (item->focus_console == FOCUS_CONSOLE_TOGGLE) ?
(selected_option_index == 0) :
item->focus_console;
app->show_stopscan_tip = item->show_stopscan_tip;
view_dispatcher_send_custom_event(app->view_dispatcher, Evil_PortalEventStartConsole);
}
static void evil_portal_scene_start_var_list_change_callback(VariableItem* item) {
furi_assert(item);
Evil_PortalApp* app = variable_item_get_context(item);
furi_assert(app);
const Evil_PortalItem* menu_item = &items[app->selected_menu_index];
uint8_t item_index = variable_item_get_current_value_index(item);
furi_assert(item_index < menu_item->num_options_menu);
variable_item_set_current_value_text(item, menu_item->options_menu[item_index]);
app->selected_option_index[app->selected_menu_index] = item_index;
}
void evil_portal_scene_start_on_enter(void* context) {
Evil_PortalApp* app = context;
VariableItemList* var_item_list = app->var_item_list;
variable_item_list_set_enter_callback(
var_item_list, evil_portal_scene_start_var_list_enter_callback, app);
VariableItem* item;
for(int i = 0; i < NUM_MENU_ITEMS; ++i) {
item = variable_item_list_add(
var_item_list,
items[i].item_string,
items[i].num_options_menu,
evil_portal_scene_start_var_list_change_callback,
app);
variable_item_set_current_value_index(item, app->selected_option_index[i]);
variable_item_set_current_value_text(
item, items[i].options_menu[app->selected_option_index[i]]);
}
variable_item_list_set_selected_item(
var_item_list, scene_manager_get_scene_state(app->scene_manager, Evil_PortalSceneStart));
view_dispatcher_switch_to_view(app->view_dispatcher, Evil_PortalAppViewVarItemList);
}
bool evil_portal_scene_start_on_event(void* context, SceneManagerEvent event) {
UNUSED(context);
Evil_PortalApp* app = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == Evil_PortalEventStartPortal) {
scene_manager_set_scene_state(
app->scene_manager, Evil_PortalSceneStart, app->selected_menu_index);
scene_manager_next_scene(app->scene_manager, Evil_PortalAppViewStartPortal);
} else if(event.event == Evil_PortalEventStartKeyboard) {
scene_manager_set_scene_state(
app->scene_manager, Evil_PortalSceneStart, app->selected_menu_index);
} else if(event.event == Evil_PortalEventStartConsole) {
scene_manager_set_scene_state(
app->scene_manager, Evil_PortalSceneStart, app->selected_menu_index);
scene_manager_next_scene(app->scene_manager, Evil_PortalAppViewConsoleOutput);
}
consumed = true;
} else if(event.type == SceneManagerEventTypeTick) {
app->selected_menu_index = variable_item_list_get_selected_item_index(app->var_item_list);
consumed = true;
}
return consumed;
}
void evil_portal_scene_start_on_exit(void* context) {
Evil_PortalApp* app = context;
variable_item_list_reset(app->var_item_list);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 B

Some files were not shown because too many files have changed in this diff Show More