mirror of https://github.com/ARMmbed/mbed-os.git
mbed_retarget: Add a minimal console implementation to provide basic functionalities
The retarget code allocates an array of FileHandle* for console and file handling (filehandles). A tiny target only needs a console (putc/getc). There is no need for file handling. The POSIX layer and the array of FileHandle* is not required for small targets that only need a console ; this code is optionally compiled out if the configuration parameter platform.stdio-minimal-console-only is set to `"true"`.pull/11796/head
parent
734072ffc3
commit
051991fafb
|
@ -45,6 +45,7 @@ public:
|
|||
Stream(const char *name = NULL);
|
||||
virtual ~Stream();
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
int putc(int c);
|
||||
int puts(const char *s);
|
||||
int getc();
|
||||
|
@ -59,7 +60,7 @@ public:
|
|||
return _file;
|
||||
}
|
||||
|
||||
protected:
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
virtual int close();
|
||||
virtual ssize_t write(const void *buffer, size_t length);
|
||||
virtual ssize_t read(void *buffer, size_t length);
|
||||
|
@ -70,10 +71,13 @@ protected:
|
|||
virtual int sync();
|
||||
virtual off_t size();
|
||||
|
||||
protected:
|
||||
virtual int _putc(int c) = 0;
|
||||
virtual int _getc() = 0;
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
std::FILE *_file;
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
/** Acquire exclusive access to this object.
|
||||
*/
|
||||
|
|
|
@ -373,7 +373,7 @@ private:
|
|||
template <class Callable, class... Args>
|
||||
void call_once(once_flag &flag, Callable&& f, Args&&... args)
|
||||
{
|
||||
if (!(core_util_atomic_load_explicit(&flag.__guard, mbed_memory_order_acquire) & 1)) {
|
||||
if (!(core_util_atomic_load_explicit((uint8_t *)&flag.__guard, mbed_memory_order_acquire) & 1)) {
|
||||
if (__cxa_guard_acquire(&flag.__guard)) {
|
||||
mstd::invoke(mstd::forward<Callable>(f), mstd::forward<Args>(args)...);
|
||||
__cxa_guard_release(&flag.__guard);
|
||||
|
|
|
@ -12,7 +12,12 @@
|
|||
},
|
||||
|
||||
"stdio-buffered-serial": {
|
||||
"help": "(Applies if target.console-uart is true.) Use UARTSerial driver to obtain buffered serial I/O on stdin/stdout/stderr. If false, unbuffered serial_getc and serial_putc are used directly.",
|
||||
"help": "(Applies if target.console-uart is true and stdio-minimal-console-only is false.) Use UARTSerial driver to obtain buffered serial I/O on stdin/stdout/stderr. If false, unbuffered serial_getc and serial_putc are used directly.",
|
||||
"value": false
|
||||
},
|
||||
|
||||
"stdio-minimal-console-only": {
|
||||
"help": "(Ignores stdio-buffered-serial) Creates a console for basic unbuffered I/O operations. Enable if your application does not require file handles to access the serial interface. The POSIX `fsync` function will always an error.",
|
||||
"value": false
|
||||
},
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ typedef unsigned int gid_t; ///< Group ID
|
|||
/** \addtogroup platform-public-api */
|
||||
/** @{*/
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
/**
|
||||
* \defgroup platform_retarget Retarget functions
|
||||
* @{
|
||||
|
@ -90,7 +91,6 @@ typedef unsigned int gid_t; ///< Group ID
|
|||
/* DIR declarations must also be here */
|
||||
#if __cplusplus
|
||||
namespace mbed {
|
||||
|
||||
class FileHandle;
|
||||
class DirHandle;
|
||||
|
||||
|
@ -185,6 +185,7 @@ typedef mbed::DirHandle DIR;
|
|||
#else
|
||||
typedef struct Dir DIR;
|
||||
#endif
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
/* The intent of this section is to unify the errno error values to match
|
||||
* the POSIX definitions for the GCC_ARM, ARMCC and IAR compilers. This is
|
||||
|
@ -559,6 +560,7 @@ struct pollfd {
|
|||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
int open(const char *path, int oflag, ...);
|
||||
#ifndef __IAR_SYSTEMS_ICC__ /* IAR provides fdopen itself */
|
||||
#if __cplusplus
|
||||
|
@ -567,12 +569,14 @@ extern "C" {
|
|||
FILE *fdopen(int fildes, const char *mode);
|
||||
#endif
|
||||
#endif
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
ssize_t write(int fildes, const void *buf, size_t nbyte);
|
||||
ssize_t read(int fildes, void *buf, size_t nbyte);
|
||||
int fsync(int fildes);
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
off_t lseek(int fildes, off_t offset, int whence);
|
||||
int ftruncate(int fildes, off_t length);
|
||||
int isatty(int fildes);
|
||||
int fsync(int fildes);
|
||||
int fstat(int fildes, struct stat *st);
|
||||
int fcntl(int fildes, int cmd, ...);
|
||||
int poll(struct pollfd fds[], nfds_t nfds, int timeout);
|
||||
|
@ -586,11 +590,12 @@ extern "C" {
|
|||
long telldir(DIR *);
|
||||
void seekdir(DIR *, long);
|
||||
int mkdir(const char *name, mode_t n);
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
#if __cplusplus
|
||||
}; // extern "C"
|
||||
|
||||
namespace mbed {
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
/** This call is an analogue to POSIX fdopen().
|
||||
*
|
||||
* It associates a C stream to an already-opened FileHandle, to allow you to
|
||||
|
@ -619,6 +624,33 @@ std::FILE *fdopen(mbed::FileHandle *fh, const char *mode);
|
|||
*/
|
||||
int bind_to_fd(mbed::FileHandle *fh);
|
||||
|
||||
#else
|
||||
/** Targets may implement this to override how to write to the console.
|
||||
*
|
||||
* If the target has provided minimal_console_putc, this is called
|
||||
* to give the target a chance to specify an alternative minimal console.
|
||||
*
|
||||
* If this is not provided, serial_putc will be used if
|
||||
* `target.console-uart` is `true`, else there will not be an output.
|
||||
*
|
||||
* @param c The char to write
|
||||
* @return The written char
|
||||
*/
|
||||
int minimal_console_putc(int c);
|
||||
|
||||
/** Targets may implement this to override how to read from the console.
|
||||
*
|
||||
* If the target has provided minimal_console_getc, this is called
|
||||
* to give the target a chance to specify an alternative minimal console.
|
||||
*
|
||||
* If this is not provided, serial_getc will be used if
|
||||
* `target.console-uart` is `true`, else no input would be captured.
|
||||
*
|
||||
* @return The char read from the serial port
|
||||
*/
|
||||
int minimal_console_getc();
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
} // namespace mbed
|
||||
|
||||
#endif // __cplusplus
|
||||
|
|
|
@ -20,9 +20,14 @@
|
|||
|
||||
namespace mbed {
|
||||
|
||||
Stream::Stream(const char *name) : FileLike(name), _file(NULL)
|
||||
Stream::Stream(const char *name) :
|
||||
FileLike(name)
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
, _file(NULL)
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
{
|
||||
// No lock needed in constructor
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
/* open ourselves */
|
||||
_file = fdopen(this, "w+");
|
||||
// fdopen() will make us buffered because Stream::isatty()
|
||||
|
@ -33,14 +38,18 @@ Stream::Stream(const char *name) : FileLike(name), _file(NULL)
|
|||
} else {
|
||||
MBED_ERROR1(MBED_MAKE_ERROR(MBED_MODULE_PLATFORM, MBED_ERROR_CODE_OPEN_FAILED), "Stream obj failure", _file);
|
||||
}
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
}
|
||||
|
||||
Stream::~Stream()
|
||||
{
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
// No lock can be used in destructor
|
||||
fclose(_file);
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
}
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
int Stream::putc(int c)
|
||||
{
|
||||
lock();
|
||||
|
@ -73,6 +82,7 @@ char *Stream::gets(char *s, int size)
|
|||
unlock();
|
||||
return ret;
|
||||
}
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
int Stream::close()
|
||||
{
|
||||
|
@ -142,6 +152,8 @@ off_t Stream::size()
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
int Stream::printf(const char *format, ...)
|
||||
{
|
||||
lock();
|
||||
|
@ -184,4 +196,6 @@ int Stream::vscanf(const char *format, std::va_list args)
|
|||
return r;
|
||||
}
|
||||
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
} // namespace mbed
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include <mstd_mutex>
|
||||
#include <time.h>
|
||||
#include "platform/platform.h"
|
||||
#include "platform/FilePath.h"
|
||||
|
@ -75,6 +76,12 @@ asm(" .global __use_full_stdio\n");
|
|||
# define PREFIX(x) x
|
||||
#endif
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
# define RETARGET_OPEN_MAX OPEN_MAX
|
||||
#else
|
||||
# define RETARGET_OPEN_MAX 3
|
||||
#endif // MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
#define FILE_HANDLE_RESERVED ((FileHandle*)0xFFFFFFFF)
|
||||
|
||||
/**
|
||||
|
@ -104,20 +111,25 @@ extern const char __stderr_name[] = "/stderr";
|
|||
unsigned char *mbed_heap_start = 0;
|
||||
uint32_t mbed_heap_size = 0;
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
/* newlib has the filehandle field in the FILE struct as a short, so
|
||||
* we can't just return a Filehandle* from _open and instead have to
|
||||
* put it in a filehandles array and return the index into that array
|
||||
*/
|
||||
static FileHandle *filehandles[OPEN_MAX] = { FILE_HANDLE_RESERVED, FILE_HANDLE_RESERVED, FILE_HANDLE_RESERVED };
|
||||
static char stdio_in_prev[OPEN_MAX];
|
||||
static char stdio_out_prev[OPEN_MAX];
|
||||
static FileHandle *filehandles[RETARGET_OPEN_MAX] = { FILE_HANDLE_RESERVED, FILE_HANDLE_RESERVED, FILE_HANDLE_RESERVED };
|
||||
static SingletonPtr<PlatformMutex> filehandle_mutex;
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
static char stdio_in_prev[RETARGET_OPEN_MAX];
|
||||
static char stdio_out_prev[RETARGET_OPEN_MAX];
|
||||
|
||||
namespace mbed {
|
||||
void mbed_set_unbuffered_stream(std::FILE *_file);
|
||||
|
||||
void remove_filehandle(FileHandle *file)
|
||||
{
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
filehandle_mutex->lock();
|
||||
/* Remove all open filehandles for this */
|
||||
for (unsigned int fh_i = 0; fh_i < sizeof(filehandles) / sizeof(*filehandles); fh_i++) {
|
||||
|
@ -126,6 +138,7 @@ void remove_filehandle(FileHandle *file)
|
|||
}
|
||||
}
|
||||
filehandle_mutex->unlock();
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,7 +221,36 @@ short DirectSerial::poll(short events) const
|
|||
}
|
||||
return revents;
|
||||
}
|
||||
#if MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
# if MBED_CONF_TARGET_CONSOLE_UART
|
||||
|
||||
static void do_serial_init()
|
||||
{
|
||||
if (stdio_uart_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
serial_init(&stdio_uart, STDIO_UART_TX, STDIO_UART_RX);
|
||||
serial_baud(&stdio_uart, MBED_CONF_PLATFORM_STDIO_BAUD_RATE);
|
||||
#if CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTS
|
||||
serial_set_flow_control(&stdio_uart, FlowControlRTS, STDIO_UART_RTS, NC);
|
||||
#elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_CTS
|
||||
serial_set_flow_control(&stdio_uart, FlowControlCTS, NC, STDIO_UART_CTS);
|
||||
#elif CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTSCTS
|
||||
serial_set_flow_control(&stdio_uart, FlowControlRTSCTS, STDIO_UART_RTS, STDIO_UART_CTS);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void do_serial_init_once()
|
||||
{
|
||||
static mstd::once_flag once;
|
||||
mstd::call_once(once, do_serial_init);
|
||||
}
|
||||
|
||||
#endif // MBED_CONF_TARGET_CONSOLE_UART
|
||||
#endif // MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
#endif // DEVICE_SERIAL
|
||||
|
||||
class Sink : public FileHandle {
|
||||
public:
|
||||
|
@ -247,7 +289,7 @@ ssize_t Sink::read(void *buffer, size_t size)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
MBED_WEAK FileHandle *mbed::mbed_target_override_console(int fd)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -292,11 +334,14 @@ static FileHandle *get_console(int fd)
|
|||
}
|
||||
return default_console();
|
||||
}
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
namespace mbed {
|
||||
/* Deal with the fact C library may not _open descriptors 0, 1, 2 - auto bind */
|
||||
FileHandle *mbed::mbed_file_handle(int fd)
|
||||
FileHandle *mbed_file_handle(int fd)
|
||||
{
|
||||
if (fd >= OPEN_MAX) {
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
if (fd >= RETARGET_OPEN_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
FileHandle *fh = filehandles[fd];
|
||||
|
@ -304,8 +349,14 @@ FileHandle *mbed::mbed_file_handle(int fd)
|
|||
filehandles[fd] = fh = get_console(fd);
|
||||
}
|
||||
return fh;
|
||||
#else
|
||||
return nullptr;
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
/**
|
||||
* Sets errno when file opening fails.
|
||||
* Wipes out the filehandle too.
|
||||
|
@ -374,13 +425,13 @@ static int reserve_filehandle()
|
|||
// find the first empty slot in filehandles, after the slots reserved for stdin/stdout/stderr
|
||||
filehandle_mutex->lock();
|
||||
int fh_i;
|
||||
for (fh_i = 3; fh_i < OPEN_MAX; fh_i++) {
|
||||
for (fh_i = 3; fh_i < RETARGET_OPEN_MAX; fh_i++) {
|
||||
/* Take a next free filehandle slot available. */
|
||||
if (filehandles[fh_i] == NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fh_i >= OPEN_MAX) {
|
||||
if (fh_i >= RETARGET_OPEN_MAX) {
|
||||
/* Too many file handles have been opened */
|
||||
errno = EMFILE;
|
||||
filehandle_mutex->unlock();
|
||||
|
@ -392,6 +443,7 @@ static int reserve_filehandle()
|
|||
return fh_i;
|
||||
}
|
||||
|
||||
|
||||
int mbed::bind_to_fd(FileHandle *fh)
|
||||
{
|
||||
int fildes = reserve_filehandle();
|
||||
|
@ -455,6 +507,8 @@ std::FILE *fdopen(FileHandle *fh, const char *mode)
|
|||
return stream;
|
||||
}
|
||||
}
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
|
||||
/* @brief standard c library fopen() retargeting function.
|
||||
*
|
||||
|
@ -508,16 +562,23 @@ extern "C" FILEHANDLE PREFIX(_open)(const char *name, int openflags)
|
|||
}
|
||||
#endif
|
||||
#ifndef __IAR_SYSTEMS_ICC__
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
/* FILENAME: "@(integer)" gives an already-allocated descriptor */
|
||||
if (name[0] == '@') {
|
||||
int fd;
|
||||
memcpy(&fd, name + 1, sizeof fd);
|
||||
return fd;
|
||||
}
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
#endif
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
return open(name, openflags_to_posix(openflags));
|
||||
#else
|
||||
return -1;
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
}
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
extern "C" int open(const char *name, int oflag, ...)
|
||||
{
|
||||
int fildes = reserve_filehandle();
|
||||
|
@ -554,12 +615,18 @@ extern "C" int open(const char *name, int oflag, ...)
|
|||
|
||||
return fildes;
|
||||
}
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
extern "C" int PREFIX(_close)(FILEHANDLE fh)
|
||||
{
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
return close(fh);
|
||||
#else
|
||||
return 0;
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
}
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
extern "C" int close(int fildes)
|
||||
{
|
||||
FileHandle *fhc = mbed_file_handle(fildes);
|
||||
|
@ -577,6 +644,7 @@ extern "C" int close(int fildes)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
static bool convert_crlf(int fd)
|
||||
{
|
||||
|
@ -673,7 +741,20 @@ finish:
|
|||
|
||||
extern "C" ssize_t write(int fildes, const void *buf, size_t length)
|
||||
{
|
||||
#if MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
if (fildes != STDOUT_FILENO && fildes != STDERR_FILENO) {
|
||||
errno = EBADF;
|
||||
return -1
|
||||
}
|
||||
|
||||
const unsigned char *buffer = static_cast<const unsigned char *>(buf);
|
||||
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
mbed::minimal_console_putc(buffer[i]);
|
||||
}
|
||||
|
||||
ssize_t ret = length;
|
||||
#else
|
||||
FileHandle *fhc = mbed_file_handle(fildes);
|
||||
if (fhc == NULL) {
|
||||
errno = EBADF;
|
||||
|
@ -681,6 +762,7 @@ extern "C" ssize_t write(int fildes, const void *buf, size_t length)
|
|||
}
|
||||
|
||||
ssize_t ret = fhc->write(buf, length);
|
||||
#endif // MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
|
@ -689,6 +771,18 @@ extern "C" ssize_t write(int fildes, const void *buf, size_t length)
|
|||
}
|
||||
}
|
||||
|
||||
#if MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
/* Write one character to a serial interface */
|
||||
MBED_WEAK int mbed::minimal_console_putc(int c)
|
||||
{
|
||||
#if MBED_CONF_TARGET_CONSOLE_UART && DEVICE_SERIAL
|
||||
do_serial_init_once();
|
||||
serial_putc(&stdio_uart, c);
|
||||
#endif // MBED_CONF_TARGET_CONSOLE_UART && DEVICE_SERIAL
|
||||
return c;
|
||||
}
|
||||
#endif // MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
#if defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
|
||||
extern "C" void PREFIX(_exit)(int return_code)
|
||||
{
|
||||
|
@ -768,6 +862,23 @@ extern "C" int PREFIX(_read)(FILEHANDLE fh, unsigned char *buffer, unsigned int
|
|||
|
||||
extern "C" ssize_t read(int fildes, void *buf, size_t length)
|
||||
{
|
||||
#if MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
if (fildes != STDIN_FILENO && fildes != STDERR_FILENO) {
|
||||
errno = EBADF;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (length == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned char *buffer = static_cast<unsigned char *>(buf);
|
||||
|
||||
buf[0] = minimal_console_getc();
|
||||
|
||||
ssize_t ret = 1;
|
||||
|
||||
#else
|
||||
FileHandle *fhc = mbed_file_handle(fildes);
|
||||
if (fhc == NULL) {
|
||||
errno = EBADF;
|
||||
|
@ -775,6 +886,7 @@ extern "C" ssize_t read(int fildes, void *buf, size_t length)
|
|||
}
|
||||
|
||||
ssize_t ret = fhc->read(buf, length);
|
||||
#endif // MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
if (ret < 0) {
|
||||
errno = -ret;
|
||||
return -1;
|
||||
|
@ -783,6 +895,19 @@ extern "C" ssize_t read(int fildes, void *buf, size_t length)
|
|||
}
|
||||
}
|
||||
|
||||
#if MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
/* Read a character from the serial interface */
|
||||
MBED_WEAK int mbed::minimal_console_getc()
|
||||
{
|
||||
#if MBED_CONF_TARGET_CONSOLE_UART && DEVICE_SERIAL
|
||||
do_serial_init_once();
|
||||
return serial_getc(&stdio_uart);
|
||||
#else
|
||||
return 0;
|
||||
#endif // MBED_CONF_TARGET_CONSOLE_UART && DEVICE_SERIAL
|
||||
}
|
||||
#endif // MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
|
||||
#ifdef __ARMCC_VERSION
|
||||
extern "C" int PREFIX(_istty)(FILEHANDLE fh)
|
||||
|
@ -790,9 +915,15 @@ extern "C" int PREFIX(_istty)(FILEHANDLE fh)
|
|||
extern "C" int _isatty(FILEHANDLE fh)
|
||||
#endif
|
||||
{
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
return isatty(fh);
|
||||
#else
|
||||
// Is attached to an interactive device
|
||||
return 1;
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
}
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
extern "C" int isatty(int fildes)
|
||||
{
|
||||
FileHandle *fhc = mbed_file_handle(fildes);
|
||||
|
@ -809,6 +940,7 @@ extern "C" int isatty(int fildes)
|
|||
return tty;
|
||||
}
|
||||
}
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
extern "C"
|
||||
#if defined(__ARMCC_VERSION)
|
||||
|
@ -819,6 +951,7 @@ long __lseek(int fh, long offset, int whence)
|
|||
int _lseek(FILEHANDLE fh, int offset, int whence)
|
||||
#endif
|
||||
{
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
#if defined(__ARMCC_VERSION)
|
||||
int whence = SEEK_SET;
|
||||
#endif
|
||||
|
@ -832,8 +965,13 @@ int _lseek(FILEHANDLE fh, int offset, int whence)
|
|||
return -1;
|
||||
}
|
||||
return off;
|
||||
#else
|
||||
// Not supported
|
||||
return -1;
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
}
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
extern "C" off_t lseek(int fildes, off_t offset, int whence)
|
||||
{
|
||||
FileHandle *fhc = mbed_file_handle(fildes);
|
||||
|
@ -873,9 +1011,11 @@ extern "C" int PREFIX(_ensure)(FILEHANDLE fh)
|
|||
return fsync(fh);
|
||||
}
|
||||
#endif
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
extern "C" int fsync(int fildes)
|
||||
{
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
FileHandle *fhc = mbed_file_handle(fildes);
|
||||
if (fhc == NULL) {
|
||||
errno = EBADF;
|
||||
|
@ -889,11 +1029,16 @@ extern "C" int fsync(int fildes)
|
|||
} else {
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
return -1;
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
}
|
||||
|
||||
|
||||
#ifdef __ARMCC_VERSION
|
||||
extern "C" long PREFIX(_flen)(FILEHANDLE fh)
|
||||
{
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
FileHandle *fhc = mbed_file_handle(fh);
|
||||
if (fhc == NULL) {
|
||||
errno = EBADF;
|
||||
|
@ -910,6 +1055,10 @@ extern "C" long PREFIX(_flen)(FILEHANDLE fh)
|
|||
return -1;
|
||||
}
|
||||
return size;
|
||||
#else
|
||||
// Not supported
|
||||
return -1;
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
}
|
||||
|
||||
// Do not compile this code for TFM secure target
|
||||
|
@ -983,7 +1132,7 @@ extern "C" __value_in_regs struct __initial_stackheap __user_setup_stackheap(uin
|
|||
|
||||
#endif
|
||||
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
#if !defined(__ARMCC_VERSION) && !defined(__ICCARM__)
|
||||
extern "C" int _fstat(int fh, struct stat *st)
|
||||
{
|
||||
|
@ -1042,12 +1191,12 @@ extern "C" int fcntl(int fildes, int cmd, ...)
|
|||
|
||||
extern "C" int poll(struct pollfd fds[], nfds_t nfds, int timeout)
|
||||
{
|
||||
if (nfds > OPEN_MAX) {
|
||||
if (nfds > RETARGET_OPEN_MAX) {
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct mbed::pollfh fhs[OPEN_MAX];
|
||||
struct mbed::pollfh fhs[RETARGET_OPEN_MAX];
|
||||
for (nfds_t n = 0; n < nfds; n++) {
|
||||
// Underlying FileHandle poll returns POLLNVAL if given NULL, so
|
||||
// we don't need to take special action.
|
||||
|
@ -1060,6 +1209,7 @@ extern "C" int poll(struct pollfd fds[], nfds_t nfds, int timeout)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
namespace std {
|
||||
extern "C" int remove(const char *path)
|
||||
|
@ -1127,6 +1277,7 @@ extern "C" char *_sys_command_string(char *cmd, int len)
|
|||
}
|
||||
#endif
|
||||
|
||||
#if !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
extern "C" DIR *opendir(const char *path)
|
||||
{
|
||||
FilePath fp(path);
|
||||
|
@ -1239,6 +1390,7 @@ extern "C" int statvfs(const char *path, struct statvfs *buf)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
#endif // !MBED_CONF_PLATFORM_STDIO_MINIMAL_CONSOLE_ONLY
|
||||
|
||||
#if defined(TOOLCHAIN_GCC)
|
||||
/* prevents the exception handling name demangling code getting pulled in */
|
||||
|
|
|
@ -110,4 +110,5 @@ pppd
|
|||
pppdebug
|
||||
ppp
|
||||
api
|
||||
uart
|
||||
_doxy_
|
||||
|
|
Loading…
Reference in New Issue