Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Desktop support (Linux / Windows / Mac) (ESF-122) #102

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

electromuis
Copy link

For a board I made using the esp32s3 I also have a desktop client written in c++.

It would be great if users could update the firmware directly from the tool. Wanting to keep the tool small by not including a python install to use esptool, I found this library to contain the most important parts.

I've done some work to make it work on x86 systems by using the https://github.com/wjwwood/serial library.

It's not completed yet and could probably use a good eye but I wanted to share it at least so other interested people could find it.

A new example is added called: desktop_esp32_example. It builds and rust on my windows system. Have not tried flashing to an actual board yet, will have to check got esptool does the resetting since normally a PC wouldn't have gpio access.

@github-actions github-actions bot changed the title Desktop support (Linux / Windows / Mac) Desktop support (Linux / Windows / Mac) (ESF-122) Mar 22, 2024
@electromuis
Copy link
Author

Update: firmware flashing works

@@ -336,7 +346,8 @@ esp_loader_error_t load_ram_binary(const uint8_t *bin)
printf("Start loading\n");
esp_loader_error_t err;
const esp_loader_bin_header_t *header = (const esp_loader_bin_header_t *)bin;
esp_loader_bin_segment_t segments[header->segments];
//esp_loader_bin_segment_t segments[header->segments];
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being moved to the heap?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because it didn't compile on MSVC

Copy link
Collaborator

@DNedic DNedic Mar 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, after C99 VLAs are a GNU extension as well. We shouldn't be using VLAs in the first place IMO but I am unsure about using malloc(), as we might want to support platforms in the future that don't have it available. Also, using malloc() in example code for embedded platforms where malloc() is often prohibited is not ideal, especially as some of these example functions happen to be used in production a lot of the time.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A simple static array with a max segment count should suffice.

@@ -295,7 +295,7 @@ esp_loader_error_t loader_spi_parameters(uint32_t total_size)
return send_cmd(&spi_cmd, sizeof(spi_cmd), NULL);
}

__attribute__ ((weak)) void loader_port_debug_print(const char *str)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably leftover code from testing, a weak symbol shouldn't hurt anything.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@DNedic I think the reason is that __attribute__((weak)) syntax is a GNU extension, and is not supported by MSVC compiler. Same for packed — MSCV has a different way of specifying the same.

I think this will still need to be cleaned up to move all the compiler-specific things into a common header.

Copy link
Collaborator

@DNedic DNedic Mar 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, we should move these platform details into a separate header if we merge this.

Copy link
Collaborator

@DNedic DNedic Mar 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since LLVM GNU extensions, is there a way to build for Windows using LLVM and just not bother with MSVC? As far as I've seen the incompatibilities go deeper than GNU extensions.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mingw might work, but I'd prefer an "if msvc else" precompiler flag. Is does actually compile but the problem is this symbol name is being used multiple times and thus the linker complains. Renaming one of them would also fix the issue.

port/serial_port.h Outdated Show resolved Hide resolved
} loader_serial_config_t;

esp_loader_error_t loader_port_serial_init(const loader_serial_config_t *config);

Copy link
Collaborator

@DNedic DNedic Mar 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a deinit function would be useful?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed

.gitmodules Outdated
@@ -1,3 +1,6 @@
[submodule "submodules/stm32-cmake"]
path = submodules/stm32-cmake
url = https://github.com/ObKo/stm32-cmake.git
[submodule "submodules/serial"]
path = submodules/serial
url = https://github.com/wjwwood/serial
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just my 2c, I would recommend fetching this project at build time using ExternalProject or FetchContent CMake modules, instead of adding a submodule into esp-serial-flasher.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea! This would be a good time to move over the stm32-cmake submodule to FetchContent as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps a find_package script which can do the fetching if needed. In my application the serial library is already present. As a note, I didn't use add_subdirectory on this since it wants catkin as a dependancy, which I don't need here.

port/serial_port.cpp Outdated Show resolved Hide resolved
@DNedic
Copy link
Collaborator

DNedic commented Mar 22, 2024

Hello @electromuis , nice work and thank you for the contribution! I've left some initial comments, most of them are probably due to this being WIP.

@electromuis
Copy link
Author

Hello @electromuis , nice work and thank you for the contribution! I've left some initial comments, most of them are probably due to this being WIP.

Thanks for the comments, added my replies. The README could also be updated since "from other host microcontrollers" doesn't count for a big desktop CPU haha

@electromuis
Copy link
Author

Tried to address each feedback point

@@ -1,8 +1,10 @@
# esp-serial-flasher

`esp-serial-flasher` is a portable C library for flashing or loading apps to RAM of Espressif SoCs from other host microcontrollers.
`esp-serial-flasher` is a portable C library for flashing or loading apps to RAM of Espressif SoCs from other host that are supported through their dedicated port drivers.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps it's better to be upfront here. I would preffer something like:

`esp-serial-flasher` is a portable C library for flashing or loading apps to RAM of Espressif SoCs from other microcontrollers, SBCs and even desktop PCs.

return;
}

// This might be the best we can do without GPIO
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please take a look at how esptool does this. There are several reset strategies depending on whether the host is Windows/Linux or MacOS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The wjwwood serial library seems to have support for setting DTR/RTS
https://github.com/wjwwood/serial/blob/69e0372cf0d3796e84ce9a09aff1d74496f68720/src/serial.cc#L404-L406

Questions is whether setting them independently is fast enough. From my experience: most likely not.

I've used the serial class from Qt which has similar abstractions and still had to resort to OS specific calls to switch DTR/RTS at the same time.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't that what @electromuis is doing here? The question I was addressing is whether the platform specifics have propagated to the library itself. If not, this code is good as is.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what he means is dtr and rts would need to switch in a single call instead of the two -> set calls listed currently.

The board I'm using currently doesn't even reset with esptool.py so hard to test

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think what he means is dtr and rts would need to switch in a single call instead of the two -> set calls listed currently.

The board I'm using currently doesn't even reset with esptool.py so hard to test

Yes that's what I've ment.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants