diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000..540b2ae --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,39 @@ +# Each line is a file pattern followed by one or more owners. + +# These owners will be the default owners for everything in +# the repo. Unless a later match takes precedence, +# @global-owner1 and @global-owner2 will be requested for +# review when someone opens a pull request. +* @FreeRTOS/pr-bar-raiser + +# Order is important; the last matching pattern takes the most +# precedence. When someone opens a pull request that only +# modifies JS files, only @js-owner and not the global +# owner(s) will be requested for a review. +# *.c FreeRTOS/pr-bar-raiser + +# You can also use email addresses if you prefer. They'll be +# used to look up users just like we do for commit author +# emails. +# *.go docs@example.com + +# In this example, @doctocat owns any files in the build/logs +# directory at the root of the repository and any of its +# subdirectories. +# /build/logs/ @doctocat + +# The `docs/*` pattern will match files like +# `docs/getting-started.md` but not further nested files like +# `docs/build-app/troubleshooting.md`. +# docs/* docs@example.com + +# In this example, @octocat owns any file in an apps directory +# anywhere in your repository. +# apps/ @octocat + +# In this example, @doctocat owns any file in the `/docs` +# directory in the root of your repository and any of its +# subdirectories. +# /docs/ @doctocat + + diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..5b627cf --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,4 @@ +## Code of Conduct +This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). +For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact +opensource-codeofconduct@amazon.com with any additional questions or comments. diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..68f0e0b --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,70 @@ +# Contribution guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, code, or +documentation, we welcome our community to be involved in this project. + +Please read through this document before submitting any issues or pull requests to ensure we are able to help you and all members of the community as effectively as possible. + +## Code of conduct +This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). +For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact +opensource-codeofconduct@amazon.com with any additional questions or comments. + + +## Security issue notifications +If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. + + +## Submitting a bugs/feature request +Have a bug to report or feature to request? Follow these steps: +1. Search on the [FreeRTOS Community Support Forums](https://forums.freertos.org/), [FreeRTOS-Plus-FAT issue tracker](https://github.com/FreeRTOS/Lab-Project-FreeRTOS-FAT/issues?utf8=%E2%9C%93&q=is%3Aissue) and [FreeRTOS GitHub issue tracker](https://github.com/FreeRTOS/FreeRTOS/issues?utf8=%E2%9C%93&q=is%3Aissue) to be sure this hasn't been already reported or discussed. +2. If your search turns up empty, create a new topic in the [forums](https://forums.freertos.org/) and work with the community to help clarify issues or refine the idea. Include as many of the details listed below. +3. Once the community has had time to discuss and digest, we welcome you to create an [issue](https://github.com/FreeRTOS/Lab-Project-FreeRTOS-FAT/issues) to report bugs or suggest features. + +When creating a new topic on the forums or filing an issue, please include as many relevant details as possible. Examples include: + +* A clear description of the situation — what you observe, what you expect, and your view on how the two differ. +* A reproducible test case or sequence of steps. +* The version of our code being used. +* Any modifications you've made relevant to the bug. +* Details of your environment or deployment. Highlight anything unusual. + + +## Contributing via pull request +Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: + +1. You are working against the latest source on the *master* branch. +2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +2. Modify the source; focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. +3. Follow the [coding style guide](https://www.freertos.org/FreeRTOS-Coding-Standard-and-Style-Guide.html). +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request interface. + NOTE: Please make sure the default option (Allow edits from maintainers) is left checked. +6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. + +GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + +## Coding style +* Please ensure that your code complies to the [FreeRTOS coding style guidelines](https://www.freertos.org/FreeRTOS-Coding-Standard-and-Style-Guide.html). + + +## Getting your pull request merged +All pull requests must be approved by our review team before it can be merged in. We appreciate your patience while pull requests are reviewed. The time it takes to review will depend on complexity and consideration of wider implications. + + +## Finding contributions to work on +Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), tackling open 'help wanted' issues is a great place to start. + + +## Licensing +The FreeRTOS-Plus-FAT library is released under the MIT open source license, the text of which can be found [here](https://github.com/FreeRTOS/FreeRTOS-Plus-FAT/blob/master/LICENSE.md) + +Additional license files can be found in the folders containing any supplementary libraries licensed by their respective copyright owners where applicable. + +We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..c6a70c9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,43 @@ +--- +name: Bug report +about: Create a report to help us improve FreeRTOS-Plus-FAT. This should only be used + for confirmed bugs. If you suspect something it is best to first discuss it on the + FreeRTOS forums linked below. +title: "[BUG]" +labels: bug +assignees: '' + +--- + +**Describe the bug** +A concise description of what the bug is. If possible, that is the code is not proprietary, please upload the code in a [GitHub fork](https://docs.github.com/en/get-started/quickstart/fork-a-repo) such that we can reproduce the bug. + +**Target** +- Development board: [e.g. HiFive11 RevB] +- Instruction Set Architecture: [e.g. RV32IMAC] +- IDE and version: [e.g. Freedom Studio 4.12.0.2019-08-2] +- Toolchain and version: [e.g. riscv64-unknown-elf-gcc-8.3.0-2019.08.0] + +**Host** +- Host OS: [e.g. MacOS] +- Version: [e.g. Mojave 10.14.6] + +**To Reproduce** +- Use project ... and configure with ... +- Run on ... and could observe ... + +**Expected behavior** +A concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Wireshark logs** +To help us identify the issue and/or reproduce it, please attach Wireshark logs if applicable. + +**Additional context** +Add any other context about the problem here. +e.g. code snippet to reproduce the issue. +e.g. stack trace, memory dump, debugger log, and many etc. + + diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..a030f0b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: FreeRTOS Community Support Forum + url: https://forums.freertos.org/ + about: Please ask and answer questions about FreeRTOS-Plus-FAT here. diff --git a/.github/ISSUE_TEMPLATE/documentation-issue.md b/.github/ISSUE_TEMPLATE/documentation-issue.md new file mode 100644 index 0000000..5a816c9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/documentation-issue.md @@ -0,0 +1,23 @@ +--- +name: Documentation issue +about: Create a report to help us improve our documentation. +title: "[DOC] " +labels: '' +assignees: '' + +--- + +**Describe the issue** +Please describe the issue and expected clarification in concise language. + +**Reference** +Please attach the URL at which you are experiencing the issue. + +**Screenshot** +If applicable, please attach screenshot. + +**Browser** +- Browser: [e.g. Chrome] +- Version: [e.g. 80.0.3987.132] + + diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md new file mode 100644 index 0000000..3c8290c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request.md @@ -0,0 +1,20 @@ +--- +name: Feature Request +about: Suggest an idea for this project +title: "[Feature Request] " +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..7d4227d --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,5 @@ +## Reporting a Vulnerability + +If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security +via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/) or directly via email to aws-security@amazon.com. +Please do **NOT** create a public github issue. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..c3c8607 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,16 @@ + + +Description +----------- + + +Test Steps +----------- + + +Related Issue +----------- + + + +By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..021575f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,110 @@ +name: CI Checks + +on: + push: + branches: ["**"] + pull_request: + branches: ["**"] + workflow_dispatch: + +jobs: + # Currently no unit tests + # Currently no spell-check + + formatting: + # Use only 18.04 since we want the uncrustify version to + # be 0.66.1_f to ensure proper formatting. + runs-on: ubuntu-18.04 + steps: + - uses: actions/checkout@v2 + - name: Install Uncrustify + run: sudo apt-get install uncrustify + - name: Run Uncrustify + run: | + uncrustify --version + find . -iname "*.[hc]" -exec uncrustify --check -c tools/uncrustify.cfg {} + + if [ "$?" = "0" ]; then + exit 0 + else + echo -e "\033[31;1;43mFormatting check (using Uncrustify) failed...\033[0m" + echo -e "\033[32;3mTo have the code uncrustified for you, please comment '/bot run uncrustify' (without the quotes) on the Pull Request.\033[0m" + exit 1 + fi + - name: Check For Trailing Whitespace + run: | + set +e + grep --exclude="README.md" -rnI -e "[[:blank:]]$" . + if [ "$?" = "0" ]; then + echo "Files have trailing whitespace." + exit 1 + else + exit 0 + fi + + # doxygen: + # runs-on: ubuntu-20.04 + # steps: + # - uses: actions/checkout@v2 + # - name: Run doxygen build + # uses: FreeRTOS/CI-CD-Github-Actions/doxygen@main + # with: + # path: ./ + + build-checks: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Build checks (Default configuration) + run: | + cmake -S . -B build/ -DFREERTOS_PLUS_FAT_TEST_CONFIGURATION=DEFAULT_CONF + make -C build/ + + # complexity: + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v2 + # - name: Setup + # run: sudo apt-get install complexity + # - name: Install Uncrustify + # run: sudo apt-get install uncrustify + # - name: Complexity + # run: | + # COMPLEXITY_PARAMS="--scores --threshold=10 --horrid-threshold=283" + # TEMP_DIR=./temp + # mkdir -p ${TEMP_DIR} + # for SOURCE_FILE in source/portable/BufferManagement/*.c source/*.c + # do + # TARGET_DIR=${TEMP_DIR}/`dirname ${SOURCE_FILE}` + # TARGET_FILE=${TARGET_DIR}/`basename ${SOURCE_FILE}` + # mkdir -p ${TARGET_DIR} + # uncrustify -c tools/uncrustify.complexity.cfg -f ${SOURCE_FILE} > ${TARGET_FILE} + # done + # find ${TEMP_DIR} -iname '*.c' | xargs complexity ${COMPLEXITY_PARAMS} + # RESULT=$? + # rm -rf ${TEMP_DIR} + # if [ "${RESULT}" = "0" ]; then + # echo "All is good." + # exit 0 + # else + # echo "Sources are too complex, rc = " ${RESULT} + # exit 1 + # fi + + git-secrets: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + with: + submodules: recursive + - name: Checkout awslabs/git-secrets + uses: actions/checkout@v2 + with: + repository: awslabs/git-secrets + ref: master + path: git-secrets + - name: Install git-secrets + run: cd git-secrets && sudo make install && cd .. + - name: Run git-secrets + run: | + git-secrets --register-aws + git-secrets --scan diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..0f7435d --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,140 @@ +name: Release automation + +on: + workflow_dispatch: + inputs: + commit_id: + description: "Commit ID to tag and create a release for" + required: true + version_number: + description: "Release Version Number (Eg, v1.0.0)" + required: true + +jobs: + tag-commit: + name: Tag commit + runs-on: ubuntu-latest + steps: + - name: Checkout code + uses: actions/checkout@v2 + with: + ref: ${{ github.event.inputs.commit_id }} + - name: Configure git identity + run: | + git config --global user.name ${{ github.actor }} + git config --global user.email ${{ github.actor }}@users.noreply.github.com + - name: create a new branch that references commit id + run: git checkout -b ${{ github.event.inputs.version_number }} ${{ github.event.inputs.commit_id }} + - name: Generate SBOM + uses: FreeRTOS/CI-CD-Github-Actions/sbom-generator@main + with: + repo_path: ./ + source_path: ./source + - name: commit SBOM file + run: | + git add . + git commit -m 'Update SBOM' + git push -u origin ${{ github.event.inputs.version_number }} + - name: Tag Commit and Push to remote + run: | + git tag ${{ github.event.inputs.version_number }} -a -m "FreeRTOS-Plus-FAT Library ${{ github.event.inputs.version_number }}" + git push origin --tags + - name: Verify tag on remote + run: | + git tag -d ${{ github.event.inputs.version_number }} + git remote update + git checkout tags/${{ github.event.inputs.version_number }} + git diff ${{ github.event.inputs.commit_id }} tags/${{ github.event.inputs.version_number }} + create-zip: + needs: tag-commit + name: Create ZIP and verify package for release asset. + runs-on: ubuntu-latest + steps: + - name: Install ZIP tools + run: sudo apt-get install zip unzip + - name: Checkout code + uses: actions/checkout@v2 + with: + ref: ${{ github.event.inputs.commit_id }} + path: FreeRTOS-Plus-FAT + submodules: recursive + - name: Checkout disabled submodules + run: | + cd FreeRTOS-Plus-FAT + git submodule update --init --checkout --recursive + - name: Create ZIP + run: | + zip -r FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}.zip FreeRTOS-Plus-FAT -x "*.git*" + ls ./ + - name: Validate created ZIP + run: | + mkdir zip-check + mv FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}.zip zip-check + cd zip-check + unzip FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}.zip -d FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }} + ls FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }} + diff -r -x "*.git*" FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}/FreeRTOS-Plus-FAT/ ../FreeRTOS-Plus-FAT/ + cd ../ + - name: Build + run: | + cd zip-check/FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}/FreeRTOS-Plus-FAT + sudo apt-get install -y lcov + sudo apt-get install unifdef + cmake -S test/unit-test -B test/unit-test/build/ + make -C test/unit-test/build/ all + - name: Test + run: | + cd zip-check/FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}/FreeRTOS-Plus-FAT + pushd test/unit-test/build/ + ctest -E system --output-on-failure + popd + make -C test/unit-test/build/ coverage + lcov --list --rc lcov_branch_coverage=1 test/unit-test/build/coverage.info + cd .. + - name: Create artifact of ZIP + uses: actions/upload-artifact@v2 + with: + name: FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}.zip + path: zip-check/FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}.zip + deploy-doxygen: + needs: tag-commit + name: Deploy doxygen documentation + runs-on: ubuntu-latest + steps: + - name: Doxygen generation + uses: FreeRTOS/CI-CD-Github-Actions/doxygen-generation@main + with: + ref: ${{ github.event.inputs.version_number }} + add_release: "true" + create-release: + needs: + - create-zip + - deploy-doxygen + name: Create Release and Upload Release Asset + runs-on: ubuntu-latest + steps: + - name: Create Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.event.inputs.version_number }} + release_name: ${{ github.event.inputs.version_number }} + body: Release ${{ github.event.inputs.version_number }} of the FreeRTOS-Plus-FAT Library. + draft: false + prerelease: false + - name: Download ZIP artifact + uses: actions/download-artifact@v2 + with: + name: FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}.zip + - name: Upload Release Asset + id: upload-release-asset + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}.zip + asset_name: FreeRTOS-Plus-FAT-${{ github.event.inputs.version_number }}.zip + asset_content_type: application/zip diff --git a/.github/workflows/uncrustify.yml b/.github/workflows/uncrustify.yml new file mode 100644 index 0000000..31ab98b --- /dev/null +++ b/.github/workflows/uncrustify.yml @@ -0,0 +1,50 @@ +name: Uncrustify the source code + +on: + issue_comment: + types: [created] + +jobs: + Uncrustify: + name: Run_Uncrustify + if: ${{ github.event.issue.pull_request && github.event.comment.body == '/bot run uncrustify' }} + runs-on: ubuntu-18.04 + steps: + - name: Dump GitHub context + env: + GITHUB_CONTEXT: ${{ toJson(github) }} + run: echo "$GITHUB_CONTEXT" + - name: get pullrequest url + run: | + echo ${{ github.event.issue.pull_request.url }} + - name: get upstream repo + id: upstreamrepo + run: | + echo "::set-output name=RemoteRepo::$(curl -H "Accept: application/vnd.github.sailor-v-preview+json" --url ${{ github.event.issue.pull_request.url }} | jq '.head.repo.full_name' | sed 's/\"//g')" + - name: get upstream branch + id: upstreambranch + run: | + echo "::set-output name=branchname::$(curl -H "Accept: application/vnd.github.sailor-v-preview+json" --url ${{ github.event.issue.pull_request.url }} | jq '.head.ref' | sed 's/\"//g')" + - name: echo upstream repo:branch + run: | + echo ${{ steps.upstreamrepo.outputs.RemoteRepo }}:${{ steps.upstreambranch.outputs.branchname }} + - name: Checkout upstream repo + uses: actions/checkout@v2 + with: + token: ${{ secrets.PAT }} + repository: ${{ steps.upstreamrepo.outputs.RemoteRepo }} + ref: ${{ steps.upstreambranch.outputs.branchname }} + - name: Install Uncrustify + run: sudo apt-get install uncrustify + - name: Run Uncrustify + run: | + uncrustify --version + find . -iname "*.[hc]" -exec uncrustify -c tools/uncrustify.cfg --no-backup --replace {} + + find . -iname "*.[hc]" -exec uncrustify -c tools/uncrustify.cfg --no-backup --replace {} + + - name: Push changes to upstream repository + run: | + git config --global user.name 'GitHub Action' + git config --global user.email 'action@github.com' + git add -A + git commit -m "Uncrustify: triggered by comment." + git push diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..9721885 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,213 @@ +cmake_minimum_required(VERSION 3.15) +cmake_policy(SET CMP0048 NEW) # project version +cmake_policy(SET CMP0076 NEW) # full paths + +######################################################################## +# Project Details +project(FreeRTOS-Plus-FAT + VERSION 0.0.1 + DESCRIPTION "FreeRTOS DOS Compatible Embedded FAT File System" + HOMEPAGE_URL https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/index.html + LANGUAGES C) + +# Do not allow in-source build. +if( ${PROJECT_SOURCE_DIR} STREQUAL ${PROJECT_BINARY_DIR} ) +message( FATAL_ERROR "In-source build is not allowed. Please build in a separate directory, such as ${PROJECT_SOURCE_DIR}/build." ) +endif() + +######################################################################## +# Options + +# Optional: FREERTOS_PLUS_FAT_DEV_SUPPORT +# - when OFF - device support is disabled and not used. +# - When ON - device support is enabled and the ff_devices.h API is used. +# Optional: FREERTOS_PLUS_FAT_PORT +# - When not defined - identifies native platform Linxu or MinGW and uses that port. +# - When defined as A_CUSTOM_PORT - the port library must be defined in advance. +# - When any of the other supported ports - the port library is defined by portable source files. +option(FREERTOS_PLUS_FAT_DEV_SUPPORT "FreeRTOS Plus FAT Device selection support" OFF) + +# Select the appropriate FAT Port +# This will fail the CMake preparation step if not set to one of those values. +set(FREERTOS_PLUS_FAT_PORT "" CACHE STRING "FreeRTOS Plus FAT Port selection") +set(FREERTOS_PLUS_FAT_PORT_LIST + A_CUSTOM_PORT + ATSAM4E + AVR32_UC3 + LPC18XX + POSIX + STM32FXX + STM32HXX + ZYNQ + ZYNQ_2019_3 +) +if(NOT FREERTOS_PLUS_FAT_PORT) + # Attempt to detect the system. + if(UNIX) + message(STATUS "Detected UNIX/Posix system setting FREERTOS_PLUS_FAT_PORT = POSIX") + set(FREERTOS_PLUS_FAT_PORT POSIX) + elseif(MINGW) + message(STATUS "Detected Windows MinGW system setting FREERTOS_PLUS_FAT_PORT = WIN_MGW") + set(FREERTOS_PLUS_FAT_PORT WIN_PCAP) + endif() +endif() + +if(NOT FREERTOS_PLUS_FAT_PORT IN_LIST FREERTOS_PLUS_FAT_PORT_LIST ) + message(FATAL_ERROR " FREERTOS_PLUS_FAT_PORT is '${FREERTOS_PLUS_FAT_PORT}'.\n" + " Please specify it from top-level CMake file (example):\n" + " set(FREERTOS_PLUS_FAT_PORT POSIX CACHE STRING \"\")\n" + " or from CMake command line option:\n" + " -DFREERTOS_PLUS_FAT_PORT=POSIX\n" + " \n" + " Available port options: (Tested means compiled with that variant)\n" + " A_CUSTOM_PORT Target: User Defined\n" + " ATSAM4E Target: ATSAM4E Tested: TODO\n" + " AVR32_UC3 Target: avr32_uc3 Tested: TODO\n" + " LPC18XX Target: lpc18xx Tested: TODO\n" + " POSIX Target: linux/Posix\n" + " STM32F4XX Target: STM32F4xx Tested: TODO\n" + " STM32F7XX Target: STM32F7xx Tested: TODO\n" + " ZYNQ Target: Xilinx Zynq Tested: TODO\n" + " ZYNQ_2019_3 Target: Xilinx Zynq 2019.3") +elseif((FREERTOS_PLUS_FAT_PORT STREQUAL "A_CUSTOM_PORT") AND (NOT TARGET freertos_plus_fat_port) ) + message(FATAL_ERROR " FREERTOS_PLUS_FAT_PORT is set to A_CUSTOM_PORT.\n" + " Please specify the custom port target with all necessary files.\n" + " For example, assuming a directory of:\n" + " FreeRTOSPlusFatPort/\n" + " CMakeLists.txt\n" + " ff_sddisk.c\n" + " Where FreeRTOSPlusFatPort/CMakeLists.txt is a modified version of:\n" + " add_library(freertos_plus_fat_port STATIC)\n" + " target_sources(freertos_plus_fat_port\n" + " PRIVATE\n" + " ff_sddisk.c)\n" + " target_link_libraries(freertos_plus_fat_port\n" + " PUBLIC\n" + " freertos_plus_fat_port_common\n" + " PRIVATE\n" + " freertos_kernel\n" + " freertos_plus_fat)") +endif() + + +# Select the appropriate Build Test configuration +# This is only used when freertos_config is not defined, otherwise the build test will be performed +# on the config defined in the freertos_config +set(FREERTOS_PLUS_FAT_TEST_CONFIGURATION "CUSTOM" CACHE STRING "FreeRTOS Plus FAT Build Test configuration") +set(FREERTOS_PLUS_FAT_TEST_CONFIGURATION_LIST + CUSTOM # Custom (external) configuration -eg from a top-level project + DEFAULT_CONF # Default (typical) configuration) +) +if(NOT FREERTOS_PLUS_FAT_TEST_CONFIGURATION IN_LIST FREERTOS_PLUS_FAT_TEST_CONFIGURATION_LIST) + message(FATAL_ERROR "Invalid FREERTOS_PLUS_FAT_TEST_CONFIGURATION value '${FREERTOS_PLUS_FAT_TEST_CONFIGURATION}' should be one of: ${FREERTOS_PLUS_FAT_TEST_CONFIGURATION_LIST}") +else() + message(STATUS "Using FreeRTOS-Plus-FAT Test Configuration : ${FREERTOS_PLUS_FAT_TEST_CONFIGURATION}") + if (NOT FREERTOS_PLUS_FAT_TEST_CONFIGURATION STREQUAL "CUSTOM") + message(WARNING "FreeRTOS-Kernel configuration settings are configured by FreeRTOS-Plus-FAT") + endif() +endif() + + +######################################################################## +# External Dependencies +# Note: For backwards compatibility - still have .gitmodules defining submodules +# To support fetching content in a higher level project see +# README.md `Consume with CMake` +# This will allow you to upgrade submodules and have one common submodule for +# all your builds despite multiple submodules having different versions. +include(FetchContent) + +FetchContent_Declare( freertos_kernel + GIT_REPOSITORY https://github.com/phelter/FreeRTOS-Kernel.git #https://github.com/FreeRTOS/FreeRTOS-Kernel.git + GIT_TAG feature/fixing-clang-gnu-compiler-warnings #master +) + +######################################################################## +add_library( freertos_plus_fat STATIC ) + +target_sources( freertos_plus_fat + PRIVATE + include/ff_crc.h + include/ff_devices.h + include/ff_dir.h + include/ff_error.h + include/ff_fat.h + include/ff_fatdef.h + include/ff_file.h + include/ff_format.h + include/ff_headers.h + include/ff_ioman.h + include/ff_locking.h + include/ff_memory.h + include/ff_old_config_defines.h + include/ff_stdio.h + include/ff_string.h + include/ff_sys.h + include/ff_time.h + include/FreeRTOS_errno_FAT.h + include/FreeRTOSFATConfigDefaults.h + + ff_crc.c + $<$:ff_dev_support.c> + ff_dir.c + ff_error.c + ff_fat.c + ff_file.c + ff_format.c + ff_ioman.c + ff_locking.c + ff_memory.c + ff_stdio.c + ff_string.c + ff_sys.c + ff_time.c +) + +target_include_directories( freertos_plus_fat SYSTEM + PUBLIC + include +) + +target_compile_definitions( freertos_plus_fat + PUBLIC + ffconfigDEV_SUPPORT=$ +) + +target_compile_options( freertos_plus_fat + PRIVATE + $<$:-Wno-cast-qual> + $<$:-Wno-constant-conversion> + $<$:-Wno-covered-switch-default> + $<$:-Wno-documentation-unknown-command> + $<$:-Wno-documentation> + $<$:-Wno-extra-semi-stmt> + $<$:-Wno-format> + $<$:-Wno-implicit-int-conversion> + $<$:-Wno-missing-variable-declarations> + $<$:-Wno-overflow> + $<$:-Wno-padded> + $<$:-Wno-pedantic> + + $<$:-Wno-reserved-macro-identifier> + $<$:-Wno-shorten-64-to-32> + $<$:-Wno-sign-conversion> + $<$:-Wno-tautological-constant-out-of-range-compare> + $<$:-Wno-type-limits> + $<$:-Wno-undef> + $<$:-Wno-unused-macros> +) + +target_link_libraries( freertos_plus_fat + PUBLIC + freertos_config + PRIVATE + freertos_plus_fat_port + freertos_kernel +) + +add_subdirectory(portable) +add_subdirectory(test) + + + +FetchContent_MakeAvailable(freertos_kernel) diff --git a/README.md b/README.md index c8adf86..cce027a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,33 @@ The [standard C library style API](https://www.freertos.org/FreeRTOS-Plus/FreeRT For more details, please visit [FreeRTOS+FAT](https://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_FAT/index.html) page. ## To consume FreeRTOS+FAT + +### Consume with CMake +If using CMake, it is recommended to use this repository using FetchContent. +Add the following into your project's main or a subdirectory's `CMakeLists.txt`: + +```cmake +FetchContent_Declare( freertos_plus_fat + GIT_REPOSITORY https://github.com/FreeRTOS/Lab-Project-FreeRTOS-FAT.git + GIT_TAG master #Note: Best practice to use specific git-hash or tagged version + GIT_SUBMODULES "" # Don't grab any submodules since not latest +) + +# ... + +set( FREERTOS_PLUS_FAT_DEV_SUPPORT OFF CACHE BOOL "" FORCE) +# Select the native compile PORT +set( FREERTOS_PLUS_FAT_PORT "POSIX" CACHE STRING "" FORCE) +# Select the cross-compile PORT +if (CMAKE_CROSSCOMPILING) + # Eg. Zynq 2019_3 version of port + set(FREERTOS_PLUS_FAT_PORT "ZYNQ_2019_3" CACHE STRING "" FORCE) +endif() + +FetchContent_MakeAvailable(freertos_plus_fat) +``` + +### Consuming stand-alone It is recommended to use this repository as a submodule. Please refer to [Git Tools — Submodules](https://git-scm.com/book/en/v2/Git-Tools-Submodules). ## Notes diff --git a/ff_dir.c b/ff_dir.c old mode 100755 new mode 100644 index 71ea6ae..dcb712d --- a/ff_dir.c +++ b/ff_dir.c @@ -3123,7 +3123,7 @@ FF_Error_t FF_CreateDirent( FF_IOManager_t * pxIOManager, memset( &xMyFile, '\0', sizeof( xMyFile ) ); - STRNCPY( xMyFile.pcFileName, pcFileName, ffconfigMAX_FILENAME - 1 ); + STRNCPY( xMyFile.pcFileName, pcFileName, ffconfigMAX_FILENAME - 1 ); xMyFile.pcFileName[ ffconfigMAX_FILENAME - 1 ] = 0; xMyFile.ulObjectCluster = FF_CreateClusterChain( pxIOManager, &xError ); diff --git a/ff_locking.c b/ff_locking.c old mode 100755 new mode 100644 index 900d1d4..cc62cc1 --- a/ff_locking.c +++ b/ff_locking.c @@ -167,19 +167,21 @@ void FF_LockDirectory( FF_IOManager_t * pxIOManager ) return; } - for (;;) + for( ; ; ) { - xEventGroupWaitBits(pxIOManager->xEventGroup, - FF_DIR_LOCK_EVENT_BITS, /* uxBitsToWaitFor */ - pdFALSE, /* xClearOnExit */ - pdFALSE, /* xWaitForAllBits n.a. */ - FF_TIME_TO_WAIT_FOR_EVENT_TICKS); + xEventGroupWaitBits( pxIOManager->xEventGroup, + FF_DIR_LOCK_EVENT_BITS, /* uxBitsToWaitFor */ + pdFALSE, /* xClearOnExit */ + pdFALSE, /* xWaitForAllBits n.a. */ + FF_TIME_TO_WAIT_FOR_EVENT_TICKS ); + /* At this point, this task is one of many potentially unblocked by - xEventGroupSetBits. The next operation will only succeed for 1 task at a - time, because it is an atomic test & set operation: */ - xBits = xEventGroupClearBits(pxIOManager->xEventGroup, - FF_DIR_LOCK_EVENT_BITS); - if ((xBits & FF_DIR_LOCK_EVENT_BITS) != 0) + * xEventGroupSetBits. The next operation will only succeed for 1 task at a + * time, because it is an atomic test & set operation: */ + xBits = xEventGroupClearBits( pxIOManager->xEventGroup, + FF_DIR_LOCK_EVENT_BITS ); + + if( ( xBits & FF_DIR_LOCK_EVENT_BITS ) != 0 ) { /* This task has cleared the desired bit. * It now 'owns' the resource. */ @@ -249,7 +251,7 @@ void FF_Assert_Lock( FF_IOManager_t * pxIOManager, if( ( aBits & FF_FAT_LOCK_EVENT_BITS ) != 0 ) { - configASSERT( ( pxIOManager->pvFATLockHandle != NULL ) && ( pxIOManager->pvFATLockHandle == handle ) ); + configASSERT( ( pxIOManager->pvFATLockHandle != NULL ) && ( pxIOManager->pvFATLockHandle == handle ) ); /* In case configASSERT() is not defined. */ ( void ) pxIOManager; ( void ) handle; @@ -272,23 +274,25 @@ void FF_LockFAT( FF_IOManager_t * pxIOManager ) configASSERT( FF_Has_Lock( pxIOManager, FF_FAT_LOCK ) == pdFALSE ); - for (;;) + for( ; ; ) { - xEventGroupWaitBits(pxIOManager->xEventGroup, - FF_FAT_LOCK_EVENT_BITS, /* uxBitsToWaitFor */ - pdFALSE, /* xClearOnExit */ - pdFALSE, /* xWaitForAllBits n.a. */ - FF_TIME_TO_WAIT_FOR_EVENT_TICKS); + xEventGroupWaitBits( pxIOManager->xEventGroup, + FF_FAT_LOCK_EVENT_BITS, /* uxBitsToWaitFor */ + pdFALSE, /* xClearOnExit */ + pdFALSE, /* xWaitForAllBits n.a. */ + FF_TIME_TO_WAIT_FOR_EVENT_TICKS ); + /* At this point, this task is one of many potentially unblocked by - xEventGroupSetBits. The next operation will only succeed for 1 task at a - time, because it is an atomic test & set operation: */ - xBits = xEventGroupClearBits(pxIOManager->xEventGroup, - FF_FAT_LOCK_EVENT_BITS); - if ((xBits & FF_FAT_LOCK_EVENT_BITS) != 0) + * xEventGroupSetBits. The next operation will only succeed for 1 task at a + * time, because it is an atomic test & set operation: */ + xBits = xEventGroupClearBits( pxIOManager->xEventGroup, + FF_FAT_LOCK_EVENT_BITS ); + + if( ( xBits & FF_FAT_LOCK_EVENT_BITS ) != 0 ) { /* This task has cleared the desired bit. * It now 'owns' the resource. */ - configASSERT(pxIOManager->pvFATLockHandle == NULL); + configASSERT( pxIOManager->pvFATLockHandle == NULL ); pxIOManager->pvFATLockHandle = xTaskGetCurrentTaskHandle(); break; } @@ -303,6 +307,7 @@ void FF_UnlockFAT( FF_IOManager_t * pxIOManager ) /* Scheduler not yet active. */ return; } + configASSERT( ( xEventGroupGetBits( pxIOManager->xEventGroup ) & FF_FAT_LOCK_EVENT_BITS ) == 0 ); pxIOManager->pvFATLockHandle = NULL; xEventGroupSetBits( pxIOManager->xEventGroup, FF_FAT_LOCK_EVENT_BITS ); diff --git a/include/FreeRTOSFATConfigDefaults.h b/include/FreeRTOSFATConfigDefaults.h old mode 100755 new mode 100644 index c779775..620bc6a --- a/include/FreeRTOSFATConfigDefaults.h +++ b/include/FreeRTOSFATConfigDefaults.h @@ -25,6 +25,7 @@ */ #ifndef FF_DEFAULTCONFIG_H +#define FF_DEFAULTCONFIG_H /* The error numbers defined in this file will be moved to the core FreeRTOS * code in future versions of FreeRTOS - at which time the following header file @@ -466,10 +467,11 @@ #endif #ifndef ffconfigFAT_USES_STAT - /* When enabled, the library keeps statistics about the use of cache - * buffers. This can be useful while configuring or optimising the - * cache size. */ - #define ffconfigFAT_USES_STAT 0 + +/* When enabled, the library keeps statistics about the use of cache + * buffers. This can be useful while configuring or optimising the + * cache size. */ + #define ffconfigFAT_USES_STAT 0 #endif #ifndef ffconfigUSE_NOTIFY @@ -506,8 +508,8 @@ #endif #ifndef FF_NOSTRCASECMP - /* When zero, the function 'strcasecmp()' will be dfined. */ - #define FF_NOSTRCASECMP 0 + /* When zero, the function 'strcasecmp()' will be dfined. */ + #define FF_NOSTRCASECMP 0 #endif #endif /* ifndef FF_DEFAULTCONFIG_H */ diff --git a/portable/CMakeLists.txt b/portable/CMakeLists.txt new file mode 100644 index 0000000..09837a0 --- /dev/null +++ b/portable/CMakeLists.txt @@ -0,0 +1,104 @@ +add_library( freertos_plus_fat_port_common STATIC ) + +target_sources( freertos_plus_fat_port_common + PRIVATE + common/ff_ramdisk.c + common/ff_ramdisk.h + common/ff_sddisk.h +) + +target_include_directories( freertos_plus_fat_port_common SYSTEM + PUBLIC + common +) + +target_compile_options( freertos_plus_fat_port_common + PRIVATE + $<$:-Wno-missing-prototypes> + $<$:-Wno-reserved-macro-identifier> + $<$:-Wno-shorten-64-to-32> + $<$:-Wno-sign-conversion> +) + +target_link_libraries( freertos_plus_fat_port_common + PRIVATE + freertos_kernel + freertos_plus_fat +) + +# ------------------------------------------------------------------- + +if (FREERTOS_PLUS_FAT_PORT STREQUAL "A_CUSTOM_PORT") + message(STATUS "Using a custom FREERTOS_PLUS_FAT_PORT.") + return() +endif() + +add_library( freertos_plus_fat_port STATIC ) + +target_sources( freertos_plus_fat_port + PRIVATE + $<$: + ATSAM4E/ff_sddisk_r.c + ATSAM4E/ff_sddisk.c> + $<$: + avr32_uc3/ff_flush.c + avr32_uc3/ff_flush.h + avr32_uc3/ff_locking.c> + $<$: + lpc18xx/ff_sddisk.c> + $<$: + linux/ff_sddisk.c> + $<$: + STM32F4xx/ff_sddisk.c + STM32F4xx/stm32f4xx_hal_sd.c + STM32F4xx/stm32f4xx_hal_sd.h + STM32F4xx/stm32f4xx_ll_sdmmc.c + STM32F4xx/stm32f4xx_ll_sdmmc.h> + $<$: + STM32F7xx/ff_sddisk.c + STM32F7xx/stm32f7xx_hal_sd.c + STM32F7xx/stm32f7xx_hal_sd.h> + $<$: + Zynq/ff_sddisk.c + Zynq/xsdps_g.c + Zynq/xsdps_hw.h + Zynq/xsdps_info.c + Zynq/xsdps_info.h + Zynq/xsdps_options.c + Zynq/xsdps_sinit.c + Zynq/xsdps.c + Zynq/xsdps.h> + $<$: + Zynq.2019.3/ff_sddisk.c + Zynq.2019.3/xsdps_g.c + Zynq.2019.3/xsdps_hw.h + Zynq.2019.3/xsdps_info.c + Zynq.2019.3/xsdps_info.h + Zynq.2019.3/xsdps_options.c + Zynq.2019.3/xsdps_sinit.c + Zynq.2019.3/xsdps.c + Zynq.2019.3/xsdps.h> +) + +target_include_directories( freertos_plus_fat_port + PRIVATE + $<$:${CMAKE_CURRENT_SOURCE_DIR}/avr32_uc3> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/STM32F4xx> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/STM32F7xx> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/Zynq> + $<$:${CMAKE_CURRENT_SOURCE_DIR}/Zynq.2019.3> +) + +target_compile_options( freertos_plus_fat_port + PRIVATE + $<$:-Wno-gnu-statement-expression> + $<$:-Wno-unused-parameter> +) + +target_link_libraries( freertos_plus_fat_port + PUBLIC + freertos_plus_fat_port_common + PRIVATE + freertos_plus_fat + freertos_kernel +) diff --git a/portable/common/ff_ramdisk.c b/portable/common/ff_ramdisk.c old mode 100755 new mode 100644 index 8904537..f48da1b --- a/portable/common/ff_ramdisk.c +++ b/portable/common/ff_ramdisk.c @@ -419,10 +419,10 @@ BaseType_t FF_RAMDiskShowPartition( FF_Disk_t * pxDisk ) FF_PRINTF( "Partition Nr %8u\n", pxDisk->xStatus.bPartitionNumber ); FF_PRINTF( "Type %8u (%s)\n", pxIOManager->xPartition.ucType, pcTypeName ); FF_PRINTF( "VolLabel '%8s' \n", pxIOManager->xPartition.pcVolumeLabel ); - FF_PRINTF( "TotalSectors %8lu\n", pxIOManager->xPartition.ulTotalSectors ); - FF_PRINTF( "SecsPerCluster %8lu\n", pxIOManager->xPartition.ulSectorsPerCluster ); - FF_PRINTF( "Size %8lu KB\n", ulTotalSizeKB ); - FF_PRINTF( "FreeSize %8lu KB ( %d perc free )\n", ulFreeSizeKB, iPercentageFree ); + FF_PRINTF( "TotalSectors %8lu\n", ( unsigned long ) pxIOManager->xPartition.ulTotalSectors ); + FF_PRINTF( "SecsPerCluster %8lu\n", ( unsigned long ) pxIOManager->xPartition.ulSectorsPerCluster ); + FF_PRINTF( "Size %8lu KB\n", ( unsigned long ) ulTotalSizeKB ); + FF_PRINTF( "FreeSize %8lu KB ( %d perc free )\n", ( unsigned long ) ulFreeSizeKB, iPercentageFree ); } return xReturn; diff --git a/portable/linux/ff_sddisk.c b/portable/linux/ff_sddisk.c new file mode 100644 index 0000000..679344a --- /dev/null +++ b/portable/linux/ff_sddisk.c @@ -0,0 +1,254 @@ +/* + * FreeRTOS+FAT Labs Build 160919 (C) 2016 Real Time Engineers ltd. + * Authors include James Walmsley, Hein Tibosch and Richard Barry + * + * + * FreeRTOS+FAT can be used under two different free open source licenses. The + * license that applies is dependent on the processor on which FreeRTOS+FAT is + * executed, as follows: + * + * If FreeRTOS+FAT is executed on one of the processors listed under the Special + * License Arrangements heading of the FreeRTOS+FAT license information web + * page, then it can be used under the terms of the FreeRTOS Open Source + * License. If FreeRTOS+FAT is used on any other processor, then it can be used + * under the terms of the GNU General Public License V2. Links to the relevant + * licenses follow: + * + * The FreeRTOS+FAT License Information Page: http://www.FreeRTOS.org/fat_license + * The FreeRTOS Open Source License: http://www.FreeRTOS.org/license + * The GNU General Public License Version 2: http://www.FreeRTOS.org/gpl-2.0.txt + * + * FreeRTOS+FAT is distributed in the hope that it will be useful. You cannot + * use FreeRTOS+FAT unless you agree that you use the software 'as is'. + * FreeRTOS+FAT is provided WITHOUT ANY WARRANTY; without even the implied + * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR + * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they + * implied, expressed, or statutory. + * + * This is a stub for allowing linux to compile. should just make it save to a file. + * + * + */ + +#include "ff_sddisk.h" + +/* Standard includes. */ +#include +#include +#include +#include + +/* FreeRTOS includes. */ +#include "FreeRTOS.h" +#include "task.h" +#include "semphr.h" +#include "portmacro.h" + +/* FreeRTOS+FAT includes. */ +#include "ff_headers.h" +#include "ff_sys.h" + +/* Dummy variables. */ +#define HUNDRED_64_BIT ( 100U ) +#define BYTES_PER_MB ( 1024U * 1024U ) +#define SECTORS_PER_MB ( BYTES_PER_MB / 512U ) + +/*-----------------------------------------------------------*/ + +BaseType_t FF_SDDiskDetect( FF_Disk_t * pxDisk ) +{ + ( void ) pxDisk; /* Unused */ + return pdTRUE; +} + +/*-----------------------------------------------------------*/ + +void FF_SDDiskFlush( FF_Disk_t * pxDisk ) +{ + if( ( pxDisk != NULL ) && + ( pxDisk->xStatus.bIsInitialised != pdFALSE ) && + ( pxDisk->pxIOManager != NULL ) ) + { + /*flush cache*/ + } +} +/*-----------------------------------------------------------*/ + +FF_Disk_t * FF_SDDiskInit( const char * pcName ) +{ + ( void ) pcName; /* Unused */ + FF_Disk_t * pxDisk = NULL; + + pxDisk = ( FF_Disk_t * ) pvPortMalloc( sizeof( *pxDisk ) ); + + if( pxDisk == NULL ) + { + FF_PRINTF( "FF_SDDiskInit: Malloc failed\n" ); + return NULL; + } + + /* Initialise the created disk structure. */ + memset( pxDisk, '\0', sizeof( *pxDisk ) ); + + /* Other stuff here*/ + + pxDisk->xStatus.bIsInitialised = pdTRUE; + + return pxDisk; +} +/*-----------------------------------------------------------*/ + +BaseType_t FF_SDDiskFormat( FF_Disk_t * pxDisk, + BaseType_t aPart ) +{ + ( void ) aPart; /* Unused */ + + if( pxDisk != NULL ) + { + FF_PRINTF( "FF_SDDISKFormat \n" ); + return pdPASS; + } + + return pdFAIL; +} +/*-----------------------------------------------------------*/ + +/* Unmount the volume */ +BaseType_t FF_SDDiskUnmount( FF_Disk_t * pxDisk ) +{ + if( ( pxDisk != NULL ) && ( pxDisk->xStatus.bIsMounted != pdFALSE ) ) + { + pxDisk->xStatus.bIsMounted = pdFALSE; + FF_PRINTF( "FF_SDDiskUnmount: Drive unmounted\n" ); + return pdPASS; + } + + return pdFAIL; +} +/*-----------------------------------------------------------*/ + +BaseType_t FF_SDDiskReinit( FF_Disk_t * pxDisk ) +{ + ( void ) pxDisk; + FF_PRINTF( "FF_SDDiskReinit: rc %08x\n", 0U ); + return pdPASS; +} +/*-----------------------------------------------------------*/ + +BaseType_t FF_SDDiskMount( FF_Disk_t * pxDisk ) +{ + if( pxDisk != NULL ) + { + pxDisk->xStatus.bIsMounted = pdTRUE; + FF_PRINTF( "****** FreeRTOS+FAT initialized %u sectors\n", ( unsigned ) pxDisk->pxIOManager->xPartition.ulTotalSectors ); + return pdPASS; + } + + return pdFAIL; +} +/*-----------------------------------------------------------*/ + +/* Get a pointer to IOMAN, which can be used for all FreeRTOS+FAT functions */ +FF_IOManager_t * sddisk_ioman( FF_Disk_t * pxDisk ) +{ + FF_IOManager_t * pxReturn; + + if( ( pxDisk != NULL ) && ( pxDisk->xStatus.bIsInitialised != pdFALSE ) ) + { + pxReturn = pxDisk->pxIOManager; + } + else + { + pxReturn = NULL; + } + + return pxReturn; +} +/*-----------------------------------------------------------*/ + +/* Release all resources */ +BaseType_t FF_SDDiskDelete( FF_Disk_t * pxDisk ) +{ + if( pxDisk != NULL ) + { + vPortFree( pxDisk ); + } + + return pdTRUE; +} +/*-----------------------------------------------------------*/ + +BaseType_t FF_SDDiskShowPartition( FF_Disk_t * pxDisk ) +{ + FF_Error_t xError; + uint64_t ullFreeSectors; + uint32_t ulTotalSizeMB, ulFreeSizeMB; + int iPercentageFree; + FF_IOManager_t * pxIOManager; + const char * pcTypeName = "unknown type"; + BaseType_t xReturn = pdPASS; + + if( pxDisk == NULL ) + { + xReturn = pdFAIL; + } + else + { + pxIOManager = pxDisk->pxIOManager; + + FF_PRINTF( "Reading FAT and calculating Free Space\n" ); + + switch( pxIOManager->xPartition.ucType ) + { + case FF_T_FAT12: + pcTypeName = "FAT12"; + break; + + case FF_T_FAT16: + pcTypeName = "FAT16"; + break; + + case FF_T_FAT32: + pcTypeName = "FAT32"; + break; + + default: + pcTypeName = "UNKOWN"; + break; + } + + FF_GetFreeSize( pxIOManager, &xError ); + + ullFreeSectors = pxIOManager->xPartition.ulFreeClusterCount * pxIOManager->xPartition.ulSectorsPerCluster; + iPercentageFree = ( int ) ( ( HUNDRED_64_BIT * ullFreeSectors + pxIOManager->xPartition.ulDataSectors / 2 ) / + ( ( uint64_t ) pxIOManager->xPartition.ulDataSectors ) ); + + ulTotalSizeMB = pxIOManager->xPartition.ulDataSectors / SECTORS_PER_MB; + ulFreeSizeMB = ( uint32_t ) ( ullFreeSectors / SECTORS_PER_MB ); + + /* It is better not to use the 64-bit format such as %Lu because it + * might not be implemented. */ + FF_PRINTF( "Partition Nr %8u\n", pxDisk->xStatus.bPartitionNumber ); + FF_PRINTF( "Type %8s (%u)\n", pcTypeName, pxIOManager->xPartition.ucType ); + FF_PRINTF( "VolLabel '%8s' \n", pxIOManager->xPartition.pcVolumeLabel ); + FF_PRINTF( "TotalSectors %8u x 512 = %u\n", + ( unsigned ) pxIOManager->xPartition.ulTotalSectors, + ( unsigned ) pxIOManager->xPartition.ulTotalSectors * 512U ); + FF_PRINTF( "DataSectors %8u\n", ( unsigned ) pxIOManager->xPartition.ulDataSectors ); + FF_PRINTF( "SecsPerCluster %8u\n", ( unsigned ) pxIOManager->xPartition.ulSectorsPerCluster ); + FF_PRINTF( "Size %8u MB\n", ( unsigned ) ulTotalSizeMB ); + FF_PRINTF( "FreeSize %8u MB ( %d perc free )\n", ( unsigned ) ulFreeSizeMB, ( int ) iPercentageFree ); + FF_PRINTF( "BeginLBA %8u\n", ( unsigned ) pxIOManager->xPartition.ulBeginLBA ); + FF_PRINTF( "FATBeginLBA %8u\n", ( unsigned ) pxIOManager->xPartition.ulFATBeginLBA ); + } + + return xReturn; +} + +/*-----------------------------------------------------------*/ + +BaseType_t FF_SDDiskInserted( BaseType_t xDriveNr ) +{ + ( void ) xDriveNr; + return pdFALSE; +} diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt new file mode 100644 index 0000000..94162a6 --- /dev/null +++ b/test/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(build-combination) diff --git a/test/build-combination/CMakeLists.txt b/test/build-combination/CMakeLists.txt new file mode 100644 index 0000000..cbaf7d0 --- /dev/null +++ b/test/build-combination/CMakeLists.txt @@ -0,0 +1,48 @@ +add_library( freertos_plus_fat_config_common INTERFACE ) +target_include_directories(freertos_plus_fat_config_common INTERFACE Common/include ) + +# ------------------------------------------------------------------- +add_library( freertos_plus_fat_config_default INTERFACE) +target_include_directories(freertos_plus_fat_config_default INTERFACE DefaultConf) +target_link_libraries(freertos_plus_fat_config_default INTERFACE freertos_plus_fat_config_common) + +# ------------------------------------------------------------------- +# Configuration for FreeRTOS-Plus-FAT tests +if(FREERTOS_PLUS_FAT_TEST_CONFIGURATION STREQUAL "CUSTOM" ) + # Check Config target is available. And then do nothing. + if(NOT TARGET freertos_config ) + message(FATAL_ERROR "FREERTOS_PLUS_FAT_TEST_CONFIGURATION = CUSTOM, but no freertos_config target defined.") + endif() +else() + add_library( freertos_config ALIAS freertos_plus_fat_config_default) +endif() + +add_executable(freertos_plus_fat_build_test) + +target_sources(freertos_plus_fat_build_test + PRIVATE + Common/main.c +) + +target_compile_options(freertos_plus_fat_build_test + PRIVATE + # $<$:-Wno-cast-qual> + # $<$:-Wno-format-nonliteral> + # $<$:-Wno-implicit-function-declaration> + # $<$:-Wno-missing-noreturn> + # $<$:-Wno-missing-prototypes> + # $<$:-Wno-missing-variable-declarations> + # $<$:-Wno-reserved-identifier> + # $<$:-Wno-shorten-64-to-32> + # $<$:-Wno-sign-conversion> + # $<$:-Wno-unused-parameter> + # $<$:-Wno-unused-macros> + # $<$:-Wno-unused-variable> +) + +target_link_libraries(freertos_plus_fat_build_test + PRIVATE + freertos_plus_fat + freertos_plus_fat_port + freertos_kernel +) diff --git a/test/build-combination/Common/include/FreeRTOSConfig.h b/test/build-combination/Common/include/FreeRTOSConfig.h new file mode 100644 index 0000000..a54951d --- /dev/null +++ b/test/build-combination/Common/include/FreeRTOSConfig.h @@ -0,0 +1,160 @@ +/* + * FreeRTOS+FAT + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://aws.amazon.com/freertos + * http://www.FreeRTOS.org + */ + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. +* http://www.freertos.org/a00110.html +* +* The bottom of this file contains some constants specific to running the UDP +* stack in this demo. Constants specific to FreeRTOS+FAT itself (rather than +* the demo) are contained in FreeRTOSFATConfig.h. +*----------------------------------------------------------*/ +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configMAX_PRIORITIES ( 7 ) +#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */ +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */ +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2048U * 1024U ) ) +#define configMAX_TASK_NAME_LEN ( 15 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_CO_ROUTINES 0 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 0 +#define configUSE_APPLICATION_TASK_TAG 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 3 /* FreeRTOS+FAT requires 2 pointers if a CWD is supported. */ +#define configRECORD_STACK_HIGH_ADDRESS 1 + +/* Hook function related definitions. */ +#define configUSE_TICK_HOOK 0 +#define configUSE_IDLE_HOOK 1 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */ + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 5 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + +/* Event group related definitions. */ +#define configUSE_EVENT_GROUPS 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Currently the TCP/IP stack is using dynamic allocation, and the MQTT task is + * using static allocation. */ +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configSUPPORT_STATIC_ALLOCATION 1 + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 1 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerGetTimerTaskHandle 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xQueueGetMutexHolder 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xEventGroupSetBitsFromISR 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_xTaskAbortDelay 1 + +/* This demo makes use of one or more example stats formatting functions. These + * format the raw data provided by the uxTaskGetSystemState() function in to human + * readable ASCII form. See the notes in the implementation of vTaskList() within + * FreeRTOS/Source/tasks.c for limitations. configUSE_STATS_FORMATTING_FUNCTIONS + * is set to 2 so the formatting functions are included without the stdio.h being + * included in tasks.c. That is because this project defines its own sprintf() + * functions. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 + +/* Assert call defined for debug builds. */ +void vAssertCalled( const char * pcFile, + unsigned long ulLine ); + +#define configASSERT( x ) + +/* The function that implements FreeRTOS printf style output, and the macro + * that maps the configPRINTF() macros to that function. */ +#define configPRINTF( X ) + +/* Non-format version thread-safe print. */ +extern void vLoggingPrint( const char * pcMessage ); +#define configPRINT( X ) + +/* Non-format version thread-safe print. */ +#define configPRINT_STRING( X ) + +/* Application specific definitions follow. **********************************/ + +/* If configINCLUDE_DEMO_DEBUG_STATS is set to one, then a few basic IP trace + * macros are defined to gather some UDP stack statistics that can then be viewed + * through the CLI interface. */ +#define configINCLUDE_DEMO_DEBUG_STATS 1 + +/* The size of the global output buffer that is available for use when there + * are multiple command interpreters running at once (for example, one on a UART + * and one on TCP/IP). This is done to prevent an output buffer being defined by + * each implementation - which would waste RAM. In this case, there is only one + * command interpreter running, and it has its own local output buffer, so the + * global buffer is just set to be one byte long as it is not used and should not + * take up unnecessary RAM. */ +#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1 + +#define configPROFILING ( 0 ) + +/* Pseudo random number generator used by some tasks. */ +extern uint32_t ulRand( void ); +#define configRAND32() ulRand() + +/* / * The platform that FreeRTOS is running on. * / */ +/* #define configPLATFORM_NAME "WinSim" */ + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/test/build-combination/Common/main.c b/test/build-combination/Common/main.c new file mode 100644 index 0000000..4a550f2 --- /dev/null +++ b/test/build-combination/Common/main.c @@ -0,0 +1,148 @@ +/* + * FreeRTOS+FAT + * Copyright (C) 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * SPDX-License-Identifier: MIT + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://aws.amazon.com/freertos + * http://www.FreeRTOS.org + */ + +/** + * @file main.c + * @brief Implements the main function. + */ + +/* FreeRTOS include. */ +#include +#include "task.h" + +/* System application includes. */ +#include "ff_headers.h" +#include "ff_stdio.h" +#include "ff_ramdisk.h" + +#define mainHOST_NAME "Build Combination" +#define mainDEVICE_NICK_NAME "Build_Combination" + +/* The number and size of sectors that will make up the RAM disk. The RAM disk + * is huge to allow some verbose FTP tests used in previous demos. */ +#define mainRAM_DISK_SECTOR_SIZE 512UL /* Currently fixed! */ +#define mainRAM_DISK_SECTORS ( ( 5UL * 1024UL * 1024UL ) / mainRAM_DISK_SECTOR_SIZE ) /* 5M bytes. */ +#define mainIO_MANAGER_CACHE_SIZE ( 15UL * mainRAM_DISK_SECTOR_SIZE ) + +/* Where the RAM disk is mounted. */ +#define mainRAM_DISK_NAME "/ram" + +/*-----------------------------------------------------------*/ +int main( void ) +{ + /* Initialize the FAT RamDisk */ + /* vLoggingPrint( "FF_RAMDiskInit\n" ); */ + + static uint8_t ucRAMDisk[ mainRAM_DISK_SECTORS * mainRAM_DISK_SECTOR_SIZE ]; + FF_Disk_t * pxDisk; + + /* Create the RAM disk. */ + pxDisk = FF_RAMDiskInit( mainRAM_DISK_NAME, ucRAMDisk, mainRAM_DISK_SECTORS, mainIO_MANAGER_CACHE_SIZE ); + configASSERT( pxDisk ); + + vTaskStartScheduler(); + + return 0; +} +/*-----------------------------------------------------------*/ + +void vApplicationIdleHook( void ) +{ + /* Exit. Just a stub. */ +} +/*-----------------------------------------------------------*/ +void vAssertCalled( const char * pcFile, + unsigned long ulLine ) +{ + ( void ) pcFile; + ( void ) ulLine; + + taskDISABLE_INTERRUPTS(); + { + while( 1 ) + { + } + } + taskENABLE_INTERRUPTS(); +} +/*-----------------------------------------------------------*/ + +void vLoggingPrint( const char * pcMessage ) +{ + ( void ) pcMessage; +} +/*-----------------------------------------------------------*/ + +void getUserCmd( char * pucUserCmd ) +{ + /* Provide a stub for this function. */ + ( void ) pucUserCmd; +} + +/*-----------------------------------------------------------*/ + +void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + uint32_t * pulIdleTaskStackSize ) +{ + /* Provide a stub for this function. */ + ( void ) ppxIdleTaskTCBBuffer; + ( void ) ppxIdleTaskStackBuffer; + ( void ) pulIdleTaskStackSize; +} + +/*-----------------------------------------------------------*/ + +void vApplicationTickHook( void ) +{ + /* Provide a stub for this function. */ +} + +/*-----------------------------------------------------------*/ + +void vApplicationDaemonTaskStartupHook( void ) +{ + /* Provide a stub for this function. */ +} + +/* + * Callback that provides the inputs necessary to generate a randomized TCP + * Initial Sequence Number per RFC 6528. THIS IS ONLY A DUMMY IMPLEMENTATION + * THAT RETURNS A PSEUDO RANDOM NUMBER SO IS NOT INTENDED FOR USE IN PRODUCTION + * SYSTEMS. + */ +void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + uint32_t * pulTimerTaskStackSize ) +{ + /* Provide a stub for this function. */ +} + +void vApplicationMallocFailedHook( void ) +{ + /* Provide a stub for this function. */ +} diff --git a/test/build-combination/DefaultConf/FreeRTOSFATConfig.h b/test/build-combination/DefaultConf/FreeRTOSFATConfig.h new file mode 100644 index 0000000..7699f05 --- /dev/null +++ b/test/build-combination/DefaultConf/FreeRTOSFATConfig.h @@ -0,0 +1,41 @@ +/* + * FreeRTOS+FAT V2.3.3 + * Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef FREERTOS_FAT_CONFIG_H +#define FREERTOS_FAT_CONFIG_H + +#define ffconfigBYTE_ORDER ( pdFREERTOS_LITTLE_ENDIAN ) + +#define ffconfigCWD_THREAD_LOCAL_INDEX ( 0 ) + +/* Note - must be deifined */ +#if !defined( portINLINE ) + #define portINLINE __inline +#endif + +/* Note: All other ffconfig values will be defined in FreeRTOSFATConfigDefaults.h when not defined here */ + +#endif /*FREERTOS_FAT_CONFIG_H */ diff --git a/test/build-combination/README.md b/test/build-combination/README.md new file mode 100644 index 0000000..ffc7896 --- /dev/null +++ b/test/build-combination/README.md @@ -0,0 +1,25 @@ +# Build Instructions + +This test aims at finding only compilation issues and as a result, the +generated binary is not runnable. + +## UNIX (Linux and Mac) + +All the CMake commands are to be run from the root of the repository. + +* Build checks (Default configuration) +``` +cmake -S . -B build -DFREERTOS_PLUS_FAT_TEST_CONFIGURATION=DEFAULT_CONF +make -C . +``` + +## Windows + +All the CMake commands are to be run from the root of the repository. + +* Build checks (Default configuration) +``` +cmake -S . -B build -DFREERTOS_PLUS_FAT_TEST_CONFIGURATION=DEFAULT_CONF -DCMAKE_GENERATOR_PLATFORM=Win32 +``` +Open the generated Visual Studio Solution file `test\build-combination\build\FreeRTOS-Plus-FAT Build Combination.sln` +in Visual Studio and click `Build --> Build Solution`.