From 782972c6a16d28d2b96d007217641336aac5b541 Mon Sep 17 00:00:00 2001 From: Nathan Hui Date: Fri, 20 Dec 2024 23:20:19 -0800 Subject: [PATCH] feat: Adds basic conio --- pc_hal/CMakeLists.txt | 3 + src/cli/conio.cpp | 134 ++++++++++++++++++++++++++++++++++-------- src/cli/conio.hpp | 28 +++++++-- 3 files changed, 135 insertions(+), 30 deletions(-) diff --git a/pc_hal/CMakeLists.txt b/pc_hal/CMakeLists.txt index 2de6688..3a6ac08 100644 --- a/pc_hal/CMakeLists.txt +++ b/pc_hal/CMakeLists.txt @@ -3,6 +3,8 @@ project(smartfin_pc) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) +find_package(Threads REQUIRED) + include_directories( . ../src/ @@ -47,3 +49,4 @@ set(SMARTFIN_SOURCE_FILES ../src/fileCLI/fileCLI.cpp ) add_executable(smartfin_pc ${SMARTFIN_SOURCE_FILES}) +target_link_libraries(smartfin_pc Threads::Threads) diff --git a/src/cli/conio.cpp b/src/cli/conio.cpp index 6783e8f..e361fa2 100644 --- a/src/cli/conio.cpp +++ b/src/cli/conio.cpp @@ -11,20 +11,47 @@ #include "product.hpp" #include -#include - +#if SF_PLATFORM == SF_PLATFORM_GLIBC +#include +#include +#include +#elif SF_PLATFORM == SF_PLATFORM_PARTICLE #include "Particle.h" - +#endif char SF_OSAL_printfBuffer[SF_OSAL_PRINTF_BUFLEN]; +#if SF_PLATFORM == SF_PLATFORM_GLIBC +pthread_t read_thread, write_thread; +#define SF_OSAL_READ_BUFLEN 2048 +char SF_OSAL_inputBuffer[SF_OSAL_READ_BUFLEN]; +std::size_t read_head_idx = 0, read_tail_idx = 0; +void *read_loop(void *_) +{ + while (true) + { + SF_OSAL_inputBuffer[read_head_idx % SF_OSAL_READ_BUFLEN] = getchar(); + read_head_idx++; + } + return nullptr; +} +#endif extern "C" { // Determines if key has been pressed - int kbhit(void) + int SF_OSAL_kbhit(void) { +#if SF_PLATFORM == SF_PLATFORM_PARTICLE return Serial.available(); +#elif SF_PLATFORM == SF_PLATFORM_GLIBC + return read_head_idx != read_tail_idx; +#endif + } + + void SF_OSAL_flush_input(void) + { + read_tail_idx = read_head_idx; } int SF_OSAL_getch(void) @@ -36,15 +63,23 @@ extern "C" } return Serial.read(); #elif SF_PLATFORM == SF_PLATFORM_GLIBC - return getchar(); + char retval = SF_OSAL_inputBuffer[read_tail_idx % SF_OSAL_READ_BUFLEN]; + read_tail_idx++; + return retval; #endif } // Write character - int putch(int ch) + int SF_OSAL_putch(int ch) { - Serial.print((char) ch); +#if SF_PLATFORM == SF_PLATFORM_PARTICLE + Serial.print((char)ch); + return ch; +#elif SF_PLATFORM == SF_PLATFORM_GLIBC + putchar(ch); + fflush(stdout); return ch; +#endif } int SF_OSAL_getline(char *buffer, int buflen) @@ -52,32 +87,60 @@ extern "C" int i = 0; char userInput; +#if SF_PLATFORM == SF_PLATFORM_PARTICLE while (i < buflen) { Particle.process(); - if (kbhit()) + if (SF_OSAL_kbhit()) { userInput = SF_OSAL_getch(); - switch(userInput) + switch (userInput) { - case '\b': - i--; - putch('\b'); - putch(' '); - putch('\b'); - break; - default: - buffer[i++] = userInput; - putch(userInput); - break; - case '\r': - buffer[i++] = 0; - putch('\r'); - putch('\n'); - return i; + case '\b': + i--; + SF_OSAL_putch('\b'); + SF_OSAL_putch(' '); + SF_OSAL_putch('\b'); + break; + default: + buffer[i++] = userInput; + SF_OSAL_putch(userInput); + break; + case '\r': + buffer[i++] = 0; + SF_OSAL_putch('\r'); + SF_OSAL_putch('\n'); + return i; } } } +#elif SF_PLATFORM == SF_PLATFORM_GLIBC + while (i < buflen) + { + if (SF_OSAL_kbhit()) + { + userInput = SF_OSAL_getch(); + switch (userInput) + { + case '\b': + i--; + SF_OSAL_putch('\b'); + SF_OSAL_putch(' '); + SF_OSAL_putch('\b'); + break; + default: + buffer[i++] = userInput; + SF_OSAL_putch(userInput); + break; + case '\r': + buffer[i++] = 0; + SF_OSAL_putch('\r'); + SF_OSAL_putch('\n'); + return i; + } + } + } +#endif return i; } @@ -90,9 +153,30 @@ extern "C" nBytes = vsnprintf(SF_OSAL_printfBuffer, SF_OSAL_PRINTF_BUFLEN, fmt, vargs); Serial.write(SF_OSAL_printfBuffer); #elif SF_PLATFORM == SF_PLATFORM_GLIBC - nBytes = vprintf(fmt, vargs); + vprintf(fmt, vargs); + fflush(stdout); #endif va_end(vargs); return nBytes; } + + void SF_OSAL_init_conio(void) + { +#if SF_PLATFORM == SF_PLATFORM_PARTICLE + Serial.begin(SF_SERIAL_SPEED); +#elif SF_PLATFORM == SF_PLATFORM_GLIBC + pthread_create(&read_thread, NULL, read_loop, NULL); + struct termios term; + tcgetattr(fileno(stdin), &term); + + term.c_lflag &= ~ECHO; + tcsetattr(fileno(stdin), 0, &term); +#endif + } + + void SF_OSAL_deinit_conio(void) + { +#if SF_PLATFORM == SF_PLATFORM_GLIBC +#endif + } } \ No newline at end of file diff --git a/src/cli/conio.hpp b/src/cli/conio.hpp index 09853e3..6526bad 100644 --- a/src/cli/conio.hpp +++ b/src/cli/conio.hpp @@ -17,16 +17,16 @@ extern "C" /** * @brief Checks if key is pressed * - * @return int whether key is pressed + * @return 1 if next keypress is available, otherwise 0 */ - int kbhit(void); + int SF_OSAL_kbhit(void); /** * @brief Pushes character to serial - * + * * @param ch character to push - * @return int Sucsess value + * @return Printed char */ - int putch(int ch); + int SF_OSAL_putch(int ch); /** * @brief Printf equivilent * @@ -51,6 +51,24 @@ extern "C" */ int SF_OSAL_getch(void); + /** + * @brief Initializes the conio facility + * + */ + void SF_OSAL_init_conio(void); + + /** + * @brief Safely deinitializes the conio facility + * + */ + void SF_OSAL_deinit_conio(void); + + /** + * @brief Flushes any input buffer + * + */ + void SF_OSAL_flush_input(void); + #ifdef __cplusplus } #endif