Skip to content

Commit f7c1d95

Browse files
ABOSTMkbumsik
authored andcommitted
[STM32MP157_DK] README: Add VirtIO
1 parent 29b6c7d commit f7c1d95

File tree

1 file changed

+145
-5
lines changed

1 file changed

+145
-5
lines changed

variants/STM32MP157_DK/README.md

+145-5
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ In this example, the user **must** upload `<Arduino build output path>/run_ardui
4343
After uploading the user can use `sh run_arduino_<sketch name>.sh start` in the console of host Linux via either SSH or Serial Console, to run the Arduino firmware.
4444

4545
#### Note
46-
* `sh run_arduino_<sketch name>.sh start` is a one-shot command, the Arduino firmware only runs for the current boot. If you want to make it run after reboot, you need to use `sh run_arduino_<sketch name>.sh install` command.
46+
47+
* `sh run_arduino_<sketch name>.sh start` is a one-shot command, the Arduino firmware only runs for the current boot. If you want to make it run after reboot, you need to use `sh run_arduino_<sketch name>.sh install` command.
4748

4849
`run_arduino_<sketch name>.sh` help page summary:
4950

@@ -63,6 +64,21 @@ After uploading the user can use `sh run_arduino_<sketch name>.sh start` in the
6364
sh run_arduino_<sketch name>.sh uninstall
6465
Uninstall the autostart service.
6566

67+
sh run_arduino_<sketch name>.sh monitor
68+
Monitor data received from the coprocessor via the virtual serial.
69+
70+
sh run_arduino_<sketch name>.sh send-msg <message...>
71+
Send a message to the coprocessor via the virtual serial.
72+
73+
sh run_arduino_<sketch name>.sh send-file <filename>
74+
Send a file content to the coprocessor via the virtual serial.
75+
76+
sh run_arduino_<sketch name>.sh minicom
77+
Launch minicom interactive serial communication program.
78+
79+
sh run_arduino_<sketch name>.sh log
80+
Print debugging log in OpenAMP trace buffer.
81+
6682
sh run_arduino_<sketch name>.sh stop
6783
Stop the coprocessor.
6884

@@ -73,6 +89,122 @@ See the source code [run_arduino_gen.sh] for the full help page and the more det
7389

7490
[run_arduino_gen.sh] is the shell script that produces a copy of the script called `run_arduino_<sketch name>.sh` but with the sketch binary self-contained.
7591

92+
## Virtual Serial
93+
94+
With Virtual Serial, you can easily implement inter-core communication between the Linux host and Arduino coprocessor. Virtual Serial uses OpenAMP rpmsg framework. This is available as `SerialVirtIO` object and you can use it as a standard Arduino Serial object.
95+
96+
Enable `SerialVirtIO` in Arduino IDE->Tools->Virtual serial support. You can optionally alias generic `Serial` object with `SerialVirtIO` as well.
97+
98+
When enabled, `/dev/ttyRPMSG0` is available to the Linux host. You can use it as a normal serial tty. `sh run_arduino_<sketch name>.sh` provides `monitor`, `minicom`, `send-msg`, `send-file` as a convenience. See above command descriptions.
99+
100+
See [OpenAMP] and [Linux RPMsg] to learn more.
101+
102+
### Configuration
103+
104+
To increase the performance of SerialVirtIO you can resize the related buffer configurations. There are three definitions you can use:
105+
106+
* [`VRING_NUM_BUFFS`](/cores/arduino/stm32/OpenAMP/virtio_config.h)
107+
* [`RPMSG_BUFFER_SIZE`](/cores/arduino/stm32/OpenAMP/virtio_config.h)
108+
* [`VIRTIO_BUFFER_SIZE`](/cores/arduino/stm32/OpenAMP/virtio_buffer.h)
109+
110+
The recommended option is to resize `VRING_NUM_BUFFS`. Be very cautious when resizing `RPMSG_BUFFER_SIZE`, which must be matched with the Linux kernel definition. Also `VIRTIO_BUFFER_SIZE` has the minimum required size depending on the other two. See their links above for further descriptions.
111+
112+
To redefine these definitions, see how to create `build_opt.h` described in Debugging section below.
113+
114+
### Virtual Serial Example
115+
116+
Here is a basic echo example:
117+
```cpp
118+
int available;
119+
char buffer[1024];
120+
121+
unsigned long time = 0;
122+
123+
void setup() {
124+
// You can SerialVirtIO.begin() and use SerialVirtIO later instead.
125+
Serial.begin(); // You don't need to configure speed, it is ignored.
126+
pinMode(LED_BUILTIN, OUTPUT);
127+
}
128+
129+
void loop() {
130+
available = Serial.available();
131+
while (available > 0) {
132+
int size = min(available, Serial.availableForWrite());
133+
Serial.readBytes(buffer, size);
134+
Serial.write(buffer, size);
135+
available -= size;
136+
}
137+
138+
// Heartbeat. If Arduino stops the LED won't flash anymore.
139+
if ((millis() - time) > 1000) {
140+
time = millis();
141+
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
142+
}
143+
}
144+
```
145+
146+
Note the use of `Serial.availableForWrite()`. SerialVirtIO has [a hard restriction of the write size], so it is important to `Serial.write()` less than the value of `Serial.availableForWrite()`.
147+
148+
After loading Arduino, You can use SerialVirtIO in two ways in this example:
149+
150+
* Run `sh run_arduino_<sketch name>.sh minicom` and type anything in the minicom console. The console will print out what you type immediately.
151+
152+
* Open two Linux consoles (using SSH)
153+
1. In the first console, run `sh run_arduino_<sketch name>.sh monitor`
154+
2. In the second console, run `sh run_arduino_<sketch name>.sh send-msg <your message>` or `sh run_arduino_<sketch name>.sh send-file <your file>`, the first console will print the content of the message.
155+
156+
## Debugging
157+
158+
For printf-style debugging, `core_debug()` is highly recommended instead of using Arduino Serial. In STM32MP1, `core_debug()` utilizes OpenAMP trace buffer and it has a minimal real-time impact (other than the overhead of printf) because it is not bound to the speed of a hardware IO peripheral while printing it.
159+
160+
Create [build_opt.h] in the sketch directory and simply put `-DCORE_DEBUG`. Additionally you can resize the buffer size of logging by redefining `VIRTIO_LOG_BUFFER_SIZE` (2kb by default). As an example you can create a file like the following:
161+
162+
```
163+
build_opt.h (in the same directory of your Sketch)
164+
-----------------------------
165+
166+
-DCORE_DEBUG
167+
-DVIRTIO_LOG_BUFFER_SIZE=4086
168+
```
169+
170+
Don't forget to change any of Arduino IDE option to reflect this as in the warning section in [build_opt.h description in wiki]. This is important because if `-DCORE_DEBUG` is not configured correctly `core_debug()` silently becomes an empty function without triggering any build error. Don't forget to add `#include "core_debug.h"` in your code in order to use `core_debug()`.
171+
172+
Also, you must enable the Virtual Serial (described in the above section) and include `SerialVirtIO.begin();` in your Arduino sketch, because this logging feature is tightly coupled to OpenAMP virtio.
173+
174+
You can use `sh run_arduino_<sketch name>.sh log` command or `cat /sys/kernel/debug/remoteproc/remoteproc0/trace0` command to print out the debug log in the Linux host.
175+
176+
Note that when overflow occurs the trace buffer is re-written from the beginning, removing existing logs. Consider increasing `VIRTIO_LOG_BUFFER_SIZE` in this case, as mentioned above.
177+
178+
See [virtio_log.h] for more information.
179+
180+
### Debugging Example
181+
182+
Here is a basic blink example with `core_debug()`:
183+
```cpp
184+
#include "core_debug.h"
185+
186+
unsigned long time = 0;
187+
unsigned long count = 1;
188+
189+
void setup() {
190+
// You must enable SerialVirtIO to use core_debug(), even if you don't use SerialVirtIO.
191+
SerialVirtIO.begin();
192+
pinMode(LED_BUILTIN, OUTPUT);
193+
}
194+
195+
void loop() {
196+
if ((millis() - time) > 1000) {
197+
time = millis();
198+
core_debug("%u seconds\n", count++);
199+
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
200+
}
201+
}
202+
```
203+
204+
Don't forget to add [build_opt.h] described above.
205+
206+
After loading Arduino, you can simply `sh run_arduino_<sketch name>.sh log` to print the current `core_debug()` logs.
207+
76208
## Pin mapping
77209

78210
The boards have two pin headers: Raspberry Pi HAT headers and Arduino shield headers. This project currently supports Arduino Shield headers only, leaving RPi HAT headers for the Linux applications.
@@ -108,7 +240,7 @@ There are additional pins for LEDs and buttons.
108240
| PA_13 | 17 / LED_RED | USER2_BTN | Active Low, LED LD6, also connected to B4 button |
109241
| PH_7 | 18 / LED_ORANGE / LED_BUILTIN | | Active High, LED LD7 |
110242

111-
[`variant.h` of the board](https://github.com/stm32duino/Arduino_Core_STM32/tree/master/variants/STM32MP157_DK/variant.h) has the complete information about the pinouts.
243+
[`variant.h` of the board] has the complete information about the pinouts.
112244

113245
## Uploading
114246

@@ -152,9 +284,8 @@ And then the Device Tree should enable TIM1 for the coprocessor, although this d
152284
## Limitations
153285

154286
* Ethernet and USB are not supported. Use them in the Linux host.
155-
* Currently there is no easy way for communication between the Linux host and Arduino coprocessor. There is ongoing work for virtual serial communications using OpenAMP rpmsg framework. Currently one possible way is to wire between UART7 (Arduino SCL/SDA pins) and USART3 (Linux RPi HAT GPIO14/GPIO15 pins), however, users should manually modify [Linux Device tree to enable `usart3` and recompile it](usart3).
156287
* I2C pins on Raspberry Pi HAT header (GPIO2 and GPIO3) are not available in Linux host. This is because the Discovery board shares I2C pins on Arduino header and those on the HAT header.
157-
* [Early firmware loading from U-Boot stage] is not supported. Only firmware loading on Linux boot stage by systemd supported. The binary itself may be loaded by U-Boot without any problems, but there is no out-of-box tool to configure U-Boot to load the firmware using Arduino IDE yet.
288+
* [Early firmware loading from U-Boot stage] is not supported. Only firmware loading on Linux boot stage by systemd (aka. `sh run_arduino_<sketch name>.sh install`) supported. The binary itself may be loaded by U-Boot without any problems, but there is no out-of-box tool to configure U-Boot to load the firmware using Arduino IDE yet.
158289
* EEPROM library: Those devices do not have non-volatile memory. The emulation is done using RETRAM. Therefore data will be preserved *only* when VBAT is supplied (e.g. A coin battery is connected to CN3 on STM32MP157A_DK1) and the coprocessor is waken up from sleep. This implies that cold boot the board may cause data loss, even if VBAT is supplied. See [discussions on RETRAM] for more detail.
159290

160291

@@ -170,11 +301,20 @@ And then the Device Tree should enable TIM1 for the coprocessor, although this d
170301

171302
[run_arduino_gen.sh]: https://github.com/stm32duino/Arduino_Tools/blob/master/run_arduino_gen.sh
172303

304+
[OpenAMP]: https://github.com/OpenAMP/open-amp/wiki/OpenAMP-Overview
305+
[Linux RPMsg]: https://wiki.st.com/stm32mpu/wiki/Linux_RPMsg_framework_overview
306+
[a hard restriction of the write size]: /cores/arduino/VirtIOSerial.cpp#L148
307+
308+
[build_opt.h]: https://github.com/stm32duino/wiki/wiki/Customize-build-options-using-build_opt.h
309+
[build_opt.h description in wiki]: https://github.com/stm32duino/wiki/wiki/Customize-build-options-using-build_opt.h
310+
[virtio_log.h]: /cores/arduino/stm32/OpenAMP/virtio_log.h
311+
312+
[`variant.h` of the board]: /variants/STM32MP157_DK/variant.h
313+
173314
[The ST Wiki page on C-Kermit]: https://wiki.st.com/stm32mpu/wiki/How_to_transfer_a_file_over_serial_console
174315
[a bug in OpenSTLinux]: https://community.st.com/s/question/0D50X0000B9vHa4/cannot-get-download-a-file-using-kermit
175316

176317
[stm32mp157c-dk2-m4-examples.dts]: https://github.com/STMicroelectronics/meta-st-stm32mp/blob/d8cbac759e1275b1a27d4ba38b64a0d83d0e8c9f/recipes-kernel/linux/linux-stm32mp/4.19/4.19.49/0029-ARM-stm32mp1-r2-DEVICETREE.patch#L4334
177318

178-
[usart3]: https://github.com/STMicroelectronics/meta-st-stm32mp/blob/d8cbac759e1275b1a27d4ba38b64a0d83d0e8c9f/recipes-kernel/linux/linux-stm32mp/4.19/4.19.49/0029-ARM-stm32mp1-r2-DEVICETREE.patch#L4274
179319
[Early firmware loading from U-Boot stage]: https://wiki.st.com/stm32mpu/wiki/How_to_start_the_coprocessor_from_the_bootloader
180320
[discussions on RETRAM]: https://community.st.com/s/question/0D50X0000B44pHUSQY/doesnt-the-mcu-coprocessor-have-nonvolatile-memory

0 commit comments

Comments
 (0)