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

Use SWO (i.e. ITM_SendChar()) rather than USB-serial converter for I/O #317

Open
dgazzoni opened this issue Dec 7, 2023 · 11 comments
Open
Labels
enhancement New feature or request

Comments

@dgazzoni
Copy link
Contributor

dgazzoni commented Dec 7, 2023

This is a feature request to replace the current I/O implementation with one that uses the Serial Wire Output interface. In the case of ST MCUs using the ST-Link programmer, the data traffic goes through the same USB cable as the ST-Link. As such there is no need to have dangling jump wires connected to USART pins, connected to an extra piece of hardware (USB-serial converter) and the use of two USB connections to the computer -- some computers such as Apple's MacBook Airs have only two USB connectors and ideally one of these should be free for the power supply.

This would entail changing the code of hal_send_str() from libopencm3 to call ITM_SendChar() in place of usart_send_blocking(). This is the easy part and if this feature request is considered, I can contribute the required changes to this code.

However, if this approach were used, it would be no longer possible to read directly from a /dev/tty* device; one would have to use st-trace from the texane stlink package (which pqm4 already depends on). Thus it would be necessary to change all the Python scripts to use this different I/O method, and for that I'm afraid my Python skills may be too meager to contribute.

I understand there may be use cases where SWO is unwelcome (for instance, I'm not familiar with the support for SWO on programmers other than ST-Link). However, it could still be made an option alongside the existing USART I/O implementation, rather than a replacement.

@rpls
Copy link
Contributor

rpls commented Dec 7, 2023

Right now, we're in the process of switching the "main" board for benchmarking to the Nucleo-L4R5ZI, which has a directly connected serial interface. So no more cumbersome connecting of wires.

I took a look at the ITM stuff in the past, and actually used it in other projects. What kept me from taking steps was the software support on the host side. As you said, we'd have to use different tools, which may be somewhat cumbersome. And back when I worked with it, the SW support in open source tools was somewhat spotty, don't know if this is still the case. Also, I would actually like to completely move away from the st-util & co tools in favor of OpenOCD. Especially since stlink will drop MacOS support, and I'd at least like to support for Linux and MacOS for mupq/pqm4.

I guess there would be the following TODOs:

  • Look into how one could use the ITM debug output in OpenOCD.
  • Look into how one could capture the output in the framework.
  • Check whether an active ITM changes the performance measurements (I don't see why it should, but I would want to make sure, it's a debugging feature in the core after all).

@dgazzoni
Copy link
Contributor Author

dgazzoni commented Dec 7, 2023

OK. I understand from your reply that there is in principle interest in including this, so if that is the case, I can commit to investigating point #1 above (ITM on OpenOCD).

@rpls
Copy link
Contributor

rpls commented Dec 7, 2023

General interest, yeah. It would be a nice option to have, not super necessary for the new board, but a more hassle-free option for other boards. FYI, the code should then go into the mupq/mupq repository, since the general OpenOCD code is there in the platforms.py file.

@rpls rpls added the enhancement New feature or request label Jan 19, 2024
@ate-wang
Copy link

Image What happens if the serial port prints garbled characters after burning the test file?

@mkannwischer
Copy link
Contributor

Image What happens if the serial port prints garbled characters after burning the test file?

The most likely cause for garbled serial output is using the wrong baud rate.
But I've never seen something like what you see in the screenshot. It's rather hard to debug from a distance especially since you are using different hardware and software than us.

I recommend going back to a simpler demo for debugging your setup. Something like https://github.com/libopencm3/libopencm3-examples. Once that is working, it should be easy to find the difference to pqm4.

@ate-wang
Copy link

I have debugged the hardware driver of libopencm3 separately and it works normally. I am using the stm32f4discovery version. The demo I used before used the USB driver. I changed the USB driver to the serial port driver and garbled characters appeared.

Image

@mkannwischer
Copy link
Contributor

I have debugged the hardware driver of libopencm3 separately and it works normally. I am using the stm32f4discovery version. The demo I used before used the USB driver. I changed the USB driver to the serial port driver and garbled characters appeared.

Image

Does the code in your screenshot work with the serial comm or not?
To double check: You are using USART2, i.e., you connect the rx wire to PA2?
Have you setup the clock for USART2 + GPIOA correctly?
You definitely need something like

  rcc_periph_clock_enable(RCC_GPIOA);
  rcc_periph_clock_enable(RCC_USART2);
  gpio_set_output_options(SERIAL_GPIO, GPIO_OTYPE_OD, GPIO_OSPEED_100MHZ, SERIAL_PINS);
  gpio_set_af(SERIAL_GPIO, GPIO_AF7, SERIAL_PINS);
  gpio_mode_setup(SERIAL_GPIO, GPIO_MODE_AF, GPIO_PUPD_PULLUP, SERIAL_PINS);
  usart_set_baudrate(SERIAL_USART, SERIAL_BAUD);
  usart_set_databits(SERIAL_USART, 8);
  usart_set_stopbits(SERIAL_USART, USART_STOPBITS_1);
  usart_set_mode(SERIAL_USART, USART_MODE_TX_RX);
  usart_set_parity(SERIAL_USART, USART_PARITY_NONE);
  usart_set_flow_control(SERIAL_USART, USART_FLOWCONTROL_NONE);
  usart_disable_rx_interrupt(SERIAL_USART);
  usart_disable_tx_interrupt(SERIAL_USART);
  usart_enable(SERIAL_USART);

somewhere.

What command are you using to receive the output on the host?

@ate-wang
Copy link

Image
I have no problem using the serial port driver test alone, but I can't find the specific logic of how to call the driver in the code

@mkannwischer
Copy link
Contributor

Image I have no problem using the serial port driver test alone, but I can't find the specific logic of how to call the driver in the code

And once you switch to 38400 baud rate it breaks?

@ate-wang
Copy link

Image
Thank you very much, the problem has been solved and the output can be normal. The problem lies in the baud rate setting.

@ate-wang
Copy link

Image
Now I have a new question. I would like to ask you what is the clock frequency used in the demo of this code. I am using the development board stm32f4discoery, and I see that the clock frequency in the demo is 25MHz, but the highest frequency is 168MHz. I would like to ask what the specific clock frequency is, because it is very important for computing performance. When I saw the performance parameter table you gave me, there was only the number of cycles, and I didn’t quite understand what it meant. I don’t know what the unit of the number of cycles is, and I want to convert this number of cycles into how many times it can be executed per second.

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

No branches or pull requests

4 participants