diff --git a/.github/workflows/check-arduino.yml b/.github/workflows/check-arduino.yml index adb330f..e13b990 100644 --- a/.github/workflows/check-arduino.yml +++ b/.github/workflows/check-arduino.yml @@ -16,10 +16,10 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Arduino Lint - uses: arduino/arduino-lint-action@v1 + uses: arduino/arduino-lint-action@v2 with: compliance: specification library-manager: update diff --git a/.github/workflows/compile-examples.yml b/.github/workflows/compile-examples-profiles.yml similarity index 58% rename from .github/workflows/compile-examples.yml rename to .github/workflows/compile-examples-profiles.yml index 2f024f0..1d63730 100644 --- a/.github/workflows/compile-examples.yml +++ b/.github/workflows/compile-examples-profiles.yml @@ -1,5 +1,5 @@ # Source: https://github.com/per1234/.github/blob/main/workflow-templates/compile-examples-private.md -name: Compile Examples +name: Compile Examples with Build Profiles # See: https://docs.github.com/en/actions/reference/events-that-trigger-workflows on: @@ -24,9 +24,12 @@ on: env: UNIVERSAL_SKETCH_PATHS: | - extras/tests - - examples/SimpleStorageWriteRead - examples/AdvancedUSBInternalOperations - examples/BackupInternalPartitions + - examples/Callbacks + - examples/InternalStoragePartitioning + - examples/Logger + - examples/SimpleStorageWriteRead SKETCHES_REPORTS_PATH: sketches-reports SKETCHES_REPORTS_ARTIFACT_NAME: sketches-reports @@ -46,31 +49,25 @@ jobs: - fqbn: arduino:mbed_portenta:envie_m7 platforms: | - name: arduino:mbed_portenta + artifact-name-suffix: arduino-mbed_portenta-envie_m7 - fqbn: arduino:renesas_portenta:portenta_c33 platforms: | - name: arduino:renesas_portenta + artifact-name-suffix: arduino-renesas_portenta-portenta_c33 - fqbn: arduino:mbed_opta:opta platforms: | - name: arduino:mbed_opta + artifact-name-suffix: arduino-mbed_opta-opta steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Compile examples uses: arduino/compile-sketches@v1 with: github-token: ${{ secrets.GITHUB_TOKEN }} - fqbn: ${{ matrix.board.fqbn }} - platforms: ${{ matrix.board.platforms }} - libraries: | - # Install the library from the local path. - - source-path: ./ - - name: Arduino_USBHostMbed5 - - name: Arduino_POSIXStorage - - name: ArduinoRS485 - # Additional library dependencies can be listed here. - # See: https://github.com/arduino/compile-sketches#libraries + cli-compile-flags: --profile ${{ matrix.board.fqbn }} sketch-paths: | ${{ env.UNIVERSAL_SKETCH_PATHS }} ${{ matrix.board.additional-sketch-paths }} @@ -78,32 +75,8 @@ jobs: sketches-report-path: ${{ env.SKETCHES_REPORTS_PATH }} - name: Save sketches report as workflow artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: if-no-files-found: error + name: sketches-report-${{ matrix.board.artifact-name-suffix }} path: ${{ env.SKETCHES_REPORTS_PATH }} - name: ${{ env.SKETCHES_REPORTS_ARTIFACT_NAME }} - - report-size-deltas: - needs: build - # Run even if some compilations failed. - if: always() && github.event_name == 'pull_request' - runs-on: ubuntu-latest - permissions: - pull-requests: write - - steps: - - name: Download sketches reports artifact - id: download-artifact - continue-on-error: true # If compilation failed for all boards then there are no artifacts - uses: actions/download-artifact@v3 - with: - name: ${{ env.SKETCHES_REPORTS_ARTIFACT_NAME }} - path: ${{ env.SKETCHES_REPORTS_PATH }} - - - name: Comment size deltas report to PR - uses: arduino/report-size-deltas@v1 - # If actions/download-artifact failed, there are no artifacts to report from. - if: steps.download-artifact.outcome == 'success' - with: - sketches-reports-source: ${{ env.SKETCHES_REPORTS_PATH }} diff --git a/.github/workflows/render-docs.yml b/.github/workflows/render-docs.yml new file mode 100644 index 0000000..29891f1 --- /dev/null +++ b/.github/workflows/render-docs.yml @@ -0,0 +1,29 @@ +name: Render Documentation + +on: + push: + branches: + - main + paths: + - ".github/workflows/render-documentation.ya?ml" + - "examples/**" + - "src/**" + pull_request: + branches: + - main + paths: + - ".github/workflows/render-documentation.ya?ml" + - "examples/**" + - "src/**" + workflow_dispatch: + +jobs: + render-docs: + permissions: + contents: write + uses: arduino/render-docs-github-action/.github/workflows/render-docs.yml@main + with: + source-path: './src' + target-path: './docs/api.md' + commit: ${{ github.event_name != 'pull_request' }} # Only commit changes if not a PR + \ No newline at end of file diff --git a/.github/workflows/report-size-deltas.yml b/.github/workflows/report-size-deltas.yml new file mode 100644 index 0000000..39e2a0a --- /dev/null +++ b/.github/workflows/report-size-deltas.yml @@ -0,0 +1,24 @@ +name: Report Size Deltas + +# See: https://docs.github.com/en/free-pro-team@latest/actions/reference/events-that-trigger-workflows +on: + push: + paths: + - ".github/workflows/report-size-deltas.yml" + schedule: + # Run at the minimum interval allowed by GitHub Actions. + # Note: GitHub Actions periodically has outages which result in workflow failures. + # In this event, the workflows will start passing again once the service recovers. + - cron: "*/5 * * * *" + workflow_dispatch: + repository_dispatch: + +jobs: + report: + runs-on: ubuntu-latest + steps: + - name: Comment size deltas reports to PRs + uses: arduino/report-size-deltas@v1 + with: + # Regex matching the names of the workflow artifacts created by the "Compile Examples" workflow + sketches-reports-source: ^sketches-report-.+ diff --git a/.github/workflows/spell-check.yml b/.github/workflows/spell-check.yml index 2c32c71..cfa5b14 100644 --- a/.github/workflows/spell-check.yml +++ b/.github/workflows/spell-check.yml @@ -19,7 +19,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Spell check uses: codespell-project/actions-codespell@v2 \ No newline at end of file diff --git a/.github/workflows/sync-labels.yml b/.github/workflows/sync-labels.yml index 92607a1..aac676e 100644 --- a/.github/workflows/sync-labels.yml +++ b/.github/workflows/sync-labels.yml @@ -24,12 +24,10 @@ env: jobs: check: runs-on: ubuntu-latest - permissions: - contents: read steps: - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download JSON schema for labels configuration file id: download-schema @@ -57,7 +55,6 @@ jobs: download: needs: check runs-on: ubuntu-latest - permissions: {} strategy: matrix: @@ -73,7 +70,7 @@ jobs: file-url: https://raw.githubusercontent.com/arduino/tooling-project-assets/main/workflow-templates/assets/sync-labels/${{ matrix.filename }} - name: Pass configuration files to next job via workflow artifact - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: path: | *.yaml @@ -84,9 +81,6 @@ jobs: sync: needs: download runs-on: ubuntu-latest - permissions: - contents: read - issues: write steps: - name: Set environment variables @@ -111,16 +105,16 @@ jobs: echo "flag=--dry-run" >> $GITHUB_OUTPUT - name: Checkout repository - uses: actions/checkout@v4 + uses: actions/checkout@v5 - name: Download configuration files artifact - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v5 with: name: ${{ env.CONFIGURATIONS_ARTIFACT }} path: ${{ env.CONFIGURATIONS_FOLDER }} - name: Remove unneeded artifact - uses: geekyeggo/delete-artifact@v2 + uses: geekyeggo/delete-artifact@v5 with: name: ${{ env.CONFIGURATIONS_ARTIFACT }} @@ -141,4 +135,4 @@ jobs: github-label-sync \ --labels "${{ env.MERGED_CONFIGURATION_PATH }}" \ ${{ steps.dry-run.outputs.flag }} \ - ${{ github.repository }} \ No newline at end of file + ${{ github.repository }} diff --git a/README.md b/README.md index 27c22dd..14f70e8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,9 @@ # 💾 Unified Storage Library -[![Check Arduino](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/check-arduino.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/check-arduino.yml) [![Compile Examples](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/compile-examples.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/compile-examples.yml) [![Spell Check](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/spell-check.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/spell-check.yml) [![Sync Labels](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/sync-labels.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/sync-labels.yml) +[![Check Arduino](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/check-arduino.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/check-arduino.yml) +[![Compile Examples](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/compile-examples-profiles.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/compile-examples-profiles.yml) +[![Spell Check](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/spell-check.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/spell-check.yml) +[![Sync Labels](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/sync-labels.yml/badge.svg)](https://github.com/arduino-libraries/Arduino_UnifiedStorage/actions/workflows/sync-labels.yml) The Arduino_UnifiedStorage library provides a unified interface to access different types of storage, including internal storage, SD cards, and USB mass storage devices. It simplifies the handling of files and directories across multiple storage mediums on Portenta, Opta, and some Nicla boards. diff --git a/docs/api.md b/docs/api.md index 5aa0520..8a9178b 100644 --- a/docs/api.md +++ b/docs/api.md @@ -5,9 +5,11 @@ `class ` [`Arduino_UnifiedStorage`](#class_arduino___unified_storage) | Abstract class representing the common features of the supported storage methods `class ` [`Folder`](#class_folder) | Class representing a directory. `class ` [`InternalStorage`](#class_internal_storage) | Represents internal storage using the Arduino Unified Storage library. +`class ` [`Partitioning`](#class_partitioning) | `class ` [`SDStorage`](#class_s_d_storage) | Represents an SD card storage using the Arduino Unified Storage library. `class ` [`UFile`](#class_u_file) | Class representing a File -`class ` [`USBStorage`](#class_u_s_b_storage) | Represents a USB storage using the Arduino Unified Storage library. +`class ` [`USBStorage`](#class_u_s_b_storage) | [USBStorage](#class_u_s_b_storage) class provides an interface to access USB storage devices. It inherits from the [Arduino_UnifiedStorage](#class_arduino___unified_storage) class and implements its pure virtual functions. +`struct ` [`Partition`](#struct_partition) | # class `Arduino_UnifiedStorage` @@ -17,15 +19,21 @@ Abstract class representing the common features of the supported storage methods Members | Descriptions --------------------------------|--------------------------------------------- -`public bool ` [`begin`](#class_arduino___unified_storage_1a350443027c76ea18f2812a54aa8ab437)`()` | Initializes the storage. -`public bool ` [`begin`](#class_arduino___unified_storage_1acb25f75f3dcdb89ebce3c7cd08970a99)`(FileSystems fs)` | Initializes the storage with the specified file system. -`public bool ` [`unmount`](#class_arduino___unified_storage_1a4281bc190ee4f2ad35265eab64ef6f7f)`()` | Unmounts the storage. -`public ` [`Folder`](#class_folder)` ` [`getRootFolder`](#class_arduino___unified_storage_1a7166075ba695d54bf74c6c71b8c4c1bf)`()` | Retrieves the root folder of the storage. -`public bool ` [`format`](#class_arduino___unified_storage_1ad6d045b4bdafd4dcb75daed305888e25)`(FileSystems fs)` | Formats the storage with the selected file system. +| [`begin`](#class_arduino___unified_storage_1a350443027c76ea18f2812a54aa8ab437) | Initializes the storage. | +| [`begin`](#class_arduino___unified_storage_1acb25f75f3dcdb89ebce3c7cd08970a99) | Initializes the storage with the specified file system. | +| [`unmount`](#class_arduino___unified_storage_1a4281bc190ee4f2ad35265eab64ef6f7f) | Unmounts the storage. | +| [`getRootFolder`](#class_arduino___unified_storage_1a7166075ba695d54bf74c6c71b8c4c1bf) | Retrieves the root folder of the storage. | +| [`format`](#class_arduino___unified_storage_1ad6d045b4bdafd4dcb75daed305888e25) | Formats the storage with the selected file system. | +| [`debugPrint`](#class_arduino___unified_storage_1ab0b726c7f98ea3623679097224290a07) | | +| [`testPrint`](#class_arduino___unified_storage_1a1fafe7a15fbd21c8705a9f86a92f6dd9) | | ## Members -### `public bool ` [`begin`](#class_arduino___unified_storage_1a350443027c76ea18f2812a54aa8ab437)`()` +### `begin` + +```cpp +bool begin() +``` Initializes the storage. @@ -33,7 +41,11 @@ Initializes the storage. true if successful, false if failed.
-### `public bool ` [`begin`](#class_arduino___unified_storage_1acb25f75f3dcdb89ebce3c7cd08970a99)`(FileSystems fs)` +### `begin` + +```cpp +bool begin(FileSystems fs) +``` Initializes the storage with the specified file system. #### Parameters @@ -43,27 +55,55 @@ Initializes the storage with the specified file system. true if successful, false if failed.
-### `public bool ` [`unmount`](#class_arduino___unified_storage_1a4281bc190ee4f2ad35265eab64ef6f7f)`()` +### `unmount` + +```cpp +bool unmount() +``` Unmounts the storage. #### Returns true if successful, false if failed.
-### `public ` [`Folder`](#class_folder)` ` [`getRootFolder`](#class_arduino___unified_storage_1a7166075ba695d54bf74c6c71b8c4c1bf)`()` +### `getRootFolder` + +```cpp +Folder getRootFolder() +``` Retrieves the root folder of the storage. #### Returns The root folder as a [Folder](#class_folder) object.
-### `public bool ` [`format`](#class_arduino___unified_storage_1ad6d045b4bdafd4dcb75daed305888e25)`(FileSystems fs)` +### `format` + +```cpp +bool format(FileSystems fs) +``` Formats the storage with the selected file system. #### Returns true if successful, false if failed.
+### `debugPrint` + +```cpp +static void debugPrint(String message) +``` + +
+ +### `testPrint` + +```cpp +static void testPrint(String message) +``` + +
+ # class `Folder` Class representing a directory. @@ -72,53 +112,69 @@ Class representing a directory. Members | Descriptions --------------------------------|--------------------------------------------- -`public ` [`Folder`](#class_folder_1a8af69fd19ba86816c60b4c2291311eb1)`()` | Blank Constructor. -`public ` [`Folder`](#class_folder_1aa2a4dc98e8c383c7b4fa503b45813fe3)`(const char * dirname)` | Constructor. -`public ` [`Folder`](#class_folder_1a6f445bfe0214a03ba00a1408e41726dd)`(String dirname)` | Constructor. -`public ` [`UFile`](#class_u_file)` ` [`createFile`](#class_folder_1a04eceb0406b02e2d8a628d3c359dba5d)`(const char * fileName, FileMode fmode)` | Creates a file inside the directory. -`public ` [`UFile`](#class_u_file)` ` [`createFile`](#class_folder_1a44255e2c0c4ffa37d7637a601bc590f6)`(String fileName, FileMode fmode)` | Creates a file inside the directory. -`public bool ` [`remove`](#class_folder_1aca893daac6c6747895d50987cf9cf34c)`()` | Removes a directory. -`public bool ` [`rename`](#class_folder_1adcbb7766d628810f716887d1e7e8d36f)`(const char * newDirname)` | Renames a directory. -`public bool ` [`rename`](#class_folder_1a14519c2a344ebfb8161c2bee2a2b5464)`(String newDirname)` | Renames a directory. -`public bool ` [`exists`](#class_folder_1aa548278d3ec09fd4abcaa827a79c40f4)`()` | Checks if the directory exists. -`public const char * ` [`getPath`](#class_folder_1a731e8d84685eca8e273affba152468a6)`()` | Returns the path of the file. -`public String ` [`getPathAsString`](#class_folder_1ac816d0fe5674c4648e97423b6f9c51f8)`()` | Returns the path of the file. -`public ` [`Folder`](#class_folder)` ` [`createSubfolder`](#class_folder_1a78f2f9b297f62b67c2e0656b15a95868)`(const char * subfolderName, bool overwrite)` | Creates a subfolder in the directory. -`public ` [`Folder`](#class_folder)` ` [`createSubfolder`](#class_folder_1ab50743664becb7b2a1fb564b5513d69c)`(String subfolderName, bool overwrite)` | Creates a subfolder in the directory. -`public std::vector< ` [`UFile`](#class_u_file)` > ` [`getFiles`](#class_folder_1a3c2e01e19b48e3aa709cbdbb0acbdd78)`()` | Returns File objects for all files in the current directory. -`public std::vector< ` [`Folder`](#class_folder)` > ` [`getFolders`](#class_folder_1a69d3df42dacbd1d64d0f527e090f1fbb)`()` | Returns [Folder](#class_folder) objects for all files in the current directory. -`public bool ` [`copyTo`](#class_folder_1aabf0818b7ee45b2d871e82e86edb4ebd)`(` [`Folder`](#class_folder)` destination, bool overwrite)` | Copies the current directory. -`public bool ` [`copyTo`](#class_folder_1a058d193f53c559eefe343b30797500eb)`(const char * destination, bool overwrite)` | Copies the current directory. -`public bool ` [`copyTo`](#class_folder_1a3162979e4c679c7f5503cc4584949714)`(String destination, bool overwrite)` | Copies the current directory. -`public bool ` [`moveTo`](#class_folder_1a5002b388b7e503ba79a8623ca6c1cbbd)`(` [`Folder`](#class_folder)` destination, bool overwrite)` | Moves the current directory. -`public bool ` [`moveTo`](#class_folder_1a0ab690abfff790a2bd9fff3dd5976e82)`(const char * destination, bool overwrite)` | Moves the current directory. -`public bool ` [`moveTo`](#class_folder_1a3125db272185165a03b891efe5985a32)`(String destination, bool overwrite)` | Move the current directory. +| [`Folder`](#class_folder_1a8af69fd19ba86816c60b4c2291311eb1) | Creates an empty [Folder](#class_folder) object. Please note that any operation on this object will fail until a valid directory is assigned to it. | +| [`Folder`](#class_folder_1aa2a4dc98e8c383c7b4fa503b45813fe3) | Creates a directory with the specified name. If the directory already exists, it returns a [Folder](#class_folder) object representing the existing directory. Otherwise, it tries to create a new directory with the specified name. If it fails the `path` property of the [Folder](#class_folder) object will be null. | +| [`Folder`](#class_folder_1a6f445bfe0214a03ba00a1408e41726dd) | Creates a directory with the specified name. If the directory already exists, it returns a [Folder](#class_folder) object representing the existing directory. Otherwise, it tries to create a new directory with the specified name. If it fails the `path` property of the [Folder](#class_folder) object will be empty. | +| [`createFile`](#class_folder_1a04eceb0406b02e2d8a628d3c359dba5d) | Creates a file inside the directory. | +| [`createFile`](#class_folder_1a44255e2c0c4ffa37d7637a601bc590f6) | Creates a file inside the directory. | +| [`remove`](#class_folder_1aca893daac6c6747895d50987cf9cf34c) | Removes a directory. | +| [`rename`](#class_folder_1adcbb7766d628810f716887d1e7e8d36f) | Renames a directory. | +| [`rename`](#class_folder_1a14519c2a344ebfb8161c2bee2a2b5464) | Renames a directory. | +| [`exists`](#class_folder_1aa548278d3ec09fd4abcaa827a79c40f4) | Checks if the directory exists. | +| [`getPath`](#class_folder_1a0ef68289c526f8bf24020389c4e09e86) | Returns the path of the file. | +| [`getPathAsString`](#class_folder_1ac816d0fe5674c4648e97423b6f9c51f8) | Returns the path of the file. | +| [`createSubfolder`](#class_folder_1a78f2f9b297f62b67c2e0656b15a95868) | Creates a subfolder in the directory. | +| [`createSubfolder`](#class_folder_1ab50743664becb7b2a1fb564b5513d69c) | Creates a subfolder in the directory. | +| [`getFiles`](#class_folder_1a2e7f604d19b8ad61524f86ade86ed4ad) | Returns File objects for all files in the current directory. | +| [`getFolders`](#class_folder_1a5554b8cc2fd1ca39dfccbd06bc635e10) | Returns [Folder](#class_folder) objects for all files in the current directory. | +| [`copyTo`](#class_folder_1aabf0818b7ee45b2d871e82e86edb4ebd) | Copies the current directory. | +| [`copyTo`](#class_folder_1a058d193f53c559eefe343b30797500eb) | Copies the current directory. | +| [`copyTo`](#class_folder_1a3162979e4c679c7f5503cc4584949714) | Copies the current directory. | +| [`moveTo`](#class_folder_1a5002b388b7e503ba79a8623ca6c1cbbd) | Moves the current directory. | +| [`moveTo`](#class_folder_1a0ab690abfff790a2bd9fff3dd5976e82) | Moves the current directory. | +| [`moveTo`](#class_folder_1a3125db272185165a03b891efe5985a32) | Move the current directory. | ## Members -### `public ` [`Folder`](#class_folder_1a8af69fd19ba86816c60b4c2291311eb1)`()` +### `Folder` -Blank Constructor. +```cpp +Folder() +``` + +Creates an empty [Folder](#class_folder) object. Please note that any operation on this object will fail until a valid directory is assigned to it.
-### `public ` [`Folder`](#class_folder_1aa2a4dc98e8c383c7b4fa503b45813fe3)`(const char * dirname)` +### `Folder` -Constructor. +```cpp +Folder(const char * dirname) +``` + +Creates a directory with the specified name. If the directory already exists, it returns a [Folder](#class_folder) object representing the existing directory. Otherwise, it tries to create a new directory with the specified name. If it fails the `path` property of the [Folder](#class_folder) object will be null. #### Parameters * `const` char * dirname - The name of the directory.
-### `public ` [`Folder`](#class_folder_1a6f445bfe0214a03ba00a1408e41726dd)`(String dirname)` +### `Folder` -Constructor. +```cpp +Folder(String dirname) +``` + +Creates a directory with the specified name. If the directory already exists, it returns a [Folder](#class_folder) object representing the existing directory. Otherwise, it tries to create a new directory with the specified name. If it fails the `path` property of the [Folder](#class_folder) object will be empty. #### Parameters * `String` dirname - The name of the directory.
-### `public ` [`UFile`](#class_u_file)` ` [`createFile`](#class_folder_1a04eceb0406b02e2d8a628d3c359dba5d)`(const char * fileName, FileMode fmode)` +### `createFile` + +```cpp +UFile createFile(const char * fileName, FileMode fmode) +``` Creates a file inside the directory. @@ -129,7 +185,11 @@ Creates a file inside the directory. A File object if successful, NULL if not.
-### `public ` [`UFile`](#class_u_file)` ` [`createFile`](#class_folder_1a44255e2c0c4ffa37d7637a601bc590f6)`(String fileName, FileMode fmode)` +### `createFile` + +```cpp +UFile createFile(String fileName, FileMode fmode) +``` Creates a file inside the directory. @@ -140,18 +200,23 @@ Creates a file inside the directory. A File object if successful, NULL if not.
-### `public bool ` [`remove`](#class_folder_1aca893daac6c6747895d50987cf9cf34c)`()` +### `remove` -Removes a directory. +```cpp +bool remove() +``` -#### Parameters -* `dirname` The name of the directory to remove. +Removes a directory. #### Returns True if the directory was removed successfully, false otherwise.
-### `public bool ` [`rename`](#class_folder_1adcbb7766d628810f716887d1e7e8d36f)`(const char * newDirname)` +### `rename` + +```cpp +bool rename(const char * newDirname) +``` Renames a directory. @@ -162,7 +227,11 @@ Renames a directory. True if the directory was renamed successfully, false otherwise.
-### `public bool ` [`rename`](#class_folder_1a14519c2a344ebfb8161c2bee2a2b5464)`(String newDirname)` +### `rename` + +```cpp +bool rename(String newDirname) +``` Renames a directory. @@ -173,7 +242,11 @@ Renames a directory. True if the directory was renamed successfully, false otherwise.
-### `public bool ` [`exists`](#class_folder_1aa548278d3ec09fd4abcaa827a79c40f4)`()` +### `exists` + +```cpp +bool exists() +``` Checks if the directory exists. @@ -181,7 +254,11 @@ Checks if the directory exists. True if the directory exists, false otherwise.
-### `public const char * ` [`getPath`](#class_folder_1a731e8d84685eca8e273affba152468a6)`()` +### `getPath` + +```cpp +const char * getPath() +``` Returns the path of the file. @@ -189,7 +266,11 @@ Returns the path of the file. The path of the file as a const char *
-### `public String ` [`getPathAsString`](#class_folder_1ac816d0fe5674c4648e97423b6f9c51f8)`()` +### `getPathAsString` + +```cpp +String getPathAsString() +``` Returns the path of the file. @@ -197,7 +278,11 @@ Returns the path of the file. The path of the file as an Arduino String
-### `public ` [`Folder`](#class_folder)` ` [`createSubfolder`](#class_folder_1a78f2f9b297f62b67c2e0656b15a95868)`(const char * subfolderName, bool overwrite)` +### `createSubfolder` + +```cpp +Folder createSubfolder(const char * subfolderName, bool overwrite) +``` Creates a subfolder in the directory. @@ -210,7 +295,11 @@ Creates a subfolder in the directory. The created subfolder.
-### `public ` [`Folder`](#class_folder)` ` [`createSubfolder`](#class_folder_1ab50743664becb7b2a1fb564b5513d69c)`(String subfolderName, bool overwrite)` +### `createSubfolder` + +```cpp +Folder createSubfolder(String subfolderName, bool overwrite) +``` Creates a subfolder in the directory. @@ -223,7 +312,11 @@ Creates a subfolder in the directory. The created subfolder.
-### `public std::vector< ` [`UFile`](#class_u_file)` > ` [`getFiles`](#class_folder_1a3c2e01e19b48e3aa709cbdbb0acbdd78)`()` +### `getFiles` + +```cpp +std::vector< UFile > getFiles() +``` Returns File objects for all files in the current directory. @@ -231,7 +324,11 @@ Returns File objects for all files in the current directory. A std::vector of File objects representing the files in the directory.
-### `public std::vector< ` [`Folder`](#class_folder)` > ` [`getFolders`](#class_folder_1a69d3df42dacbd1d64d0f527e090f1fbb)`()` +### `getFolders` + +```cpp +std::vector< Folder > getFolders() +``` Returns [Folder](#class_folder) objects for all files in the current directory. @@ -239,7 +336,11 @@ Returns [Folder](#class_folder) objects for all files in the current directory. A std::vector of [Folder](#class_folder) objects representing the files in the directory.
-### `public bool ` [`copyTo`](#class_folder_1aabf0818b7ee45b2d871e82e86edb4ebd)`(` [`Folder`](#class_folder)` destination, bool overwrite)` +### `copyTo` + +```cpp +bool copyTo( Folder destination, bool overwrite) +``` Copies the current directory. @@ -250,7 +351,11 @@ Copies the current directory. True upon success, false otherwise.
-### `public bool ` [`copyTo`](#class_folder_1a058d193f53c559eefe343b30797500eb)`(const char * destination, bool overwrite)` +### `copyTo` + +```cpp +bool copyTo(const char * destination, bool overwrite) +``` Copies the current directory. @@ -263,7 +368,11 @@ Copies the current directory. True upon success, false otherwise.
-### `public bool ` [`copyTo`](#class_folder_1a3162979e4c679c7f5503cc4584949714)`(String destination, bool overwrite)` +### `copyTo` + +```cpp +bool copyTo(String destination, bool overwrite) +``` Copies the current directory. @@ -276,7 +385,11 @@ Copies the current directory. True upon success, false otherwise.
-### `public bool ` [`moveTo`](#class_folder_1a5002b388b7e503ba79a8623ca6c1cbbd)`(` [`Folder`](#class_folder)` destination, bool overwrite)` +### `moveTo` + +```cpp +bool moveTo( Folder destination, bool overwrite) +``` Moves the current directory. @@ -289,7 +402,11 @@ Moves the current directory. True upon success, false otherwise.
-### `public bool ` [`moveTo`](#class_folder_1a0ab690abfff790a2bd9fff3dd5976e82)`(const char * destination, bool overwrite)` +### `moveTo` + +```cpp +bool moveTo(const char * destination, bool overwrite) +``` Moves the current directory. @@ -302,7 +419,11 @@ Moves the current directory. True upon success, false otherwise.
-### `public bool ` [`moveTo`](#class_folder_1a3125db272185165a03b891efe5985a32)`(String destination, bool overwrite)` +### `moveTo` + +```cpp +bool moveTo(String destination, bool overwrite) +``` Move the current directory. @@ -317,7 +438,7 @@ True upon success, false otherwise. # class `InternalStorage` -``` +```cpp class InternalStorage : public Arduino_UnifiedStorage ``` @@ -328,24 +449,36 @@ Represents internal storage using the Arduino Unified Storage library. Members | Descriptions --------------------------------|--------------------------------------------- -`public ` [`InternalStorage`](#class_internal_storage_1ac45948ef554bc659efed81240140192e)`()` | Default constructor for the [InternalStorage](#class_internal_storage) class. -`public ` [`InternalStorage`](#class_internal_storage_1ac13cad019a2ae66647d1c3604690eca7)`(int partition, const char * name, FileSystems fs)` | Constructs an [InternalStorage](#class_internal_storage) object with the specified partition, name, and file system. -`public virtual bool ` [`begin`](#class_internal_storage_1a984731348dfbdade84e24250133a033e)`()` | Initializes the internal storage. -`public virtual bool ` [`begin`](#class_internal_storage_1a90cd409874d9c578ce3add4df88875e5)`(FileSystems fs)` | Initializes the internal storage with the specified file system. -`public virtual bool ` [`unmount`](#class_internal_storage_1a663446e2135a4e91d7fdb8ca638cc027)`()` | Unmounts the internal storage. -`public virtual ` [`Folder`](#class_folder)` ` [`getRootFolder`](#class_internal_storage_1a87142ddbdad62217e33851b32572082d)`()` | Retrieves the root folder of the internal storage. -`public void ` [`setQSPIPartition`](#class_internal_storage_1a2ca8680537077ca3e189be2ca6dcc634)`(int partition)` | Sets the QSPI partition number. -`public void ` [`setQSPIPartitionName`](#class_internal_storage_1ae0fbe264a758a4026548df66ec05f8c8)`(const char * name)` | Sets the QSPI partition name. -`public virtual bool ` [`format`](#class_internal_storage_1a9ee819a55de5d411e6b10bdc9942c601)`(FileSystems fs)` | Formats the internal storage with the selected file system. +| [`InternalStorage`](#class_internal_storage_1ac45948ef554bc659efed81240140192e) | Constructs an [InternalStorage](#class_internal_storage) object with default settings. If no partitions are available, it restores the default partitioning scheme (See [restoreDefaultPartitions()](#class_internal_storage_1ace77d2372832c2f9ef39d382cc443259) for more info). If partitions are available, it sets the partition number, file system type, and partition name based on the last partition available. When using the default partitioning scheme the last partition would be the user partition. | +| [`InternalStorage`](#class_internal_storage_1ac13cad019a2ae66647d1c3604690eca7) | Constructs an [InternalStorage](#class_internal_storage) object with the specified partition, name, and file system. | +| [`~InternalStorage`](#class_internal_storage_1a718df11687329b437bc4e2bf420490c0) | | +| [`begin`](#class_internal_storage_1a984731348dfbdade84e24250133a033e) | Initializes the internal storage. | +| [`begin`](#class_internal_storage_1a90cd409874d9c578ce3add4df88875e5) | Initializes the internal storage with the specified file system. | +| [`unmount`](#class_internal_storage_1a663446e2135a4e91d7fdb8ca638cc027) | Unmounts the internal storage. | +| [`getRootFolder`](#class_internal_storage_1a87142ddbdad62217e33851b32572082d) | Retrieves the root folder of the internal storage. | +| [`format`](#class_internal_storage_1a9ee819a55de5d411e6b10bdc9942c601) | Formats the internal storage with the selected file system. | +| [`getBlockDevice`](#class_internal_storage_1af347558e09045a5dd868f93b24286bab) | Retrieves the block device associated with the internal storage. | +| [`partition`](#class_internal_storage_1acd4f9617061b962f38b20a4c6ddb8d48) | Partitions the internal storage according to the partitioning scheme given in the `partitions` parameter erasing the existing partitions | +| [`partition`](#class_internal_storage_1aefb31c03b94006e75b18111f07c99331) | Creates one partition spanning over the whole size of the internal storage drive erasing the existing partitions. | +| [`restoreDefaultPartitions`](#class_internal_storage_1ace77d2372832c2f9ef39d382cc443259) | Restores the default partitioning scheme (1MB FAT32 for Certificates, 5MB FAT32 for OTA, 8MB user storage) to the internal storage drive erasing the existing partitions. | +| [`readPartitions`](#class_internal_storage_1a3d3303d7eb80a5d9471c60cb2bffc3b3) | Reads the partitioning scheme from the MBR sector of the internal storage drive and returns a vector of structs of type [Partition](#struct_partition) that represents the partitioning scheme | ## Members -### `public ` [`InternalStorage`](#class_internal_storage_1ac45948ef554bc659efed81240140192e)`()` +### `InternalStorage` -Default constructor for the [InternalStorage](#class_internal_storage) class. +```cpp +InternalStorage() +``` + +Constructs an [InternalStorage](#class_internal_storage) object with default settings. If no partitions are available, it restores the default partitioning scheme (See [restoreDefaultPartitions()](#class_internal_storage_1ace77d2372832c2f9ef39d382cc443259) for more info). If partitions are available, it sets the partition number, file system type, and partition name based on the last partition available. When using the default partitioning scheme the last partition would be the user partition.
-### `public ` [`InternalStorage`](#class_internal_storage_1ac13cad019a2ae66647d1c3604690eca7)`(int partition, const char * name, FileSystems fs)` +### `InternalStorage` + +```cpp +InternalStorage(int partition, const char * name, FileSystems fs) +``` Constructs an [InternalStorage](#class_internal_storage) object with the specified partition, name, and file system. @@ -357,7 +490,19 @@ Constructs an [InternalStorage](#class_internal_storage) object with the specifi * `fs` The desired file system (FS_FAT or FS_LITTLEFS).
-### `public virtual bool ` [`begin`](#class_internal_storage_1a984731348dfbdade84e24250133a033e)`()` +### `~InternalStorage` + +```cpp +~InternalStorage() +``` + +
+ +### `begin` + +```cpp +virtual bool begin() +``` Initializes the internal storage. @@ -365,7 +510,11 @@ Initializes the internal storage. true if successful, false if failed.
-### `public virtual bool ` [`begin`](#class_internal_storage_1a90cd409874d9c578ce3add4df88875e5)`(FileSystems fs)` +### `begin` + +```cpp +virtual bool begin(FileSystems fs) +``` Initializes the internal storage with the specified file system. @@ -376,7 +525,11 @@ Initializes the internal storage with the specified file system. true if successful, false if failed.
-### `public virtual bool ` [`unmount`](#class_internal_storage_1a663446e2135a4e91d7fdb8ca638cc027)`()` +### `unmount` + +```cpp +virtual bool unmount() +``` Unmounts the internal storage. @@ -384,7 +537,11 @@ Unmounts the internal storage. true if successful, false if failed.
-### `public virtual ` [`Folder`](#class_folder)` ` [`getRootFolder`](#class_internal_storage_1a87142ddbdad62217e33851b32572082d)`()` +### `getRootFolder` + +```cpp +virtual Folder getRootFolder() +``` Retrieves the root folder of the internal storage. @@ -392,41 +549,136 @@ Retrieves the root folder of the internal storage. The root folder as a [Folder](#class_folder) object.
-### `public void ` [`setQSPIPartition`](#class_internal_storage_1a2ca8680537077ca3e189be2ca6dcc634)`(int partition)` +### `format` -Sets the QSPI partition number. +```cpp +virtual bool format(FileSystems fs) +``` -#### Parameters -* `partition` The partition number. +Formats the internal storage with the selected file system. + +#### Returns +true if successful, false if failed.
-### `public void ` [`setQSPIPartitionName`](#class_internal_storage_1ae0fbe264a758a4026548df66ec05f8c8)`(const char * name)` +### `getBlockDevice` -Sets the QSPI partition name. +```cpp +BlockDeviceType * getBlockDevice() +``` + +Retrieves the block device associated with the internal storage. + +#### Returns +The block device as a BlockDevice object. +
+ +### `partition` + +```cpp +static bool partition(std::vector< Partition > partitions) +``` +Partitions the internal storage according to the partitioning scheme given in the `partitions` parameter erasing the existing partitions #### Parameters -* `name` The name of the partition. +* `partitions` - vector of structs of type [Partition](#struct_partition) that represents the partitioning scheme + +#### Returns +true if successful, false if failed.
-### `public virtual bool ` [`format`](#class_internal_storage_1a9ee819a55de5d411e6b10bdc9942c601)`(FileSystems fs)` +### `partition` -Formats the internal storage with the selected file system. +```cpp +static bool partition() +``` +Creates one partition spanning over the whole size of the internal storage drive erasing the existing partitions. #### Returns true if successful, false if failed.
+### `restoreDefaultPartitions` -Retrieves the block device associated with the internal storage. +```cpp +static bool restoreDefaultPartitions() +``` +Restores the default partitioning scheme (1MB FAT32 for Certificates, 5MB FAT32 for OTA, 8MB user storage) to the internal storage drive erasing the existing partitions. #### Returns -The block device as a BlockDevice object. +true if successful, false if failed.
+### `readPartitions` -# class `SDStorage` +```cpp +static std::vector< Partition > readPartitions() +``` + +Reads the partitioning scheme from the MBR sector of the internal storage drive and returns a vector of structs of type [Partition](#struct_partition) that represents the partitioning scheme +#### Returns +vector of structs of type [Partition](#struct_partition) +
+ +# class `Partitioning` + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +| [`eraseMBRSector`](#class_partitioning_1a662f276b27785e76cdf9f89c5356e784) | Erases the first block (4096 bytes) of the BlockDevice to delete any already existing MBR partition table | +| [`partitionDrive`](#class_partitioning_1a803b6e9a67304c6551d2a90ed5473985) | Partitions the BlockDevice according to the partitioning schemme given by the vector of [Partition](#struct_partition) structs | +| [`readPartitions`](#class_partitioning_1affe78fdf2a8a5f8324668de3353b402d) | Reads and unpacks the MBR partition information and returns a list of partitions it can find on the drive | + +## Members + +### `eraseMBRSector` + +```cpp +static bool eraseMBRSector(BlockDeviceType * blockDevice) +``` + +Erases the first block (4096 bytes) of the BlockDevice to delete any already existing MBR partition table +#### Parameters +* `The` BlockDevice on which the MBR sector is situated. + +#### Returns +True upon success, False on failure +
+ +### `partitionDrive` + +```cpp +static bool partitionDrive(BlockDeviceType * blockDevice, std::vector< Partition > partitions) +``` + +Partitions the BlockDevice according to the partitioning schemme given by the vector of [Partition](#struct_partition) structs +#### Parameters +* `blockDevice` - the BlockDevice which we would like to partition. +* `partitions` - a vector of [Partition](#struct_partition) structs that represents the partitioning scheme + +#### Returns +True upon success, False on failure +
+ +### `readPartitions` + +```cpp +static std::vector< Partition > readPartitions(BlockDeviceType * blockDevice) ``` + +Reads and unpacks the MBR partition information and returns a list of partitions it can find on the drive +#### Parameters +* `blockDevice` on which the MBR sector is situated. + +#### Returns +std::vector of [Partition](#struct_partition) containing size and filesystem information about each partition +
+ +# class `SDStorage` + +```cpp class SDStorage : public Arduino_UnifiedStorage ``` @@ -437,21 +689,29 @@ Represents an SD card storage using the Arduino Unified Storage library. Members | Descriptions --------------------------------|--------------------------------------------- -`public ` [`SDStorage`](#class_s_d_storage_1a992cb710f41462a7a35c6dfdc838f01f)`()` | Default constructor for the [SDStorage](#class_s_d_storage) class. -`public virtual bool ` [`begin`](#class_s_d_storage_1ab49c772b785b6c97940baca60ae386ec)`()` | Initializes the SD card storage. -`public virtual bool ` [`begin`](#class_s_d_storage_1a19520df98c5a52d403ac26a873f65860)`(FileSystems fs)` | Initializes the SD card storage with the specified file system. -`public virtual bool ` [`unmount`](#class_s_d_storage_1a6f4d671e685d660d0aff8648d8288b9c)`()` | Unmounts the SD card storage. -`public virtual ` [`Folder`](#class_folder)` ` [`getRootFolder`](#class_s_d_storage_1a2f7327c327985d88bd1305310ec0c5e8)`()` | Retrieves the root folder of the SD card storage. -`public virtual bool ` [`format`](#class_s_d_storage_1a93cac8330a5950138985e3712db1dc07)`(FileSystems fs)` | Formats the SD card storage with the selected file system. +| [`SDStorage`](#class_s_d_storage_1a992cb710f41462a7a35c6dfdc838f01f) | Default constructor for the [SDStorage](#class_s_d_storage) class. | +| [`begin`](#class_s_d_storage_1ab49c772b785b6c97940baca60ae386ec) | Initializes the SD card storage. | +| [`begin`](#class_s_d_storage_1a19520df98c5a52d403ac26a873f65860) | Initializes the SD card storage with the specified file system. | +| [`unmount`](#class_s_d_storage_1a6f4d671e685d660d0aff8648d8288b9c) | Unmounts the SD card storage. | +| [`getRootFolder`](#class_s_d_storage_1a2f7327c327985d88bd1305310ec0c5e8) | Retrieves the root folder of the SD card storage. | +| [`format`](#class_s_d_storage_1a93cac8330a5950138985e3712db1dc07) | Formats the SD card storage with the selected file system. | ## Members -### `public ` [`SDStorage`](#class_s_d_storage_1a992cb710f41462a7a35c6dfdc838f01f)`()` +### `SDStorage` + +```cpp +SDStorage() +``` Default constructor for the [SDStorage](#class_s_d_storage) class.
-### `public virtual bool ` [`begin`](#class_s_d_storage_1ab49c772b785b6c97940baca60ae386ec)`()` +### `begin` + +```cpp +virtual bool begin() +``` Initializes the SD card storage. @@ -459,7 +719,11 @@ Initializes the SD card storage. true if successful, false if failed.
-### `public virtual bool ` [`begin`](#class_s_d_storage_1a19520df98c5a52d403ac26a873f65860)`(FileSystems fs)` +### `begin` + +```cpp +virtual bool begin(FileSystems fs) +``` Initializes the SD card storage with the specified file system. @@ -470,7 +734,11 @@ Initializes the SD card storage with the specified file system. true if successful, false if failed.
-### `public virtual bool ` [`unmount`](#class_s_d_storage_1a6f4d671e685d660d0aff8648d8288b9c)`()` +### `unmount` + +```cpp +virtual bool unmount() +``` Unmounts the SD card storage. @@ -478,7 +746,11 @@ Unmounts the SD card storage. true if successful, false if failed.
-### `public virtual ` [`Folder`](#class_folder)` ` [`getRootFolder`](#class_s_d_storage_1a2f7327c327985d88bd1305310ec0c5e8)`()` +### `getRootFolder` + +```cpp +virtual Folder getRootFolder() +``` Retrieves the root folder of the SD card storage. @@ -486,7 +758,11 @@ Retrieves the root folder of the SD card storage. The root folder as a [Folder](#class_folder) object.
-### `public virtual bool ` [`format`](#class_s_d_storage_1a93cac8330a5950138985e3712db1dc07)`(FileSystems fs)` +### `format` + +```cpp +virtual bool format(FileSystems fs) +``` Formats the SD card storage with the selected file system. @@ -494,9 +770,6 @@ Formats the SD card storage with the selected file system. true if successful, false if failed.
- -
- # class `UFile` Class representing a File @@ -505,44 +778,53 @@ Class representing a File Members | Descriptions --------------------------------|--------------------------------------------- -`public ` [`UFile`](#class_u_file_1a2a04504d0135d28465e0547bec062ebf)`()` | Constructor. -`public ` [`UFile`](#class_u_file_1acdd969b1c2f115fc105f6d08bd67b121)`(const char * path)` | Constructor. -`public ` [`~UFile`](#class_u_file_1a4f74e28f98898e3603140b6409fa52ba)`()` | -`public bool ` [`changeMode`](#class_u_file_1a744ad88f2037e87e3f5375c7aec28f6d)`(FileMode mode)` | Closes the file, and opens it again with a new file mode. -`public bool ` [`open`](#class_u_file_1aa52ff2913386374e6e83ba35f595d213)`(const char * filename, FileMode mode)` | Opens a file with the specified mode. -`public bool ` [`open`](#class_u_file_1a0247abf7053b47463f73ca8cb1c7c23c)`(String filename, FileMode mode)` | Opens a file with the specified mode. -`public void ` [`close`](#class_u_file_1ab5731b8e40a87a44a7322bf151597c55)`()` | Closes the file and releases any allocated resources. -`public bool ` [`seek`](#class_u_file_1aa117a19e5efe6508e5e87ab65abbb560)`(size_t offset)` | Seeks to a specific position in the file. -`public size_t ` [`read`](#class_u_file_1a8192f041831d58ba8186798676c5ad3a)`(uint8_t * buffer, size_t size)` | Reads data from the file into a buffer. -`public String ` [`readAsString`](#class_u_file_1ad70a29b0e436906bdaa7b99e3fc9e1b3)`()` | Reads the contents of the file as an Arduino String. -`public size_t ` [`write`](#class_u_file_1a16625e123db35bf19f9088828d9e1305)`(const uint8_t * buffer, size_t size)` | Writes data to the file from a buffer. -`public size_t ` [`write`](#class_u_file_1a68ee9ecdb0a6efd9816f3382de67905e)`(String)` | Writes a string to the file. -`public bool ` [`remove`](#class_u_file_1a0e9efb7c54053b6f507f6caa704fc101)`()` | Removes the file. -`public bool ` [`rename`](#class_u_file_1a0511c1a498bcbce549b49db9e188c2c0)`(const char * newFilename)` | Renames the file. -`public bool ` [`rename`](#class_u_file_1a2122cd3e0e16481ecaff1af897790c03)`(String newFilename)` | Renames the file. -`public bool ` [`exists`](#class_u_file_1a4963afa70289718a3bd1ca50b6adb420)`()` | Checks if the file exists. -`public bool ` [`copyTo`](#class_u_file_1a6178616dea1a897b0e4033dfdc7bc41d)`(const char * destinationPath, bool overwrite)` | Copies the file to the specified destination path. -`public bool ` [`copyTo`](#class_u_file_1a908edbee6d38619798d63f72f8f58dd1)`(String destinationPath, bool overwrite)` | Copies the file to the specified destination path. -`public bool ` [`copyTo`](#class_u_file_1a9e06719446533b73505a6f6a66091fa7)`(` [`Folder`](#class_folder)` destinationFolder, bool overwrite)` | Copies the file to the specified destination path. -`public bool ` [`moveTo`](#class_u_file_1abadd4af5700d94b2c3d74dd4dce51bdc)`(const char * destinationPath, bool overwrite)` | Moves the file to the specified destination path. -`public bool ` [`moveTo`](#class_u_file_1ae676e42f3e5ad423da3386985fc8261f)`(String destinationPath, bool overwrite)` | Moves the file to the specified destination path. -`public bool ` [`moveTo`](#class_u_file_1a69f6a7cccce8cc40eb6698df15f38635)`(` [`Folder`](#class_folder)` destinationFolder, bool overwrite)` | Copies the file to the specified destination folder. -`public ` [`Folder`](#class_folder)` ` [`getParentFolder`](#class_u_file_1a087b79b6d62a3ed122d1f8b0f25b0d24)`()` | Returns a reference to the parent folder of the current folder. -`public const char * ` [`getPath`](#class_u_file_1a41592023ea53cd1b46f383097a3db1f8)`()` | Returns the path of the directory. -`public String ` [`getPathAsString`](#class_u_file_1a5adef9f3d538f92e51e52c4b1f3ada76)`()` | Returns the path of the directory. -`public uint32_t ` [`available`](#class_u_file_1a82ad0fb6cffaf23aea794b508ec57bbb)`()` | Returns the number of bytes available to read. -`public int ` [`read`](#class_u_file_1a62b544ebe9c3b144268016e6427917b5)`()` | Returns one byte from the file. -`public size_t ` [`write`](#class_u_file_1a4db87498c1a4205145816c14df704de7)`(uint8_t value)` | Writes one byte to the file. +| [`UFile`](#class_u_file_1a2a04504d0135d28465e0547bec062ebf) | Constructor. | +| [`UFile`](#class_u_file_1acdd969b1c2f115fc105f6d08bd67b121) | Constructor. | +| [`~UFile`](#class_u_file_1a4f74e28f98898e3603140b6409fa52ba) | | +| [`changeMode`](#class_u_file_1a744ad88f2037e87e3f5375c7aec28f6d) | Closes the file, and opens it again with a new file mode. | +| [`open`](#class_u_file_1aa52ff2913386374e6e83ba35f595d213) | Opens a file with the specified mode. | +| [`open`](#class_u_file_1a0247abf7053b47463f73ca8cb1c7c23c) | Opens a file with the specified mode. | +| [`open`](#class_u_file_1a013a90e9e0a4b44a0fde722f1e9af6bc) | Opens a file that was already initialized with a path. | +| [`close`](#class_u_file_1ab5731b8e40a87a44a7322bf151597c55) | Closes the file and releases any allocated resources. | +| [`seek`](#class_u_file_1aa117a19e5efe6508e5e87ab65abbb560) | Seeks to a specific position in the file. | +| [`read`](#class_u_file_1a8192f041831d58ba8186798676c5ad3a) | Reads data from the file into a buffer. | +| [`readAsString`](#class_u_file_1ad70a29b0e436906bdaa7b99e3fc9e1b3) | Reads the contents of the file as an Arduino String. | +| [`write`](#class_u_file_1a16625e123db35bf19f9088828d9e1305) | Writes data to the file from a buffer. | +| [`write`](#class_u_file_1a68ee9ecdb0a6efd9816f3382de67905e) | Writes a string to the file. | +| [`remove`](#class_u_file_1a0e9efb7c54053b6f507f6caa704fc101) | Removes the file. | +| [`rename`](#class_u_file_1a0511c1a498bcbce549b49db9e188c2c0) | Renames the file. | +| [`rename`](#class_u_file_1a2122cd3e0e16481ecaff1af897790c03) | Renames the file. | +| [`exists`](#class_u_file_1a4963afa70289718a3bd1ca50b6adb420) | Checks if the file exists. | +| [`copyTo`](#class_u_file_1a6178616dea1a897b0e4033dfdc7bc41d) | Copies the file to the specified destination path. | +| [`copyTo`](#class_u_file_1a908edbee6d38619798d63f72f8f58dd1) | Copies the file to the specified destination path. | +| [`copyTo`](#class_u_file_1a9e06719446533b73505a6f6a66091fa7) | Copies the file to the specified destination path. | +| [`moveTo`](#class_u_file_1abadd4af5700d94b2c3d74dd4dce51bdc) | Moves the file to the specified destination path. | +| [`moveTo`](#class_u_file_1ae676e42f3e5ad423da3386985fc8261f) | Moves the file to the specified destination path. | +| [`moveTo`](#class_u_file_1a69f6a7cccce8cc40eb6698df15f38635) | Copies the file to the specified destination folder. | +| [`getParentFolder`](#class_u_file_1a087b79b6d62a3ed122d1f8b0f25b0d24) | Returns a reference to the parent folder of the current folder. | +| [`getPath`](#class_u_file_1a122edcf553a8929b703d70c6aa8a6e80) | Returns the path of the directory. | +| [`getPathAsString`](#class_u_file_1a5adef9f3d538f92e51e52c4b1f3ada76) | Returns the path of the directory. | +| [`available`](#class_u_file_1a82ad0fb6cffaf23aea794b508ec57bbb) | Returns the number of bytes available to read. | +| [`read`](#class_u_file_1a62b544ebe9c3b144268016e6427917b5) | Returns one byte from the file. | +| [`write`](#class_u_file_1a4db87498c1a4205145816c14df704de7) | Writes one byte to the file. | ## Members -### `public ` [`UFile`](#class_u_file_1a2a04504d0135d28465e0547bec062ebf)`()` +### `UFile` + +```cpp +UFile() +``` Constructor.
-### `public ` [`UFile`](#class_u_file_1acdd969b1c2f115fc105f6d08bd67b121)`(const char * path)` +### `UFile` + +```cpp +UFile(const char * path) +``` Constructor. @@ -550,11 +832,19 @@ Constructor. * `const` char * path - path of the file
-### `public ` [`~UFile`](#class_u_file_1a4f74e28f98898e3603140b6409fa52ba)`()` +### `~UFile` + +```cpp +~UFile() +```
-### `public bool ` [`changeMode`](#class_u_file_1a744ad88f2037e87e3f5375c7aec28f6d)`(FileMode mode)` +### `changeMode` + +```cpp +bool changeMode(FileMode mode) +``` Closes the file, and opens it again with a new file mode. @@ -565,7 +855,11 @@ Closes the file, and opens it again with a new file mode. True if operation was successful, false otherwise.
-### `public bool ` [`open`](#class_u_file_1aa52ff2913386374e6e83ba35f595d213)`(const char * filename, FileMode mode)` +### `open` + +```cpp +bool open(const char * filename, FileMode mode) +``` Opens a file with the specified mode. @@ -578,7 +872,11 @@ Opens a file with the specified mode. True if the file was opened successfully, false otherwise.
-### `public bool ` [`open`](#class_u_file_1a0247abf7053b47463f73ca8cb1c7c23c)`(String filename, FileMode mode)` +### `open` + +```cpp +bool open(String filename, FileMode mode) +``` Opens a file with the specified mode. @@ -591,13 +889,36 @@ Opens a file with the specified mode. True if the file was opened successfully, false otherwise.
-### `public void ` [`close`](#class_u_file_1ab5731b8e40a87a44a7322bf151597c55)`()` +### `open` + +```cpp +bool open(FileMode mode) +``` + +Opens a file that was already initialized with a path. + +#### Parameters +* `mode` The file mode (READ, WRITE, or APPEND). The default is READ. + +#### Returns +True if the file was opened successfully, false otherwise. +
+ +### `close` + +```cpp +void close() +``` Closes the file and releases any allocated resources.
-### `public bool ` [`seek`](#class_u_file_1aa117a19e5efe6508e5e87ab65abbb560)`(size_t offset)` +### `seek` + +```cpp +bool seek(size_t offset) +``` Seeks to a specific position in the file. @@ -608,7 +929,11 @@ Seeks to a specific position in the file. True if the seek operation was successful, false otherwise.
-### `public size_t ` [`read`](#class_u_file_1a8192f041831d58ba8186798676c5ad3a)`(uint8_t * buffer, size_t size)` +### `read` + +```cpp +size_t read(uint8_t * buffer, size_t size) +``` Reads data from the file into a buffer. @@ -621,7 +946,11 @@ Reads data from the file into a buffer. The number of bytes read from the file.
-### `public String ` [`readAsString`](#class_u_file_1ad70a29b0e436906bdaa7b99e3fc9e1b3)`()` +### `readAsString` + +```cpp +String readAsString() +``` Reads the contents of the file as an Arduino String. @@ -629,7 +958,11 @@ Reads the contents of the file as an Arduino String. The file contents as a String.
-### `public size_t ` [`write`](#class_u_file_1a16625e123db35bf19f9088828d9e1305)`(const uint8_t * buffer, size_t size)` +### `write` + +```cpp +size_t write(const uint8_t * buffer, size_t size) +``` Writes data to the file from a buffer. @@ -642,7 +975,11 @@ Writes data to the file from a buffer. The number of bytes written to the file.
-### `public size_t ` [`write`](#class_u_file_1a68ee9ecdb0a6efd9816f3382de67905e)`(String)` +### `write` + +```cpp +size_t write(String) +``` Writes a string to the file. @@ -653,7 +990,11 @@ Writes a string to the file. The number of bytes written to the file.
-### `public bool ` [`remove`](#class_u_file_1a0e9efb7c54053b6f507f6caa704fc101)`()` +### `remove` + +```cpp +bool remove() +``` Removes the file. @@ -661,7 +1002,11 @@ Removes the file. True if the file was removed successfully, false otherwise.
-### `public bool ` [`rename`](#class_u_file_1a0511c1a498bcbce549b49db9e188c2c0)`(const char * newFilename)` +### `rename` + +```cpp +bool rename(const char * newFilename) +``` Renames the file. @@ -672,7 +1017,11 @@ Renames the file. True if the file was renamed successfully, false otherwise.
-### `public bool ` [`rename`](#class_u_file_1a2122cd3e0e16481ecaff1af897790c03)`(String newFilename)` +### `rename` + +```cpp +bool rename(String newFilename) +``` Renames the file. @@ -683,7 +1032,11 @@ Renames the file. True if the file was renamed successfully, false otherwise.
-### `public bool ` [`exists`](#class_u_file_1a4963afa70289718a3bd1ca50b6adb420)`()` +### `exists` + +```cpp +bool exists() +``` Checks if the file exists. @@ -691,7 +1044,11 @@ Checks if the file exists. True if the file exists, false otherwise.
-### `public bool ` [`copyTo`](#class_u_file_1a6178616dea1a897b0e4033dfdc7bc41d)`(const char * destinationPath, bool overwrite)` +### `copyTo` + +```cpp +bool copyTo(const char * destinationPath, bool overwrite) +``` Copies the file to the specified destination path. @@ -702,7 +1059,11 @@ Copies the file to the specified destination path. True upon success, false otherwise.
-### `public bool ` [`copyTo`](#class_u_file_1a908edbee6d38619798d63f72f8f58dd1)`(String destinationPath, bool overwrite)` +### `copyTo` + +```cpp +bool copyTo(String destinationPath, bool overwrite) +``` Copies the file to the specified destination path. @@ -713,7 +1074,11 @@ Copies the file to the specified destination path. True upon success, false otherwise.
-### `public bool ` [`copyTo`](#class_u_file_1a9e06719446533b73505a6f6a66091fa7)`(` [`Folder`](#class_folder)` destinationFolder, bool overwrite)` +### `copyTo` + +```cpp +bool copyTo( Folder destinationFolder, bool overwrite) +``` Copies the file to the specified destination path. @@ -724,7 +1089,11 @@ Copies the file to the specified destination path. True upon success, false otherwise.
-### `public bool ` [`moveTo`](#class_u_file_1abadd4af5700d94b2c3d74dd4dce51bdc)`(const char * destinationPath, bool overwrite)` +### `moveTo` + +```cpp +bool moveTo(const char * destinationPath, bool overwrite) +``` Moves the file to the specified destination path. @@ -735,7 +1104,11 @@ Moves the file to the specified destination path. True upon success, false otherwise.
-### `public bool ` [`moveTo`](#class_u_file_1ae676e42f3e5ad423da3386985fc8261f)`(String destinationPath, bool overwrite)` +### `moveTo` + +```cpp +bool moveTo(String destinationPath, bool overwrite) +``` Moves the file to the specified destination path. @@ -746,7 +1119,11 @@ Moves the file to the specified destination path. True upon success, false otherwise.
-### `public bool ` [`moveTo`](#class_u_file_1a69f6a7cccce8cc40eb6698df15f38635)`(` [`Folder`](#class_folder)` destinationFolder, bool overwrite)` +### `moveTo` + +```cpp +bool moveTo( Folder destinationFolder, bool overwrite) +``` Copies the file to the specified destination folder. @@ -757,7 +1134,11 @@ Copies the file to the specified destination folder. True upon success, false otherwise.
-### `public ` [`Folder`](#class_folder)` ` [`getParentFolder`](#class_u_file_1a087b79b6d62a3ed122d1f8b0f25b0d24)`()` +### `getParentFolder` + +```cpp +Folder getParentFolder() +``` Returns a reference to the parent folder of the current folder. @@ -765,7 +1146,11 @@ Returns a reference to the parent folder of the current folder. A directory object representing the current folder.
-### `public const char * ` [`getPath`](#class_u_file_1a41592023ea53cd1b46f383097a3db1f8)`()` +### `getPath` + +```cpp +const char * getPath() +``` Returns the path of the directory. @@ -773,7 +1158,11 @@ Returns the path of the directory. The path of the file as a const char *
-### `public String ` [`getPathAsString`](#class_u_file_1a5adef9f3d538f92e51e52c4b1f3ada76)`()` +### `getPathAsString` + +```cpp +String getPathAsString() +``` Returns the path of the directory. @@ -781,7 +1170,11 @@ Returns the path of the directory. The path of the file as a String
-### `public uint32_t ` [`available`](#class_u_file_1a82ad0fb6cffaf23aea794b508ec57bbb)`()` +### `available` + +```cpp +uint32_t available() +``` Returns the number of bytes available to read. @@ -789,7 +1182,11 @@ Returns the number of bytes available to read. The number of bytes available to read as int
-### `public int ` [`read`](#class_u_file_1a62b544ebe9c3b144268016e6427917b5)`()` +### `read` + +```cpp +int read() +``` Returns one byte from the file. @@ -797,7 +1194,11 @@ Returns one byte from the file. An int representing one byte from the file
-### `public size_t ` [`write`](#class_u_file_1a4db87498c1a4205145816c14df704de7)`(uint8_t value)` +### `write` + +```cpp +size_t write(uint8_t value) +``` Writes one byte to the file. @@ -807,33 +1208,45 @@ Writes one byte to the file. # class `USBStorage` -``` +```cpp class USBStorage : public Arduino_UnifiedStorage ``` -Represents a USB storage using the Arduino Unified Storage library. +[USBStorage](#class_u_s_b_storage) class provides an interface to access USB storage devices. It inherits from the [Arduino_UnifiedStorage](#class_arduino___unified_storage) class and implements its pure virtual functions. ## Summary Members | Descriptions --------------------------------|--------------------------------------------- -`public ` [`USBStorage`](#class_u_s_b_storage_1ad084f3bd2479b0a1daa88013f3cfe23a)`()` | Default constructor for the [USBStorage](#class_u_s_b_storage) class. -`public virtual bool ` [`begin`](#class_u_s_b_storage_1aabf0868054a1741ffe4018301d145cb1)`()` | Initializes the USB storage. -`public virtual bool ` [`begin`](#class_u_s_b_storage_1a9fac27a863b6d73bb78f956be4517f67)`(FileSystems fs)` | Initializes the USB storage with the specified file system. -`public virtual bool ` [`unmount`](#class_u_s_b_storage_1acb602dc07465880ebaec64dca1b36506)`()` | Unmounts the USB storage. -`public virtual ` [`Folder`](#class_folder)` ` [`getRootFolder`](#class_u_s_b_storage_1a1d39336ddd7ec401dc2ed99c3117af59)`()` | Retrieves the root folder of the USB storage. -`public virtual bool ` [`format`](#class_u_s_b_storage_1a8aec32e4e48d081183ad880a61836bc5)`(FileSystems fs)` | Formats the USB storage with the selected file system. -`public bool ` [`isConnected`](#class_u_s_b_storage_1a228919e4b7f6fe0619fbcb33da9a9534)`()` | Checks if the USB storage is connected. +| [`USBStorage`](#class_u_s_b_storage_1ad084f3bd2479b0a1daa88013f3cfe23a) | Default constructor for the [USBStorage](#class_u_s_b_storage) class. | +| [`begin`](#class_u_s_b_storage_1aabf0868054a1741ffe4018301d145cb1) | Initializes the USB storage. | +| [`begin`](#class_u_s_b_storage_1a9fac27a863b6d73bb78f956be4517f67) | Initializes the USB storage with the specified file system. | +| [`unmount`](#class_u_s_b_storage_1acb602dc07465880ebaec64dca1b36506) | Unmounts the USB storage. | +| [`getRootFolder`](#class_u_s_b_storage_1a1d39336ddd7ec401dc2ed99c3117af59) | Retrieves the root folder of the USB storage. | +| [`format`](#class_u_s_b_storage_1a8aec32e4e48d081183ad880a61836bc5) | Formats the USB storage with the selected file system. | +| [`isMounted`](#class_u_s_b_storage_1a2d3e3a732f2a43ab67e2fcd05e4ac058) | Checks if the USB storage is mounted. | +| [`onConnect`](#class_u_s_b_storage_1a1dfb2b9dde7fbdc26c0bf73be9babe25) | Sets the callback function to be called when a USB connection is established. | +| [`removeOnConnectCallback`](#class_u_s_b_storage_1afc58782a3f5207356d29392cb31730a0) | Removes the callback function that is executed when the USB storage device is connected. | +| [`onDisconnect`](#class_u_s_b_storage_1a10ac0c8965eee6041b384a4823bb9720) | Sets a callback function to be called when the USB storage device is disconnected. | +| [`removeOnDisconnectCallback`](#class_u_s_b_storage_1a2333fb1697b7ca72e5127cf60fc6680f) | Removes the callback function that is called when the USB storage device is disconnected. | ## Members -### `public ` [`USBStorage`](#class_u_s_b_storage_1ad084f3bd2479b0a1daa88013f3cfe23a)`()` +### `USBStorage` + +```cpp +USBStorage() +``` Default constructor for the [USBStorage](#class_u_s_b_storage) class.
-### `public virtual bool ` [`begin`](#class_u_s_b_storage_1aabf0868054a1741ffe4018301d145cb1)`()` +### `begin` + +```cpp +virtual bool begin() +``` Initializes the USB storage. @@ -841,7 +1254,11 @@ Initializes the USB storage. true if successful, false if failed.
-### `public virtual bool ` [`begin`](#class_u_s_b_storage_1a9fac27a863b6d73bb78f956be4517f67)`(FileSystems fs)` +### `begin` + +```cpp +virtual bool begin(FileSystems fs) +``` Initializes the USB storage with the specified file system. @@ -852,7 +1269,11 @@ Initializes the USB storage with the specified file system. true if successful, false if failed.
-### `public virtual bool ` [`unmount`](#class_u_s_b_storage_1acb602dc07465880ebaec64dca1b36506)`()` +### `unmount` + +```cpp +virtual bool unmount() +``` Unmounts the USB storage. @@ -860,7 +1281,11 @@ Unmounts the USB storage. true if successful, false if failed.
-### `public virtual ` [`Folder`](#class_folder)` ` [`getRootFolder`](#class_u_s_b_storage_1a1d39336ddd7ec401dc2ed99c3117af59)`()` +### `getRootFolder` + +```cpp +virtual Folder getRootFolder() +``` Retrieves the root folder of the USB storage. @@ -868,7 +1293,11 @@ Retrieves the root folder of the USB storage. The root folder as a [Folder](#class_folder) object.
-### `public virtual bool ` [`format`](#class_u_s_b_storage_1a8aec32e4e48d081183ad880a61836bc5)`(FileSystems fs)` +### `format` + +```cpp +virtual bool format(FileSystems fs) +``` Formats the USB storage with the selected file system. @@ -876,11 +1305,86 @@ Formats the USB storage with the selected file system. true if successful, false if failed.
-### `public bool ` [`isConnected`](#class_u_s_b_storage_1a228919e4b7f6fe0619fbcb33da9a9534)`()` +### `isMounted` + +```cpp +bool isMounted() +``` -Checks if the USB storage is connected. +Checks if the USB storage is mounted. #### Returns -true if connected, false otherwise. +true if mounted, false otherwise. +
+ +### `onConnect` + +```cpp +void onConnect(void(*)() callbackFunction) +``` + +Sets the callback function to be called when a USB connection is established. + +#### Parameters +* `callbackFunction` A pointer to the function to be called when a USB connection is established. +
+ +### `removeOnConnectCallback` + +```cpp +void removeOnConnectCallback() +``` + +Removes the callback function that is executed when the USB storage device is connected. + +
+ +### `onDisconnect` + +```cpp +void onDisconnect(void(*)() callbackFunction) +``` + +Sets a callback function to be called when the USB storage device is disconnected. + +#### Parameters +* `callbackFunction` A pointer to the function to be called when the USB storage device is disconnected. +
+ +### `removeOnDisconnectCallback` + +```cpp +void removeOnDisconnectCallback() +``` + +Removes the callback function that is called when the USB storage device is disconnected. + +
+ +# struct `Partition` + +## Summary + + Members | Descriptions +--------------------------------|--------------------------------------------- +| [`size`](#struct_partition_1a718bdba639f222d90d23480b58caa1f9) | | +| [`fileSystemType`](#struct_partition_1af5c05bc6faa14fb253c3a39e5e883529) | | + +## Members + +### `size` + +```cpp +int size +``` + +
+ +### `fileSystemType` + +```cpp +FileSystems fileSystemType +``` +
diff --git a/examples/AdvancedUSBInternalOperations/AdvancedUSBInternalOperations.ino b/examples/AdvancedUSBInternalOperations/AdvancedUSBInternalOperations.ino index 11f73ea..241c579 100644 --- a/examples/AdvancedUSBInternalOperations/AdvancedUSBInternalOperations.ino +++ b/examples/AdvancedUSBInternalOperations/AdvancedUSBInternalOperations.ino @@ -4,7 +4,7 @@ Demonstrates advanced usage of the "Arduino_UnifiedStorage" library with USB & internal storage, including file operations. Creates, copies, and moves files between storage types, and prints folder contents. - In the setup function, the code initializes serial communication, mounts both USB & internal storage and + In the setup function, the code initializes Serial communication, mounts both USB & internal storage and reformats the internal storage for a clean file system. Then, it creates a root directory in the internal storage and creates a subdirectory with a file inside it containing the string "Hello World!". @@ -28,7 +28,6 @@ USBStorage usbStorage; InternalStorage internalStorage; - // Helper function to prints the contents of a folder, including subdirectories (marked as "[D]") and files (marked as "[F]"). void printFolderContents(Folder dir, int indentation = 0) { std::vector directories = dir.getFolders(); @@ -37,46 +36,45 @@ void printFolderContents(Folder dir, int indentation = 0) { // Print directories for (Folder subdir : directories) { for (int i = 0; i < indentation; i++) { - Serial.print(" "); + Arduino_UnifiedStorage::debugPrint(" "); } - Serial.print("[D] "); - Serial.println(subdir.getPath()); + Arduino_UnifiedStorage::debugPrint("[D] "); + Arduino_UnifiedStorage::debugPrint(subdir.getPath()); printFolderContents(subdir, indentation + 1); } // Print files for (UFile file : files) { for (int i = 0; i < indentation; i++) { - Serial.print(" "); + Arduino_UnifiedStorage::debugPrint(" "); } - Serial.print("[F] "); - Serial.println(file.getPath()); + Arduino_UnifiedStorage::debugPrint("[F] "); + Arduino_UnifiedStorage::debugPrint(file.getPath()); } } - - void setup() { - Serial.begin(115200); - while (!Serial); +#if !defined(ARDUINO_OPTA) + Serial.begin(115200); + while(!Serial); +#else + beginRS485(115200); +#endif // toggle this to enable debugging output - Arduino_UnifiedStorage::debuggingModeEnabled = false; - - usbStorage = USBStorage(); - internalStorage = InternalStorage(); + Arduino_UnifiedStorage::debuggingModeEnabled = true; // Mount the USB storage if(usbStorage.begin()){ - Serial.println("USB storage mounted."); + Arduino_UnifiedStorage::debugPrint("USB storage mounted."); } else { - Serial.println(errno); + Arduino_UnifiedStorage::debugPrint(String(errno)); } if(internalStorage.begin()){ - Serial.println("Internal storage mounted."); + Arduino_UnifiedStorage::debugPrint("Internal storage mounted."); } else { - Serial.println(errno); + Arduino_UnifiedStorage::debugPrint(String(errno)); } // Create a root directory in the internal storage @@ -93,27 +91,27 @@ void setup() { // Copy the file from internal storage to USB storage bool success = file.copyTo(usbStorage.getRootFolder(), true); if (success) { - Serial.println("File copied successfully from internal storage to USB storage."); + Arduino_UnifiedStorage::debugPrint("File copied successfully from internal storage to USB storage."); } else { - Serial.println("Failed to copy file from internal storage to USB storage."); - Serial.println(getErrno()); + Arduino_UnifiedStorage::debugPrint("Failed to copy file from internal storage to USB storage."); + Arduino_UnifiedStorage::debugPrint(getErrno()); } // Move the subdirectory from internal storage to USB storage success = subdir.moveTo(usbStorage.getRootFolder(), true); if (success) { - Serial.println("Subdirectory moved successfully from internal storage to USB storage."); + Arduino_UnifiedStorage::debugPrint("Subdirectory moved successfully from internal storage to USB storage."); } else { - Serial.println("Failed to move subdirectory from internal storage to USB storage."); - Serial.println(getErrno()); + Arduino_UnifiedStorage::debugPrint("Failed to move subdirectory from internal storage to USB storage."); + Arduino_UnifiedStorage::debugPrint(getErrno()); } // Print contents of the USB storage - //Serial.println("USB storage contents:"); - //printFolderContents(usbStorage.getRootFolder()); + Arduino_UnifiedStorage::debugPrint("USB storage contents:"); + printFolderContents(usbStorage.getRootFolder()); // Print contents of the internal storage - Serial.println("Internal storage contents:"); + Arduino_UnifiedStorage::debugPrint("Internal storage contents:"); printFolderContents(internalStorage.getRootFolder()); } diff --git a/examples/AdvancedUSBInternalOperations/sketch.yaml b/examples/AdvancedUSBInternalOperations/sketch.yaml new file mode 100644 index 0000000..4f09a49 --- /dev/null +++ b/examples/AdvancedUSBInternalOperations/sketch.yaml @@ -0,0 +1,31 @@ +profiles: + arduino:mbed_portenta:envie_m7: + notes: Portenta H7 family & Portenta Machine Control + fqbn: arduino:mbed_portenta:envie_m7 + platforms: + - platform: arduino:mbed_portenta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:renesas_portenta:portenta_c33: + notes: Portenta C33 + fqbn: arduino:renesas_portenta:portenta_c33 + platforms: + - platform: arduino:renesas_portenta (1.0.5) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:mbed_opta:opta: + notes: Portenta Opta family + fqbn: arduino:mbed_opta:opta + platforms: + - platform: arduino:mbed_opta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) \ No newline at end of file diff --git a/examples/BackupInternalPartitions/BackupInternalPartitions.ino b/examples/BackupInternalPartitions/BackupInternalPartitions.ino index d181d76..e3f132d 100644 --- a/examples/BackupInternalPartitions/BackupInternalPartitions.ino +++ b/examples/BackupInternalPartitions/BackupInternalPartitions.ino @@ -4,7 +4,7 @@ This code demonstrates how the "Arduino_UnifiedStorage" can be used to access multiple partitions on the internal storage, and transfer information to a USB Mass storage device. - In the setup function, the code initializes serial communication, and registers a callback for the insertion of the USB Drive. + In the setup function, the code initializes Serial communication, and registers a callback for the insertion of the USB Drive. If the device is successfully mounted, a folder for this instance of a backup will be created on the USB Drive. @@ -38,13 +38,12 @@ volatile boolean connected = false; USBStorage thumbDrive; - void addSomeFakeFiles(Folder * folder){ - Serial.println("Adding some fake files to: " + String(folder -> getPathAsString())); + Arduino_UnifiedStorage::testPrint("Adding some fake files to: " + String(folder -> getPathAsString())); for (int i = 0; i < random(0, 9); i++){ UFile thisFile = folder -> createFile("File_"+ String(random(999)), FileMode::WRITE); - Serial.println("\t * " + thisFile.getPathAsString()); + Arduino_UnifiedStorage::testPrint("\t * " + thisFile.getPathAsString()); thisFile.write("writing stuff to the file"); thisFile.close(); } @@ -53,7 +52,7 @@ void addSomeFakeFiles(Folder * folder){ Folder subfolder = folder -> createSubfolder("ChildFolder_"+ String(random(999))); for (int i = 0; i < random(0, 9); i++){ UFile thisFile = subfolder.createFile("File_"+ String(random(999)), FileMode::WRITE); - Serial.println("\t * " + thisFile.getPathAsString()); + Arduino_UnifiedStorage::testPrint("\t * " + thisFile.getPathAsString()); thisFile.write("writing stuff to the file"); thisFile.close(); } @@ -61,44 +60,43 @@ void addSomeFakeFiles(Folder * folder){ void move(Folder * source, Folder * dest){ for(Folder f: source -> getFolders()){ - Serial.println("Copying folder :" + String(f.getPathAsString())); + Arduino_UnifiedStorage::testPrint("Copying folder :" + String(f.getPathAsString())); f.moveTo(*dest); } for(UFile f: source -> getFiles()){ - Serial.println("Copying file :" + String(f.getPathAsString())); + Arduino_UnifiedStorage::testPrint("Copying file :" + String(f.getPathAsString())); f.moveTo(*dest); } } - - - void setup(){ randomSeed(analogRead(A0)); +#if !defined(ARDUINO_OPTA) Serial.begin(115200); while(!Serial); +#else + beginRS485(115200); +#endif // toggle this to enable debugging output Arduino_UnifiedStorage::debuggingModeEnabled = false; - thumbDrive = USBStorage(); - bool thumbMounted = thumbDrive.begin(FS_FAT); if(thumbMounted){ - Serial.println("USB Thumb Drive has been mounted"); + Arduino_UnifiedStorage::testPrint("USB Thumb Drive has been mounted"); Folder thumbRoot = thumbDrive.getRootFolder(); String folderName = "InternalBackup_" + String(millis()); - Serial.println(folderName); + Arduino_UnifiedStorage::testPrint(folderName); Folder backupFolder = thumbRoot.createSubfolder(folderName); int partitionIndex = 0; std::vector partitions = InternalStorage::readPartitions(); - Serial.println("Found " + String(partitions.size()) + " partitions on internalStorage \n"); + Arduino_UnifiedStorage::testPrint("Found " + String(partitions.size()) + " partitions on internalStorage \n"); for (auto part: partitions){ partitionIndex++; @@ -109,7 +107,7 @@ void setup(){ thisPartition.begin(); Folder partitionRootFolder = thisPartition.getRootFolder(); - Serial.println(partitionRootFolder.getPathAsString()); + Arduino_UnifiedStorage::testPrint(partitionRootFolder.getPathAsString()); if(createFakeFiles){ addSomeFakeFiles(&partitionRootFolder); @@ -121,14 +119,9 @@ void setup(){ thumbDrive.unmount(); - - Serial.println("DONE, you can restart the board now"); + Arduino_UnifiedStorage::testPrint("DONE, you can restart the board now"); } - - } - void loop(){ - } diff --git a/examples/BackupInternalPartitions/sketch.yaml b/examples/BackupInternalPartitions/sketch.yaml new file mode 100644 index 0000000..4f09a49 --- /dev/null +++ b/examples/BackupInternalPartitions/sketch.yaml @@ -0,0 +1,31 @@ +profiles: + arduino:mbed_portenta:envie_m7: + notes: Portenta H7 family & Portenta Machine Control + fqbn: arduino:mbed_portenta:envie_m7 + platforms: + - platform: arduino:mbed_portenta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:renesas_portenta:portenta_c33: + notes: Portenta C33 + fqbn: arduino:renesas_portenta:portenta_c33 + platforms: + - platform: arduino:renesas_portenta (1.0.5) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:mbed_opta:opta: + notes: Portenta Opta family + fqbn: arduino:mbed_opta:opta + platforms: + - platform: arduino:mbed_opta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) \ No newline at end of file diff --git a/examples/Callbacks/Callbacks.ino b/examples/Callbacks/Callbacks.ino index 5b215d5..fc8bc20 100644 --- a/examples/Callbacks/Callbacks.ino +++ b/examples/Callbacks/Callbacks.ino @@ -13,7 +13,6 @@ - You can also customize the LED indicators for different boards according to your hardware configuration. */ - #include "Arduino_UnifiedStorage.h" #if defined(ARDUINO_PORTENTA_H7_M7) @@ -27,17 +26,32 @@ USBStorage usbStorage = USBStorage(); void connectionCallback(){ +#if defined(ARDUINO_PORTENTA_H7_M7) + digitalWrite(CALLBACK_LED, LOW); +#elif defined(ARDUINO_PORTENTA_C33) + digitalWrite(CALLBACK_LED, LOW); +#elif defined(ARDUINO_OPTA) digitalWrite(CALLBACK_LED, HIGH); +#endif } void disconnectionCallback(){ +#if defined(ARDUINO_PORTENTA_H7_M7) + digitalWrite(CALLBACK_LED, HIGH); +#elif defined(ARDUINO_PORTENTA_C33) + digitalWrite(CALLBACK_LED, HIGH); +#elif defined(ARDUINO_OPTA) digitalWrite(CALLBACK_LED, LOW); +#endif } void setup(){ pinMode(CALLBACK_LED, OUTPUT); usbStorage.onConnect(connectionCallback); usbStorage.onDisconnect(disconnectionCallback); +#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_C33) + digitalWrite(CALLBACK_LED, HIGH); +#endif } void loop(){ diff --git a/examples/Callbacks/sketch.yaml b/examples/Callbacks/sketch.yaml new file mode 100644 index 0000000..4f09a49 --- /dev/null +++ b/examples/Callbacks/sketch.yaml @@ -0,0 +1,31 @@ +profiles: + arduino:mbed_portenta:envie_m7: + notes: Portenta H7 family & Portenta Machine Control + fqbn: arduino:mbed_portenta:envie_m7 + platforms: + - platform: arduino:mbed_portenta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:renesas_portenta:portenta_c33: + notes: Portenta C33 + fqbn: arduino:renesas_portenta:portenta_c33 + platforms: + - platform: arduino:renesas_portenta (1.0.5) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:mbed_opta:opta: + notes: Portenta Opta family + fqbn: arduino:mbed_opta:opta + platforms: + - platform: arduino:mbed_opta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) \ No newline at end of file diff --git a/examples/InternalStoragePartitioning/InternalStoragePartitioning.ino b/examples/InternalStoragePartitioning/InternalStoragePartitioning.ino index 58d6934..1764eba 100644 --- a/examples/InternalStoragePartitioning/InternalStoragePartitioning.ino +++ b/examples/InternalStoragePartitioning/InternalStoragePartitioning.ino @@ -4,13 +4,13 @@ This example demonstrates the usage of the "Arduino_UnifiedStorage" library for retrieving and creating partitions on the internal storage. The code should help you understand how to work with partitions and perform file operations in different partitions. - It creates the partitions specified in the std::vector you find at the top of the sketch. + It creates the partitions specified in the std::vector you find at the top of the sketch. You can define your own, as long as the size of all partitions doesn't exceed the size of your board's QSPI flash( if you are in doubt about that check docs.arduino.com for more information) and as long as you don't have more than 4 partitions (MBR limitation) The Partition struct has two values: - `size` the size of your partition in kilobytes - 'fileSystemType` which can be either `FS_FAT` or `FS_LITTLEFS` - Here are a few examples of valid partitioning schemes: + Here are a few examples of valid partitioning schemes: - std::vector partitioningScheme = {{16384, FS_FAT}}; - std::vector partitioningScheme = {{2048, FS_FAT}, {6144, FS_FAT} {8192, FS_LITTLEFS}}; - std::vector partitioningScheme = {{4096, FS_LITTLEFS}, {4096, FS_FAT}, {4096, FS_LITTLEFS}, {4096, FS_FAT}}; @@ -23,9 +23,9 @@ INSTRUCTIONS: 1. Check compatibility with your board and make sure you have "POSIXStorage" and "Arduino_UnifiedStorage" installed - 2. Connect your board to the serial monitor - 3. Wait for the sketch to run - 4. Modify the partitioning scheme according to your needs + 2. Connect your board to the Serial monitor + 3. Wait for the sketch to run + 4. Modify the partitioning scheme according to your needs Created: 26th October 2023 By: Cristian Dragomir @@ -36,7 +36,7 @@ #include // Create a vector of partitions with one partition of 16MB using LittleFS -std::vector partitioningScheme = { +std::vector partitioningScheme = { {1024, FS_FAT}, // 1 MB for certificates {5120, FS_FAT}, // 5 MB for OTA firmware updates {8192, FS_LITTLEFS} // 8 MB for user data @@ -50,7 +50,7 @@ void testWriting(Arduino_UnifiedStorage *storage) { // Create a new file named "file.txt" for writing UFile file = root.createFile("file.txt", FileMode::WRITE); Serial.println("\t\t - File path: " + file.getPathAsString()); - + // Write data to the file file.write("writing stuff to the file"); @@ -65,7 +65,7 @@ void testWriting(Arduino_UnifiedStorage *storage) { void testAllPartitions(std::vector partitions) { for (size_t i = 1; i < partitions.size() + 1; ++i) { const char *partitionName = createPartitionName(i); - + // Create an InternalStorage object for the partition InternalStorage thisPartition = InternalStorage(i, partitionName, partitions[i - 1].fileSystemType); @@ -74,6 +74,8 @@ void testAllPartitions(std::vector partitions) { Serial.println("\t - Successfully mounted partition: /" + String(partitionName)); Serial.println("\t - Testing file operations: "); testWriting(&thisPartition); // Test writing to a file in the partition + thisPartition.unmount(); + freePartitionName(partitionName); } Serial.println(); @@ -113,7 +115,7 @@ void setup() { delay(1000); - // Read the MBR sector and display the partitions + // Read the MBR sector and display the partitions listPartitions(); } diff --git a/examples/InternalStoragePartitioning/sketch.yaml b/examples/InternalStoragePartitioning/sketch.yaml new file mode 100644 index 0000000..4f09a49 --- /dev/null +++ b/examples/InternalStoragePartitioning/sketch.yaml @@ -0,0 +1,31 @@ +profiles: + arduino:mbed_portenta:envie_m7: + notes: Portenta H7 family & Portenta Machine Control + fqbn: arduino:mbed_portenta:envie_m7 + platforms: + - platform: arduino:mbed_portenta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:renesas_portenta:portenta_c33: + notes: Portenta C33 + fqbn: arduino:renesas_portenta:portenta_c33 + platforms: + - platform: arduino:renesas_portenta (1.0.5) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:mbed_opta:opta: + notes: Portenta Opta family + fqbn: arduino:mbed_opta:opta + platforms: + - platform: arduino:mbed_opta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) \ No newline at end of file diff --git a/examples/Logger/Logger.ino b/examples/Logger/Logger.ino index fcfcaab..39d17fd 100644 --- a/examples/Logger/Logger.ino +++ b/examples/Logger/Logger.ino @@ -25,7 +25,6 @@ #include "Arduino_UnifiedStorage.h" #include - #if defined(ARDUINO_PORTENTA_H7_M7) #define USB_MOUNTED_LED LED_BLUE #elif defined(ARDUINO_PORTENTA_C33) @@ -53,12 +52,13 @@ bool backingUP = false; void connectionCallback(){ usbAvailable = true; usbStorage.removeOnConnectCallback(); + Arduino_UnifiedStorage::testPrint("USB drive connected."); } void disconnectionCallback(){ usbAvailable = false; usbStorage.onConnect(connectionCallback); - + Arduino_UnifiedStorage::testPrint("USB drive disconnected."); } // Function to run a given method periodically void runPeriodically(void (*method)(), unsigned long interval, unsigned long* variable) { @@ -89,7 +89,6 @@ void moveDataToQSPI() { } } - void performUpdate() { UFile logFile = internalStorage.getRootFolder().createFile("log.txt", FileMode::READ); UFile backupFile = backupFolder.createFile("backup_file.txt", FileMode::APPEND); // Create or open the backup file @@ -98,10 +97,10 @@ void performUpdate() { backingUP = true; unsigned lastUpdateBytes = lastUpdateFile.readAsString().toInt(); // Read the last update size from the file - Arduino_UnifiedStorage::debugPrint("Last update bytes: " + String(lastUpdateBytes)); + Arduino_UnifiedStorage::testPrint("Last update bytes: " + String(lastUpdateBytes)); if (lastUpdateBytes >= bytesWritten) { - Arduino_UnifiedStorage::debugPrint("No new data to copy. "); + Arduino_UnifiedStorage::testPrint("No new data to copy. "); backupFile.close(); lastUpdateFile.close(); backingUP = false; @@ -110,14 +109,14 @@ void performUpdate() { logFile.seek(lastUpdateBytes); // Move the file pointer to the last update position unsigned long totalBytesToMove = bytesWritten - lastUpdateBytes; - Arduino_UnifiedStorage::debugPrint("New update bytes: " + String(totalBytesToMove)); + Arduino_UnifiedStorage::testPrint("New update bytes: " + String(totalBytesToMove)); uint8_t* buffer = new uint8_t[totalBytesToMove]; size_t bytesRead = logFile.read(buffer, totalBytesToMove); size_t bytesMoved = backupFile.write(buffer, bytesRead); // Only write the bytes that haven't been backed up yet - Arduino_UnifiedStorage::debugPrint("Successfully copied " + String(bytesMoved) + " new bytes. "); + Arduino_UnifiedStorage::testPrint("Successfully copied " + String(bytesMoved) + " new bytes. "); lastUpdateFile.changeMode(FileMode::WRITE); // Open the last update file in write mode lastUpdateFile.write(String(lastUpdateBytes + bytesMoved)); // Update the last update size @@ -126,7 +125,6 @@ void performUpdate() { logFile.close(); lastUpdateFile.close(); - usbStorage.unmount(); // Unmount the USB storage digitalWrite(USB_MOUNTED_LED, HIGH); @@ -139,76 +137,66 @@ void performUpdate() { void backupToUSB() { if(usbAvailable && !usbIntialized){ usbStorage.begin(); - Arduino_UnifiedStorage::debugPrint("First drive insertion, creating folders... "); + Arduino_UnifiedStorage::testPrint("First drive insertion, creating folders... "); Folder usbRoot = usbStorage.getRootFolder(); String folderName = "LoggerBackup" + String(random(9999)); backupFolder = usbRoot.createSubfolder(folderName); - Arduino_UnifiedStorage::debugPrint("Successfully created backup folder: " + backupFolder.getPathAsString()); + Arduino_UnifiedStorage::testPrint("Successfully created backup folder: " + backupFolder.getPathAsString()); usbStorage.unmount(); usbIntialized = true; } else if(usbAvailable && usbIntialized) { - Arduino_UnifiedStorage::debugPrint("USB Mass storage is available "); + Arduino_UnifiedStorage::testPrint("USB Mass storage is available "); delay(100); if (!usbStorage.isMounted()) { - Arduino_UnifiedStorage::debugPrint("Mounting USB Mass Storage "); + Arduino_UnifiedStorage::testPrint("Mounting USB Mass Storage "); digitalWrite(USB_MOUNTED_LED, LOW); if(usbStorage.begin()){ performUpdate(); } } else if (usbStorage.isMounted()) { - Arduino_UnifiedStorage::debugPrint("USB Mass storage is connected, performing update "); + Arduino_UnifiedStorage::testPrint("USB Mass storage is connected, performing update "); performUpdate(); } } else { - Arduino_UnifiedStorage::debugPrint("USB Mass storage is not available "); + Arduino_UnifiedStorage::testPrint("USB Mass storage is not available "); } - - } void setup() { randomSeed(analogRead(A0)); - #if !defined(ARDUINO_OPTA) - Serial.begin(115200); - while(!Serial); - #else - beginRS485(115200); - #endif +#if !defined(ARDUINO_OPTA) + Serial.begin(115200); + while(!Serial); +#else + beginRS485(115200); +#endif // toggle this to enable debugging output Arduino_UnifiedStorage::debuggingModeEnabled = false; - usbStorage = USBStorage(); - internalStorage = InternalStorage(); - usbStorage.onConnect(connectionCallback); usbStorage.onDisconnect(disconnectionCallback); pinMode(USB_MOUNTED_LED, OUTPUT); - Arduino_UnifiedStorage::debugPrint("Formatting internal storage... "); + Arduino_UnifiedStorage::testPrint("Formatting internal storage... "); int formatted = internalStorage.format(FS_LITTLEFS); - Arduino_UnifiedStorage::debugPrint("QSPI Format status: " + String(formatted)); - - + Arduino_UnifiedStorage::testPrint("QSPI Format status: " + String(formatted)); if (!internalStorage.begin()) { - Arduino_UnifiedStorage::debugPrint("Failed to initialize internal storage "); + Arduino_UnifiedStorage::testPrint("Failed to initialize internal storage "); return; } else { - Arduino_UnifiedStorage::debugPrint("Initialized storage "); + Arduino_UnifiedStorage::testPrint("Initialized storage "); } - } void loop() { - - runPeriodically(logDataToRAM, 100, &lastLog); runPeriodically(moveDataToQSPI, 1000, &lastMove); runPeriodically(backupToUSB, 10000, &lastBackup); diff --git a/examples/Logger/sketch.yaml b/examples/Logger/sketch.yaml new file mode 100644 index 0000000..4f09a49 --- /dev/null +++ b/examples/Logger/sketch.yaml @@ -0,0 +1,31 @@ +profiles: + arduino:mbed_portenta:envie_m7: + notes: Portenta H7 family & Portenta Machine Control + fqbn: arduino:mbed_portenta:envie_m7 + platforms: + - platform: arduino:mbed_portenta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:renesas_portenta:portenta_c33: + notes: Portenta C33 + fqbn: arduino:renesas_portenta:portenta_c33 + platforms: + - platform: arduino:renesas_portenta (1.0.5) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:mbed_opta:opta: + notes: Portenta Opta family + fqbn: arduino:mbed_opta:opta + platforms: + - platform: arduino:mbed_opta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) \ No newline at end of file diff --git a/examples/SimpleStorageWriteRead/SimpleStorageWriteRead.ino b/examples/SimpleStorageWriteRead/SimpleStorageWriteRead.ino index 51a4a65..a885b8c 100644 --- a/examples/SimpleStorageWriteRead/SimpleStorageWriteRead.ino +++ b/examples/SimpleStorageWriteRead/SimpleStorageWriteRead.ino @@ -29,6 +29,20 @@ #include "Arduino_UnifiedStorage.h" +// Set one of the following to "true" and the rest to "false" in order to select one storage medium +#define USE_SD_STORAGE false +#define USE_USB_STORAGE false +#define USE_INTERNAL_STORAGE true + +#if defined(USE_SD_STORAGE) && (USE_SD_STORAGE == true) +SDStorage storage; // Create an instance for interacting with SD card storage +#elif defined(USE_USB_STORAGE) && (USE_USB_STORAGE == true) +USBStorage storage; // Create an instance for interacting with USB storage +#elif defined(USE_INTERNAL_STORAGE) && (USE_INTERNAL_STORAGE == true) +InternalStorage storage; +#else +#error "No valid storage option defined! Please define one of USE_SD_STORAGE, USE_USB_STORAGE, or USE_INTERNAL_STORAGE as true." +#endif void printFolderContents(Folder dir, int indentation = 0) { std::vector directories = dir.getFolders(); @@ -37,44 +51,41 @@ void printFolderContents(Folder dir, int indentation = 0) { // Print directories for (Folder subdir : directories) { for (int i = 0; i < indentation; i++) { - Serial.print(" "); + Arduino_UnifiedStorage::testPrint(" "); } - Serial.print("[D] "); - Serial.println(subdir.getPath()); + Arduino_UnifiedStorage::testPrint("[D] "); + Arduino_UnifiedStorage::testPrint(subdir.getPath()); printFolderContents(subdir, indentation + 1); } // Print files for (UFile file : files) { for (int i = 0; i < indentation; i++) { - Serial.print(" "); + Arduino_UnifiedStorage::testPrint(" "); } - Serial.print("[F] "); - Serial.println(file.getPath()); + Arduino_UnifiedStorage::testPrint("[F] "); + Arduino_UnifiedStorage::testPrint(file.getPath()); } } +void setup() { -// Uncomment one of the three lines below to select between SD card, USB or internal storage -//SDStorage storage; // Create an instance for interacting with SD card storage -//USBStorage storage; // Create an instance for interacting with USB storage -InternalStorage storage; + uint8_t index = 0u; + char data[20]; - -void setup() { - Serial.begin(115200); - while (!Serial); +// if we are on the Arduino Opta, and have decided to log on an USB drive connected to the USB-C connecter, we have to output the serial data through the RJ45 channel. +#if (defined(ARDUINO_OPTA)) && (defined(USE_USB_STORAGE) && (USE_USB_STORAGE == true)) + beginRS485(115200); +#else + Serial.begin(115200); + while (!Serial); +#endif // toggle this to enable debugging output Arduino_UnifiedStorage::debuggingModeEnabled = false; - - storage = InternalStorage(); - // storage = SDStorage(); // Uncomment this line to use SD card storage - // storage = USBStorage(); // Uncomment this line to use USB storage - if(!storage.begin()){ - Serial.println("Error mounting storage device."); + Arduino_UnifiedStorage::testPrint("Error mounting storage device."); } // Create a root directory in storage device @@ -96,7 +107,8 @@ void setup() { file3.write("This is file 3."); // Read data from the files using seek and available - Serial.println("Reading data from files using seek and available:"); + Arduino_UnifiedStorage::testPrint("Reading data from files using seek and available:"); + Arduino_UnifiedStorage::testPrint("\n\r"); // Close and open files in reading mode file1.changeMode(FileMode::READ); @@ -106,27 +118,33 @@ void setup() { // Read data from file1 file1.seek(0); // Move the file pointer to the beginning + //memset(data, 0u, sizeof(data)); + std::fill(std::begin(data), std::end(data), 0u); while (file1.available()) { - char data = file1.read(); - Serial.write(data); + data[index++] = file1.read(); } - Serial.println(); + Arduino_UnifiedStorage::testPrint(data); // Read data from file2 file2.seek(0); // Move the file pointer to the beginning + index = 0u; + //memset(data, 0u, sizeof(data)); + std::fill(std::begin(data), std::end(data), 0u); while (file2.available()) { - char data = file2.read(); - Serial.print(data); + data[index++] = file2.read(); } - Serial.println(); + Arduino_UnifiedStorage::testPrint(data); // Read data from file3 file3.seek(0); // Move the file pointer to the beginning + index = 0u; + //memset(data, 0u, sizeof(data)); + std::fill(std::begin(data), std::end(data), 0u); while (file3.available()) { - char data = file3.read(); - Serial.print(data); + data[index++] = file3.read(); } - Serial.println(); + Arduino_UnifiedStorage::testPrint(data); + Arduino_UnifiedStorage::testPrint("\n\r"); printFolderContents(storage.getRootFolder()); } diff --git a/examples/SimpleStorageWriteRead/sketch.yaml b/examples/SimpleStorageWriteRead/sketch.yaml new file mode 100644 index 0000000..4f09a49 --- /dev/null +++ b/examples/SimpleStorageWriteRead/sketch.yaml @@ -0,0 +1,31 @@ +profiles: + arduino:mbed_portenta:envie_m7: + notes: Portenta H7 family & Portenta Machine Control + fqbn: arduino:mbed_portenta:envie_m7 + platforms: + - platform: arduino:mbed_portenta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:renesas_portenta:portenta_c33: + notes: Portenta C33 + fqbn: arduino:renesas_portenta:portenta_c33 + platforms: + - platform: arduino:renesas_portenta (1.0.5) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) + arduino:mbed_opta:opta: + notes: Portenta Opta family + fqbn: arduino:mbed_opta:opta + platforms: + - platform: arduino:mbed_opta (4.1.1) + libraries: + - Arduino_USBHostMbed5 (0.3.1) + - Arduino_POSIXStorage (1.2.0) + - Arduino_UnifiedStorage (1.1.0) + - ArduinoRS485 (1.0.5) \ No newline at end of file diff --git a/library.properties b/library.properties index 82711d1..d040296 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=Arduino_UnifiedStorage -version=1.1.0 +version=1.1.2 author=Arduino maintainer=Arduino sentence=Simplify cross-device storage management on Portenta platforms with a single library supporting SD, Flash, and USB storage access. @@ -7,5 +7,5 @@ paragraph=With this versatile library, you can seamlessly handle various storage category=Data Storage url=https://github.com/arduino-libraries/Arduino_UnifiedStorage architectures=renesas_portenta,mbed_portenta,mbed_opta -depends=Arduino_POSIXStorage +depends=Arduino_POSIXStorage,ArduinoRS485 includes=Arduino_UnifiedStorage.h diff --git a/src/Folder.h b/src/Folder.h index 6780834..f2de1e3 100644 --- a/src/Folder.h +++ b/src/Folder.h @@ -52,7 +52,6 @@ class Folder { /** * @brief Removes a directory. - * @param dirname The name of the directory to remove. * @return True if the directory was removed successfully, false otherwise. */ bool remove(); @@ -168,4 +167,4 @@ class Folder { std::string path; }; -#endif \ No newline at end of file +#endif diff --git a/src/InternalStorage.cpp b/src/InternalStorage.cpp index 034ff81..079bc04 100644 --- a/src/InternalStorage.cpp +++ b/src/InternalStorage.cpp @@ -6,21 +6,32 @@ InternalStorage::InternalStorage(){ //Arduino_UnifiedStorage::debugPrint("[InternalStorage][INFO] No partitions found, restoring default partitions"); restoreDefaultPartitions(); - } else { - int lastPartitionNumber = partitionsAvailable.size(); - FileSystems lastPartitionFileSystem = partitionsAvailable.back().fileSystemType; - //Arduino_UnifiedStorage::debugPrint("[InternalStorage][INFO] Found " + String(lastPartitionNumber) + " partitions, using last partition as internal storage"); - - this -> partitionNumber = lastPartitionNumber; - this -> fileSystemType = lastPartitionFileSystem; - this -> partitionName = (char *)"internal"; + // re-read table + partitionsAvailable = Partitioning::readPartitions(QSPIFBlockDeviceType::get_default_instance()); } + + int lastPartitionNumber = partitionsAvailable.size(); + FileSystems lastPartitionFileSystem = partitionsAvailable.back().fileSystemType; + //Arduino_UnifiedStorage::debugPrint("[InternalStorage][INFO] Found " + String(lastPartitionNumber) + " partitions, using last partition as internal storage"); + + this -> partitionNumber = lastPartitionNumber; + this -> fileSystemType = lastPartitionFileSystem; + this -> partitionName = (char *)"internal"; + this -> blockDevice = BlockDeviceType::get_default_instance(); + this -> mbrBlockDevice = new MBRBlockDeviceType(this -> blockDevice, this->partitionNumber); } InternalStorage::InternalStorage(int partition, const char * name, FileSystems fileSystemType){ this -> partitionNumber = partition; - this -> partitionName = (char *)name; + this -> partitionName = name; this -> fileSystemType = fileSystemType; + this -> blockDevice = BlockDeviceType::get_default_instance(); + this -> mbrBlockDevice = new MBRBlockDeviceType(this -> blockDevice, this->partitionNumber); +} + +InternalStorage::~InternalStorage() +{ + delete this -> mbrBlockDevice; } bool InternalStorage::begin(FileSystems fileSystemType){ @@ -49,9 +60,6 @@ std::vector InternalStorage::readPartitions(){ } bool InternalStorage::begin(){ - - this -> blockDevice = BlockDeviceType::get_default_instance(); - this -> mbrBlockDevice = new MBRBlockDeviceType(this->blockDevice, this->partitionNumber); if(this -> fileSystemType == FS_FAT){ this -> fileSystem = new FATFileSystemType(this->partitionName); @@ -61,7 +69,7 @@ bool InternalStorage::begin(){ Arduino_UnifiedStorage::debugPrint("[InternalStorage][begin][INFO] Mounting partition " + String(this->partitionNumber) + " as LittleFS"); } - int err = this -> fileSystem -> mount(mbrBlockDevice); + int err = this -> fileSystem -> mount(this -> mbrBlockDevice); if(err!=0){ Arduino_UnifiedStorage::debugPrint("[InternalStorage][ERROR] Could not mount partition " + String(this->partitionNumber) + " as " + prettyPrintFileSystemType(this->fileSystemType) + ", error code: " + String(errno)); } @@ -69,7 +77,15 @@ bool InternalStorage::begin(){ } bool InternalStorage::unmount(){ - int err = this -> fileSystem -> unmount(); + int err = 0; + + if(this -> fileSystem) + { + err = this -> fileSystem -> unmount(); + delete this -> fileSystem; + this -> fileSystem = NULL; + } + return err == 0; } @@ -78,23 +94,26 @@ Folder InternalStorage::getRootFolder(){ } bool InternalStorage::format(FileSystems fs){ - this -> begin(); + FileSystemType * tmpFileSystem = nullptr; + this -> begin(); this -> unmount(); this -> fileSystemType = fs; if(fs == FS_FAT){ - this -> fileSystem = new FATFileSystemType(this->partitionName); - int err = this -> fileSystem -> reformat(this-> mbrBlockDevice); + tmpFileSystem = new FATFileSystemType(this->partitionName); + int err = tmpFileSystem -> reformat(this-> mbrBlockDevice); if(err != 0){ Arduino_UnifiedStorage::debugPrint("[InternalStorage][format][ERROR] Error formatting partition " + String(this->partitionNumber) + " as FAT: " + String(errno)); - } + } + delete tmpFileSystem; return err == 0; } if (fs == FS_LITTLEFS) { - this -> fileSystem = new LittleFileSystemType(this->partitionName); - int err = this -> fileSystem -> reformat(this-> mbrBlockDevice); + tmpFileSystem = new LittleFileSystemType(this->partitionName); + int err = tmpFileSystem -> reformat(this-> mbrBlockDevice); if(err != 0){ Arduino_UnifiedStorage::debugPrint("[InternalStorage][format][ERROR] Error formatting partition " + String(this->partitionNumber) + " as LittleFS: " + String(errno)); } + delete tmpFileSystem; return err == 0; } diff --git a/src/InternalStorage.h b/src/InternalStorage.h index cfe4b10..13ff514 100644 --- a/src/InternalStorage.h +++ b/src/InternalStorage.h @@ -10,35 +10,37 @@ */ class InternalStorage : public Arduino_UnifiedStorage { public: - + /** * Constructs an InternalStorage object with default settings. * If no partitions are available, it restores the default partitioning scheme (See restoreDefaultPartitions() for more info). * If partitions are available, it sets the partition number, file system type, and partition name based on the last partition available. - * When using the default partitioning scheme the last partition would be the user partition. + * When using the default partitioning scheme the last partition would be the user partition. */ InternalStorage(); /** * Constructs an InternalStorage object with the specified partition, name, and file system. - * + * * @param partition The partition number. * @param name The name of the partition. * @param fs The desired file system (FS_FAT or FS_LITTLEFS). */ InternalStorage(int partition, const char *name, FileSystems fs); + ~InternalStorage(); + /** * Initializes the internal storage. - * + * * @return true if successful, false if failed. */ bool begin() override; /** * Initializes the internal storage with the specified file system. - * + * * @param fs The desired file system (FS_FAT or FS_LITTLEFS). * @return true if successful, false if failed. */ @@ -46,14 +48,14 @@ class InternalStorage : public Arduino_UnifiedStorage { /** * Unmounts the internal storage. - * + * * @return true if successful, false if failed. */ bool unmount() override; /** * Retrieves the root folder of the internal storage. - * + * * @return The root folder as a Folder object. */ Folder getRootFolder() override; @@ -61,7 +63,7 @@ class InternalStorage : public Arduino_UnifiedStorage { /** * Formats the internal storage with the selected file system. - * + * * @return true if successful, false if failed. */ bool format(FileSystems fs) override; @@ -69,7 +71,7 @@ class InternalStorage : public Arduino_UnifiedStorage { /** * Retrieves the block device associated with the internal storage. - * + * * @return The block device as a BlockDevice object. */ BlockDeviceType *getBlockDevice(); @@ -86,7 +88,7 @@ class InternalStorage : public Arduino_UnifiedStorage { * Creates one partition spanning over the whole size of the internal storage drive erasing the existing partitions. * @return true if successful, false if failed. */ - static bool partition(); + static bool partition(); /** * Restores the default partitioning scheme (1MB FAT32 for Certificates, 5MB FAT32 for OTA, 8MB user storage) to the internal storage drive erasing the existing partitions. @@ -96,7 +98,7 @@ class InternalStorage : public Arduino_UnifiedStorage { /** * Reads the partitioning scheme from the MBR sector of the internal storage drive and returns a vector of structs of type Partition that represents the partitioning scheme - * @return vector of structs of type Partition + * @return vector of structs of type Partition */ static std::vector readPartitions(); @@ -105,7 +107,7 @@ class InternalStorage : public Arduino_UnifiedStorage { MBRBlockDeviceType * mbrBlockDevice; FileSystemType * fileSystem; int partitionNumber; - char * partitionName; + const char * partitionName; FileSystems fileSystemType; }; diff --git a/src/Partitioning.cpp b/src/Partitioning.cpp index 2a4f196..de9af76 100644 --- a/src/Partitioning.cpp +++ b/src/Partitioning.cpp @@ -21,7 +21,7 @@ bool Partitioning::eraseMBRSector(BlockDeviceType * blockDevice) } bool Partitioning::isPartitionSchemeValid(BlockDeviceType * blockDevice, std::vector partitions){ - size_t driveSize = blockDevice -> size() / 1024; // + size_t driveSize = blockDevice -> size() / 1024; // size_t totalSize = 0; for (size_t i = 1; i < partitions.size() + 1; ++i) { @@ -72,7 +72,7 @@ bool Partitioning::formatPartition(BlockDeviceType * blockDevice, int partitionN } bool Partitioning::createAndFormatPartitions(BlockDeviceType * blockDevice, std::vector partitions){ - + bool success = true; // initialize to true int lastPartitionEnd = 0; @@ -117,7 +117,7 @@ bool Partitioning::partitionDrive(BlockDeviceType * blockDevice, std::vector Partitioning::readPartitions(BlockDeviceType * blockDevice){ std::vector partitions; - + auto returnCode = blockDevice->init(); if (returnCode) { Arduino_UnifiedStorage::debugPrint("[Partitioning][readPartitions][ERROR] Unable to read the Block Device."); @@ -135,17 +135,18 @@ std::vector Partitioning::readPartitions(BlockDeviceType * blockDevic returnCode = blockDevice->read(buffer, 512 - buffer_size, buffer_size); if (returnCode) { Arduino_UnifiedStorage::debugPrint("[Partitioning][readPartitions][ERROR] Unable to read the Master Boot Record"); - + blockDevice->deinit(); delete[] buffer; return partitions; } auto table_start_offset = buffer_size - sizeof(mbrTable); auto table = reinterpret_cast(&buffer[table_start_offset]); - + if (table->signature[0] != mbrMagicNumbers[0] || table->signature[1] != mbrMagicNumbers[1]) { - + Arduino_UnifiedStorage::debugPrint("[Partitioning][readPartitions][INFO] MBR Not Found - Flash Memory doesn't have partitions."); + blockDevice->deinit(); delete[] buffer; return partitions; } @@ -156,9 +157,9 @@ std::vector Partitioning::readPartitions(BlockDeviceType * blockDevic Partition partition; /*This code calculates the size of a partition in kilobytes. - It takes the Logical Block Address (LBA) size of the partition, + It takes the Logical Block Address (LBA) size of the partition, multiplies it by 4096 (the size of a block in bytes), - and then shifts the result 10 bits to the right to convert it to kilobytes. + and then shifts the result 10 bits to the right to convert it to kilobytes. */ partition.size = (entry.lbaSize * 4096) >> 10; @@ -171,24 +172,30 @@ std::vector Partitioning::readPartitions(BlockDeviceType * blockDevic MBRBlockDeviceType * mbrBlocKDevice = new MBRBlockDeviceType(blockDevice, partitionIndex); FATFileSystemType * fatProbeFileSystem = new FATFileSystemType("probing"); LittleFileSystemType * littleFsProbeFilesystem = new LittleFileSystemType("probing"); - - if(fatProbeFileSystem -> mount(mbrBlocKDevice) == 0){ - Arduino_UnifiedStorage::debugPrint("[Partitioning][readPartitions][INFO] Partition " + String(partitionIndex) + " is formatted with FAT file system"); - fatProbeFileSystem -> unmount(); - partition.fileSystemType = FS_FAT; - partitions.push_back(partition); - - } else if (littleFsProbeFilesystem -> mount(mbrBlocKDevice) == 0){ - Arduino_UnifiedStorage::debugPrint("[Partitioning][readPartitions][INFO] Partition " + String(partitionIndex) + " is formatted with LittleFS file system"); - littleFsProbeFilesystem -> unmount(); - partition.fileSystemType = FS_LITTLEFS; - partitions.push_back(partition); - } else { - Arduino_UnifiedStorage::debugPrint("[Partitioning][readPartitions][INFO] Partition " + String(partitionIndex) + " is not formatted with a recognized file system"); + + if(mbrBlocKDevice && fatProbeFileSystem && littleFsProbeFilesystem) + { + if(fatProbeFileSystem -> mount(mbrBlocKDevice) == 0){ + Arduino_UnifiedStorage::debugPrint("[Partitioning][readPartitions][INFO] Partition " + String(partitionIndex) + " is formatted with FAT file system"); + fatProbeFileSystem -> unmount(); + partition.fileSystemType = FS_FAT; + partitions.push_back(partition); + delete mbrBlocKDevice; + delete fatProbeFileSystem; + } else if (littleFsProbeFilesystem -> mount(mbrBlocKDevice) == 0){ + Arduino_UnifiedStorage::debugPrint("[Partitioning][readPartitions][INFO] Partition " + String(partitionIndex) + " is formatted with LittleFS file system"); + littleFsProbeFilesystem -> unmount(); + partition.fileSystemType = FS_LITTLEFS; + partitions.push_back(partition); + delete mbrBlocKDevice; + delete littleFsProbeFilesystem; + } else { + Arduino_UnifiedStorage::debugPrint("[Partitioning][readPartitions][INFO] Partition " + String(partitionIndex) + " is not formatted with a recognized file system"); + } } - - } + } + blockDevice->deinit(); delete[] buffer; return partitions; } diff --git a/src/Types.h b/src/Types.h index 1afad3e..833c7c1 100644 --- a/src/Types.h +++ b/src/Types.h @@ -3,7 +3,7 @@ #include "Boards.h" -enum FileMode { READ, WRITE, APPEND }; +enum class FileMode { READ, WRITE, APPEND }; #if defined(USES_RENESAS_CORE) #include "BlockDevice.h" diff --git a/src/UFile.cpp b/src/UFile.cpp index be8c806..0ac8b10 100644 --- a/src/UFile.cpp +++ b/src/UFile.cpp @@ -21,13 +21,13 @@ bool UFile::open(const char* filename, FileMode fileMode) { path = filename; // Set the mode based on the fileMode switch (fileMode) { - case READ: + case FileMode::READ: mode = "r+"; break; - case WRITE: + case FileMode::WRITE: mode = "w+"; break; - case APPEND: + case FileMode::APPEND: mode = "a+"; break; default: @@ -51,6 +51,15 @@ bool UFile::open(String filename, FileMode mode) { return open(filename.c_str(), mode); } +bool UFile::open(FileMode mode) { + if (path.empty()) { + // Path is not set + return false; + } + + return open(path.c_str(), mode); +} + void UFile::close() { // Close the file if (filePointer != nullptr) { diff --git a/src/UFile.h b/src/UFile.h index 105147c..3f1bc8e 100644 --- a/src/UFile.h +++ b/src/UFile.h @@ -52,6 +52,12 @@ class UFile{ */ bool open(String filename, FileMode mode); + /** + * @brief Opens a file that was already initialized with a path. + * @param mode The file mode (READ, WRITE, or APPEND). The default is READ. + * @return True if the file was opened successfully, false otherwise. + */ + bool open(FileMode mode = FileMode::READ); /** * @brief Closes the file and releases any allocated resources. diff --git a/src/Utils.h b/src/Utils.h index 4a6ee36..0d70578 100644 --- a/src/Utils.h +++ b/src/Utils.h @@ -39,7 +39,7 @@ [[gnu::unused]] static String prettyPrintFileSystemType(FileSystems f){ if(f == 0) return "FAT"; - else if(f == 1) return "LitlleFS"; + else if(f == 1) return "LittleFS"; else return ""; } @@ -56,11 +56,17 @@ // Dynamically allocate memory for the string and copy the generated value char* dynamicName = new char[strlen(partitionName) + 1]; - strcpy(dynamicName, partitionName); + if(dynamicName) + { + strcpy(dynamicName, partitionName); + } return dynamicName; } +[[gnu::unused]] static void freePartitionName(const char* partitionName) { + delete[] partitionName; +} [[gnu::unused]] static bool copyFolder(const char* source, const char* destination) { DIR* dir = opendir(source); @@ -88,7 +94,16 @@ size_t destinationPathLength = strlen(destination) + strlen(entry->d_name) + 1; char* sourcePath = new char[sourcePathLength]; + if(!sourcePath) + { + return false; + } char* destinationPath = new char[destinationPathLength]; + if(!destinationPath) + { + delete[] sourcePath; + return false; + } snprintf(sourcePath, sourcePathLength, "%s/%s", source, entry->d_name); @@ -97,8 +112,8 @@ struct stat fileInfo; if (stat(sourcePath, &fileInfo) != 0) { closedir(dir); - delete(sourcePath); - delete(destinationPath); + delete[] sourcePath; + delete[] destinationPath; return false; } @@ -106,8 +121,8 @@ // Recursively copy subdirectories if (!copyFolder(sourcePath, destinationPath)) { closedir(dir); - delete(sourcePath); - delete(destinationPath); + delete[] sourcePath; + delete[] destinationPath; return false; } } else { @@ -115,8 +130,8 @@ FILE* sourceFile = fopen(sourcePath, "r"); if (sourceFile == nullptr) { closedir(dir); - delete(sourcePath); - delete(destinationPath); + delete[] sourcePath; + delete[] destinationPath; return false; } @@ -124,8 +139,8 @@ if (destinationFile == nullptr) { fclose(sourceFile); closedir(dir); - delete(sourcePath); - delete(destinationPath); + delete[] sourcePath; + delete[] destinationPath; return false; } @@ -137,6 +152,10 @@ fclose(sourceFile); fclose(destinationFile); } + + delete[] sourcePath; + delete[] destinationPath; + } closedir(dir); @@ -215,4 +234,4 @@ -#endif +#endif