1 /* SPIFFS filesystem example.
2 This example code is in the Public Domain (or CC0 licensed, at your option.)
3
4 Unless required by applicable law or agreed to in writing, this
5 software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
6 CONDITIONS OF ANY KIND, either express or implied.
7 */
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <errno.h>
12 #include <sys/unistd.h>
13 #include <sys/stat.h>
14 #include <fcntl.h>
15 #include "esp_err.h"
16 #include "esp_log.h"
17 #include "esp_vfs_semihost.h"
18
19 static const char *TAG = "example";
20
21 #define STRINGIFY(s) STRINGIFY2(s)
22 #define STRINGIFY2(s) #s
23
24 static uint8_t s_buf[512];
25
app_main(void)26 void app_main(void)
27 {
28 // Register host FS at '/host'. On the host file will be written/read in the current semihosting dir of OpenOCD
29 esp_err_t ret = esp_vfs_semihost_register("/host", NULL);
30 if (ret != ESP_OK) {
31 ESP_LOGE(TAG, "Failed to register semihost driver (%s)!", esp_err_to_name(ret));
32 return;
33 }
34
35 ESP_LOGW(TAG, "Switch to semihosted stdout");
36 FILE *fout = freopen("/host/esp32_stdout.txt", "w", stdout);
37 if (fout == NULL) {
38 ESP_LOGE(TAG, "Failed to reopen stdout (%d)!", errno);
39 return;
40 }
41 // Increase file buffer to perform data transfers using larger chunks.
42 // Every read/write triggers breakpoint, so transferring of small chunks is quite inefficient.
43 setvbuf(fout, (char *)s_buf, _IOFBF, sizeof(s_buf));
44
45 // this will be printed to the file on host
46 ESP_LOGW(TAG, "Switched to semihosted stdout");
47 for (int i = 0; i < 100; i++) {
48 // printf is also redirected and sends data to the file on host
49 printf("Semihosted stdout write %d\n", i);
50 }
51 ESP_LOGW(TAG, "Switch to UART stdout");
52 fflush(fout); // ensure that all data are sent to the host file
53 // ftell can also be used, get file size before closing it in `freopen`
54 int count = ftell(fout);
55 stdout = freopen("/dev/uart/" STRINGIFY(CONFIG_ESP_CONSOLE_UART_NUM), "w", fout);
56 if (stdout == NULL) {
57 ESP_LOGE(TAG, "Failed to reopen semihosted stdout (%d)!", errno);
58 return;
59 }
60 // all remaining messages will be printed to UART
61 ESP_LOGW(TAG, "Switched back to UART stdout");
62 ESP_LOGI(TAG, "Wrote %d bytes", count);
63
64 printf("====================== HOST DATA START =========================\n");
65 // open() can also be used to access files on the host
66 int fd = open("/host/host_file.txt", O_RDONLY, 0);
67 if (fd == -1) {
68 ESP_LOGE(TAG, "Failed to open file (%d)!", errno);
69 return;
70 }
71 ssize_t read_bytes;
72 count = 0;
73 do {
74 read_bytes = read(fd, s_buf, sizeof(s_buf));
75 if(read_bytes == -1) {
76 ESP_LOGE(TAG, "Failed to read file (%d)!", errno);
77 } else if(read_bytes > 0) {
78 fwrite(s_buf, 1, read_bytes, stdout);
79 count += read_bytes;
80 }
81 } while(read_bytes > 0);
82 printf("====================== HOST DATA END =========================\n");
83 ESP_LOGI(TAG, "Read %d bytes", count);
84 if (close(fd) == -1) {
85 ESP_LOGE(TAG, "Failed to close file (%d)!", errno);
86 }
87
88 ret = esp_vfs_semihost_unregister("/host");
89 if (ret != ESP_OK) {
90 ESP_LOGE(TAG, "Failed to unregister semihost driver (%s)!", esp_err_to_name(ret));
91 }
92 }
93