diff --git a/CMakeLists.txt b/CMakeLists.txt index 3ecab55a..1e895be5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,26 +238,35 @@ if(DEFINED PICO_BOARD OR PIP_FREERTOS) if(PIP_FREERTOS OR (DEFINED PICO_BOARD AND DEFINED PICO_FREERTOS)) add_definitions(-DPIP_FREERTOS) endif() - set(PIP_HAS_FILESYSTEM OFF CACHE BOOL "" FORCE) + # Common for all embedded targets: no /proc, no dlopen, no FFT, no console UI set(PIP_HAS_PROCESS OFF CACHE BOOL "" FORCE) set(PIP_HAS_DYNLIB OFF CACHE BOOL "" FORCE) set(PIP_HAS_FFT OFF CACHE BOOL "" FORCE) - set(PIP_HAS_SERIAL OFF CACHE BOOL "" FORCE) set(PIP_BUILD_CONSOLE OFF CACHE BOOL "" FORCE) if(DEFINED PICO_BOARD) if(NOT DEFINED PICO_FREERTOS) set(PIP_HAS_THREADS OFF CACHE BOOL "" FORCE) endif() - # pico-sdk lwip provides only a partial POSIX socket layer (no netinet/in.h, - # poll.h), so PIEthernet/PICAN and the paho.mqtt.c library cannot be built - # on Pico yet; keep sockets off by default + # Pico: no flash filesystem by default, no termios serial, and pico-sdk lwip + # provides only a partial POSIX socket layer (no netinet/in.h, poll.h), so + # PIEthernet/PICAN and the paho.mqtt.c library cannot be built on Pico yet + set(PIP_HAS_FILESYSTEM OFF CACHE BOOL "" FORCE) + set(PIP_HAS_SERIAL OFF CACHE BOOL "" FORCE) set(PIP_HAS_SOCKET OFF CACHE BOOL "" FORCE) set(PIP_BUILD_MQTT_CLIENT OFF CACHE BOOL "" FORCE) message(STATUS "Building PIP for Pi Pico SDK ${PICO_SDK_VERSION_STRING}") else() - if(NOT DEFINED LWIP) - set(PIP_HAS_SOCKET OFF CACHE BOOL "" FORCE) - endif() + # Generic FreeRTOS (e.g. ESP32): the platform provides a filesystem (SPIFFS), + # lwIP sockets and UART termios, so keep them enabled. Build only the module + # set the old FREERTOS builds used (crypt, compress, io_utils) + set(PIP_BUILD_USB OFF CACHE BOOL "" FORCE) + set(PIP_BUILD_LUA OFF CACHE BOOL "" FORCE) + set(PIP_BUILD_OPENCL OFF CACHE BOOL "" FORCE) + set(PIP_BUILD_CLIENT_SERVER OFF CACHE BOOL "" FORCE) + set(PIP_BUILD_CLOUD OFF CACHE BOOL "" FORCE) + set(PIP_BUILD_HTTP_CLIENT OFF CACHE BOOL "" FORCE) + set(PIP_BUILD_HTTP_SERVER OFF CACHE BOOL "" FORCE) + set(PIP_BUILD_MQTT_CLIENT OFF CACHE BOOL "" FORCE) endif() # ICU is not available/needed on embedded targets, esp-pip depends on LOCAL install set(ICU OFF) @@ -287,33 +296,39 @@ if(NOT PIP_HAS_THREADS) message(STATUS "PIP_BUILD_CLOUD requires PIP_HAS_THREADS and PIP_HAS_SOCKET, disabling PIP_BUILD_CLOUD") set(PIP_BUILD_CLOUD OFF CACHE BOOL "" FORCE) endif() + # PIHTTPClient works through a PIThread pool, PIMQTTClient through PIThreadPoolWorker, + # PIClientServer/PICloud through PIThread/PIThreadNotifier/PIDiagnostics + if(PIP_BUILD_HTTP_CLIENT) + message(STATUS "PIP_BUILD_HTTP_CLIENT requires PIP_HAS_THREADS, disabling PIP_BUILD_HTTP_CLIENT") + set(PIP_BUILD_HTTP_CLIENT OFF CACHE BOOL "" FORCE) + endif() + if(PIP_BUILD_MQTT_CLIENT) + message(STATUS "PIP_BUILD_MQTT_CLIENT requires PIP_HAS_THREADS, disabling PIP_BUILD_MQTT_CLIENT") + set(PIP_BUILD_MQTT_CLIENT OFF CACHE BOOL "" FORCE) + endif() + if(PIP_BUILD_CLIENT_SERVER) + message(STATUS "PIP_BUILD_CLIENT_SERVER requires PIP_HAS_THREADS, disabling PIP_BUILD_CLIENT_SERVER") + set(PIP_BUILD_CLIENT_SERVER OFF CACHE BOOL "" FORCE) + endif() +endif() +if(PIP_BUILD_CLIENT_SERVER AND NOT PIP_HAS_SOCKET) + message(STATUS "PIP_BUILD_CLIENT_SERVER requires PIP_HAS_SOCKET, disabling PIP_BUILD_CLIENT_SERVER") + set(PIP_BUILD_CLIENT_SERVER OFF CACHE BOOL "" FORCE) endif() if(PIP_BUILD_CLOUD AND NOT PIP_HAS_SOCKET) message(STATUS "PIP_BUILD_CLOUD requires PIP_HAS_SOCKET, disabling PIP_BUILD_CLOUD") set(PIP_BUILD_CLOUD OFF CACHE BOOL "" FORCE) endif() +if(PIP_BUILD_MQTT_CLIENT AND NOT PIP_HAS_SOCKET) + message(STATUS "PIP_BUILD_MQTT_CLIENT requires PIP_HAS_SOCKET, disabling PIP_BUILD_MQTT_CLIENT") + set(PIP_BUILD_MQTT_CLIENT OFF CACHE BOOL "" FORCE) +endif() -if(PIP_HAS_FILESYSTEM) - add_definitions(-DPIP_HAS_FILESYSTEM) -endif() -if(PIP_HAS_THREADS) - add_definitions(-DPIP_HAS_THREADS) -endif() -if(PIP_HAS_SOCKET) - add_definitions(-DPIP_HAS_SOCKET) -endif() -if(PIP_HAS_PROCESS) - add_definitions(-DPIP_HAS_PROCESS) -endif() -if(PIP_HAS_DYNLIB) - add_definitions(-DPIP_HAS_DYNLIB) -endif() -if(PIP_HAS_FFT) - add_definitions(-DPIP_HAS_FFT) -endif() -if(PIP_HAS_SERIAL) - add_definitions(-DPIP_HAS_SERIAL) -endif() +foreach(_PIP_FLAG PIP_HAS_FILESYSTEM PIP_HAS_THREADS PIP_HAS_SOCKET PIP_HAS_PROCESS PIP_HAS_DYNLIB PIP_HAS_FFT PIP_HAS_SERIAL) + if(${_PIP_FLAG}) + add_definitions(-D${_PIP_FLAG}) + endif() +endforeach() if (TESTS) set(PIP_ROOT_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}") @@ -465,7 +480,7 @@ else() endif() endif() set(CMAKE_C_FLAGS "${CMAKE_CXX_FLAGS}") -if(DEFINED ENV{QNX_HOST}) +if(DEFINED ENV{QNX_HOST} OR PIP_FREERTOS) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-32") endif() @@ -529,13 +544,20 @@ if (NOT CROSSTOOLS) pip_find_lib(sodium) if(sodium_FOUND) pip_module(crypt "sodium" "PIP crypt support" "" "" "") - pip_module(client_server "pip_io_utils" "PIP client-server helper" "" "" "") - pip_module(cloud "pip_io_utils" "PIP cloud support" "" "" "") endif() endif() + if (PIP_BUILD_CLIENT_SERVER) + pip_module(client_server "pip_io_utils" "PIP client-server helper" "" "" "") + endif() - if (PIP_BUILD_FFTW) + if (PIP_BUILD_CLOUD) + pip_module(cloud "pip_io_utils" "PIP cloud support" "" "" "") + endif() + + + # The fftw module implements PIFFT declared only with PIP_HAS_FFT + if (PIP_BUILD_FFTW AND PIP_HAS_FFT) # Check if PIP support fftw3 for PIFFT using in math module set(FFTW_LIB_NAME fftw3) set(FFTW_LIB_SUFFIXES "") @@ -738,8 +760,9 @@ string(REPLACE ";" "," PIP_EXPORTS_STR "${PIP_EXPORTS}") target_compile_definitions(pip PRIVATE "PICODE_DEFINES=\"${PIP_EXPORTS_STR}\"") -# Host tools are not built for Pico SDK cross builds -if (NOT DEFINED PICO_SDK_PATH) +# Host tools are not built for embedded targets or without filesystem +# support (all utils rely on PIFile/PIDir) +if (PIP_HAS_FILESYSTEM AND (NOT DEFINED PICO_SDK_PATH) AND (NOT PIP_FREERTOS)) set(_PIP_HOST_TOOLS ON) else() set(_PIP_HOST_TOOLS OFF) @@ -760,11 +783,23 @@ if(_PIP_HOST_TOOLS) add_subdirectory("utils/value_tree_translator") if(PIP_UTILS AND (NOT CROSSTOOLS)) add_subdirectory("utils/system_calib") - add_subdirectory("utils/udp_file_transfer") + # uses PITimer, PIEthernet and console tiles + if(PIP_HAS_THREADS AND PIP_HAS_SOCKET) + add_subdirectory("utils/udp_file_transfer") + endif() if(sodium_FOUND) - add_subdirectory("utils/system_daemon") - add_subdirectory("utils/crypt_tool") - add_subdirectory("utils/cloud_dispatcher") + # cloud peer daemon needs the console UI and the PICloud transport + if(PIP_BUILD_CONSOLE AND PIP_BUILD_CLOUD) + add_subdirectory("utils/system_daemon") + endif() + # cloud dispatcher talks over PICloud::TCP + if(PIP_BUILD_CLOUD) + add_subdirectory("utils/cloud_dispatcher") + endif() + # crypt tool needs the PICrypt module + if(PIP_BUILD_CRYPT) + add_subdirectory("utils/crypt_tool") + endif() endif() endif() endif() diff --git a/libs/io_utils/pibroadcast.cpp b/libs/io_utils/pibroadcast.cpp index 2ea80bba..40c7f746 100644 --- a/libs/io_utils/pibroadcast.cpp +++ b/libs/io_utils/pibroadcast.cpp @@ -21,7 +21,7 @@ #include "piliterals_time.h" -#ifdef PIP_HAS_SOCKET +#if defined(PIP_HAS_SOCKET) && defined(PIP_HAS_THREADS) /** \class PIBroadcast * \brief Broadcast for all interfaces, including loopback @@ -271,4 +271,4 @@ void PIBroadcast::run() { if (ac) addressesChanged(); } -#endif // PIP_HAS_SOCKET +#endif // PIP_HAS_SOCKET && PIP_HAS_THREADS diff --git a/libs/io_utils/pipackedtcp.cpp b/libs/io_utils/pipackedtcp.cpp index a00751b4..bcbb8243 100644 --- a/libs/io_utils/pipackedtcp.cpp +++ b/libs/io_utils/pipackedtcp.cpp @@ -22,7 +22,7 @@ #include "piethernet.h" #include "piliterals.h" -#ifdef PIP_HAS_SOCKET +#if defined(PIP_HAS_SOCKET) && defined(PIP_HAS_THREADS) /** \class PIPackedTCP pipackedtcp.h @@ -200,4 +200,4 @@ bool PIPackedTCP::closeDevice() { return eth->close(); } -#endif // PIP_HAS_SOCKET +#endif // PIP_HAS_SOCKET && PIP_HAS_THREADS diff --git a/libs/main/core/picout.cpp b/libs/main/core/picout.cpp index 0c33c9ef..ce2283b1 100644 --- a/libs/main/core/picout.cpp +++ b/libs/main/core/picout.cpp @@ -709,7 +709,6 @@ void PICout::applyFormat(PICoutFormat f) { } -#ifdef PIP_HAS_THREADS PIString PICout::getBuffer() { PIMutexLocker ml(PICout::__mutex__()); PIString ret = PICout::__string__(); @@ -729,7 +728,6 @@ void PICout::clearBuffer() { PIMutexLocker ml(PICout::__mutex__()); PICout::__string__().clear(); } -#endif // PIP_HAS_THREADS bool PICout::setOutputDevice(PICout::OutputDevice d, bool on) { diff --git a/libs/main/core/piobject.cpp b/libs/main/core/piobject.cpp index 9bfba4bc..30bc7ba1 100644 --- a/libs/main/core/piobject.cpp +++ b/libs/main/core/piobject.cpp @@ -172,7 +172,7 @@ bool PIObject::__MetaFunc::canConnectTo(const __MetaFunc & dst, int & args_count } -PIObject::PIObject(const PIString & name): _signature_(__PIOBJECT_SIGNATURE__), emitter_(0), thread_safe_(false), proc_event_queue(false) { +PIObject::PIObject(const PIString & name): _signature_(__PIOBJECT_SIGNATURE__), emitter_(0) { in_event_cnt = 0; setName(name); setDebug(true); diff --git a/libs/main/core/piobject.h b/libs/main/core/piobject.h index 16c63915..64659038 100644 --- a/libs/main/core/piobject.h +++ b/libs/main/core/piobject.h @@ -740,9 +740,11 @@ public: return proc_event_queue; } +#ifdef PIP_HAS_THREADS //! \~english Schedules the object for deferred deletion. //! \~russian Планирует отложенное удаление объекта. void deleteLater(); +#endif // PIP_HAS_THREADS //! \events //! \{ diff --git a/libs/main/io_devices/pican.cpp b/libs/main/io_devices/pican.cpp index 15ed3279..b3dc8cca 100644 --- a/libs/main/io_devices/pican.cpp +++ b/libs/main/io_devices/pican.cpp @@ -20,9 +20,6 @@ #include "pipropertystorage.h" #include "piwaitevent_p.h" -#if defined(LINUX) && defined(PIP_HAS_SOCKET) -# define PIP_CAN -#endif #ifdef PIP_CAN # include # include @@ -38,36 +35,29 @@ #endif -REGISTER_DEVICE(PICAN) - #ifdef PIP_CAN +REGISTER_DEVICE(PICAN) PRIVATE_DEFINITION_START(PICAN) PIWaitEvent event; PRIVATE_DEFINITION_END(PICAN) -#endif PICAN::PICAN(const PIString & path, PIIODevice::DeviceMode mode): PIIODevice(path, mode) { setThreadedReadBufferSize(256); setPath(path); -#ifdef PIP_CAN can_id = 0; sock = -1; PRIVATE->event.create(); -#endif } PICAN::~PICAN() { stopAndWait(); close(); -#ifdef PIP_CAN PRIVATE->event.destroy(); -#endif } bool PICAN::openDevice() { -#ifdef PIP_CAN piCout << "PICAN open device" << path(); sock = socket(PF_CAN, SOCK_RAW, CAN_RAW); if (sock < 0) { @@ -105,28 +95,21 @@ bool PICAN::openDevice() { } piCout << "PICAN Open OK!"; return true; -#else - piCoutObj << "PICAN not implemented on windows"; - return false; -#endif } bool PICAN::closeDevice() { -#ifdef PIP_CAN interrupt(); if (sock != -1) { ::shutdown(sock, SHUT_RDWR); ::close(sock); sock = -1; } -#endif return true; } ssize_t PICAN::readDevice(void * read_to, ssize_t max_size) { -#ifdef PIP_CAN if (sock == -1) return -1; // piCout << "PICAN read"; can_frame frame = {}; @@ -139,13 +122,10 @@ ssize_t PICAN::readDevice(void * read_to, ssize_t max_size) { memcpy(read_to, frame.data, piMini(frame.can_dlc, max_size)); readed_id = frame.can_id; return piMini(frame.can_dlc, max_size); -#endif - return 0; } ssize_t PICAN::writeDevice(const void * data, ssize_t max_size) { -#ifdef PIP_CAN if (sock == -1) return -1; // piCout << "PICAN write" << can_id << max_size; if (max_size > 8) { @@ -163,8 +143,6 @@ ssize_t PICAN::writeDevice(const void * data, ssize_t max_size) { return -1; } return max_size; -#endif - return 0; } @@ -184,9 +162,7 @@ int PICAN::readedCANID() const { void PICAN::interrupt() { -#ifdef PIP_CAN PRIVATE->event.interrupt(); -#endif } @@ -222,3 +198,5 @@ void PICAN::configureFromVariantDevice(const PIPropertyStorage & d) { setPath(d.propertyValueByName("path").toString()); setCANID(d.propertyValueByName("CAN ID").toString().toInt(16)); } + +#endif // PIP_CAN diff --git a/libs/main/io_devices/pican.h b/libs/main/io_devices/pican.h index 37938818..b67ba30d 100644 --- a/libs/main/io_devices/pican.h +++ b/libs/main/io_devices/pican.h @@ -27,7 +27,13 @@ #include "piiodevice.h" +// CAN raw sockets (PF_CAN) exist only on Linux +#if defined(LINUX) && defined(PIP_HAS_SOCKET) +# define PIP_CAN +#endif + +#ifdef PIP_CAN //! \~\ingroup IO //! \~\brief //! \~english CAN device based on interface name and frame identifier. @@ -76,5 +82,6 @@ private: int sock = -1; int can_id, readed_id; }; +#endif // PIP_CAN #endif // PICAN_H diff --git a/libs/main/io_devices/pifile.cpp b/libs/main/io_devices/pifile.cpp index 199d5ca0..43739826 100644 --- a/libs/main/io_devices/pifile.cpp +++ b/libs/main/io_devices/pifile.cpp @@ -46,7 +46,7 @@ # include # endif # define S_IFHDN 0x40 -# if defined(QNX) || defined(ANDROID) +# if defined(QNX) || defined(ANDROID) || defined(FREERTOS) # define _fopen_call_ fopen # define _fseek_call_ fseek # define _ftell_call_ ftell diff --git a/libs/main/io_devices/piiodevice.cpp b/libs/main/io_devices/piiodevice.cpp index d4e76c90..5001ecad 100644 --- a/libs/main/io_devices/piiodevice.cpp +++ b/libs/main/io_devices/piiodevice.cpp @@ -138,9 +138,10 @@ PIIODevice::PIIODevice(const PIString & path, PIIODevice::DeviceMode mode): PIOb PIIODevice::~PIIODevice() { +#ifdef PIP_HAS_THREADS destroying = true; +#endif stopAndWait(); - (void)destroying; } diff --git a/libs/main/io_devices/piserial.cpp b/libs/main/io_devices/piserial.cpp index 128c5b64..3ee91136 100644 --- a/libs/main/io_devices/piserial.cpp +++ b/libs/main/io_devices/piserial.cpp @@ -31,7 +31,14 @@ # include -# ifdef WINDOWS +// Serial pin control (TIOCMBIS/TIOCMBIC/TIOCMGET) is not provided by embedded +// termios shims (ESP-IDF, Arduino), so disable it on embedded builds +# if defined(PIP_EMBEDDED) +# ifndef PISERIAL_NO_PINS +# define PISERIAL_NO_PINS +# endif +# endif +# if defined(PISERIAL_NO_PINS) || defined(WINDOWS) # define TIOCM_LE 1 # define TIOCM_DTR 4 # define TIOCM_RTS 7 @@ -379,7 +386,8 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) { piCoutObj << "setBit" << bname << " error: \"" << path() << "\" is not opened!"; return false; } -# ifdef WINDOWS +# ifndef PISERIAL_NO_PINS +# ifdef WINDOWS static int bit_map_on[] = {0, 0, 0, 0, SETDTR, 0, 0, SETRTS, 0, 0, 0}; static int bit_map_off[] = {0, 0, 0, 0, CLRDTR, 0, 0, CLRRTS, 0, 0, 0}; int action = (on ? bit_map_on : bit_map_off)[bit]; @@ -390,12 +398,13 @@ bool PISerial::setBit(int bit, bool on, const PIString & bname) { } return true; } -# else +# else if (ioctl(fd, on ? TIOCMBIS : TIOCMBIC, &bit) < 0) { piCoutObj << "setBit" << bname << " error: " << errorString(); return false; } return true; +# endif # endif piCoutObj << "setBit" << bname << " doesn`t implemented, sorry :-("; return false; @@ -407,11 +416,13 @@ bool PISerial::isBit(int bit, const PIString & bname) const { piCoutObj << "isBit" << bname << " error: \"" << path() << "\" is not opened!"; return false; } -# ifdef WINDOWS -# else +# ifndef PISERIAL_NO_PINS +# ifdef WINDOWS +# else int ret = 0; if (ioctl(fd, TIOCMGET, &ret) < 0) piCoutObj << "isBit" << bname << " error: " << errorString(); return ret & bit; +# endif # endif piCoutObj << "isBit" << bname << " doesn`t implemented, sorry :-("; return false; diff --git a/libs/main/io_utils/pibroadcast.h b/libs/main/io_utils/pibroadcast.h index 60a8cc6c..11e02944 100644 --- a/libs/main/io_utils/pibroadcast.h +++ b/libs/main/io_utils/pibroadcast.h @@ -34,7 +34,7 @@ //! \~\brief //! \~english Multi-channel sender and receiver over multicast, broadcast and loopback endpoints. //! \~russian Многоканальный отправитель и приемник через multicast-, broadcast- и loopback-конечные точки. -#ifdef PIP_HAS_SOCKET +#if defined(PIP_HAS_SOCKET) && defined(PIP_HAS_THREADS) class PIP_IO_UTILS_EXPORT PIBroadcast : public PIThread , public PIEthUtilBase { @@ -183,6 +183,6 @@ private: int lo_pcnt; bool _started, _send_only, _reinit; }; -#endif // PIP_HAS_SOCKET +#endif // PIP_HAS_SOCKET && PIP_HAS_THREADS #endif // PIBROADCAST_H diff --git a/libs/main/io_utils/pipackedtcp.h b/libs/main/io_utils/pipackedtcp.h index b23535fb..ff956577 100644 --- a/libs/main/io_utils/pipackedtcp.h +++ b/libs/main/io_utils/pipackedtcp.h @@ -24,7 +24,7 @@ #ifndef pipackedtcp_H #define pipackedtcp_H -#ifdef PIP_HAS_SOCKET +#if defined(PIP_HAS_SOCKET) && defined(PIP_HAS_THREADS) # include "piiodevice.h" # include "pinetworkaddress.h" @@ -123,6 +123,6 @@ private: REGISTER_DEVICE(PIPackedTCP) -#endif // PIP_HAS_SOCKET +#endif // PIP_HAS_SOCKET && PIP_HAS_THREADS #endif diff --git a/libs/main/system/pihidevice.cpp b/libs/main/system/pihidevice.cpp index d6f8f2ee..bfcd906d 100644 --- a/libs/main/system/pihidevice.cpp +++ b/libs/main/system/pihidevice.cpp @@ -17,13 +17,6 @@ # include # include # include -# else -// Stubs for embedded/non-Linux builds -# define EV_SYN 0 -# define EV_KEY 1 -# define EV_REL 2 -# define EV_ABS 3 -# define EVIOCGABS(_v) 0 # endif # else // clang-format off @@ -408,10 +401,10 @@ PIVector PIHIDevice::allDevices(bool try_open) { auto readAxes = [readFile, checkBit, &hd_i, &dev](const PIString & file, bool is_relative) { PIVector ret; +# ifdef LINUX ullong bits = readFile(hd_i.path + file).toULLong(16); // piCout<< PICoutManipulators::Bin << abs; if (bits > 0) { -# ifdef LINUX int fd = ::open(dev.path.dataAscii(), O_RDONLY); if (fd < 0) { // piCout << "Warning: can`t open" << dev.path << errorString(); @@ -436,20 +429,8 @@ PIVector PIHIDevice::allDevices(bool try_open) { } } if (fd >= 0) ::close(fd); -# else - // Stub implementation for non-Linux builds - PIHIDeviceInfo::AxisInfo ai; - ai.is_relative = is_relative; - ai.min = 0; - ai.max = 1024; - for (int bit = 0; bit < 64; ++bit) { - if (checkBit(bits, bit, PIString::fromNumber(bit))) { - ai.data_index = bit; - ret << ai; - } - } -# endif } +# endif return ret; }; diff --git a/utils/code_model_generator/main.cpp b/utils/code_model_generator/main.cpp index 9048c289..f5e6843b 100755 --- a/utils/code_model_generator/main.cpp +++ b/utils/code_model_generator/main.cpp @@ -27,8 +27,6 @@ #include "pitranslator.h" #include "stream.h" -#if !defined(PICO_SDK) - using namespace PICoutManipulators; @@ -280,5 +278,3 @@ int main(int argc, char * argv[]) { } return 0; } - -#endif // !PICO_SDK