#include "unistd.h" #include #include #include #include #include "third_party/printf/printf.h" #include "fcntl.h" #include "uart.h" #ifdef errno #undef errno #endif #if defined(__GNUC__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wold-style-cast" #endif enum class FileType { kUART, kUARTDirect, }; struct File { FileType type; int flags; void *extra; }; static constexpr size_t kFilesCount = 5; static File files[5] { { FileType::kUART, O_NONBLOCK, reinterpret_cast(&g_uart1), }, // STDIN_FILENO { FileType::kUART, O_NONBLOCK, reinterpret_cast(&g_uart1), }, // STDOUT_FILENO { FileType::kUARTDirect, 0, reinterpret_cast(&g_uart1), }, // STDERR_FILENO { FileType::kUART, O_NONBLOCK, reinterpret_cast(&g_uart3), }, // WIFI_FILENO { FileType::kUART, O_NONBLOCK, reinterpret_cast(&g_uart4), }, // GPS_FILENO }; int errno{}; extern "C" [[noreturn]] void vApplicationMallocFailedHook(void) { for (;;); } extern "C" [[noreturn]] void vApplicationStackOverflowHook(void *task_handle, char *task_name) { (void) task_handle; (void) task_name; for (;;); } extern "C" void vApplicationIdleHook(void) { } extern "C" [[noreturn]] void _exit(int __status) { (void) __status; for (;;); } /* func can be NULL, in which case no function information is given. */ extern "C" [[noreturn]] void __assert_func ( const char *file, int line, const char *func, const char *failedexpr) { dprintf(STDERR_FILENO, "assertion \"%s\" failed: file \"%s\", line %d%s%s\n", failedexpr, file, line, func ? ", function: " : "", func ? func : ""); abort(); /* NOTREACHED */ } static File* FileOfDescriptor(int fd) { if (fd < 0 || static_cast(fd) >= kFilesCount) return nullptr; return files + fd; } extern "C" ssize_t read(int fd, void *buf, size_t nbytes) { File* file = FileOfDescriptor(fd); if (file == nullptr) { errno = EBADF; return -1; } size_t ret{}; switch (file->type) { case FileType::kUART: ret = UARTRead(reinterpret_cast(file->extra), buf, nbytes); // XXX if fcntl support for disabling O_NONBLOCK will ever be added, // then it has to something with this block of code if (ret == 0) { errno = EWOULDBLOCK; ret = -1; } break; case FileType::kUARTDirect: ret = UARTReadDirect(reinterpret_cast(file->extra), buf, nbytes); break; } return ret; } extern "C" ssize_t write(int fd, const void *buf, size_t nbytes) { File* file = FileOfDescriptor(fd); if (file == nullptr) { errno = EBADF; return -1; } size_t ret{}; switch (file->type) { case FileType::kUART: ret = UARTWrite(reinterpret_cast(file->extra), buf, nbytes); break; case FileType::kUARTDirect: ret = UARTWriteDirect(reinterpret_cast(file->extra), buf, nbytes); break; } return ret; } static void dputchar(char c, void* fd) { write(reinterpret_cast(fd), &c, 1); } static void dputchar(char c, int fd) { write(fd, &c, 1); } extern "C" int dprintf(int fd, const char * format, ...) { va_list args; va_start(args, format); const int ret = vfctprintf(dputchar, reinterpret_cast(fd), format, args); va_end(args); return ret; } extern "C" int vdprintf(int fd, const char * format, va_list args) { return vfctprintf(dputchar, reinterpret_cast(fd), format, args); } extern "C" void putchar_(char c) { dputchar(c, STDIN_FILENO); }