Closed lcgamboa closed 1 year ago
Hello @lcgamboa ,
Thanks for your feedback, bootstrapping for downloading is not supported yet on ESP32-C3 target emulation. I am currently implementing the missing components to get this feature to work, I will get back to you soon.
Hi @o-marshmallow ,
Thank you for the information and your excellent work in adding ESP32-C3 support to Qemu. I developed a simulator called PICSimLab that uses ESP32 (and now ESP32-C3) support from Espressif's Qemu.
With the Qemu ESP32, I use a virtual serial connection with tty0tty that allows esptool.py to reset the simulator (to change the boot mode) and flash the program as if it were a real ESP32. This makes it much easier to test the programs in the simulator and the real hardware just by changing the serial port to be used by esptool.py. That's why I asked about the same support in ESP32-C3.
I'll be waiting.
Hello @lcgamboa ,
Sorry for the delay of response, the commit that enables C3 target to be interfaced with esptool.py
has been merged to Github.
Moreover, since the process is a bit different than the ESP32's, please check the new documentation:
https://github.com/espressif/esp-toolchain-docs/blob/main/qemu/esp32c3/README.md#using-esptoolpy-and-espefusepy-to-interact-with-qemu
How to you reset the chip with esptool.py
, as far as I know, the hard reset won't work as documented:
Note: esptool can not reset the emulated chip using the RTS signal, because the state of RTS is not transmitted over TCP to QEMU. To reset the emulated chip, run system_reset command in QEMU console (started at step 1).
In any case, if you encounter any other issue or if you have any other feature request, feel free to open a new issue! :smile:
Hi @o-marshmallow ,
thank you for your support. I use a slightly modified version of Qemu which together with PICSimLab supports reset using the RTS pin (using tty0tty or com0com). I followed the documentation and everything worked correctly. I still couldn't make the Qemu ESP32C3 work through serial emulator like the Qemu ESP32 due to some problems in the uart that I reported in this issue https://github.com/espressif/qemu/issues/79 .
Hi @o-marshmallow ,
I managed to make it work using the RTS reset by the serial emulator. The first time always fails after clearing the memory. I believe that the stub does not work correctly due to the problem I described in issue https://github.com/espressif/qemu/issues/79. With the stub working it will be possible to use idf.py directly instead of esptool.py to flash (as I use with Qemu ESP32).
The problem I have now is that after writing the flash memory, Qemu doesn't use the new flash content. The system_reset command does not call the esp32c3_cpu_reset function. In the implementation of Qemu ESP32 works without problems. When I close PICSimLab the content of the flash is saved in a file and used when the program is opened again, after that the program previously recorded by esptool.py works. In the example in the figure, it starts with the blink on gpio 18 being replaced by a blink on gpio 10 (onboard LED).
Hi @lcgamboa ,
How did you create the SPI flash image file? On my side, after creating the image file with the following command:
dd if=/dev/zero of=flash_image.bin bs=1MiB count=4
and booting C3 machine into download mode with:
./qemu-system-riscv32 -nographic -machine esp32c3 -drive file=flash_image.bin,if=mtd,format=raw -global driver=esp32c3.gpio,property=strap_mode,value=0x02 -serial tcp::5555,server,nowait
I am able to flash the emulate SPI Flash with ESP-IDF:
cd esp-project/build
esptool.py -p socket://localhost:5555 --chip esp32c3 --no-stub --before no_reset --after no_reset write_flash @flash_args
Then I need to close the first process (QEMU) with quit
command from QEMU monitor, and restart a new QEMU process, without the strap mode to get the new flash content to be started:
./qemu-system-riscv32 -nographic -machine esp32c3 -drive file=flash_image.bin,if=mtd,format=raw
Using system_reset
command in QEMU monitor has no effect because the strap_mode
is still set to boot into download mode, so the machine does reset, but in download mode still.
And this is the same for the ESP32, using system_reset
in QEMU monitor after flashing the ESP32 will reset it inside download mode because the strap_mode is unchanged across resets.
Basically the process I use is the same, except that I use a modified version of Qemu that changes the value of strap_mode
during system_reset
.
The same effect of the code I use can be achieved by adding this code below on the official Qemu code from Espressif in gpio reset for ESP32 implementation.
static void esp32_gpio_reset(DeviceState *dev)
{
static int reset_cont=0;
if(reset_cont > 0){
Esp32GpioState *s = ESP32_GPIO(dev);
s->strap_mode = ESP32_STRAP_MODE_FLASH_BOOT;
}
reset_cont++;
}
With this modification, after recording the program following the steps in the ESP32 documentation, a system_reset
is enough for the program to work without having to restart Qemu.
As for the ESP32C3 implementation, system_reset
does not call the esp32_gpio_reset ()
function. (Would I be missing a qemu_register_reset
?)
By forcing call of esp32_gpio_reset
with the correct strap_mode
value for C3, Qemu runs the old program loaded during startup and not the one that was written to flash by esptool. The program is correctly loaded in the flash file, but it is not reloaded to run on the CPU as with the ESP32 implementation (Would it be a lack of a cpu_reset
?)
Sorry if my questions go beyond the proposal of the basic operation, but I'm using the ESP32 implementation as a basis for comparison. Thank you for your support and excellent work.
Hi @lcgamboa ,
Thank you for the details, I understand better what you mean! After checking the source code, the ESP32-C3 machine does lack a call to qemu_register_reset
that will invoke our reset function when using system_reset
function.
The thing is there is still some work to do on the reset as we can improve the way the devices are reset. Currently they are on a separated bus than the default QEMU Machine one, which has no reason to be on the C3. I would like to improve this.
As it may take a bit of time before these modifications can be merged, here is a quick and no-so-dirty fix that will help you: reset_strap.diff.txt
After applying this fix, a reset will change the strap_mode
to boot on the flash as you did on the ESP32. Ideally, I would like to implement that as an "official" feature, with a special value for the strap_mode
that would reset itself after a reset. I will see if I can implement this too.
It does go a bit beyond the original issue but I agree that the C3 machine must at least match the ESP32 implementation and standards :smile:
Thank you for your support!
Hi @o-marshmallow ,
thanks for your patch file, with it the operation of C3 was equal to ESP32 Qemu.
I tried to change the value of the strap_mode
property initially with the qom-set command:
{ "execute": "qom-set", "arguments": { "path": "/machine/soc/gpio", "property": "strap_mode", "value": "0x0f" }
,but apparently after the realization of machine the property cannot be changed.
I consider this issue fully closed now. I'll wait for the changes to be merged.
@lcgamboa, I also tried via the QEMU monitor to change the strap value, I encountered the same error. Couldn't find a way to remove the GPIO controller, change the strap and reload it either.
Anyway, it'll be simpler to have a special value that would switch to flash boot after a reset.
I did several tests and I couldn't get the new ESP32-C3 qemu machine to communicate with esptool.py. Is bootstrapping support for downloading currently implemented? Using ESP32 machine works without problems as described in the wiki. Any help or information is welcome.