vfs: Adds example for semihosting VFS driver

This commit is contained in:
Alexey Gerenkov 2019-02-19 22:57:03 +03:00
parent 4fc14e8eb6
commit b5ac319160
8 changed files with 312 additions and 0 deletions

View file

@ -0,0 +1,6 @@
# The following lines of boilerplate have to be in your project's CMakeLists
# in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(semihost_vfs)

View file

@ -0,0 +1,9 @@
#
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
# project subdirectory.
#
PROJECT_NAME := semihost_vfs
include $(IDF_PATH)/make/project.mk

View file

@ -0,0 +1,91 @@
# Semihosting VFS driver example
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This example demonstrates how to use semihosting VFS driver with ESP32. Example does the following steps:
1. Uses `esp_vfs_semihost_register` function to register exposed host directory in VFS, enabling C standard library and POSIX functions to be used.
2. Redirects `stdout` from the UART to the file on the host using `freopen`.
3. Prints several messages to the redirected.
4. Switches back to UART `stdout` using `freopen`.
5. Opens text file on the host.
6. Reads the file and prints its content on stdout.
## How to use example
### Hardware and tools required
This example does not require any special hardware, and can be run on any common development board.
This example requires [OpenOCD](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/jtag-debugging/index.html#run-openocd).
NOTE: In order to run this example you need OpenOCD version `v0.10.0-esp32-20190313` or later.
Run OpenOCD using command:
```
bin/openocd -s share/openocd/scripts -f interface/ftdi/esp32_devkitj_v1.cfg -c 'set ESP_SEMIHOST_BASEDIR '$IDF_PATH/examples/storage/semihost_vfs/data -f board/esp-wroom-32.cfg
```
This command also configures OpenOCD to expose example project `data` subdirectory to the target's semihosting VFS driver.
### Configure the project
If using Make based build system, run `make menuconfig` and set serial port under Serial Flasher Options.
If using CMake based build system, no configuration is required.
### Build and flash
Build the project and flash it to the board, then run monitor tool to view serial output:
```
make -j4 flash monitor
```
Or, for CMake based build system (replace PORT with serial port name):
```
idf.py -p PORT flash monitor
```
(To exit the serial monitor, type ``Ctrl-]``.)
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
## Example output
There are two types of outputs produced by example:
1. File `esp32_stdout.txt` in the host directory mounted to the target:
```
W (274) example: Switched to semihosted stdout
Semihosted stdout write 0
Semihosted stdout write 1
Semihosted stdout write 2
...
Semihosted stdout write 98
Semihosted stdout write 99
W (274) example: Switch to UART stdout
```
2. On the boards console:
```
W (274) example: Switch to semihosted stdout
W (274) example: Switched back to UART stdout
I (274) example: Wrote 2798 bytes
====================== HOST DATA START =========================
The following are the graphical (non-control) characters defined by
ISO 8859-1 (1987). Descriptions in words aren't all that helpful,
but they're the best we can do in text. A graphics file illustrating
the character set should be available from the same archive as this
file.
Hex Description Hex Description
20 SPACE
...
7D RIGHT CURLY BRACKET FD SMALL LETTER Y WITH ACUTE
7E TILDE FE SMALL LETTER THORN (Icelandic)
FF SMALL LETTER Y WITH DIAERESIS
====================== HOST DATA END =========================
I (694) example: Read 6121 bytes
```

View file

@ -0,0 +1,104 @@
The following are the graphical (non-control) characters defined by
ISO 8859-1 (1987). Descriptions in words aren't all that helpful,
but they're the best we can do in text. A graphics file illustrating
the character set should be available from the same archive as this
file.
Hex Description Hex Description
20 SPACE
21 EXCLAMATION MARK A1 INVERTED EXCLAMATION MARK
22 QUOTATION MARK A2 CENT SIGN
23 NUMBER SIGN A3 POUND SIGN
24 DOLLAR SIGN A4 CURRENCY SIGN
25 PERCENT SIGN A5 YEN SIGN
26 AMPERSAND A6 BROKEN BAR
27 APOSTROPHE A7 SECTION SIGN
28 LEFT PARENTHESIS A8 DIAERESIS
29 RIGHT PARENTHESIS A9 COPYRIGHT SIGN
2A ASTERISK AA FEMININE ORDINAL INDICATOR
2B PLUS SIGN AB LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
2C COMMA AC NOT SIGN
2D HYPHEN-MINUS AD SOFT HYPHEN
2E FULL STOP AE REGISTERED SIGN
2F SOLIDUS AF OVERLINE
30 DIGIT ZERO B0 DEGREE SIGN
31 DIGIT ONE B1 PLUS-MINUS SIGN
32 DIGIT TWO B2 SUPERSCRIPT TWO
33 DIGIT THREE B3 SUPERSCRIPT THREE
34 DIGIT FOUR B4 ACUTE ACCENT
35 DIGIT FIVE B5 MICRO SIGN
36 DIGIT SIX B6 PILCROW SIGN
37 DIGIT SEVEN B7 MIDDLE DOT
38 DIGIT EIGHT B8 CEDILLA
39 DIGIT NINE B9 SUPERSCRIPT ONE
3A COLON BA MASCULINE ORDINAL INDICATOR
3B SEMICOLON BB RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
3C LESS-THAN SIGN BC VULGAR FRACTION ONE QUARTER
3D EQUALS SIGN BD VULGAR FRACTION ONE HALF
3E GREATER-THAN SIGN BE VULGAR FRACTION THREE QUARTERS
3F QUESTION MARK BF INVERTED QUESTION MARK
40 COMMERCIAL AT C0 CAPITAL LETTER A WITH GRAVE
41 CAPITAL LETTER A C1 CAPITAL LETTER A WITH ACUTE
42 CAPITAL LETTER B C2 CAPITAL LETTER A WITH CIRCUMFLEX
43 CAPITAL LETTER C C3 CAPITAL LETTER A WITH TILDE
44 CAPITAL LETTER D C4 CAPITAL LETTER A WITH DIAERESIS
45 CAPITAL LETTER E C5 CAPITAL LETTER A WITH RING ABOVE
46 CAPITAL LETTER F C6 CAPITAL LETTER AE
47 CAPITAL LETTER G C7 CAPITAL LETTER C WITH CEDILLA
48 CAPITAL LETTER H C8 CAPITAL LETTER E WITH GRAVE
49 CAPITAL LETTER I C9 CAPITAL LETTER E WITH ACUTE
4A CAPITAL LETTER J CA CAPITAL LETTER E WITH CIRCUMFLEX
4B CAPITAL LETTER K CB CAPITAL LETTER E WITH DIAERESIS
4C CAPITAL LETTER L CC CAPITAL LETTER I WITH GRAVE
4D CAPITAL LETTER M CD CAPITAL LETTER I WITH ACUTE
4E CAPITAL LETTER N CE CAPITAL LETTER I WITH CIRCUMFLEX
4F CAPITAL LETTER O CF CAPITAL LETTER I WITH DIAERESIS
50 CAPITAL LETTER P D0 CAPITAL LETTER ETH (Icelandic)
51 CAPITAL LETTER Q D1 CAPITAL LETTER N WITH TILDE
52 CAPITAL LETTER R D2 CAPITAL LETTER O WITH GRAVE
53 CAPITAL LETTER S D3 CAPITAL LETTER O WITH ACUTE
54 CAPITAL LETTER T D4 CAPITAL LETTER O WITH CIRCUMFLEX
55 CAPITAL LETTER U D5 CAPITAL LETTER O WITH TILDE
56 CAPITAL LETTER V D6 CAPITAL LETTER O WITH DIAERESIS
57 CAPITAL LETTER W D7 MULTIPLICATION SIGN
58 CAPITAL LETTER X D8 CAPITAL LETTER O WITH STROKE
59 CAPITAL LETTER Y D9 CAPITAL LETTER U WITH GRAVE
5A CAPITAL LETTER Z DA CAPITAL LETTER U WITH ACUTE
5B LEFT SQUARE BRACKET DB CAPITAL LETTER U WITH CIRCUMFLEX
5C REVERSE SOLIDUS DC CAPITAL LETTER U WITH DIAERESIS
5D RIGHT SQUARE BRACKET DD CAPITAL LETTER Y WITH ACUTE
5E CIRCUMFLEX ACCENT DE CAPITAL LETTER THORN (Icelandic)
5F LOW LINE DF SMALL LETTER SHARP S (German)
60 GRAVE ACCENT E0 SMALL LETTER A WITH GRAVE
61 SMALL LETTER A E1 SMALL LETTER A WITH ACUTE
62 SMALL LETTER B E2 SMALL LETTER A WITH CIRCUMFLEX
63 SMALL LETTER C E3 SMALL LETTER A WITH TILDE
64 SMALL LETTER D E4 SMALL LETTER A WITH DIAERESIS
65 SMALL LETTER E E5 SMALL LETTER A WITH RING ABOVE
66 SMALL LETTER F E6 SMALL LETTER AE
67 SMALL LETTER G E7 SMALL LETTER C WITH CEDILLA
68 SMALL LETTER H E8 SMALL LETTER E WITH GRAVE
69 SMALL LETTER I E9 SMALL LETTER E WITH ACUTE
6A SMALL LETTER J EA SMALL LETTER E WITH CIRCUMFLEX
6B SMALL LETTER K EB SMALL LETTER E WITH DIAERESIS
6C SMALL LETTER L EC SMALL LETTER I WITH GRAVE
6D SMALL LETTER M ED SMALL LETTER I WITH ACUTE
6E SMALL LETTER N EE SMALL LETTER I WITH CIRCUMFLEX
6F SMALL LETTER O EF SMALL LETTER I WITH DIAERESIS
70 SMALL LETTER P F0 SMALL LETTER ETH (Icelandic)
71 SMALL LETTER Q F1 SMALL LETTER N WITH TILDE
72 SMALL LETTER R F2 SMALL LETTER O WITH GRAVE
73 SMALL LETTER S F3 SMALL LETTER O WITH ACUTE
74 SMALL LETTER T F4 SMALL LETTER O WITH CIRCUMFLEX
75 SMALL LETTER U F5 SMALL LETTER O WITH TILDE
76 SMALL LETTER V F6 SMALL LETTER O WITH DIAERESIS
77 SMALL LETTER W F7 DIVISION SIGN
78 SMALL LETTER X F8 SMALL LETTER O WITH STROKE
79 SMALL LETTER Y F9 SMALL LETTER U WITH GRAVE
7A SMALL LETTER Z FA SMALL LETTER U WITH ACUTE
7B LEFT CURLY BRACKET FB SMALL LETTER U WITH CIRCUMFLEX
7C VERTICAL LINE FC SMALL LETTER U WITH DIAERESIS
7D RIGHT CURLY BRACKET FD SMALL LETTER Y WITH ACUTE
7E TILDE FE SMALL LETTER THORN (Icelandic)
FF SMALL LETTER Y WITH DIAERESIS

View file

@ -0,0 +1,4 @@
set(COMPONENT_SRCS "semihost_vfs_example_main.c")
set(COMPONENT_ADD_INCLUDEDIRS ".")
register_component()

View file

@ -0,0 +1,4 @@
#
# "main" pseudo-component makefile.
#
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)

View file

@ -0,0 +1,92 @@
/* SPIFFS filesystem example.
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "esp_err.h"
#include "esp_log.h"
#include "esp_vfs_semihost.h"
static const char *TAG = "example";
#define STRINGIFY(s) STRINGIFY2(s)
#define STRINGIFY2(s) #s
static uint8_t s_buf[512];
void app_main(void)
{
// Register host FS at '/host'. On the host file will be written/read in the current semihosting dir of OpenOCD
esp_err_t ret = esp_vfs_semihost_register("/host", NULL);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to register semihost driver (%s)!", esp_err_to_name(ret));
return;
}
ESP_LOGW(TAG, "Switch to semihosted stdout");
FILE *fout = freopen("/host/esp32_stdout.txt", "w", stdout);
if (fout == NULL) {
ESP_LOGE(TAG, "Failed to reopen stdout (%d)!", errno);
return;
}
// Increase file buffer to perform data transfers using larger chunks.
// Every read/write triggers breakpoint, so transfering of small chunks is quite inefficient.
setvbuf(fout, (char *)s_buf, _IOFBF, sizeof(s_buf));
// this will be printed to the file on host
ESP_LOGW(TAG, "Switched to semihosted stdout");
for (int i = 0; i < 100; i++) {
// printf is also redirected and sends data to the file on host
printf("Semihosted stdout write %d\n", i);
}
ESP_LOGW(TAG, "Switch to UART stdout");
fflush(fout); // ensure that all data are sent to the host file
// ftell can also be used, get file size before closing it in `freopen`
int count = ftell(fout);
stdout = freopen("/dev/uart/" STRINGIFY(CONFIG_CONSOLE_UART_NUM), "w", fout);
if (stdout == NULL) {
ESP_LOGE(TAG, "Failed to reopen semihosted stdout (%d)!", errno);
return;
}
// all remaining messages will be printed to UART
ESP_LOGW(TAG, "Switched back to UART stdout");
ESP_LOGI(TAG, "Wrote %d bytes", count);
printf("====================== HOST DATA START =========================\n");
// open() can also be used to access files on the host
int fd = open("/host/host_file.txt", O_RDONLY, 0);
if (fd == -1) {
ESP_LOGE(TAG, "Failed to open file (%d)!", errno);
return;
}
ssize_t read_bytes;
count = 0;
do {
read_bytes = read(fd, s_buf, sizeof(s_buf));
if(read_bytes == -1) {
ESP_LOGE(TAG, "Failed to read file (%d)!", errno);
} else if(read_bytes > 0) {
fwrite(s_buf, 1, read_bytes, stdout);
count += read_bytes;
}
} while(read_bytes > 0);
printf("====================== HOST DATA END =========================\n");
ESP_LOGI(TAG, "Read %d bytes", count);
if (close(fd) == -1) {
ESP_LOGE(TAG, "Failed to close file (%d)!", errno);
}
ret = esp_vfs_semihost_unregister("/host");
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to unregister semihost driver (%s)!", esp_err_to_name(ret));
}
}

View file

@ -0,0 +1,2 @@
# need this to detect that OpenOCD is connected
CONFIG_ESP32_DEBUG_OCDAWARE=y