diff --git a/components/esp32/cpu_start.c b/components/esp32/cpu_start.c index 769bd3eaf3..6998140aff 100644 --- a/components/esp32/cpu_start.c +++ b/components/esp32/cpu_start.c @@ -164,9 +164,10 @@ void start_cpu0_default(void) esp_setup_syscalls(); esp_vfs_dev_uart_register(); esp_reent_init(_GLOBAL_REENT); - _GLOBAL_REENT->_stdout = fopen("/dev/uart/0", "w"); // use fdopen here? - _GLOBAL_REENT->_stderr = _GLOBAL_REENT->_stdout; - _GLOBAL_REENT->_stdin = _GLOBAL_REENT->_stdout; + const char* default_uart_dev = "/dev/uart/0"; + _GLOBAL_REENT->_stdout = fopen(default_uart_dev, "w"); + _GLOBAL_REENT->_stderr = fopen(default_uart_dev, "w"); + _GLOBAL_REENT->_stdin = fopen(default_uart_dev, "r"); do_global_ctors(); esp_ipc_init(); spi_flash_init(); diff --git a/components/vfs/include/esp_vfs.h b/components/vfs/include/esp_vfs.h index 0d1c3d1479..2d9e52c5af 100644 --- a/components/vfs/include/esp_vfs.h +++ b/components/vfs/include/esp_vfs.h @@ -71,8 +71,8 @@ typedef struct size_t (*write)(int fd, const void * data, size_t size); }; union { - _off_t (*lseek_p)(void* p, int fd, _off_t size, int mode); - _off_t (*lseek)(int fd, _off_t size, int mode); + off_t (*lseek_p)(void* p, int fd, off_t size, int mode); + off_t (*lseek)(int fd, off_t size, int mode); }; union { ssize_t (*read_p)(void* ctx, int fd, void * dst, size_t size); @@ -137,7 +137,7 @@ esp_err_t esp_vfs_register(const char* base_path, const esp_vfs_t* vfs, void* ct */ ssize_t esp_vfs_write(struct _reent *r, int fd, const void * data, size_t size); -_off_t esp_vfs_lseek(struct _reent *r, int fd, _off_t size, int mode); +off_t esp_vfs_lseek(struct _reent *r, int fd, off_t size, int mode); ssize_t esp_vfs_read(struct _reent *r, int fd, void * dst, size_t size); int esp_vfs_open(struct _reent *r, const char * path, int flags, int mode); int esp_vfs_close(struct _reent *r, int fd); diff --git a/components/vfs/vfs.c b/components/vfs/vfs.c index afc7149bad..bf26968ff7 100644 --- a/components/vfs/vfs.c +++ b/components/vfs/vfs.c @@ -167,7 +167,7 @@ ssize_t esp_vfs_write(struct _reent *r, int fd, const void * data, size_t size) return ret; } -_off_t esp_vfs_lseek(struct _reent *r, int fd, _off_t size, int mode) +off_t esp_vfs_lseek(struct _reent *r, int fd, off_t size, int mode) { const vfs_entry_t* vfs = get_vfs_for_fd(fd); if (vfs == NULL) { diff --git a/components/vfs/vfs_uart.c b/components/vfs/vfs_uart.c index 179c5e2585..6b6fad8e4b 100644 --- a/components/vfs/vfs_uart.c +++ b/components/vfs/vfs_uart.c @@ -1,3 +1,17 @@ +// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + #include #include "esp_vfs.h" #include "esp_attr.h" @@ -6,6 +20,7 @@ #include "soc/uart_struct.h" static uart_dev_t* s_uarts[3] = {&UART0, &UART1, &UART2}; +static _lock_t s_uart_locks[3]; // per-UART locks, lazily initialized static int IRAM_ATTR uart_open(const char * path, int flags, int mode) { @@ -36,21 +51,12 @@ static size_t IRAM_ATTR uart_write(int fd, const void * data, size_t size) assert(fd >=0 && fd < 3); const char *data_c = (const char *)data; uart_dev_t* uart = s_uarts[fd]; - static _lock_t stdout_lock; /* lazily initialised */ - /* Even though newlib does stream locking on stdout, we need - a dedicated stdout UART lock... - - This is because each task has its own _reent structure with - unique FILEs for stdin/stdout/stderr, so these are - per-thread (lazily initialised by __sinit the first time a - stdio function is used, see findfp.c:235. - - It seems like overkill to allocate a FILE-per-task and lock - a thread-local stream, but I see no easy way to fix this - (pre-__sinit_, tasks have "fake" FILEs ie __sf_fake_stdout - which aren't fully valid.) - */ - _lock_acquire_recursive(&stdout_lock); + /* + * Even though newlib does stream locking on each individual stream, we need + * a dedicated UART lock if two streams (stdout and stderr) point to the + * same UART. + */ + _lock_acquire_recursive(&s_uart_locks[fd]); for (size_t i = 0; i < size; i++) { #if CONFIG_NEWLIB_STDOUT_ADDCR if (data_c[i]=='\n') { @@ -59,7 +65,7 @@ static size_t IRAM_ATTR uart_write(int fd, const void * data, size_t size) #endif uart_tx_char(uart, data_c[i]); } - _lock_release_recursive(&stdout_lock); + _lock_release_recursive(&s_uart_locks[fd]); return size; } diff --git a/make/test_build_system.sh b/make/test_build_system.sh index 7c8cbc1f1e..d08ae6c8a2 100755 --- a/make/test_build_system.sh +++ b/make/test_build_system.sh @@ -59,9 +59,9 @@ function run_tests() print_status "Updating component source file rebuilds component" # touch a file & do a build take_build_snapshot - touch ${IDF_PATH}/components/esp32/syscalls.c + touch ${IDF_PATH}/components/esp32/cpu_start.c make || failure "Failed to partial build" - assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/syscalls.o + assert_rebuilt ${APP_BINS} esp32/libesp32.a esp32/cpu_start.o assert_not_rebuilt lwip/liblwip.a freertos/libfreertos.a ${BOOTLOADER_BINS} partitions_singleapp.bin print_status "Bootloader source file rebuilds bootloader"