From 7ce0c2d6631265afd6ecabcb659ab852ed2f0de7 Mon Sep 17 00:00:00 2001 From: Alrik Vidstrom Date: Wed, 6 Sep 2023 19:42:34 +0200 Subject: [PATCH 1/7] Add support for register_hotplug_callback() for H7 boards --- src/Arduino_POSIXStorage.cpp | 37 +++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/src/Arduino_POSIXStorage.cpp b/src/Arduino_POSIXStorage.cpp index 4c0d451..b092390 100644 --- a/src/Arduino_POSIXStorage.cpp +++ b/src/Arduino_POSIXStorage.cpp @@ -480,7 +480,8 @@ int mountOrFormat(const enum StorageDevices deviceName, const enum FileSystems fileSystem, const enum ActionTypes mountOrFormat) { - // Determine if we're running on Machine Control or not on the first call to mount() or mkfs() --> + // Determine if we're running on Machine Control or not on the first call to mount(), mkfs(), or + // register_hotplug_callback() --> if (false == hasMountedBefore) { hasMountedBefore = true; @@ -599,6 +600,24 @@ int register_hotplug_callback(const enum StorageDevices deviceName, void (* cons case DEV_USB: { // Curly braces necessary to keep new variables inside the case statement + // Determine if we're running on Machine Control or not on the first call to mount(), mkfs(), or + // register_hotplug_callback() --> + if (false == hasMountedBefore) + { + hasMountedBefore = true; + if (BOARD_MACHINE_CONTROL == detectBoardType()) + { + runningOnMachineControl = true; + } + } + // <-- +#if defined(ARDUINO_PORTENTA_H7_M7) + if (true == runningOnMachineControl) + { + // We need to apply power manually to the female USB A connector on the Machine Control + mbed::DigitalOut enablePower(PB_14, 0); + } +#endif // A USB mass storage device is already mounted at that mount point, or // registered for the hotplug event if (nullptr != usb.device) @@ -606,11 +625,6 @@ int register_hotplug_callback(const enum StorageDevices deviceName, void (* cons errno = EBUSY; return -1; } -#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_OPTA) - // There is no support for callbacks in the USBHostMSD class on this platform - errno = ENOTSUP; - return -1; -#else // We must create a USBHostMSD object to attach the callback to, but we // don't create a file system object because we don't fully mount() anything USBHostMSD *usbHostDevice = nullptr; @@ -620,10 +634,15 @@ int register_hotplug_callback(const enum StorageDevices deviceName, void (* cons errno = ENOTBLK; return -1; } +#if ((defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_OPTA))) + // The Arduino_USBHostMbed5 library doesn't initialize the USB stack until + // the first connect() call because of an older bugfix (commit 72d0aa6), so + // we perform one connect() here to initialize the stack + usbHostDevice->connect(); +#endif if (false == (usbHostDevice->attach_detected_callback(callbackFunction))) { - delete usbHostDevice; // Ok to delete, because this isn't on the H7 - usbHostDevice = nullptr; + deleteDevice(DEV_USB, &usb); errno = EINVAL; return -1; } @@ -632,7 +651,7 @@ int register_hotplug_callback(const enum StorageDevices deviceName, void (* cons // Prevent multiple registrations hotplugCallbackAlreadyRegistered = true; return 0; -#endif + } // Curly braces necessary to keep new variables inside the case statement default: errno = ENOTBLK; From ba43834113dfea921c8f1f8dc0b0f7ec70324eab Mon Sep 17 00:00:00 2001 From: Alrik Vidstrom Date: Wed, 20 Sep 2023 18:00:00 +0200 Subject: [PATCH 2/7] Add function to register a disconnect callback and adapt tests Adds a function to register a disconnect callback for USB thumb drives. Also adapts the tests to this new functionality, as well as the previous addition of callback support for the H7 boards. --- .../Arduino_POSIXStorage_Test.ino | 115 ++++++--- src/Arduino_POSIXStorage.cpp | 235 +++++++++++------- src/Arduino_POSIXStorage.h | 17 +- 3 files changed, 234 insertions(+), 133 deletions(-) diff --git a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino index 4f5aee4..1b3e461 100644 --- a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino +++ b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino @@ -24,7 +24,7 @@ enum TestTypes : uint8_t // !!! TEST CONFIGURATION !!! --> -constexpr enum TestTypes selectedTest = TEST_PORTENTA_C33_SDCARD; +constexpr enum TestTypes selectedTest = TEST_PORTENTA_H7_USB; // Notice that formtting tests can take a while to complete @@ -35,12 +35,18 @@ constexpr enum TestTypes selectedTest = TEST_PORTENTA_C33_SDCARD; // <-- !!! TEST CONFIGURATION !!! volatile bool usbAttached = false; +volatile bool usbDetached = false; void usbCallback() { usbAttached = true; } +void usbCallback2() +{ + usbDetached = true; +} + void setup() { bool allTestsOk = true; enum StorageDevices deviceName; @@ -104,60 +110,55 @@ void setup() { } // <-- Register hotplug callback for SD Card test - if (TEST_PORTENTA_C33_USB == selectedTest) + // Register unplug callback for SD Card test --> + if (DEV_SDCARD == deviceName) { - // Register nullptr callback test --> - retVal = register_hotplug_callback(DEV_USB, nullptr); - if ((-1 != retVal) || (EFAULT != errno)) + // Using usbCallback2() is fine because it doesn't get registered anyway + retVal = register_unplug_callback(DEV_SDCARD, usbCallback2); + if ((-1 != retVal) || (ENOTSUP != errno)) { allTestsOk = false; - Serial.print("[FAIL] Register nullptr callback test failed"); + Serial.print("[FAIL] Register unplug callback for SD Card test failed"); Serial.println(); } - // <-- Register nullptr callback test } + // <-- Register unplug callback for SD Card test - if ((TEST_PORTENTA_H7_USB == selectedTest) || (TEST_PORTENTA_MACHINE_CONTROL_USB == selectedTest) || (TEST_OPTA_USB == selectedTest)) + if (DEV_USB == deviceName) { - // Register unsupported callback test --> - retVal = register_hotplug_callback(DEV_USB, usbCallback); - if ((-1 != retVal) || (ENOTSUP != errno)) + // Register nullptr callback test (hotplug) --> + retVal = register_hotplug_callback(DEV_USB, nullptr); + if ((-1 != retVal) || (EFAULT != errno)) { allTestsOk = false; - Serial.println("[FAIL] Register unsupported callback test"); + Serial.print("[FAIL] Register nullptr callback test failed (hotplug)"); Serial.println(); } - // <-- Register unsupported callback test + // <-- Register nullptr callback test (hotplug) + + // Register nullptr callback test (unplug) --> + retVal = register_unplug_callback(DEV_USB, nullptr); + if ((-1 != retVal) || (EFAULT != errno)) + { + allTestsOk = false; + Serial.print("[FAIL] Register nullptr callback test failed (unplug)"); + Serial.println(); + } + // <-- Register nullptr callback test (unplug) } - // This isn't a test, just wait for a USB thumb drive --> + // Wait for a USB thumb drive --> if (DEV_USB == deviceName) { Serial.println("Please insert a thumb drive"); - if (TEST_PORTENTA_C33_USB == selectedTest) - { - // This board supports hotplug callbacks - (void) register_hotplug_callback(DEV_USB, usbCallback); - while (false == usbAttached) { - delay(500); - } - } - else if ((TEST_PORTENTA_H7_USB == selectedTest) || (TEST_PORTENTA_MACHINE_CONTROL_USB == selectedTest) || (TEST_OPTA_USB == selectedTest)) - { - // These boards don't support hotplug callbacks, so loop on mount() tries - while (0 != mount(DEV_USB, FS_FAT, MNT_DEFAULT)) { - delay(500); - } - (void) umount(DEV_USB); - } - else - { - for ( ; ;) ; // Shouldn't get here unless there's a bug in the test code + (void) register_hotplug_callback(DEV_USB, usbCallback); + while (false == usbAttached) { + delay(500); } Serial.println("Thank you!"); Serial.println(); } - // <-- This isn't a test, just wait for a USB thumb drive + // <-- Wait for a USB thumb drive #if defined(PERFORM_FORMATTING_TESTS) Serial.println("The formatting tests you selected can take a while to complete"); @@ -335,26 +336,35 @@ void setup() { (void) umount(deviceName); // <-- mount() when already mounted test - if (TEST_PORTENTA_C33_USB == selectedTest) + if (DEV_USB == deviceName) { - // Register multiple callbacks test --> + // Register multiple callbacks test (hotplug) --> retVal = register_hotplug_callback(DEV_USB, usbCallback); if ((-1 != retVal) || (EBUSY != errno)) { allTestsOk = false; - Serial.println("[FAIL] Register multiple callbacks test failed"); + Serial.println("[FAIL] Register multiple callbacks test failed (hotplug)"); } - // <-- Register multiple callbacks test + // <-- Register multiple callbacks test (hotplug) } - // Deregister callback not supported test --> + // Deregister callback not supported test (hotplug) --> retVal = deregister_hotplug_callback(DEV_USB); if ((-1 != retVal) || (ENOSYS != errno)) { allTestsOk = false; Serial.println("[FAIL] Deregister callback not supported test failed"); } - // <-- Deregister callback not supported test + // <-- Deregister callback not supported test (hotplug) + + // Deregister callback not supported test (unplug) --> + retVal = deregister_unplug_callback(DEV_USB); + if ((-1 != retVal) || (ENOSYS != errno)) + { + allTestsOk = false; + Serial.println("[FAIL] Deregister callback not supported test failed"); + } + // <-- Deregister callback not supported test (unplug) // Remove before persistent storage test --> (void) mount(deviceName, FS_FAT, MNT_DEFAULT); @@ -451,6 +461,31 @@ void setup() { (void) umount(deviceName); // <-- Persistent storage test + // Wait for USB thumb drive removal --> + if (DEV_USB == deviceName) + { + Serial.println(); + Serial.println("Please remove the thumb drive"); + (void) register_unplug_callback(DEV_USB, usbCallback2); + while (false == usbDetached) { + delay(500); + } + Serial.println("Thank you!"); + } + // <-- Wait for USB thumb drive removal + + if (DEV_USB == deviceName) + { + // Register multiple callbacks test (unplug) --> + retVal = register_unplug_callback(DEV_USB, usbCallback); + if ((-1 != retVal) || (EBUSY != errno)) + { + allTestsOk = false; + Serial.println("[FAIL] Register multiple callbacks test failed (unplug)"); + } + // <-- Register multiple callbacks test (unplug) + } + // Final report --> Serial.println(); Serial.println("Testing complete."); diff --git a/src/Arduino_POSIXStorage.cpp b/src/Arduino_POSIXStorage.cpp index b092390..5b5c6e0 100644 --- a/src/Arduino_POSIXStorage.cpp +++ b/src/Arduino_POSIXStorage.cpp @@ -72,8 +72,6 @@ #error "The POSIXStorage library does not support this board" #endif - - /* ********************************************************************************************************* * Library-internal using declarations @@ -116,6 +114,12 @@ enum BoardTypes : uint8_t BOARD_PORTENTA_C33 }; +enum CallbackTypes : uint8_t +{ + CALLBACK_HOTPLUG, + CALLBACK_UNPLUG +}; + /* ********************************************************************************************************* * Unnamed namespace for library-internal global variables @@ -130,6 +134,7 @@ struct DeviceFileSystemCombination usb = {nullptr, nullptr}; // <-- bool hotplugCallbackAlreadyRegistered = false; +bool unplugCallbackAlreadyRegistered = false; // Used to handle special case (powering USB A female socket separately) for Machine Control --> bool hasMountedBefore = false; @@ -235,6 +240,28 @@ enum BoardTypes detectBoardType() #endif } // End of detectBoardType() +void portentaMachineControlPowerHandling() +{ + // Determine if we're running on Machine Control or not on the first call to mount(), mkfs(), + // register_hotplug_callback(), or register_unplug_callback() --> + if (false == hasMountedBefore) + { + hasMountedBefore = true; + if (BOARD_MACHINE_CONTROL == detectBoardType()) + { + runningOnMachineControl = true; + } + } + // <-- +#if defined(ARDUINO_PORTENTA_H7_M7) + if (true == runningOnMachineControl) + { + // We need to apply power manually to the female USB A connector on the Machine Control + mbed::DigitalOut enablePower(PB_14, 0); + } +#endif +} // End of portentaMachineControl() + void deleteDevice(const enum StorageDevices deviceName, struct DeviceFileSystemCombination * const deviceFileSystemCombination) { // The USBHostMSD class for the H7 doesn't correctly support object destruction, so we only delete @@ -411,14 +438,6 @@ int mountOrFormatSDCard(const enum FileSystems fileSystem, int mountOrFormatUSBDevice(const enum FileSystems fileSystem, const enum ActionTypes mountOrFormat) { -#if defined(ARDUINO_PORTENTA_H7_M7) - if (true == runningOnMachineControl) - { - // We need to apply power manually to the female USB A connector on the Machine Control - mbed::DigitalOut enablePower(PB_14, 0); - } -#endif - // We'll need a USBHostMSD pointer because connect() and connected() we'll use later aren't member // functions of the base class BlockDevice USBHostMSD *usbHostDevice = nullptr; @@ -480,17 +499,7 @@ int mountOrFormat(const enum StorageDevices deviceName, const enum FileSystems fileSystem, const enum ActionTypes mountOrFormat) { - // Determine if we're running on Machine Control or not on the first call to mount(), mkfs(), or - // register_hotplug_callback() --> - if (false == hasMountedBefore) - { - hasMountedBefore = true; - if (BOARD_MACHINE_CONTROL == detectBoardType()) - { - runningOnMachineControl = true; - } - } - // <-- + portentaMachineControlPowerHandling(); switch (deviceName) { case DEV_SDCARD: @@ -502,6 +511,91 @@ int mountOrFormat(const enum StorageDevices deviceName, } } // End of mountOrFormat() +// WARNING: Don't set errno and return -1 in this function - just return 0 for success or the errno code! +int register_callback(const enum StorageDevices deviceName, void (* const callbackFunction)(), enum CallbackTypes callbackType) +{ + if (((CALLBACK_HOTPLUG == callbackType) && (true == hotplugCallbackAlreadyRegistered)) || + ((CALLBACK_UNPLUG == callbackType) && (true == unplugCallbackAlreadyRegistered))) + { + return EBUSY; + } + if (nullptr == callbackFunction) + { + return EFAULT; + } + switch (deviceName) + { + case DEV_SDCARD: // There is no support for callbacks in the any of the SD Card block device classes + return ENOTSUP; + case DEV_USB: + { // Curly braces necessary to keep new variables inside the case statement + + portentaMachineControlPowerHandling(); + USBHostMSD *usbHostDevice = nullptr; + if (nullptr == usb.device) + { + // We must create a USBHostMSD object to attach the callback to, but we + // don't create a file system object because we don't fully mount() anything + usbHostDevice = new(std::nothrow) USBHostMSD; + if (nullptr == usbHostDevice) + { + return ENOTBLK; + } +#if ((defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_OPTA))) + // The Arduino_USBHostMbed5 library doesn't initialize the USB stack until + // the first connect() call because of an older bugfix (commit 72d0aa6), so + // we perform one connect() here to initialize the stack + usbHostDevice->connect(); +#endif + // This is necessary for future calls to mount(), umount(), and mkfs() + usb.device = usbHostDevice; + } + else + { + // Ok to downcast with static_cast because we know for sure that usb.device isn't pointing to a + // base-class object, and dynamic_cast wouldn't work anyway because compilation is done with -fno-rtti + usbHostDevice = static_cast(usb.device); + } + bool attachCallbackReturn = false; + if (CALLBACK_HOTPLUG == callbackType) + { + attachCallbackReturn = usbHostDevice->attach_detected_callback(callbackFunction); + } + else if (CALLBACK_UNPLUG == callbackType) + { + attachCallbackReturn = usbHostDevice->attach_removed_callback(callbackFunction); + } + else + { + // This should only happen if there's a bug in the code + attachCallbackReturn = false; + } + if (false == attachCallbackReturn) + { + deleteDevice(DEV_USB, &usb); + return EINVAL; + } + // Prevent multiple registrations + if (CALLBACK_HOTPLUG == callbackType) + { + hotplugCallbackAlreadyRegistered = true; + } + else if (CALLBACK_UNPLUG == callbackType) + { + unplugCallbackAlreadyRegistered = true; + } + else + { + // This should only happen if there's a bug in the code + } + return 0; + + } // Curly braces necessary to keep new variables inside the case statement + default: + return ENOTBLK; + } +} // End of register_unplug_callback() + } // End of unnamed namespace /* @@ -582,90 +676,47 @@ int umount(const enum StorageDevices deviceName) int register_hotplug_callback(const enum StorageDevices deviceName, void (* const callbackFunction)()) { - if (true == hotplugCallbackAlreadyRegistered) + const int callbackReturn = register_callback(deviceName, callbackFunction, CALLBACK_HOTPLUG); + if (0 != callbackReturn) { - errno = EBUSY; + errno = callbackReturn; return -1; } - if (nullptr == callbackFunction) + else { - errno = EFAULT; - return -1; + return 0; } - switch (deviceName) - { - case DEV_SDCARD: // There is no support for callbacks in the any of the SD Card block device classes - errno = ENOTSUP; - return -1; - case DEV_USB: - { // Curly braces necessary to keep new variables inside the case statement +} // End of register_hotplug_callback() - // Determine if we're running on Machine Control or not on the first call to mount(), mkfs(), or - // register_hotplug_callback() --> - if (false == hasMountedBefore) - { - hasMountedBefore = true; - if (BOARD_MACHINE_CONTROL == detectBoardType()) - { - runningOnMachineControl = true; - } - } - // <-- -#if defined(ARDUINO_PORTENTA_H7_M7) - if (true == runningOnMachineControl) - { - // We need to apply power manually to the female USB A connector on the Machine Control - mbed::DigitalOut enablePower(PB_14, 0); - } -#endif - // A USB mass storage device is already mounted at that mount point, or - // registered for the hotplug event - if (nullptr != usb.device) - { - errno = EBUSY; - return -1; - } - // We must create a USBHostMSD object to attach the callback to, but we - // don't create a file system object because we don't fully mount() anything - USBHostMSD *usbHostDevice = nullptr; - usbHostDevice = new(std::nothrow) USBHostMSD; - if (nullptr == usbHostDevice) - { - errno = ENOTBLK; - return -1; - } -#if ((defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_OPTA))) - // The Arduino_USBHostMbed5 library doesn't initialize the USB stack until - // the first connect() call because of an older bugfix (commit 72d0aa6), so - // we perform one connect() here to initialize the stack - usbHostDevice->connect(); -#endif - if (false == (usbHostDevice->attach_detected_callback(callbackFunction))) - { - deleteDevice(DEV_USB, &usb); - errno = EINVAL; - return -1; - } - // This is necessary for future calls to mount(), umount(), and mkfs() - usb.device = usbHostDevice; - // Prevent multiple registrations - hotplugCallbackAlreadyRegistered = true; - return 0; +// Not supported by the layer below on these platforms, but might be on other platforms +int deregister_hotplug_callback(const enum StorageDevices deviceName) +{ + (void) deviceName; // Remove when implemented, only here to silence -Wunused-parameter + errno = ENOSYS; + return -1; +} // End of deregister_hotplug_callback() - } // Curly braces necessary to keep new variables inside the case statement - default: - errno = ENOTBLK; - return -1; - } -} // End of hotplug_register_callback() +int register_unplug_callback(const enum StorageDevices deviceName, void (* const callbackFunction)()) +{ + const int callbackReturn = register_callback(deviceName, callbackFunction, CALLBACK_UNPLUG); + if (0 != callbackReturn) + { + errno = callbackReturn; + return -1; + } + else + { + return 0; + } +} // End of register__unplug_callback() // Not supported by the layer below on these platforms, but might be on other platforms -int deregister_hotplug_callback(const enum StorageDevices deviceName) +int deregister_unplug_callback(const enum StorageDevices deviceName) { (void) deviceName; // Remove when implemented, only here to silence -Wunused-parameter errno = ENOSYS; return -1; -} // End of hotplug_deregister_callback() +} // End of deregister_unplug_callback() /* ********************************************************************************************************* diff --git a/src/Arduino_POSIXStorage.h b/src/Arduino_POSIXStorage.h index d38bdbd..dec1730 100644 --- a/src/Arduino_POSIXStorage.h +++ b/src/Arduino_POSIXStorage.h @@ -135,7 +135,7 @@ int mount(const enum StorageDevices deviceName, int umount(const enum StorageDevices deviceName); /** -* @brief Register a hotplug callback function. Currently only supported for DEV_USB on Portenta C33. +* @brief Register a hotplug callback function. * @param deviceName The device to register for: DEV_SDCARD or DEV_USB. * @param callbackFunction A function pointer to the callback. * @return On success: 0. On failure: -1 with an error code in the errno variable. @@ -149,6 +149,21 @@ int register_hotplug_callback(const enum StorageDevices deviceName, void (* cons */ int deregister_hotplug_callback(const enum StorageDevices deviceName); +/** +* @brief Register an unplug callback function. +* @param deviceName The device to register for: DEV_SDCARD or DEV_USB. +* @param callbackFunction A function pointer to the callback. +* @return On success: 0. On failure: -1 with an error code in the errno variable. +*/ +int register_unplug_callback(const enum StorageDevices deviceName, void (* const callbackFunction)()); + +/** +* @brief Deregister a previously registered unplug callback function. Not currently supported on any platform. +* @param deviceName The device to deregister for: DEV_SDCARD or DEV_USB. +* @return On success: 0. On failure: -1 with an error code in the errno variable. +*/ +int deregister_unplug_callback(const enum StorageDevices deviceName); + /** * @brief Format a device (make file system). * @param deviceName The device to format: DEV_SDCARD or DEV_USB. From a74c369502661ce809bfd676664b9ca34986a229 Mon Sep 17 00:00:00 2001 From: Alrik Vidstrom Date: Thu, 21 Sep 2023 17:32:36 +0200 Subject: [PATCH 3/7] Make minor improvements to the code Some minor imporovements after reviewing the code before the final tests. --- .../Arduino_POSIXStorage_Test.ino | 4 +- src/Arduino_POSIXStorage.cpp | 37 ++++++++----------- 2 files changed, 17 insertions(+), 24 deletions(-) diff --git a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino index 1b3e461..48aeee9 100644 --- a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino +++ b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino @@ -24,7 +24,7 @@ enum TestTypes : uint8_t // !!! TEST CONFIGURATION !!! --> -constexpr enum TestTypes selectedTest = TEST_PORTENTA_H7_USB; +constexpr enum TestTypes selectedTest = TEST_PORTENTA_C33_SDCARD; // Notice that formtting tests can take a while to complete @@ -477,7 +477,7 @@ void setup() { if (DEV_USB == deviceName) { // Register multiple callbacks test (unplug) --> - retVal = register_unplug_callback(DEV_USB, usbCallback); + retVal = register_unplug_callback(DEV_USB, usbCallback2); if ((-1 != retVal) || (EBUSY != errno)) { allTestsOk = false; diff --git a/src/Arduino_POSIXStorage.cpp b/src/Arduino_POSIXStorage.cpp index 5b5c6e0..7333db1 100644 --- a/src/Arduino_POSIXStorage.cpp +++ b/src/Arduino_POSIXStorage.cpp @@ -243,7 +243,7 @@ enum BoardTypes detectBoardType() void portentaMachineControlPowerHandling() { // Determine if we're running on Machine Control or not on the first call to mount(), mkfs(), - // register_hotplug_callback(), or register_unplug_callback() --> + // register_hotplug_callback(), or register_unplug_callback() if (false == hasMountedBefore) { hasMountedBefore = true; @@ -251,16 +251,15 @@ void portentaMachineControlPowerHandling() { runningOnMachineControl = true; } - } - // <-- #if defined(ARDUINO_PORTENTA_H7_M7) - if (true == runningOnMachineControl) - { - // We need to apply power manually to the female USB A connector on the Machine Control - mbed::DigitalOut enablePower(PB_14, 0); - } + if (true == runningOnMachineControl) + { + // We need to apply power manually to the female USB A connector on the Machine Control + mbed::DigitalOut enablePower(PB_14, 0); + } #endif -} // End of portentaMachineControl() + } +} // End of portentaMachineControlPowerHandling() void deleteDevice(const enum StorageDevices deviceName, struct DeviceFileSystemCombination * const deviceFileSystemCombination) { @@ -556,7 +555,7 @@ int register_callback(const enum StorageDevices deviceName, void (* const callba // base-class object, and dynamic_cast wouldn't work anyway because compilation is done with -fno-rtti usbHostDevice = static_cast(usb.device); } - bool attachCallbackReturn = false; + bool attachCallbackReturn; if (CALLBACK_HOTPLUG == callbackType) { attachCallbackReturn = usbHostDevice->attach_detected_callback(callbackFunction); @@ -657,7 +656,7 @@ int umount(const enum StorageDevices deviceName) return -1; } // See note (1) at the bottom of the file - int unmountRet = deviceFileSystemCombination->fileSystem->unmount(); + const int unmountRet = deviceFileSystemCombination->fileSystem->unmount(); if (0 == unmountRet) { // Ok to delete with base class pointer because the destructor of the base class is virtual @@ -682,13 +681,10 @@ int register_hotplug_callback(const enum StorageDevices deviceName, void (* cons errno = callbackReturn; return -1; } - else - { - return 0; - } + return 0; } // End of register_hotplug_callback() -// Not supported by the layer below on these platforms, but might be on other platforms +// Currently not supported on any platform, but might be in the future int deregister_hotplug_callback(const enum StorageDevices deviceName) { (void) deviceName; // Remove when implemented, only here to silence -Wunused-parameter @@ -704,13 +700,10 @@ int register_unplug_callback(const enum StorageDevices deviceName, void (* const errno = callbackReturn; return -1; } - else - { - return 0; - } -} // End of register__unplug_callback() + return 0; +} // End of register_unplug_callback() -// Not supported by the layer below on these platforms, but might be on other platforms +// Currently not supported on any platform, but might be in the future int deregister_unplug_callback(const enum StorageDevices deviceName) { (void) deviceName; // Remove when implemented, only here to silence -Wunused-parameter From 9a53b8fb5387db7720aedef50816d054469bc8ef Mon Sep 17 00:00:00 2001 From: Alrik Vidstrom Date: Thu, 21 Sep 2023 17:42:35 +0200 Subject: [PATCH 4/7] Add minor improvements in the test sketch --- .../Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino index 48aeee9..8c950b2 100644 --- a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino +++ b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino @@ -353,7 +353,7 @@ void setup() { if ((-1 != retVal) || (ENOSYS != errno)) { allTestsOk = false; - Serial.println("[FAIL] Deregister callback not supported test failed"); + Serial.println("[FAIL] Deregister callback not supported test failed (hotplug)"); } // <-- Deregister callback not supported test (hotplug) @@ -362,7 +362,7 @@ void setup() { if ((-1 != retVal) || (ENOSYS != errno)) { allTestsOk = false; - Serial.println("[FAIL] Deregister callback not supported test failed"); + Serial.println("[FAIL] Deregister callback not supported test failed (unplug)"); } // <-- Deregister callback not supported test (unplug) From 8a75ab20a25e1ce164f10f35ccc049606c5fe38c Mon Sep 17 00:00:00 2001 From: Alrik Vidstrom Date: Thu, 21 Sep 2023 17:51:09 +0200 Subject: [PATCH 5/7] Add check for Opta before disconnect tests We can't perform the disconnect tests because we log to USB on the Opta. --- .../Arduino_POSIXStorage_Test.ino | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino index 8c950b2..ab93599 100644 --- a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino +++ b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino @@ -24,13 +24,13 @@ enum TestTypes : uint8_t // !!! TEST CONFIGURATION !!! --> -constexpr enum TestTypes selectedTest = TEST_PORTENTA_C33_SDCARD; +constexpr enum TestTypes selectedTest = TEST_PORTENTA_C33_USB; // Notice that formtting tests can take a while to complete // Uncomment the line below to include testing of LITTLEFS and FAT formatting with mkfs(): -//#define PERFORM_FORMATTING_TESTS +#define PERFORM_FORMATTING_TESTS // <-- !!! TEST CONFIGURATION !!! @@ -461,29 +461,33 @@ void setup() { (void) umount(deviceName); // <-- Persistent storage test - // Wait for USB thumb drive removal --> - if (DEV_USB == deviceName) + // These tests can't be performed on the Opta because we log to USB + if (TEST_OPTA_USB != selectedTest) { - Serial.println(); - Serial.println("Please remove the thumb drive"); - (void) register_unplug_callback(DEV_USB, usbCallback2); - while (false == usbDetached) { - delay(500); + // Wait for USB thumb drive removal --> + if (DEV_USB == deviceName) + { + Serial.println(); + Serial.println("Please remove the thumb drive"); + (void) register_unplug_callback(DEV_USB, usbCallback2); + while (false == usbDetached) { + delay(500); + } + Serial.println("Thank you!"); } - Serial.println("Thank you!"); - } - // <-- Wait for USB thumb drive removal + // <-- Wait for USB thumb drive removal - if (DEV_USB == deviceName) - { - // Register multiple callbacks test (unplug) --> - retVal = register_unplug_callback(DEV_USB, usbCallback2); - if ((-1 != retVal) || (EBUSY != errno)) + if (DEV_USB == deviceName) { - allTestsOk = false; - Serial.println("[FAIL] Register multiple callbacks test failed (unplug)"); + // Register multiple callbacks test (unplug) --> + retVal = register_unplug_callback(DEV_USB, usbCallback2); + if ((-1 != retVal) || (EBUSY != errno)) + { + allTestsOk = false; + Serial.println("[FAIL] Register multiple callbacks test failed (unplug)"); + } + // <-- Register multiple callbacks test (unplug) } - // <-- Register multiple callbacks test (unplug) } // Final report --> From 783a3fc21f8ac5b95702282a8a5fb52e9b799466 Mon Sep 17 00:00:00 2001 From: Alrik Vidstrom Date: Thu, 21 Sep 2023 20:33:36 +0200 Subject: [PATCH 6/7] Minor changes to Opta tests --- .../Arduino_POSIXStorage_Test.ino | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino index ab93599..6a12c32 100644 --- a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino +++ b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino @@ -18,13 +18,13 @@ enum TestTypes : uint8_t TEST_PORTENTA_H7_USB, TEST_PORTENTA_MACHINE_CONTROL_SDCARD, TEST_PORTENTA_MACHINE_CONTROL_USB, - TEST_OPTA_SDCARD, - TEST_OPTA_USB + TEST_OPTA_SDCARD, // Not currently implemented + TEST_OPTA_USB // Logging to thumb drive }; // !!! TEST CONFIGURATION !!! --> -constexpr enum TestTypes selectedTest = TEST_PORTENTA_C33_USB; +constexpr enum TestTypes selectedTest = TEST_PORTENTA_C33_SDCARD; // Notice that formtting tests can take a while to complete @@ -77,13 +77,15 @@ void setup() { Serial.println("Testing started, please wait..."); Serial.println(); - if ((TEST_PORTENTA_MACHINE_CONTROL_SDCARD == selectedTest) || (TEST_OPTA_SDCARD == selectedTest)) + if (TEST_PORTENTA_MACHINE_CONTROL_SDCARD == selectedTest) { - // Machine Control and Opta no SD Card supported test --> + // Machine Control no SD Card supported test --> retVal = mount(DEV_SDCARD, FS_FAT, MNT_DEFAULT); if ((-1 != retVal) || (ENOTBLK != errno)) { - Serial.println("[FAIL] Machine Control and Opta no SD Card supported test failed"); + Serial.println("[FAIL] Machine Control no SD Card supported test failed"); + Serial.println(); + Serial.println("FAILURE: Finished with errors (see list above for details)"); } else { @@ -91,8 +93,8 @@ void setup() { Serial.println(); Serial.println("SUCCESS: Finished without errors"); (void) umount(DEV_SDCARD); - for ( ; ; ) ; // Stop testing here } + for ( ; ; ) ; // Stop testing here // <-- Machine Control and Opta no SD Card supported test } @@ -507,7 +509,7 @@ void setup() { // Opta final report --> if (TEST_OPTA_USB == selectedTest) { - (void) mount(deviceName, FS_FAT, MNT_DEFAULT); + (void) mount(DEV_USB, FS_FAT, MNT_DEFAULT); FILE *logFile = fopen("/usb/testlog.txt", "w"); if (true == allTestsOk) { @@ -519,7 +521,7 @@ void setup() { fprintf(logFile, "FAILURE: Finished with errors"); fclose(logFile); } - (void) umount(deviceName); + (void) umount(DEV_USB); } // <-- } From d565fff05020dacd026893d44f9f89491fa65a9f Mon Sep 17 00:00:00 2001 From: Alrik Vidstrom Date: Thu, 21 Sep 2023 20:49:21 +0200 Subject: [PATCH 7/7] Turn off formatting tests by default --- .../Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino index 6a12c32..0cf71ff 100644 --- a/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino +++ b/extras/tests/Arduino_POSIXStorage_Test/Arduino_POSIXStorage_Test.ino @@ -30,7 +30,7 @@ constexpr enum TestTypes selectedTest = TEST_PORTENTA_C33_SDCARD; // Uncomment the line below to include testing of LITTLEFS and FAT formatting with mkfs(): -#define PERFORM_FORMATTING_TESTS +//#define PERFORM_FORMATTING_TESTS // <-- !!! TEST CONFIGURATION !!!