diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 0ffa4fcfd952a..6f84de6f60ead 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -1,4 +1,10 @@ -#all: Reformat remaining C code that doesn't have a space after a comma. +# all: Fix spelling mistakes based on codespell check. +b1229efbd1509654dec6053865ab828d769e29db + +# top: Update Python formatting to black "2023 stable style". +8b2748269244304854b3462cb8902952b4dcb892 + +# all: Reformat remaining C code that doesn't have a space after a comma. 5b700b0af90591d6b1a2c087bb8de6b7f1bfdd2d # ports: Reformat more C and Python source code. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index ac9d97041a505..7bad9562964af 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -7,7 +7,7 @@ assignees: '' --- -* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please see the MicroPython Forum (https://forum.micropython.org/) or raise a documentation request instead. +* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please use the Discussions tab or raise a documentation request instead. * In your issue, please include a clear and concise description of what the bug is, the expected output, and how to replicate it. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 318d9416ee74a..f3662464da337 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,7 +1,7 @@ blank_issues_enabled: false contact_links: - - name: MicroPython Forum - url: https://forum.micropython.org/ + - name: MicroPython GitHub Discussions + url: https://github.com/orgs/micropython/discussions about: Community discussion about all things MicroPython. This is the best place to start if you have questions about using MicroPython or getting started with MicroPython development. - name: MicroPython Documentation url: https://docs.micropython.org/ diff --git a/.github/ISSUE_TEMPLATE/documentation.md b/.github/ISSUE_TEMPLATE/documentation.md index c86c1ec2b8ed6..e36fa62ac29a4 100644 --- a/.github/ISSUE_TEMPLATE/documentation.md +++ b/.github/ISSUE_TEMPLATE/documentation.md @@ -7,7 +7,7 @@ assignees: '' --- -* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please see the MicroPython Forum -- https://forum.micropython.org/ +* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please use the Discussions tab instead. * Describe what was missing from the documentation and/or what was incorrect/incomplete. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 3976699b28ed6..81b55d98e0da8 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -7,7 +7,7 @@ assignees: '' --- -* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please see the MicroPython Forum (https://forum.micropython.org/) or raise a documentation request instead. +* Please search existing issues before raising a new issue. For questions about MicroPython or for help using MicroPython, or any sort of "how do I?" requests, please use the Discussions tab or raise a documentation request instead. * Describe the feature you'd like to see added to MicroPython. In particular, what does this feature enable and why is it useful. MicroPython aims to strike a balance between functionality and code size, so please consider whether this feature can be optionally enabled and whether it can be provided in other ways (e.g. pure-Python library). diff --git a/.github/ISSUE_TEMPLATE/security.md b/.github/ISSUE_TEMPLATE/security.md index 2bbfede6ce069..cfe4a4befdb14 100644 --- a/.github/ISSUE_TEMPLATE/security.md +++ b/.github/ISSUE_TEMPLATE/security.md @@ -1,6 +1,6 @@ --- name: Security report -about: Report a security issue or vunerability in MicroPython +about: Report a security issue or vulnerability in MicroPython title: '' labels: security assignees: '' diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000000..2c7d1708395e2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + # Maintain dependencies for GitHub Actions + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" diff --git a/.github/workflows/code_formatting.yml b/.github/workflows/code_formatting.yml index 5c0196d2edbfa..81a2715f1b335 100644 --- a/.github/workflows/code_formatting.yml +++ b/.github/workflows/code_formatting.yml @@ -2,15 +2,29 @@ name: Check code formatting on: [push, pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: - build: + code-formatting: runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 - name: Install packages run: source tools/ci.sh && ci_code_formatting_setup - name: Run code formatting run: source tools/ci.sh && ci_code_formatting_run - name: Check code formatting run: git diff --exit-code + + code-spelling: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + - name: Install packages + run: source tools/ci.sh && ci_code_spell_setup + - name: Run spell checker + run: source tools/ci.sh && ci_code_spell_run diff --git a/.github/workflows/code_size.yml b/.github/workflows/code_size.yml index 7570261e7d23b..5d955703b666a 100644 --- a/.github/workflows/code_size.yml +++ b/.github/workflows/code_size.yml @@ -12,11 +12,15 @@ on: - 'ports/bare-arm/**' - 'ports/minimal/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: 100 - name: Install packages @@ -24,4 +28,18 @@ jobs: - name: Build run: source tools/ci.sh && ci_code_size_build - name: Compute code size difference - run: tools/metrics.py diff --error-threshold 0 ~/size0 ~/size1 + run: tools/metrics.py diff ~/size0 ~/size1 | tee diff + - name: Save PR number + if: github.event_name == 'pull_request' + env: + PR_NUMBER: ${{ github.event.number }} + run: echo $PR_NUMBER > pr_number + - name: Upload diff + if: github.event_name == 'pull_request' + uses: actions/upload-artifact@v3 + with: + name: code-size-report + path: | + diff + pr_number + retention-days: 1 diff --git a/.github/workflows/code_size_comment.yml b/.github/workflows/code_size_comment.yml new file mode 100644 index 0000000000000..8baf76a47a7f6 --- /dev/null +++ b/.github/workflows/code_size_comment.yml @@ -0,0 +1,105 @@ +name: Code size comment + +on: + workflow_run: + workflows: [Check code size] + types: [completed] + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + comment: + runs-on: ubuntu-20.04 + steps: + - name: 'Download artifact' + id: download-artifact + uses: actions/github-script@v6 + with: + result-encoding: string + script: | + const fs = require('fs'); + + const allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, + }); + + const matchArtifact = allArtifacts.data.artifacts.filter((artifact) => { + return artifact.name == "code-size-report" + }); + + if (matchArtifact.length === 0) { + console.log('no matching artifact found'); + console.log('result: "skip"'); + + return 'skip'; + } + + const download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: matchArtifact[0].id, + archive_format: 'zip', + }); + + fs.writeFileSync(`${process.env.GITHUB_WORKSPACE}/code-size-report.zip`, Buffer.from(download.data)); + + console.log('artifact downloaded to `code-size-report.zip`'); + console.log('result: "ok"'); + + return 'ok'; + - name: 'Unzip artifact' + if: steps.download-artifact.outputs.result == 'ok' + run: unzip code-size-report.zip + - name: Post comment to pull request + if: steps.download-artifact.outputs.result == 'ok' + uses: actions/github-script@v6 + with: + github-token: ${{secrets.GITHUB_TOKEN}} + script: | + const fs = require('fs'); + + const prNumber = Number(fs.readFileSync('pr_number')); + const codeSizeReport = `Code size report: + + \`\`\` + ${fs.readFileSync('diff')} + \`\`\` + `; + + const comments = await github.paginate( + github.rest.issues.listComments, + { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + } + ); + + comments.reverse(); + + const previousComment = comments.find(comment => + comment.user.login === 'github-actions[bot]' + ) + + // if github-actions[bot] already made a comment, update it, + // otherwise create a new comment. + + if (previousComment) { + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: previousComment.id, + body: codeSizeReport, + }); + } else { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: prNumber, + body: codeSizeReport, + }); + } diff --git a/.github/workflows/commit_formatting.yml b/.github/workflows/commit_formatting.yml index 5f96fbb934426..0b27038f2d264 100644 --- a/.github/workflows/commit_formatting.yml +++ b/.github/workflows/commit_formatting.yml @@ -2,13 +2,17 @@ name: Check commit message formatting on: [push, pull_request] +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 with: fetch-depth: '100' - - uses: actions/setup-python@v1 + - uses: actions/setup-python@v4 - name: Check commit message formatting run: source tools/ci.sh && ci_commit_formatting_run diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index ec6b4c7f1962a..e9b17007476c1 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -5,13 +5,17 @@ on: paths: - docs/** +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v1 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 - name: Install Python packages run: pip install Sphinx - name: Build docs diff --git a/.github/workflows/examples.yml b/.github/workflows/examples.yml index 53a817af2b313..450805a6bde41 100644 --- a/.github/workflows/examples.yml +++ b/.github/workflows/examples.yml @@ -10,12 +10,16 @@ on: - 'py/**' - 'shared/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: embedding: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build - run: make -C examples/embedding + run: make -C examples/embedding -f micropython_embed.mk && make -C examples/embedding - name: Run - run: test "$(./examples/embedding/hello-embed)" = "Hello world of easy embedding!" + run: ./examples/embedding/embed | grep "hello world" diff --git a/.github/workflows/mpremote.yml b/.github/workflows/mpremote.yml new file mode 100644 index 0000000000000..14aef03e0773c --- /dev/null +++ b/.github/workflows/mpremote.yml @@ -0,0 +1,29 @@ +name: Package mpremote + +on: + push: + pull_request: + paths: + - '.github/workflows/*.yml' + - 'tools/**' + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + # Setting this to zero means fetch all history and tags, + # which hatch-vcs can use to discover the version tag. + fetch-depth: 0 + - uses: actions/setup-python@v4 + - name: Install build tools + run: pip install build + - name: Build mpremote wheel + run: cd tools/mpremote && python -m build --wheel + - name: Archive mpremote wheel + uses: actions/upload-artifact@v3 + with: + name: mpremote + path: | + tools/mpremote/dist/mpremote*.whl diff --git a/.github/workflows/mpy_format.yml b/.github/workflows/mpy_format.yml index ab90bb339aa1b..66abb19b81a46 100644 --- a/.github/workflows/mpy_format.yml +++ b/.github/workflows/mpy_format.yml @@ -5,13 +5,19 @@ on: pull_request: paths: - '.github/workflows/*.yml' + - 'examples/**' + - 'tests/**' - 'tools/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: test: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 # use 20.04 to get python2 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_mpy_format_setup - name: Test mpy-tool.py diff --git a/.github/workflows/ports.yml b/.github/workflows/ports.yml index e9e6de284cfae..fb574ad981908 100644 --- a/.github/workflows/ports.yml +++ b/.github/workflows/ports.yml @@ -8,11 +8,15 @@ on: - 'tools/**' - ports/** +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build ports download metadata run: mkdir boards && ./tools/autobuild/build-downloads.py . ./boards diff --git a/.github/workflows/ports_cc3200.yml b/.github/workflows/ports_cc3200.yml index 0eaa36da3796e..b58bc24b58b0a 100644 --- a/.github/workflows/ports_cc3200.yml +++ b/.github/workflows/ports_cc3200.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/cc3200/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_cc3200_setup - name: Build diff --git a/.github/workflows/ports_esp32.yml b/.github/workflows/ports_esp32.yml index de88de3755421..2cc9f592bf23e 100644 --- a/.github/workflows/ports_esp32.yml +++ b/.github/workflows/ports_esp32.yml @@ -8,25 +8,21 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/esp32/**' -jobs: - build_idf402: - runs-on: ubuntu-20.04 - steps: - - uses: actions/checkout@v2 - - name: Install packages - run: source tools/ci.sh && ci_esp32_idf402_setup - - name: Build - run: source tools/ci.sh && ci_esp32_build +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true - build_idf44: +jobs: + build_idf50: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages - run: source tools/ci.sh && ci_esp32_idf44_setup + run: source tools/ci.sh && ci_esp32_idf50_setup - name: Build run: source tools/ci.sh && ci_esp32_build diff --git a/.github/workflows/ports_esp8266.yml b/.github/workflows/ports_esp8266.yml index f4ce1f8212d87..ba89d5e9529eb 100644 --- a/.github/workflows/ports_esp8266.yml +++ b/.github/workflows/ports_esp8266.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/esp8266/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_esp8266_setup && ci_esp8266_path >> $GITHUB_PATH - name: Build diff --git a/.github/workflows/ports_javascript.yml b/.github/workflows/ports_javascript.yml deleted file mode 100644 index 244dc966aa6d9..0000000000000 --- a/.github/workflows/ports_javascript.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: javascript port - -on: - push: - pull_request: - paths: - - '.github/workflows/*.yml' - - 'tools/**' - - 'py/**' - - 'extmod/**' - - 'lib/**' - - 'ports/javascript/**' - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Install packages - run: source tools/ci.sh && ci_javascript_setup - - name: Build - run: source tools/ci.sh && ci_javascript_build - - name: Run tests - run: source tools/ci.sh && ci_javascript_run_tests diff --git a/.github/workflows/ports_mimxrt.yml b/.github/workflows/ports_mimxrt.yml index 8fbc2209e4139..d91562534188a 100644 --- a/.github/workflows/ports_mimxrt.yml +++ b/.github/workflows/ports_mimxrt.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/mimxrt/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_mimxrt_setup - name: Build diff --git a/.github/workflows/ports_nrf.yml b/.github/workflows/ports_nrf.yml index 1ba3b0ce61e96..89211217800b0 100644 --- a/.github/workflows/ports_nrf.yml +++ b/.github/workflows/ports_nrf.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/nrf/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_nrf_setup - name: Build diff --git a/.github/workflows/ports_powerpc.yml b/.github/workflows/ports_powerpc.yml index 88fa59767b756..a15c4da97fa6a 100644 --- a/.github/workflows/ports_powerpc.yml +++ b/.github/workflows/ports_powerpc.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/powerpc/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_powerpc_setup - name: Build diff --git a/.github/workflows/ports_qemu-arm.yml b/.github/workflows/ports_qemu-arm.yml index 0489a93d5ad16..93ec4da76700e 100644 --- a/.github/workflows/ports_qemu-arm.yml +++ b/.github/workflows/ports_qemu-arm.yml @@ -8,16 +8,21 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/qemu-arm/**' - 'tests/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build_and_test: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_qemu_arm_setup - name: Build and run test suite diff --git a/.github/workflows/ports_renesas-ra.yml b/.github/workflows/ports_renesas-ra.yml index 20e068ee75d75..33e17a385a1e3 100644 --- a/.github/workflows/ports_renesas-ra.yml +++ b/.github/workflows/ports_renesas-ra.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/renesas-ra/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build_renesas_ra_board: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_renesas_ra_setup - name: Build diff --git a/.github/workflows/ports_rp2.yml b/.github/workflows/ports_rp2.yml index 668b79cae256c..f042ff1151ab1 100644 --- a/.github/workflows/ports_rp2.yml +++ b/.github/workflows/ports_rp2.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/rp2/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_rp2_setup - name: Build diff --git a/.github/workflows/ports_samd.yml b/.github/workflows/ports_samd.yml index bde4ed965faa0..9833a2fae2ef9 100644 --- a/.github/workflows/ports_samd.yml +++ b/.github/workflows/ports_samd.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/samd/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_samd_setup - name: Build diff --git a/.github/workflows/ports_stm32.yml b/.github/workflows/ports_stm32.yml index 4634339c96a6a..b278ea862ce61 100644 --- a/.github/workflows/ports_stm32.yml +++ b/.github/workflows/ports_stm32.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/stm32/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build_pyb: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_stm32_setup - name: Build @@ -25,7 +30,7 @@ jobs: build_nucleo: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_stm32_setup - name: Build diff --git a/.github/workflows/ports_teensy.yml b/.github/workflows/ports_teensy.yml index 7ae77c80af604..f1299603259a6 100644 --- a/.github/workflows/ports_teensy.yml +++ b/.github/workflows/ports_teensy.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'drivers/**' - 'ports/teensy/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_teensy_setup - name: Build diff --git a/.github/workflows/ports_unix.yml b/.github/workflows/ports_unix.yml index 63cc1c0faa921..87c58055b988b 100644 --- a/.github/workflows/ports_unix.yml +++ b/.github/workflows/ports_unix.yml @@ -8,16 +8,22 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'examples/**' + - 'mpy-cross/**' - 'ports/unix/**' - 'tests/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: minimal: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build run: source tools/ci.sh && ci_unix_minimal_build - name: Run main test suite @@ -29,18 +35,18 @@ jobs: reproducible: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build with reproducible date run: source tools/ci.sh && ci_unix_minimal_build env: SOURCE_DATE_EPOCH: 1234567890 - name: Check reproducible build date - run: echo | ports/unix/micropython-minimal -i | grep 'on 2009-02-13;' + run: echo | ports/unix/build-minimal/micropython -i | grep 'on 2009-02-13;' standard: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build run: source tools/ci.sh && ci_unix_standard_build - name: Run main test suite @@ -49,22 +55,10 @@ jobs: if: failure() run: tests/run-tests.py --print-failures - dev: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - name: Build - run: source tools/ci.sh && ci_unix_dev_build - - name: Run main test suite - run: source tools/ci.sh && ci_unix_dev_run_tests - - name: Print failures - if: failure() - run: tests/run-tests.py --print-failures - coverage: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_unix_coverage_setup - name: Build @@ -82,7 +76,7 @@ jobs: (cd ports/unix && gcov -o build-coverage/py ../../py/*.c || true) (cd ports/unix && gcov -o build-coverage/extmod ../../extmod/*.c || true) - name: Upload coverage to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v3 with: fail_ci_if_error: true verbose: true @@ -91,9 +85,9 @@ jobs: run: tests/run-tests.py --print-failures coverage_32bit: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 # use 20.04 to get libffi-dev:i386 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_unix_32bit_setup - name: Build @@ -109,9 +103,9 @@ jobs: run: tests/run-tests.py --print-failures nanbox: - runs-on: ubuntu-latest + runs-on: ubuntu-20.04 # use 20.04 to get python2, and libffi-dev:i386 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_unix_32bit_setup - name: Build @@ -125,7 +119,7 @@ jobs: float: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build run: source tools/ci.sh && ci_unix_float_build - name: Run main test suite @@ -137,7 +131,7 @@ jobs: stackless_clang: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_unix_clang_setup - name: Build @@ -151,7 +145,7 @@ jobs: float_clang: runs-on: ubuntu-20.04 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_unix_clang_setup - name: Build @@ -165,7 +159,7 @@ jobs: settrace: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build run: source tools/ci.sh && ci_unix_settrace_build - name: Run main test suite @@ -177,7 +171,7 @@ jobs: settrace_stackless: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build run: source tools/ci.sh && ci_unix_settrace_stackless_build - name: Run main test suite @@ -189,8 +183,8 @@ jobs: macos: runs-on: macos-11.0 steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 with: python-version: '3.8' - name: Build @@ -204,7 +198,7 @@ jobs: qemu_mips: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_unix_qemu_mips_setup - name: Build @@ -218,7 +212,7 @@ jobs: qemu_arm: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_unix_qemu_arm_setup - name: Build diff --git a/.github/workflows/ports_webassembly.yml b/.github/workflows/ports_webassembly.yml new file mode 100644 index 0000000000000..2e0865662f061 --- /dev/null +++ b/.github/workflows/ports_webassembly.yml @@ -0,0 +1,32 @@ +name: webassembly port + +on: + push: + pull_request: + paths: + - '.github/workflows/*.yml' + - 'tools/**' + - 'py/**' + - 'extmod/**' + - 'shared/**' + - 'lib/**' + - 'ports/webassembly/**' + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Install packages + run: source tools/ci.sh && ci_webassembly_setup + - name: Build + run: source tools/ci.sh && ci_webassembly_build + - name: Run tests + run: source tools/ci.sh && ci_webassembly_run_tests + - name: Print failures + if: failure() + run: tests/run-tests.py --print-failures diff --git a/.github/workflows/ports_windows.yml b/.github/workflows/ports_windows.yml index 1bfe40c7fded2..b31718c591402 100644 --- a/.github/workflows/ports_windows.yml +++ b/.github/workflows/ports_windows.yml @@ -8,15 +8,20 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'ports/unix/**' - 'ports/windows/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_windows_setup - name: Build diff --git a/.github/workflows/ports_zephyr.yml b/.github/workflows/ports_zephyr.yml index d9ae2b8c55a2a..f64401b316a5b 100644 --- a/.github/workflows/ports_zephyr.yml +++ b/.github/workflows/ports_zephyr.yml @@ -8,14 +8,19 @@ on: - 'tools/**' - 'py/**' - 'extmod/**' + - 'shared/**' - 'lib/**' - 'ports/zephyr/**' +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Install packages run: source tools/ci.sh && ci_zephyr_setup - name: Install Zephyr diff --git a/.github/workflows/ruff.yml b/.github/workflows/ruff.yml new file mode 100644 index 0000000000000..b8e43dc78f17c --- /dev/null +++ b/.github/workflows/ruff.yml @@ -0,0 +1,10 @@ +# https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python +name: Python code lint with ruff +on: [push, pull_request] +jobs: + ruff: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - run: pip install --user ruff + - run: ruff --format=github . diff --git a/.gitignore b/.gitignore index 7342489927888..2d20cb18970e8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,48 +1,25 @@ -# Compiled Sources -################### -*.o -*.a -*.elf -*.bin -*.map -*.hex -*.dis -*.exe - -# Packages -############ - -# Logs and Databases -###################### -*.log - -# VIM Swap Files -###################### -*.swp +# This .gitignore file is intended to be minimal. +# +# If you find that you need additional rules, such as IDE temporary +# files, please do so either via a global .gitignore file (registered +# with core.excludesFile), or by adding private repository-specific +# rules to .git/info/exclude. See https://git-scm.com/docs/gitignore +# for more information. # Build directories -###################### build/ build-*/ +docs/genrst/ # Test failure outputs -###################### tests/results/* # Python cache files -###################### __pycache__/ -*.pyc # Customized Makefile/project overrides -###################### GNUmakefile user.props -# Generated rst files -###################### -genrst/ - # MacOS desktop metadata files -###################### .DS_Store diff --git a/.gitmodules b/.gitmodules index 118e023debf8d..992fec3d1836f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,7 +13,7 @@ [submodule "lib/stm32lib"] path = lib/stm32lib url = https://github.com/micropython/stm32lib - branch = work-F0-1.9.0+F4-1.16.0+F7-1.7.0+G4-1.3.0+H7-1.6.0+L0-1.11.2+L4-1.17.0+WB-1.10.0+WL-1.1.0 + branch = work-F0-1.9.0+F4-1.16.0+F7-1.7.0+G0-1.5.1+G4-1.3.0+H7-1.6.0+L0-1.11.2+L1-1.10.3+L4-1.17.0+WB-1.10.0+WL-1.1.0 [submodule "lib/nrfx"] path = lib/nrfx url = https://github.com/NordicSemiconductor/nrfx.git @@ -50,3 +50,9 @@ url = https://github.com/andrewleech/wiznet_ioLibrary_Driver.git # Requires https://github.com/Wiznet/ioLibrary_Driver/pull/120 # url = https://github.com/Wiznet/ioLibrary_Driver.git +[submodule "lib/cyw43-driver"] + path = lib/cyw43-driver + url = https://github.com/georgerobotics/cyw43-driver.git +[submodule "lib/micropython-lib"] + path = lib/micropython-lib + url = https://github.com/micropython/micropython-lib.git diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000000000..e9815a4b2e64c --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,17 @@ +repos: + - repo: local + hooks: + - id: codeformat + name: MicroPython codeformat.py for changed files + entry: tools/codeformat.py -v -f + language: python + - id: verifygitlog + name: MicroPython git commit message format checker + entry: tools/verifygitlog.py --check-file --ignore-rebase + language: python + verbose: true + stages: [commit-msg] + - repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.0.265 + hooks: + - id: ruff diff --git a/CODECONVENTIONS.md b/CODECONVENTIONS.md index 78fb912a6ab75..d44b382b25ead 100644 --- a/CODECONVENTIONS.md +++ b/CODECONVENTIONS.md @@ -11,7 +11,7 @@ It's also ok to drop file extensions. Besides prefix, first line of a commit message should describe a change clearly and to the point, and be a grammatical sentence with -final full stop. First line should fit within 72 characters. Examples +final full stop. First line must fit within 72 characters. Examples of good first line of commit messages: py/objstr: Add splitlines() method. @@ -27,12 +27,9 @@ change beyond 5 lines would likely require such detailed description. To get good practical examples of good commits and their messages, browse the `git log` of the project. -When committing you are encouraged to sign-off your commit by adding -"Signed-off-by" lines and similar, eg using "git commit -s". If you don't -explicitly sign-off in this way then the commit message, which includes your -name and email address in the "Author" line, implies your sign-off. In either -case, of explicit or implicit sign-off, you are certifying and signing off -against the following: +When committing you must sign-off your commit by adding "Signed-off-by:" +line(s) at the end of the commit message, e.g. using `git commit -s`. You +are then certifying and signing off against the following: * That you wrote the change yourself, or took it from a project with a compatible license (in the latter case the commit message, and possibly @@ -49,10 +46,9 @@ against the following: * Your contribution including commit message will be publicly and indefinitely available for anyone to access, including redistribution under the terms of the project's license. -* Your signature for all of the above, which is the "Signed-off-by" line - or the "Author" line in the commit message, includes your full real name and - a valid and active email address by which you can be contacted in the - foreseeable future. +* Your signature for all of the above, which is the "Signed-off-by" line, + includes your full real name and a valid and active email address by + which you can be contacted in the foreseeable future. Code auto-formatting ==================== @@ -65,6 +61,96 @@ changes to the correct style. Without arguments this tool will reformat all source code (and may take some time to run). Otherwise pass as arguments to the tool the files that changed and it will only reformat those. +uncrustify +========== + +Only [uncrustify](https://github.com/uncrustify/uncrustify) v0.71 or v0.72 can +be used for MicroPython. Different uncrustify versions produce slightly +different formatting, and the configuration file formats are often +incompatible. v0.73 or newer *will not work*. + +Depending on your operating system version, it may be possible to install a pre-compiled +uncrustify version: + +Ubuntu, Debian +-------------- + +Ubuntu versions 21.10 or 22.04LTS, and Debian versions bullseye or bookworm all +include v0.72 so can be installed directly: + +``` +$ apt install uncrustify +``` + +Arch Linux +---------- + +The current Arch uncrustify version is too new. There is an [old Arch package +for v0.72](https://archive.archlinux.org/packages/u/uncrustify/) that can be +installed from the Arch Linux archive ([more +information](https://wiki.archlinux.org/title/Downgrading_packages#Arch_Linux_Archive)). Use +the [IgnorePkg feature](https://wiki.archlinux.org/title/Pacman#Skip_package_from_being_upgraded) +to prevent it re-updating. + +Brew +---- + +This command may work, please raise a new Issue if it doesn't: + +``` +curl -L https://github.com/Homebrew/homebrew-core/raw/2b07d8192623365078a8b855a164ebcdf81494a6/Formula/uncrustify.rb > uncrustify.rb && brew install uncrustify.rb && rm uncrustify.rb +``` + +Automatic Pre-Commit Hooks +========================== + +To have code formatting and commit message conventions automatically checked, +a configuration file is provided for the [pre-commit](https://pre-commit.com/) +tool. + +First install `pre-commit`, either from your system package manager or via +`pip`. When installing `pre-commit` via pip, it is recommended to use a +virtual environment. Other sources, such as Brew are also available, see +[the docs](https://pre-commit.com/index.html#install) for details. + +``` +$ apt install pre-commit # Ubuntu, Debian +$ pacman -Sy python-precommit # Arch Linux +$ brew install pre-commit # Brew +$ pip install pre-commit # PyPI +``` + +Next, install [uncrustify (see above)](#uncrustify). Other dependencies are managed by +pre-commit automatically, but uncrustify needs to be installed and available on +the PATH. + +Then, inside the MicroPython repository, register the git hooks for pre-commit +by running: + +``` +$ pre-commit install --hook-type pre-commit --hook-type commit-msg +``` + +pre-commit will now automatically run during `git commit` for both code and +commit message formatting. + +The same formatting checks will be run by CI for any Pull Request submitted to +MicroPython. Pre-commit allows you to see any failure more quickly, and in many +cases will automatically correct it in your local working copy. + +To unregister `pre-commit` from your MicroPython repository, run: + +``` +$ pre-commit uninstall --hook-type pre-commit --hook-type commit-msg +``` + +Tips: + +* To skip pre-commit checks on a single commit, use `git commit -n` (for + `--no-verify`). +* To ignore the pre-commit message format check temporarily, start the commit + message subject line with "WIP" (for "Work In Progress"). + Python code conventions ======================= @@ -165,7 +251,7 @@ Documentation conventions ========================= MicroPython generally follows CPython in documentation process and -conventions. reStructuredText syntax is used for the documention. +conventions. reStructuredText syntax is used for the documentation. Specific conventions/suggestions: diff --git a/LICENSE b/LICENSE index 2b9a64b89a723..07c88b0a03231 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013-2022 Damien P. George +Copyright (c) 2013-2023 Damien P. George Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -35,9 +35,7 @@ used during the build process and is not part of the compiled source code. / (MIT) /drivers - /cc3000 (BSD-3-clause) /cc3100 (BSD-3-clause) - /wiznet5k (BSD-3-clause) /lib /asf4 (Apache-2.0) /axtls (BSD-3-clause) @@ -62,12 +60,15 @@ used during the build process and is not part of the compiled source code. /tinytest (BSD-3-clause) /tinyusb (MIT) /uzlib (Zlib) + /wiznet5k (MIT) /logo (uses OFL-1.1) /ports /cc3200 /hal (BSD-3-clause) /simplelink (BSD-3-clause) /FreeRTOS (GPL-2.0 with FreeRTOS exception) + /esp32 + /ppp_set_auth.* (Apache-2.0) /stm32 /usbd*.c (MCD-ST Liberty SW License Agreement V2) /stm32_it.* (MIT + BSD-3-clause) diff --git a/README.md b/README.md index 920f10a5035b8..6482899b251d9 100644 --- a/README.md +++ b/README.md @@ -15,174 +15,134 @@ code-base, including project-wide name changes and API changes. MicroPython implements the entire Python 3.4 syntax (including exceptions, `with`, `yield from`, etc., and additionally `async`/`await` keywords from -Python 3.5). The following core datatypes are provided: `str` (including -basic Unicode support), `bytes`, `bytearray`, `tuple`, `list`, `dict`, `set`, -`frozenset`, `array.array`, `collections.namedtuple`, classes and instances. -Builtin modules include `sys`, `time`, and `struct`, etc. Select ports have -support for `_thread` module (multithreading). Note that only a subset of -Python 3 functionality is implemented for the data types and modules. - -MicroPython can execute scripts in textual source form or from precompiled -bytecode, in both cases either from an on-device filesystem or "frozen" into -the MicroPython executable. - -See the repository http://github.com/micropython/pyboard for the MicroPython -board (PyBoard), the officially supported reference electronic circuit board. - -Major components in this repository: -- py/ -- the core Python implementation, including compiler, runtime, and +Python 3.5 and some select features from later versions). The following core +datatypes are provided: `str`(including basic Unicode support), `bytes`, +`bytearray`, `tuple`, `list`, `dict`, `set`, `frozenset`, `array.array`, +`collections.namedtuple`, classes and instances. Builtin modules include +`os`, `sys`, `time`, `re`, and `struct`, etc. Select ports have support for +`_thread` module (multithreading), `socket` and `ssl` for networking, and +`asyncio`. Note that only a subset of Python 3 functionality is implemented +for the data types and modules. + +MicroPython can execute scripts in textual source form (.py files) or from +precompiled bytecode (.mpy files), in both cases either from an on-device +filesystem or "frozen" into the MicroPython executable. + +MicroPython also provides a set of MicroPython-specific modules to access +hardware-specific functionality and peripherals such as GPIO, Timers, ADC, +DAC, PWM, SPI, I2C, CAN, Bluetooth, and USB. + +Getting started +--------------- + +See the [online documentation](https://docs.micropython.org/) for API +references and information about using MicroPython and information about how +it is implemented. + +We use [GitHub Discussions](https://github.com/micropython/micropython/discussions) +as our forum, and [Discord](https://discord.gg/RB8HZSAExQ) for chat. These +are great places to ask questions and advice from the community or to discuss your +MicroPython-based projects. + +For bugs and feature requests, please [raise an issue](https://github.com/micropython/micropython/issues/new/choose) +and follow the templates there. + +For information about the [MicroPython pyboard](https://store.micropython.org/pyb-features), +the officially supported board from the +[original Kickstarter campaign](https://www.kickstarter.com/projects/214379695/micro-python-python-for-microcontrollers), +see the [schematics and pinouts](http://github.com/micropython/pyboard) and +[documentation](https://docs.micropython.org/en/latest/pyboard/quickref.html). + +Contributing +------------ + +MicroPython is an open-source project and welcomes contributions. To be +productive, please be sure to follow the +[Contributors' Guidelines](https://github.com/micropython/micropython/wiki/ContributorGuidelines) +and the [Code Conventions](https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md). +Note that MicroPython is licenced under the MIT license, and all contributions +should follow this license. + +About this repository +--------------------- + +This repository contains the following components: +- [py/](py/) -- the core Python implementation, including compiler, runtime, and core library. -- mpy-cross/ -- the MicroPython cross-compiler which is used to turn scripts +- [mpy-cross/](mpy-cross/) -- the MicroPython cross-compiler which is used to turn scripts into precompiled bytecode. -- ports/unix/ -- a version of MicroPython that runs on Unix. -- ports/stm32/ -- a version of MicroPython that runs on the PyBoard and similar - STM32 boards (using ST's Cube HAL drivers). -- ports/minimal/ -- a minimal MicroPython port. Start with this if you want - to port MicroPython to another microcontroller. -- tests/ -- test framework and test scripts. -- docs/ -- user documentation in Sphinx reStructuredText format. Rendered - HTML documentation is available at http://docs.micropython.org. - -Additional components: -- ports/bare-arm/ -- a bare minimum version of MicroPython for ARM MCUs. Used - mostly to control code size. -- ports/teensy/ -- a version of MicroPython that runs on the Teensy 3.1 - (preliminary but functional). -- ports/pic16bit/ -- a version of MicroPython for 16-bit PIC microcontrollers. -- ports/cc3200/ -- a version of MicroPython that runs on the CC3200 from TI. -- ports/esp8266/ -- a version of MicroPython that runs on Espressif's ESP8266 SoC. -- ports/esp32/ -- a version of MicroPython that runs on Espressif's ESP32 SoC. -- ports/nrf/ -- a version of MicroPython that runs on Nordic's nRF51 and nRF52 MCUs. -- extmod/ -- additional (non-core) modules implemented in C. -- tools/ -- various tools, including the pyboard.py module. -- examples/ -- a few example Python scripts. - -The subdirectories above may include READMEs with additional info. +- [ports/](ports/) -- platform-specific code for the various ports and architectures that MicroPython runs on. +- [lib/](lib/) -- submodules for external dependencies. +- [tests/](tests/) -- test framework and test scripts. +- [docs/](docs/) -- user documentation in Sphinx reStructuredText format. This is used to generate the [online documentation](http://docs.micropython.org). +- [extmod/](extmod/) -- additional (non-core) modules implemented in C. +- [tools/](tools/) -- various tools, including the pyboard.py module. +- [examples/](examples/) -- a few example Python scripts. "make" is used to build the components, or "gmake" on BSD-based systems. You will also need bash, gcc, and Python 3.3+ available as the command `python3` (if your system only has Python 2.7 then invoke make with the additional option -`PYTHON=python2`). +`PYTHON=python2`). Some ports (rp2 and esp32) additionally use CMake. + +Supported platforms & architectures +----------------------------------- + +MicroPython runs on a wide range of microcontrollers, as well as on Unix-like +(including Linux, BSD, macOS, WSL) and Windows systems. + +Microcontroller targets can be as small as 256kiB flash + 16kiB RAM, although +devices with at least 512kiB flash + 128kiB RAM allow a much more +full-featured experience. + +The [Unix](ports/unix) and [Windows](ports/windows) ports allow both +development and testing of MicroPython itself, as well as providing +lightweight alternative to CPython on these platforms (in particular on +embedded Linux systems). + +The ["minimal"](ports/minimal) port provides an example of a very basic +MicroPython port and can be compiled as both a standalone Linux binary as +well as for ARM Cortex M4. Start with this if you want to port MicroPython to +another microcontroller. Additionally the ["bare-arm"](ports/bare-arm) port +is an example of the absolute minimum configuration, and is used to keep +track of the code size of the core runtime and VM. + +In addition, the following ports are provided in this repository: + - [cc3200](ports/cc3200) -- Texas Instruments CC3200 (including PyCom WiPy). + - [esp32](ports/esp32) -- Espressif ESP32 SoC (including ESP32S2, ESP32S3, ESP32C3). + - [esp8266](ports/esp8266) -- Espressif ESP8266 SoC. + - [mimxrt](ports/mimxrt) -- NXP m.iMX RT (including Teensy 4.x). + - [nrf](ports/nrf) -- Nordic Semiconductor nRF51 and nRF52. + - [pic16bit](ports/pic16bit) -- Microchip PIC 16-bit. + - [powerpc](ports/powerpc) -- IBM PowerPC (including Microwatt) + - [qemu-arm](ports/qemu-arm) -- QEMU-based emulated target, for testing) + - [renesas-ra](ports/renesas-ra) -- Renesas RA family. + - [rp2](ports/rp2) -- Raspberry Pi RP2040 (including Pico and Pico W). + - [samd](ports/samd) -- Microchip (formerly Atmel) SAMD21 and SAMD51. + - [stm32](ports/stm32) -- STMicroelectronics STM32 family (including F0, F4, F7, G0, G4, H7, L0, L4, WB) + - [teensy](ports/teensy) -- Teensy 3.x. + - [webassembly](ports/webassembly) -- Emscripten port targeting browsers and NodeJS. + - [zephyr](ports/zephyr) -- Zephyr RTOS. The MicroPython cross-compiler, mpy-cross ----------------------------------------- -Most ports require the MicroPython cross-compiler to be built first. This -program, called mpy-cross, is used to pre-compile Python scripts to .mpy -files which can then be included (frozen) into the firmware/executable for -a port. To build mpy-cross use: +Most ports require the [MicroPython cross-compiler](mpy-cross) to be built +first. This program, called mpy-cross, is used to pre-compile Python scripts +to .mpy files which can then be included (frozen) into the +firmware/executable for a port. To build mpy-cross use: $ cd mpy-cross $ make -The Unix version ----------------- - -The "unix" port requires a standard Unix environment with gcc and GNU make. -x86 and x64 architectures are supported (i.e. x86 32- and 64-bit), as well -as ARM and MIPS. Making full-featured port to another architecture requires -writing some assembly code for the exception handling and garbage collection. -Alternatively, fallback implementation based on setjmp/longjmp can be used. - -To build (see section below for required dependencies): - - $ cd ports/unix - $ make submodules - $ make - -Then to give it a try: - - $ ./micropython - >>> list(5 * x + y for x in range(10) for y in [4, 2, 1]) - -Use `CTRL-D` (i.e. EOF) to exit the shell. -Learn about command-line options (in particular, how to increase heap size -which may be needed for larger applications): - - $ ./micropython -h - -Run complete testsuite: - - $ make test - -Unix version comes with a builtin package manager called upip, e.g.: - - $ ./micropython -m upip install micropython-pystone - $ ./micropython -m pystone - -Browse available modules on -[PyPI](https://pypi.python.org/pypi?%3Aaction=search&term=micropython). -Standard library modules come from -[micropython-lib](https://github.com/micropython/micropython-lib) project. - External dependencies --------------------- -Building MicroPython ports may require some dependencies installed. - -For Unix port, `libffi` library and `pkg-config` tool are required. On -Debian/Ubuntu/Mint derivative Linux distros, install `build-essential` -(includes toolchain and make), `libffi-dev`, and `pkg-config` packages. - -Other dependencies can be built together with MicroPython. This may -be required to enable extra features or capabilities, and in recent -versions of MicroPython, these may be enabled by default. To build -these additional dependencies, in the port directory you're -interested in (e.g. `ports/unix/`) first execute: +The core MicroPython VM and runtime has no external dependencies, but a given +port might depend on third-party drivers or vendor HALs. This repository +includes [several submodules](lib/) linking to these external dependencies. +Before compiling a given port, use + $ cd ports/name $ make submodules -This will fetch all the relevant git submodules (sub repositories) that -the port needs. Use the same command to get the latest versions of -submodules as they are updated from time to time. After that execute: - - $ make deplibs - -This will build all available dependencies (regardless whether they -are used or not). If you intend to build MicroPython with additional -options (like cross-compiling), the same set of options should be passed -to `make deplibs`. To actually enable/disable use of dependencies, edit -`ports/unix/mpconfigport.mk` file, which has inline descriptions of the options. -For example, to build SSL module (required for `upip` tool described above, -and so enabled by default), `MICROPY_PY_USSL` should be set to 1. - -For some ports, building required dependences is transparent, and happens -automatically. But they still need to be fetched with the `make submodules` -command. - -The STM32 version ------------------ - -The "stm32" port requires an ARM compiler, arm-none-eabi-gcc, and associated -bin-utils. For those using Arch Linux, you need arm-none-eabi-binutils, -arm-none-eabi-gcc and arm-none-eabi-newlib packages. Otherwise, try here: -https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm - -To build: - - $ cd ports/stm32 - $ make submodules - $ make - -You then need to get your board into DFU mode. On the pyboard, connect the -3V3 pin to the P1/DFU pin with a wire (on PYBv1.0 they are next to each other -on the bottom left of the board, second row from the bottom). - -Then to flash the code via USB DFU to your device: - - $ make deploy - -This will use the included `tools/pydfu.py` script. If flashing the firmware -does not work it may be because you don't have the correct permissions, and -need to use `sudo make deploy`. -See the README.md file in the ports/stm32/ directory for further details. - -Contributing ------------- - -MicroPython is an open-source project and welcomes contributions. To be -productive, please be sure to follow the -[Contributors' Guidelines](https://github.com/micropython/micropython/wiki/ContributorGuidelines) -and the [Code Conventions](https://github.com/micropython/micropython/blob/master/CODECONVENTIONS.md). -Note that MicroPython is licenced under the MIT license, and all contributions -should follow this license. +to ensure that all required submodules are initialised. diff --git a/docs/Makefile b/docs/Makefile index 05709617c35b9..766a669a500dc 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -3,7 +3,7 @@ # You can set these variables from the command line. PYTHON = python3 -SPHINXOPTS = -W --keep-going +SPHINXOPTS = -W --keep-going -j auto SPHINXBUILD = sphinx-build PAPER = BUILDDIR = build/$(MICROPY_PORT) diff --git a/docs/conf.py b/docs/conf.py index a7a4ab08c5b03..a966b3a02570a 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -33,6 +33,7 @@ 'downloads':[ ('PDF', url_pattern % micropy_version + '/micropython-docs.pdf'), ], + 'is_release': micropy_version != 'latest', } @@ -66,7 +67,7 @@ # General information about the project. project = 'MicroPython' -copyright = '- The MicroPython Documentation is Copyright © 2014-2022, Damien P. George, Paul Sokolovsky, and contributors' +copyright = '- The MicroPython Documentation is Copyright © 2014-2023, Damien P. George, Paul Sokolovsky, and contributors' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -74,7 +75,7 @@ # # We don't follow "The short X.Y version" vs "The full version, including alpha/beta/rc tags" # breakdown, so use the same version identifier for both to avoid confusion. -version = release = '1.19.1' +version = release = micropy_version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -166,6 +167,10 @@ # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ['static'] +# Add a custom CSS file for HTML generation +html_css_files = [ + 'custom.css', +] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. @@ -228,7 +233,7 @@ # Additional stuff for the LaTeX preamble. #'preamble': '', # Include 3 levels of headers in PDF ToC -'preamble': '\setcounter{tocdepth}{2}', +'preamble': r'\setcounter{tocdepth}{2}', } # Grouping the document tree into LaTeX files. List of tuples diff --git a/docs/develop/cmodules.rst b/docs/develop/cmodules.rst index 143057f7f1e06..75dbc953c06f8 100644 --- a/docs/develop/cmodules.rst +++ b/docs/develop/cmodules.rst @@ -49,9 +49,17 @@ A MicroPython user C module is a directory with the following files: in your ``micropython.mk`` to a local make variable, eg ``EXAMPLE_MOD_DIR := $(USERMOD_DIR)`` - Your ``micropython.mk`` must add your modules source files relative to your - expanded copy of ``$(USERMOD_DIR)`` to ``SRC_USERMOD``, eg - ``SRC_USERMOD += $(EXAMPLE_MOD_DIR)/example.c`` + Your ``micropython.mk`` must add your modules source files to the + ``SRC_USERMOD_C`` or ``SRC_USERMOD_LIB_C`` variables. The former will be + processed for ``MP_QSTR_`` and ``MP_REGISTER_MODULE`` definitions, the latter + will not (e.g. helpers and library code that isn't MicroPython-specific). + These paths should include your expanded copy of ``$(USERMOD_DIR)``, e.g.:: + + SRC_USERMOD_C += $(EXAMPLE_MOD_DIR)/modexample.c + SRC_USERMOD_LIB_C += $(EXAMPLE_MOD_DIR)/utils/algorithm.c + + Similarly, use ``SRC_USERMOD_CXX`` and ``SRC_USERMOD_LIB_CXX`` for C++ + source files. If you have custom compiler options (like ``-I`` to add directories to search for header files), these should be added to ``CFLAGS_USERMOD`` for C code @@ -87,9 +95,12 @@ A MicroPython user C module is a directory with the following files: Basic example ------------- -This simple module named ``cexample`` provides a single function -``cexample.add_ints(a, b)`` which adds the two integer args together and returns -the result. It can be found in the MicroPython source tree +The ``cexample`` module provides examples for a function and a class. The +``cexample.add_ints(a, b)`` function adds two integer args together and returns +the result. The ``cexample.Timer()`` type creates timers that can be used to +measure the elapsed time since the object is instantiated. + +The module can be found in the MicroPython source tree `in the examples directory `_ and has a source file and a Makefile fragment with content as described above:: @@ -264,3 +275,13 @@ can now be accessed in Python just like any other builtin module, e.g. import cexample print(cexample.add_ints(1, 3)) # should display 4 + +.. code-block:: python + + from cexample import Timer + from time import sleep_ms + + watch = Timer() + sleep_ms(1000) + print(watch.time()) + # should display approximately 1000 diff --git a/docs/develop/compiler.rst b/docs/develop/compiler.rst index 2007657490f55..cac92585ff4ee 100644 --- a/docs/develop/compiler.rst +++ b/docs/develop/compiler.rst @@ -147,10 +147,17 @@ The most relevant method you should know about is this: .. code-block:: c mp_obj_t mp_compile(mp_parse_tree_t *parse_tree, qstr source_file, bool is_repl) { + // Create a context for this module, and set its globals dict. + mp_module_context_t *context = m_new_obj(mp_module_context_t); + context->module.globals = mp_globals_get(); + // Compile the input parse_tree to a raw-code structure. - mp_raw_code_t *rc = mp_compile_to_raw_code(parse_tree, source_file, is_repl); + mp_compiled_module_t cm; + cm.context = context; + mp_compile_to_raw_code(parse_tree, source_file, is_repl, &cm); + // Create and return a function object that executes the outer module. - return mp_make_function_from_raw_code(rc, MP_OBJ_NULL, MP_OBJ_NULL); + return mp_make_function_from_raw_code(cm.rc, cm.context, NULL); } The compiler compiles the code in four passes: scope, stack size, code size and emit. diff --git a/docs/develop/gettingstarted.rst b/docs/develop/gettingstarted.rst index 36062ddc008bd..c2d3816d425a4 100644 --- a/docs/develop/gettingstarted.rst +++ b/docs/develop/gettingstarted.rst @@ -103,7 +103,7 @@ For the stm32 port, the ARM cross-compiler is required: $ sudo apt-get install arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-newlib See the `ARM GCC -toolchain `_ +toolchain `_ for the latest details. Python is also required. Python 2 is supported for now, but we recommend using Python 3. @@ -322,7 +322,8 @@ tests tools - Contains helper tools including the ``upip`` and the ``pyboard.py`` module. + Contains scripts used by the build and CI process, as well as user tools such + as ``pyboard.py`` and ``mpremote``. examples diff --git a/docs/develop/optimizations.rst b/docs/develop/optimizations.rst index d972cde66616a..7f2c8cbe7282c 100644 --- a/docs/develop/optimizations.rst +++ b/docs/develop/optimizations.rst @@ -25,6 +25,8 @@ into the firmware image as part of the main firmware compilation process, which the bytecode will be executed from ROM. This can lead to a significant memory saving, and reduce heap fragmentation. +See :ref:`manifest` for more information. + Variables --------- diff --git a/docs/develop/porting.rst b/docs/develop/porting.rst index 3d0553205c11a..63919b97a6ccd 100644 --- a/docs/develop/porting.rst +++ b/docs/develop/porting.rst @@ -38,6 +38,7 @@ The basic MicroPython firmware is implemented in the main port file, e.g ``main. .. code-block:: c + #include "py/builtin.h" #include "py/compile.h" #include "py/gc.h" #include "py/mperrno.h" @@ -98,8 +99,8 @@ We also need a Makefile at this point for the port: include $(TOP)/extmod/extmod.mk # Set CFLAGS and libraries. - CFLAGS = -I. -I$(BUILD) -I$(TOP) - LIBS = -lm + CFLAGS += -I. -I$(BUILD) -I$(TOP) + LIBS += -lm # Define the required source files. SRC_C = \ @@ -110,6 +111,9 @@ We also need a Makefile at this point for the port: shared/runtime/pyexec.c \ shared/runtime/stdout_helpers.c \ + # Define source files containung qstrs. + SRC_QSTR += shared/readline/readline.c shared/runtime/pyexec.c + # Define the required object files. OBJ = $(PY_CORE_O) $(addprefix $(BUILD)/, $(SRC_C:.c=.o)) @@ -147,9 +151,6 @@ The following is an example of an ``mpconfigport.h`` file: #define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT) - // Enable u-modules to be imported with their standard name, like sys. - #define MICROPY_MODULE_WEAK_LINKS (1) - // Fine control over Python builtins, classes, modules, etc. #define MICROPY_PY_ASYNC_AWAIT (0) #define MICROPY_PY_BUILTINS_SET (0) @@ -174,9 +175,6 @@ The following is an example of an ``mpconfigport.h`` file: #define MP_STATE_PORT MP_STATE_VM - #define MICROPY_PORT_ROOT_POINTERS \ - const char *readline_hist[8]; - This configuration file contains machine-specific configurations including aspects like if different MicroPython features should be enabled e.g. ``#define MICROPY_ENABLE_GC (1)``. Making this Setting ``(0)`` disables the feature. diff --git a/docs/differences/index_template.txt b/docs/differences/index_template.txt index dbbd7fc099a25..1bbfbfedce921 100644 --- a/docs/differences/index_template.txt +++ b/docs/differences/index_template.txt @@ -13,6 +13,7 @@ above. The sections below describe the current status of these features. ../differences/python_37.rst ../differences/python_38.rst ../differences/python_39.rst + ../differences/python_310.rst For the features of Python that are implemented by MicroPython, there are sometimes differences in their behaviour compared to standard Python. The diff --git a/docs/differences/python_310.rst b/docs/differences/python_310.rst new file mode 100644 index 0000000000000..f9d92db655372 --- /dev/null +++ b/docs/differences/python_310.rst @@ -0,0 +1,238 @@ +.. _python_310: + +Python 3.10 +=========== + +Python 3.10.0 (final) was released on the 4 October 2021. The Features for 3.10 are +defined in `PEP 619 `_ +and a detailed description of the changes can be found in +`What's New in Python 3.10 `_. + +.. table:: + :widths: 20 60 20 + + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | **New syntax features** | **Status** | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 634 `_ | Structural Pattern Matching: Specification | [#spm]_ | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 635 `_ | Structural Pattern Matching: Motivation and | [#spm]_ | + | | Rationale | | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 636 `_ | Structural Pattern Matching: Tutorial | [#spm]_ | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `bpo-12782 | Parenthesized context managers are now officially | | + | `_ | allowed | | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | **New features in the standard library** | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 618 `_ | Add Optional Length-Checking To zip | | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | **Interpreter improvements** | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 626 `_ | Precise line numbers for debugging and other tools | | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | **New typing features** | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 604 `_ | Allow writing union types as X | Y | | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 613 `_ | Explicit Type Aliases | | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 612 `_ | Parameter Specification Variables | | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | **Important deprecations, removals or restrictions** | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 644 `_ | Require OpenSSL 1.1.1 or newer | | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 632 `_ | Deprecate distutils module. | Not relevant | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 623 `_ | Deprecate and prepare for the removal of the wstr | Not relevant | + | | member in PyUnicodeObject. | | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 624 `_ | Remove Py_UNICODE encoder APIs | Not relevant | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + | `PEP 597 `_ | Add optional EncodingWarning | | + +--------------------------------------------------------+----------------------------------------------------+--------------+ + + +Other Language Changes: + +.. table:: + :widths: 90 10 + + +-------------------------------------------------------------------------------------------------------------+---------------+ + | The :class:`int` type has a new method :meth:`int.bit_count`, returning the | | + | number of ones in the binary expansion of a given integer, also known | | + | as the population count. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | The views returned by :meth:`dict.keys`, :meth:`dict.values` and | | + | :meth:`dict.items` now all have a ``mapping`` attribute that gives a | | + | :class:`types.MappingProxyType` object wrapping the original | | + | dictionary. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | :pep:`618`: The :func:`zip` function now has an optional ``strict`` flag, used | | + | to require that all the iterables have an equal length. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | Builtin and extension functions that take integer arguments no longer accept | | + | :class:`~decimal.Decimal`\ s, :class:`~fractions.Fraction`\ s and other | | + | objects that can be converted to integers only with a loss (e.g. that have | | + | the :meth:`~object.__int__` method but do not have the | | + | :meth:`~object.__index__` method). | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | If :func:`object.__ipow__` returns :const:`NotImplemented`, the operator will | | + | correctly fall back to :func:`object.__pow__` and :func:`object.__rpow__` as expected. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | Assignment expressions can now be used unparenthesized within set literals | | + | and set comprehensions, as well as in sequence indexes (but not slices). | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | Functions have a new ``__builtins__`` attribute which is used to look for | | + | builtin symbols when a function is executed, instead of looking into | | + | ``__globals__['__builtins__']``. The attribute is initialized from | | + | ``__globals__["__builtins__"]`` if it exists, else from the current builtins. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | Two new builtin functions -- :func:`aiter` and :func:`anext` have been added | | + | to provide asynchronous counterparts to :func:`iter` and :func:`next`, | | + | respectively. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | Static methods (:func:`@staticmethod `) and class methods | | + | (:func:`@classmethod `) now inherit the method attributes | | + | (``__module__``, ``__name__``, ``__qualname__``, ``__doc__``, | | + | ``__annotations__``) and have a new ``__wrapped__`` attribute. | | + | Moreover, static methods are now callable as regular functions. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | Annotations for complex targets (everything beside ``simple name`` targets | | + | defined by :pep:`526`) no longer cause any runtime effects with ``from __future__ import annotations``. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | Class and module objects now lazy-create empty annotations dicts on demand. | | + | The annotations dicts are stored in the object’s ``__dict__`` for | | + | backwards compatibility. This improves the best practices for working | | + | with ``__annotations__``. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | Annotations consist of ``yield``, ``yield from``, ``await`` or named expressions | | + | are now forbidden under ``from __future__ import annotations`` due to their side | | + | effects. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | Usage of unbound variables, ``super()`` and other expressions that might | | + | alter the processing of symbol table as annotations are now rendered | | + | effectless under ``from __future__ import annotations``. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | Hashes of NaN values of both :class:`float` type and | | + | :class:`decimal.Decimal` type now depend on object identity. Formerly, they | | + | always hashed to ``0`` even though NaN values are not equal to one another. | | + | This caused potentially quadratic runtime behavior due to excessive hash | | + | collisions when creating dictionaries and sets containing multiple NaNs. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | A :exc:`SyntaxError` (instead of a :exc:`NameError`) will be raised when deleting | | + | the :const:`__debug__` constant. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + | :exc:`SyntaxError` exceptions now have ``end_lineno`` and | | + | ``end_offset`` attributes. They will be ``None`` if not determined. | | + +-------------------------------------------------------------------------------------------------------------+---------------+ + +Changes to built-in modules: + +.. table:: + :widths: 90 10 + + +---------------------------------------------------------------------------------------------------------------+---------------+ + | `asyncio `_ | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add missing :meth:`~asyncio.events.AbstractEventLoop.connect_accepted_socket` | | + | method. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | `array `_ | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | The :meth:`~array.array.index` method of :class:`array.array` now has | | + | optional *start* and *stop* parameters. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | `gc `_ | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add audit hooks for :func:`gc.get_objects`, :func:`gc.get_referrers` and | | + | :func:`gc.get_referents`. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | `hashlib `_ | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | The hashlib module requires OpenSSL 1.1.1 or newer. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | The hashlib module has preliminary support for OpenSSL 3.0.0. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | The pure-Python fallback of :func:`~hashlib.pbkdf2_hmac` is deprecated. In | | + | the future PBKDF2-HMAC will only be available when Python has been built with | | + | OpenSSL support. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | `os `_ | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add :func:`os.cpu_count()` support for VxWorks RTOS. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add a new function :func:`os.eventfd` and related helpers to wrap the | | + | ``eventfd2`` syscall on Linux. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add :func:`os.splice()` that allows to move data between two file | | + | descriptors without copying between kernel address space and user | | + | address space, where one of the file descriptors must refer to a | | + | pipe. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add :data:`~os.O_EVTONLY`, :data:`~os.O_FSYNC`, :data:`~os.O_SYMLINK` | | + | and :data:`~os.O_NOFOLLOW_ANY` for macOS. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | `platform `_ | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add :func:`platform.freedesktop_os_release()` to retrieve operation system | | + | identification from `freedesktop.org os-release | | + | `_ standard file. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | `socket `_ | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | The exception :exc:`socket.timeout` is now an alias of :exc:`TimeoutError`. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add option to create MPTCP sockets with ``IPPROTO_MPTCP``. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add ``IP_RECVTOS`` option to receive the type of service (ToS) or DSCP/ECN fields. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | `ssl `_ | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | The ssl module requires OpenSSL 1.1.1 or newer. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | The ssl module has preliminary support for OpenSSL 3.0.0 and new option | | + | :data:`~ssl.OP_IGNORE_UNEXPECTED_EOF`. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Deprecated function and use of deprecated constants now result in | | + | a :exc:`DeprecationWarning`. :attr:`ssl.SSLContext.options` has | | + | :data:`~ssl.OP_NO_SSLv2` and :data:`~ssl.OP_NO_SSLv3` set by default and | | + | therefore cannot warn about setting the flag again. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | The ssl module now has more secure default settings. Ciphers without forward | | + | secrecy or SHA-1 MAC are disabled by default. Security level 2 prohibits | | + | weak RSA, DH, and ECC keys with less than 112 bits of security. | | + | :class:`~ssl.SSLContext` defaults to minimum protocol version TLS 1.2. | | + | Settings are based on Hynek Schlawack's research. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | The deprecated protocols SSL 3.0, TLS 1.0, and TLS 1.1 are no longer | | + | officially supported. Python does not block them actively. However | | + | OpenSSL build options, distro configurations, vendor patches, and cipher | | + | suites may prevent a successful handshake. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add a *timeout* parameter to the :func:`ssl.get_server_certificate` function. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | The ssl module uses heap-types and multi-phase initialization. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | A new verify flag :data:`~ssl.VERIFY_X509_PARTIAL_CHAIN` has been added. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | `sys `_ | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add :data:`sys.orig_argv` attribute: the list of the original command line | | + | arguments passed to the Python executable. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | Add :data:`sys.stdlib_module_names`, containing the list of the standard library | | + | module names. | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | `_thread `_ | + +---------------------------------------------------------------------------------------------------------------+---------------+ + | :func:`_thread.interrupt_main` now takes an optional signal number to | | + | simulate (the default is still :data:`signal.SIGINT`). | | + +---------------------------------------------------------------------------------------------------------------+---------------+ + +.. rubric:: Notes + +.. [#spm] The structural pattern matching feature is discussed in `issue #7847 `_. + diff --git a/docs/differences/python_35.rst b/docs/differences/python_35.rst index 94b10b5837374..0fdc6121a1dd0 100644 --- a/docs/differences/python_35.rst +++ b/docs/differences/python_35.rst @@ -5,55 +5,60 @@ Python 3.5 Below is a list of finalised/accepted PEPs for Python 3.5 grouped into their impact to MicroPython. - +----------------------------------------------------------------------------------------------------------+---------------+ - | **Extensions to the syntax:** | **Status** | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 448 `_ | additional unpacking generalizations | Partial | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 465 `_ | a new matrix multiplication operator | Completed | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 492 `_ | coroutines with async and await syntax | Completed | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | **Extensions and changes to runtime:** | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 461 `_ | % formatting for binary strings | Completed | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 475 `_ | retrying system calls that fail with EINTR | Completed | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 479 `_ | change StopIteration handling inside generators | Completed | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | **Standard library changes:** | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 471 `_ | os.scandir() | | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 485 `_ | math.isclose(), a function for testing | Completed | - | | approximate equality | | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | **Miscellaneous changes:** | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 441 `_ | improved Python zip application support | | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 486 `_ | make the Python Launcher aware of virtual | Not relevant | - | | environments | | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 484 `_ | type hints (advisory only) | In Progress | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 488 `_ | elimination of PYO files | Not relevant | - +--------------------------------------------------------+-------------------------------------------------+---------------+ - | `PEP 489 `_ | redesigning extension module loading | | - +--------------------------------------------------------+-------------------------------------------------+---------------+ +.. table:: + :widths: 30 50 20 + +--------------------------------------------------------------------------------------------------------------+--------------------+ + | **Extensions to the syntax** | **Status** | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 448 `_ | Additional unpacking generalizations | Partial | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 465 `_ | A new matrix multiplication operator | Complete | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 492 `_ | Coroutines with ``async`` and ``await`` syntax | Complete | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | **Extensions and changes to runtime** | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 461 `_ | % formatting for binary strings | Complete | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 475 `_ | Retrying system calls that fail with ``EINTR`` | Complete | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 479 `_ | Change ``StopIteration`` handling inside generators | Complete | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | **Standard library changes** | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 471 `_ | ``os.scandir()`` | | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 485 `_ | ``math.isclose()``, a function for testing | Complete | + | | approximate equality | | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | **Miscellaneous changes** | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 441 `_ | Improved Python zip application support | | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 486 `_ | Make the Python Launcher aware of virtual | Not relevant | + | | environments | | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 484 `_ | Type hints (advisory only) | Complete [#fth]_ | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 488 `_ | Elimination of PYO files | Not relevant | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ + | `PEP 489 `_ | Redesigning extension module loading | | + +--------------------------------------------------------+-----------------------------------------------------+--------------------+ Other Language Changes: - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Added the *namereplace* error handlers. The *backslashreplace* error handlers now work with decoding and | | - | translating. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Property docstrings are now writable. This is especially useful for collections.namedtuple() docstrings | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Circular imports involving relative imports are now supported. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ +.. table:: + :widths: 90 10 + + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Added the *namereplace* error handlers. The *backslashreplace* error handlers now work with decoding and | | + | translating. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Property docstrings are now writable. This is especially useful for collections.namedtuple() docstrings | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Circular imports involving relative imports are now supported. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ New Modules: @@ -65,117 +70,124 @@ New Modules: Changes to built-in modules: - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `collections `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *OrderedDict* class is now implemented in C, which makes it 4 to 100 times faster. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | *OrderedDict.items()* , *OrderedDict.keys()* , *OrderedDict.values()* views now support reversed() | | - | iteration. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The deque class now defines *index()*, *insert()*, and *copy()*, and supports the + and * operators. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Docstrings produced by namedtuple() can now be updated. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The UserString class now implements the *__getnewargs__()*, *__rmod__()*, *casefold()*, *format_map()*, | | - | *isprintable()*, and *maketrans()* methods to match the corresponding methods of str. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `heapq `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Element comparison in *merge()* can now be customized by passing a key function in a new optional key | | - | keyword argument, and a new optional *reverse* keyword argument can be used to reverse element comparison | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `io `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new *BufferedIOBase.readinto1()* method, that uses at most one call to the underlying raw stream's | | - | *RawIOBase.read()* or *RawIOBase.readinto()* methods | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `json `_ | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | JSON decoder now raises JSONDecodeError instead of ValueError to provide better context information about | | - | the error. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `math `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Two new constants have been added to the math module: *inf* and *nan*. | Completed | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new function *isclose()* provides a way to test for approximate equality. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new *gcd()* function has been added. The *fractions.gcd()* function is now deprecated. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `os `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The new *scandir()* function returning an iterator of DirEntry objects has been added. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *urandom()* function now uses the *getrandom()* syscall on Linux 3.17 or newer, and *getentropy()* on | | - | OpenBSD 5.6 and newer, removing the need to use /dev/urandom and avoiding failures due to potential file | | - | descriptor exhaustion. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | New *get_blocking()* and *set_blocking()* functions allow getting and setting a file descriptor's blocking| | - | mode (O_NONBLOCK.) | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | There is a new *os.path.commonpath()* function returning the longest common sub-path of each passed | | - | pathname | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `re `_ | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | References and conditional references to groups with fixed length are now allowed in lookbehind assertions| | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The number of capturing groups in regular expressions is no longer limited to 100. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *sub()* and *subn()* functions now replace unmatched groups with empty strings instead of raising an | | - | exception. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *re.error* exceptions have new attributes, msg, pattern, pos, lineno, and colno, that provide better | | - | context information about the error | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `socket `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Functions with timeouts now use a monotonic clock, instead of a system clock. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new *socket.sendfile()* method allows sending a file over a socket by using the high-performance | | - | *os.sendfile()* function on UNIX, resulting in uploads being from 2 to 3 times faster than when using | | - | plain *socket.send()* | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *socket.sendall()* method no longer resets the socket timeout every time bytes are received or sent. | | - | The socket timeout is now the maximum total duration to send all data. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The backlog argument of the *socket.listen()* method is now optional. By default it is set to SOMAXCONN or| Completed | - | to 128, whichever is less. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `ssl `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Memory BIO Support | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | Application-Layer Protocol Negotiation Support | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | There is a new *SSLSocket.version()* method to query the actual protocol version in use. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The SSLSocket class now implements a *SSLSocket.sendfile()* method. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *SSLSocket.send()* method now raises either the *ssl.SSLWantReadError* or *ssl.SSLWantWriteError* | | - | exception on a non-blocking socket if the operation would block. Previously, it would return 0. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *cert_time_to_seconds()* function now interprets the input time as UTC and not as local time, per RFC | | - | 5280. Additionally, the return value is always an int. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | New *SSLObject.shared_ciphers()* and *SSLSocket.shared_ciphers()* methods return the list of ciphers sent | | - | by the client during the handshake. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *SSLSocket.do_handshake()*, *SSLSocket.read()*, *SSLSocket.shutdown()*, and *SSLSocket.write()* | | - | methods of the SSLSocket class no longer reset the socket timeout every time bytes are received or sent. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *match_hostname()* function now supports matching of IP addresses. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `sys `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new *set_coroutine_wrapper()* function allows setting a global hook that will be called whenever a | | - | coroutine object is created by an async def function. A corresponding *get_coroutine_wrapper()* can be | | - | used to obtain a currently set wrapper. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | A new *is_finalizing()* function can be used to check if the Python interpreter is shutting down. | | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | `time `_ | - +-----------------------------------------------------------------------------------------------------------+---------------+ - | The *monotonic()* function is now always available | | - +-----------------------------------------------------------------------------------------------------------+---------------+ +.. table:: + :widths: 90 10 + + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `collections `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *OrderedDict* class is now implemented in C, which makes it 4 to 100 times faster. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | *OrderedDict.items()* , *OrderedDict.keys()* , *OrderedDict.values()* views now support reversed() | | + | iteration. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The deque class now defines *index()*, *insert()*, and *copy()*, and supports the + and * operators. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Docstrings produced by namedtuple() can now be updated. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The UserString class now implements the *__getnewargs__()*, *__rmod__()*, *casefold()*, *format_map()*, | | + | *isprintable()*, and *maketrans()* methods to match the corresponding methods of str. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `heapq `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Element comparison in *merge()* can now be customized by passing a key function in a new optional key | | + | keyword argument, and a new optional *reverse* keyword argument can be used to reverse element comparison | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `io `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new *BufferedIOBase.readinto1()* method, that uses at most one call to the underlying raw stream's | | + | *RawIOBase.read()* or *RawIOBase.readinto()* methods | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `json `_ | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | JSON decoder now raises JSONDecodeError instead of ValueError to provide better context information about | | + | the error. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `math `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Two new constants have been added to the math module: *inf* and *nan*. | Complete | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new function *isclose()* provides a way to test for approximate equality. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new *gcd()* function has been added. The *fractions.gcd()* function is now deprecated. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `os `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The new *scandir()* function returning an iterator of DirEntry objects has been added. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *urandom()* function now uses the *getrandom()* syscall on Linux 3.17 or newer, and *getentropy()* on | | + | OpenBSD 5.6 and newer, removing the need to use /dev/urandom and avoiding failures due to potential file | | + | descriptor exhaustion. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | New *get_blocking()* and *set_blocking()* functions allow getting and setting a file descriptor's blocking| | + | mode (O_NONBLOCK.) | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | There is a new *os.path.commonpath()* function returning the longest common sub-path of each passed | | + | pathname | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `re `_ | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | References and conditional references to groups with fixed length are now allowed in lookbehind assertions| | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The number of capturing groups in regular expressions is no longer limited to 100. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *sub()* and *subn()* functions now replace unmatched groups with empty strings instead of raising an | | + | exception. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *re.error* exceptions have new attributes, msg, pattern, pos, lineno, and colno, that provide better | | + | context information about the error | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `socket `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Functions with timeouts now use a monotonic clock, instead of a system clock. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new *socket.sendfile()* method allows sending a file over a socket by using the high-performance | | + | *os.sendfile()* function on UNIX, resulting in uploads being from 2 to 3 times faster than when using | | + | plain *socket.send()* | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *socket.sendall()* method no longer resets the socket timeout every time bytes are received or sent. | | + | The socket timeout is now the maximum total duration to send all data. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The backlog argument of the *socket.listen()* method is now optional. By default it is set to SOMAXCONN or| Complete | + | to 128, whichever is less. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `ssl `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Memory BIO Support | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | Application-Layer Protocol Negotiation Support | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | There is a new *SSLSocket.version()* method to query the actual protocol version in use. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The SSLSocket class now implements a *SSLSocket.sendfile()* method. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *SSLSocket.send()* method now raises either the *ssl.SSLWantReadError* or *ssl.SSLWantWriteError* | | + | exception on a non-blocking socket if the operation would block. Previously, it would return 0. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *cert_time_to_seconds()* function now interprets the input time as UTC and not as local time, per RFC | | + | 5280. Additionally, the return value is always an int. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | New *SSLObject.shared_ciphers()* and *SSLSocket.shared_ciphers()* methods return the list of ciphers sent | | + | by the client during the handshake. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *SSLSocket.do_handshake()*, *SSLSocket.read()*, *SSLSocket.shutdown()*, and *SSLSocket.write()* | | + | methods of the SSLSocket class no longer reset the socket timeout every time bytes are received or sent. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *match_hostname()* function now supports matching of IP addresses. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `sys `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new *set_coroutine_wrapper()* function allows setting a global hook that will be called whenever a | | + | coroutine object is created by an async def function. A corresponding *get_coroutine_wrapper()* can be | | + | used to obtain a currently set wrapper. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | A new *is_finalizing()* function can be used to check if the Python interpreter is shutting down. | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | `time `_ | + +-----------------------------------------------------------------------------------------------------------+---------------+ + | The *monotonic()* function is now always available | | + +-----------------------------------------------------------------------------------------------------------+---------------+ + +.. rubric:: Notes + +.. [#fth] The MicroPython parser correct ignores all type hints. However, the ``typing`` module is not built-in. diff --git a/docs/differences/python_36.rst b/docs/differences/python_36.rst index edf6bef02300a..3315b0594dafc 100644 --- a/docs/differences/python_36.rst +++ b/docs/differences/python_36.rst @@ -5,53 +5,59 @@ Python 3.6 Python 3.6 beta 1 was released on 12 Sep 2016, and a summary of the new features can be found here: - +-----------------------------------------------------------------------------------------------------------+--------------+ - | **New Syntax Features:** | **Status** | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 498 `_ | Literal String Formatting | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 515 `_ | Underscores in Numeric Literals | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 525 `_ | Asynchronous Generators | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 526 `_ | Syntax for Variable Annotations (provisional) | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 530 `_ | Asynchronous Comprehensions | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | **New Built-in Features:** | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 468 `_ | Preserving the order of *kwargs* in a function | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 487 `_ | Simpler customization of class creation | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 520 `_ | Preserving Class Attribute Definition Order | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | **Standard Library Changes:** | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 495 `_ | Local Time Disambiguation | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 506 `_ | Adding A Secrets Module To The Standard Library | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 519 `_ | Adding a file system path protocol | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | **CPython internals:** | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 509 `_ | Add a private version to dict | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 523 `_ | Adding a frame evaluation API to CPython | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | **Linux/Window Changes** | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 524 `_ | Make os.urandom() blocking on Linux | | - | | (during system startup) | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 528 `_ | Change Windows console encoding to UTF-8 | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ - | `PEP 529 `_ | Change Windows filesystem encoding to UTF-8 | | - +--------------------------------------------------------+--------------------------------------------------+--------------+ +.. table:: + :widths: 30 50 20 + + +-----------------------------------------------------------------------------------------------------------+-----------------+ + | **New Syntax Features** | **Status** | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 498 `_ | Literal String Formatting | Complete | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 515 `_ | Underscores in Numeric Literals | Complete | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 525 `_ | Asynchronous Generators | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 526 `_ | Syntax for Variable Annotations (provisional) | Complete | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 530 `_ | Asynchronous Comprehensions | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | **New Built-in Features** | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 468 `_ | Preserving the order of *kwargs* in a function | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 487 `_ | Simpler customization of class creation | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 520 `_ | Preserving Class Attribute Definition Order | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | **Standard Library Changes** | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 495 `_ | Local Time Disambiguation | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 506 `_ | Adding A Secrets Module To The Standard Library | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 519 `_ | Adding a file system path protocol | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | **CPython Internals** | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 509 `_ | Add a private version to dict | Won't do | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 523 `_ | Adding a frame evaluation API to CPython | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | **Linux/Window Changes** | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 524 `_ | Make ``os.urandom()`` blocking on Linux | | + | | (during system startup) | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 528 `_ | Change Windows console encoding to UTF-8 | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ + | `PEP 529 `_ | Change Windows filesystem encoding to UTF-8 | | + +--------------------------------------------------------+--------------------------------------------------+-----------------+ Other Language Changes: +.. table:: + :widths: 90 10 + +-------------------------------------------------------------------------------------------------------------+---------------+ | A *global* or *nonlocal* statement must now textually appear before the first use of the affected name in | | | the same scope. Previously this was a SyntaxWarning. | | @@ -71,6 +77,9 @@ Other Language Changes: Changes to built-in modules: +.. table:: + :widths: 90 10 + +--------------------------------------------------------------------------------------------------------------+----------------+ | `array `_ | | +--------------------------------------------------------------------------------------------------------------+----------------+ @@ -78,7 +87,7 @@ Changes to built-in modules: +--------------------------------------------------------------------------------------------------------------+----------------+ | `binascii `_ | | +--------------------------------------------------------------------------------------------------------------+----------------+ - | The b2a_base64() function now accepts an optional newline keyword argument to control whether the newline | Completed | + | The b2a_base64() function now accepts an optional newline keyword argument to control whether the newline | Complete | | character is appended to the return value | | +--------------------------------------------------------------------------------------------------------------+----------------+ | `cmath `_ | | @@ -121,7 +130,7 @@ Changes to built-in modules: +--------------------------------------------------------------------------------------------------------------+----------------+ | `math `_ | +--------------------------------------------------------------------------------------------------------------+----------------+ - | The new math.tau (τ) constant has been added | Completed | + | The new math.tau (τ) constant has been added | Complete | +--------------------------------------------------------------------------------------------------------------+----------------+ | `os `_ | +--------------------------------------------------------------------------------------------------------------+----------------+ @@ -136,7 +145,7 @@ Changes to built-in modules: | `re `_ | +--------------------------------------------------------------------------------------------------------------+----------------+ | Added support of modifier spans in regular expressions. Examples: *'(?i:p)ython'* matches 'python' and | | - | 'Python', but not 'PYTHON'; *'(?i)g(?-i:v)r'* matches *'GvR'* and *'gvr'*, but not *'GVR'* . | | + | 'Python', but not 'PYTHON'; *'(?i)g(?-i:v)r'* matches *'GvR'* and *'gvr'*, but not *'GVR'*. | | +--------------------------------------------------------------------------------------------------------------+----------------+ | Match object groups can be accessed by *__getitem__*, which is equivalent to *group()*. So *mo['name']* is | | | now equivalent to *mo.group('name')*. | | diff --git a/docs/differences/python_37.rst b/docs/differences/python_37.rst index c46678e931dd1..86d1b6e81f96d 100644 --- a/docs/differences/python_37.rst +++ b/docs/differences/python_37.rst @@ -5,72 +5,81 @@ Python 3.7 New Features: - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | **Features:** | **Status** | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 538 `_ | Coercing the legacy C locale to a UTF-8 based | | - | | locale | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 539 `_ | A New C-API for Thread-Local Storage in CPython | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 540 `_ | UTF-8 mode | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 552 `_ | Deterministic pyc | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 553 `_ | Built-in breakpoint() | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 557 `_ | Data Classes | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 560 `_ | Core support for typing module and generic types | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 562 `_ | Module __getattr__ and __dir__ | Partially done | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 563 `_ | Postponed Evaluation of Annotations | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 564 `_ | Time functions with nanosecond resolution | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 565 `_ | Show DeprecationWarning in __main__ | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ - | `PEP 567 `_ | Context Variables | | - +--------------------------------------------------------+--------------------------------------------------+----------------+ +.. table:: + :widths: 20 60 20 + + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | **Feature** | **Status** | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 538 `_ | Coercing the legacy C locale to a UTF-8 based | | + | | locale | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 539 `_ | A New C-API for Thread-Local Storage in CPython | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 540 `_ | UTF-8 mode | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 552 `_ | Deterministic pyc | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 553 `_ | Built-in ``breakpoint()`` | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 557 `_ | Data Classes | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 560 `_ | Core support for typing module and generic types | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 562 `_ | Module ``__getattr__`` and ``__dir__`` | Partial | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 563 `_ | Postponed Evaluation of Annotations | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 564 `_ | Time functions with nanosecond resolution | Partial [#ftimenanosec]_ | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 565 `_ | Show DeprecationWarning in ``__main__`` | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ + | `PEP 567 `_ | Context Variables | | + +--------------------------------------------------------+--------------------------------------------------+--------------------------------------+ Other Language Changes: - +----------------------------------------------------------------------------------------------------------+----------------+ - | async and await are now reserved keywords | Completed | - +----------------------------------------------------------------------------------------------------------+----------------+ - | dict objects must preserve insertion-order | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | More than 255 arguments can now be passed to a function; a function can now have more than 255 parameters| | - +----------------------------------------------------------------------------------------------------------+----------------+ - | bytes.fromhex() and bytearray.fromhex() now ignore all ASCII whitespace, not only spaces | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | str, bytes, and bytearray gained support for the new isascii() method, which can be used to test if a | | - | string or bytes contain only the ASCII characters | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | ImportError now displays module name and module __file__ path whenfrom ... import ... fails | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | Circular imports involving absolute imports with binding a submodule to a name are now supported | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | object.__format__(x, '') is now equivalent to str(x) rather than format(str(self), '') | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | In order to better support dynamic creation of stack traces, types.TracebackType can now be instantiated | | - | from Python code, and the tb_next attribute on tracebacks is now writable | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | When using the -m switch, sys.path[0] is now eagerly expanded to the full starting directory path, rather| | - | than being left as the empty directory (which allows imports from the current working directory at the | | - | time when an import occurs) | | - +----------------------------------------------------------------------------------------------------------+----------------+ - | The new -X importtime option or the PYTHONPROFILEIMPORTTIME environment variable can be used to show the | | - | timing of each module import | | - +----------------------------------------------------------------------------------------------------------+----------------+ +.. table:: + :widths: 90 10 + + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``async`` and ``await`` are now reserved keywords | Complete | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``dict`` objects must preserve insertion-order | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | More than 255 arguments can now be passed to a function; a function can now have more than 255 parameters | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``bytes.fromhex()`` and ``bytearray.fromhex()`` now ignore all ASCII whitespace, not only spaces | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``str``, ``bytes``, and ``bytearray`` gained support for the new ``isascii()`` method, which can be used to | | + | test if a string or bytes contain only the ASCII characters | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``ImportError`` now displays module name and module ``__file__`` path when ``from ... import ...`` fails | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | Circular imports involving absolute imports with binding a submodule to a name are now supported | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | ``object.__format__(x, '')`` is now equivalent to ``str(x)`` rather than ``format(str(self), '')`` | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | In order to better support dynamic creation of stack traces, ``types.TracebackType`` can now be | | + | instantiated from Python code, and the ``tb_next`` attribute on tracebacks is now writable | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | When using the ``-m`` switch, ``sys.path[0]`` is now eagerly expanded to the full starting directory path, | | + | rather than being left as the empty directory (which allows imports from the current working directory | | + | at the time when an import occurs) | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ + | The new ``-X importtime`` option or the ``PYTHONPROFILEIMPORTTIME`` environment variable can be used to | | + | show the timing of each module import | | + +-----------------------------------------------------------------------------------------------------------------+----------------+ Changes to built-in modules: +.. table:: + :widths: 90 10 + +------------------------------------------------------------------------------------------------------------+----------------+ | `asyncio `_ | | +------------------------------------------------------------------------------------------------------------+----------------+ - | asyncio (many, may need a separate ticket) | | + | Too many to list | | +------------------------------------------------------------------------------------------------------------+----------------+ | `gc `_ | | +------------------------------------------------------------------------------------------------------------+----------------+ @@ -93,3 +102,7 @@ Changes to built-in modules: +------------------------------------------------------------------------------------------------------------+----------------+ | Mostly updates to support nanosecond resolution in PEP564, see above | | +------------------------------------------------------------------------------------------------------------+----------------+ + +.. rubric:: Notes + +.. [#ftimenanosec] Only :func:`time.time_ns` is implemented. diff --git a/docs/differences/python_38.rst b/docs/differences/python_38.rst index 47840a8b40ec3..32fd68d2caeac 100644 --- a/docs/differences/python_38.rst +++ b/docs/differences/python_38.rst @@ -5,15 +5,18 @@ Python 3.8 Python 3.8.0 (final) was released on the 14 October 2019. The Features for 3.8 are defined in `PEP 569 `_ and -a detailed description of the changes can be found in What's New in `Python +a detailed description of the changes can be found in `What's New in Python 3.8. `_ +.. table:: + :widths: 20 60 20 + +--------------------------------------------------------+---------------------------------------------------+---------------+ - | **Features:** | Status | + | **Features** | **Status** | +--------------------------------------------------------+---------------------------------------------------+---------------+ | `PEP 570 `_ | Positional-only arguments | | +--------------------------------------------------------+---------------------------------------------------+---------------+ - | `PEP 572 `_ | Assignment Expressions | | + | `PEP 572 `_ | Assignment Expressions | Complete | +--------------------------------------------------------+---------------------------------------------------+---------------+ | `PEP 574 `_ | Pickle protocol 5 with out-of-band data | | +--------------------------------------------------------+---------------------------------------------------+---------------+ @@ -25,13 +28,16 @@ a detailed description of the changes can be found in What's New in `Python +--------------------------------------------------------+---------------------------------------------------+---------------+ | **Miscellaneous** | +------------------------------------------------------------------------------------------------------------+---------------+ - | f-strings support = for self-documenting expressions and debugging | Completed | + | f-strings support = for self-documenting expressions and debugging | Complete | +------------------------------------------------------------------------------------------------------------+---------------+ Other Language Changes: +.. table:: + :widths: 90 10 + +------------------------------------------------------------------------------------------------------------+-------------+ - | A *continue* statement was illegal in the *finally* clause due to a problem with the implementation. In | Completed | + | A *continue* statement was illegal in the *finally* clause due to a problem with the implementation. In | Complete | | Python 3.8 this restriction was lifted | | +------------------------------------------------------------------------------------------------------------+-------------+ | The *bool*, *int* , and *fractions.Fraction* types now have an *as_integer_ratio()* method like that found | | @@ -72,14 +78,17 @@ Other Language Changes: Changes to built-in modules: +.. table:: + :widths: 90 10 + +------------------------------------------------------------------------------------------------------------+-------------+ - | `asyncio` | + | `asyncio `_ | +------------------------------------------------------------------------------------------------------------+-------------+ - | *asyncio.run()* has graduated from the provisional to stable API | Completed | + | *asyncio.run()* has graduated from the provisional to stable API | Complete | +------------------------------------------------------------------------------------------------------------+-------------+ | Running *python -m asyncio* launches a natively async REPL | | +------------------------------------------------------------------------------------------------------------+-------------+ - | The exception *asyncio.CancelledError* now inherits from *BaseException* rather than *Exception* and no | Completed | + | The exception *asyncio.CancelledError* now inherits from *BaseException* rather than *Exception* and no | Complete | | longer inherits from *concurrent.futures.CancelledError* | | +------------------------------------------------------------------------------------------------------------+-------------+ | Added *asyncio.Task.get_coro()* for getting the wrapped coroutine within an *asyncio.Task* | | @@ -90,12 +99,12 @@ Changes to built-in modules: | Added support for Happy Eyeballs to *asyncio.loop.create_connection()*. To specify the behavior, two new | | | parameters have been added: *happy_eyeballs_delay* and interleave. | | +------------------------------------------------------------------------------------------------------------+-------------+ - | `gc` | + | `gc `_ | +------------------------------------------------------------------------------------------------------------+-------------+ | *get_objects()* can now receive an optional generation parameter indicating a generation to get objects | | | from. (Note, though, that while *gc* is a built-in, *get_objects()* is not implemented for MicroPython) | | +------------------------------------------------------------------------------------------------------------+-------------+ - | `math` | + | `math `_ | +------------------------------------------------------------------------------------------------------------+-------------+ | Added new function *math.dist()* for computing Euclidean distance between two points | | +------------------------------------------------------------------------------------------------------------+-------------+ @@ -109,9 +118,9 @@ Changes to built-in modules: | Added a new function *math.isqrt()* for computing accurate integer square roots without conversion to | | | floating point | | +------------------------------------------------------------------------------------------------------------+-------------+ - | The function *math.factorial()* no longer accepts arguments that are not int-like | Completed | + | The function *math.factorial()* no longer accepts arguments that are not int-like | Complete | +------------------------------------------------------------------------------------------------------------+-------------+ - | `sys` | + | `sys `_ | +------------------------------------------------------------------------------------------------------------+-------------+ | Add new *sys.unraisablehook()* function which can be overridden to control how "unraisable exceptions" | | | are handled | | diff --git a/docs/differences/python_39.rst b/docs/differences/python_39.rst index 6852dd635ea82..f68abc50740ac 100644 --- a/docs/differences/python_39.rst +++ b/docs/differences/python_39.rst @@ -8,35 +8,41 @@ defined in `PEP 596 and a detailed description of the changes can be found in `What's New in Python 3.9 `_ - +--------------------------------------------------------+----------------------------------------------------+--------------+ - | **Features:** | | **Status** | - +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 573 `_ | fast access to module state from methods of C | | - | | extension types | | - +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 584 `_ | union operators added to dict | | - +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 585 `_ | type hinting generics in standard collections | | - +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 593 `_ | flexible function and variable annotations | | - +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 602 `_ | CPython adopts an annual release cycle. Instead of | | - | | annual, aiming for two month release cycle | | - +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 614 `_ | relaxed grammar restrictions on decorators | | - +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 615 `_ | the IANA Time Zone Database is now present in the | | - | | standard library in the zoneinfo module | | - +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 616 `_ | string methods to remove prefixes and suffixes | | - +--------------------------------------------------------+----------------------------------------------------+--------------+ - | `PEP 617 `_ | CPython now uses a new parser based on PEG | | - +--------------------------------------------------------+----------------------------------------------------+--------------+ +.. table:: + :widths: 20 60 20 + + +--------------------------------------------------------+----------------------------------------------------+----------------------+ + | **Features** | | **Status** | + +--------------------------------------------------------+----------------------------------------------------+----------------------+ + | `PEP 573 `_ | Fast access to module state from methods of C | Not relevant | + | | extension types | | + +--------------------------------------------------------+----------------------------------------------------+----------------------+ + | `PEP 584 `_ | Union operators added to dict | Complete [#pep584]_ | + +--------------------------------------------------------+----------------------------------------------------+----------------------+ + | `PEP 585 `_ | Type hinting generics in standard collections | | + +--------------------------------------------------------+----------------------------------------------------+----------------------+ + | `PEP 593 `_ | Flexible function and variable annotations | | + +--------------------------------------------------------+----------------------------------------------------+----------------------+ + | `PEP 602 `_ | CPython adopts an annual release cycle. Instead of | Not relevant | + | | annual, aiming for two month release cycle | | + +--------------------------------------------------------+----------------------------------------------------+----------------------+ + | `PEP 614 `_ | Relaxed grammar restrictions on decorators | | + +--------------------------------------------------------+----------------------------------------------------+----------------------+ + | `PEP 615 `_ | The IANA Time Zone Database is now present in the | | + | | standard library in the zoneinfo module | | + +--------------------------------------------------------+----------------------------------------------------+----------------------+ + | `PEP 616 `_ | String methods to remove prefixes and suffixes | | + +--------------------------------------------------------+----------------------------------------------------+----------------------+ + | `PEP 617 `_ | CPython now uses a new parser based on PEG | Not relevant | + +--------------------------------------------------------+----------------------------------------------------+----------------------+ Other Language Changes: +.. table:: + :widths: 90 10 + +-------------------------------------------------------------------------------------------------------------+---------------+ - | *__import__()* now raises *ImportError* instead of *ValueError* | Completed | + | *__import__()* now raises *ImportError* instead of *ValueError* | Complete | +-------------------------------------------------------------------------------------------------------------+---------------+ | Python now gets the absolute path of the script filename specified on the command line (ex: *python3* | | | *script.py*): the *__file__* attribute of the *__main__* module became an absolute path, rather than a | | @@ -62,8 +68,11 @@ Other Language Changes: Changes to built-in modules: +.. table:: + :widths: 90 10 + +---------------------------------------------------------------------------------------------------------------+---------------+ - | `asyncio` | + | `asyncio `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Due to significant security concerns, the reuse_address parameter of *asyncio.loop.create_datagram_endpoint()*| | | is no longer supported | | @@ -82,13 +91,13 @@ Changes to built-in modules: +---------------------------------------------------------------------------------------------------------------+---------------+ | *asyncio* now raises *TyperError* when calling incompatible methods with an *ssl.SSLSocket* socket | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | `gc` | + | `gc `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Garbage collection does not block on resurrected objects | | +---------------------------------------------------------------------------------------------------------------+---------------+ | Added a new function *gc.is_finalized()* to check if an object has been finalized by the garbage collector | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | `math` | + | `math `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Expanded the *math.gcd()* function to handle multiple arguments. Formerly, it only supported two arguments | | +---------------------------------------------------------------------------------------------------------------+---------------+ @@ -98,24 +107,28 @@ Changes to built-in modules: +---------------------------------------------------------------------------------------------------------------+---------------+ | Added *math.ulp()*: return the value of the least significant bit of a float | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | `os` | + | `os `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Exposed the Linux-specific *os.pidfd_open()* and *os.P_PIDFD* | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | The *os.unsetenv()* function is now also available on Windows | Completed | + | The *os.unsetenv()* function is now also available on Windows | Complete | +---------------------------------------------------------------------------------------------------------------+---------------+ - | The *os.putenv()* and *os.unsetenv()* functions are now always available | Completed | + | The *os.putenv()* and *os.unsetenv()* functions are now always available | Complete | +---------------------------------------------------------------------------------------------------------------+---------------+ | Added *os.waitstatus_to_exitcode()* function: convert a wait status to an exit code | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | `random` | + | `random `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Added a new *random.Random.randbytes* method: generate random bytes | | +---------------------------------------------------------------------------------------------------------------+---------------+ - | `sys` | + | `sys `_ | +---------------------------------------------------------------------------------------------------------------+---------------+ | Added a new *sys.platlibdir* attribute: name of the platform-specific library directory | | +---------------------------------------------------------------------------------------------------------------+---------------+ | Previously, *sys.stderr* was block-buffered when non-interactive. Now stderr defaults to always being | | | line-buffered | | +---------------------------------------------------------------------------------------------------------------+---------------+ + +.. rubric:: Notes + +.. [#pep584] PEP 584 ``dict`` union operator is only available on MicroPython builds with ``MICROPY_CPYTHON_COMPAT`` enabled. diff --git a/docs/esp32/quickref.rst b/docs/esp32/quickref.rst index 3cbb673c04b52..5be737fa2d763 100644 --- a/docs/esp32/quickref.rst +++ b/docs/esp32/quickref.rst @@ -57,7 +57,6 @@ The :mod:`esp32` module:: import esp32 - esp32.hall_sensor() # read the internal hall sensor esp32.raw_temperature() # read the internal temperature of the MCU, in Fahrenheit esp32.ULP() # access to the Ultra-Low-Power Co-processor @@ -68,6 +67,9 @@ by reading the temperature sensor immediately after waking up from sleep. Networking ---------- +WLAN +^^^^ + The :mod:`network` module:: import network @@ -110,6 +112,55 @@ calling ``wlan.config(reconnects=n)``, where n are the number of desired reconne attempts (0 means it won't retry, -1 will restore the default behaviour of trying to reconnect forever). +LAN +^^^ + +To use the wired interfaces one has to specify the pins and mode :: + + import network + + lan = network.LAN(mdc=PIN_MDC, ...) # Set the pin and mode configuration + lan.active(True) # activate the interface + lan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses + + +The keyword arguments for the constructor defining the PHY type and interface are: + +- mdc=pin-object # set the mdc and mdio pins. +- mdio=pin-object +- power=pin-object # set the pin which switches the power of the PHY device. +- phy_type= # Select the PHY device type. Supported devices are PHY_LAN8710, + PHY_LAN8720, PH_IP101, PHY_RTL8201, PHY_DP83848 and PHY_KSZ8041 +- phy_addr=number # The address number of the PHY device. +- ref_clk_mode=mode # Defines, whether the ref_clk at the ESP32 is an input + or output. Suitable values are Pin.IN and Pin.OUT. +- ref_clk=pin-object # defines the Pin used for ref_clk. + +These are working configurations for LAN interfaces of popular boards:: + + # Olimex ESP32-GATEWAY: power controlled by Pin(5) + # Olimex ESP32 PoE and ESP32-PoE ISO: power controlled by Pin(12) + + lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), power=machine.Pin(5), + phy_type=network.PHY_LAN8720, phy_addr=0, + ref_clk=machine.Pin(17), ref_clk_mode=machine.Pin.OUT) + + # Wireless-Tag's WT32-ETH01 + + lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), + phy_type=network.PHY_LAN8720, phy_addr=1, power=None) + + # Wireless-Tag's WT32-ETH01 v1.4 + + lan = network.LAN(mdc=machine.Pin(23), mdio=machine.Pin(18), + phy_type=network.PHY_LAN8720, phy_addr=1, + power=machine.Pin(16)) + + # Espressif ESP32-Ethernet-Kit_A_V1.2 + + lan = network.LAN(id=0, mdc=Pin(23), mdio=Pin(18), power=Pin(5), + phy_type=network.PHY_IP101, phy_addr=1) + Delay and timing ---------------- @@ -216,9 +267,10 @@ They each have default GPIO assigned to them, however depending on your ESP32 variant and board, these pins may conflict with embedded flash, onboard PSRAM or peripherals. -Any GPIO can be used for hardware UARTs using the GPIO matrix, so to avoid -conflicts simply provide ``tx`` and ``rx`` pins when constructing. The default -pins listed below. +Any GPIO can be used for hardware UARTs using the GPIO matrix, except for +input-only pins 34-39 that can be used as ``rx``. To avoid conflicts simply +provide ``tx`` and ``rx`` pins when constructing. The default pins listed +below. ===== ===== ===== ===== \ UART0 UART1 UART2 @@ -240,8 +292,8 @@ Use the :ref:`machine.PWM ` class:: from machine import Pin, PWM - pwm0 = PWM(Pin(0)) # create PWM object from a pin - freq = pwm0.freq() # get current frequency (default 5kHz) + pwm0 = PWM(Pin(0), freq=5000, duty_u16=32768) # create PWM object from a pin + freq = pwm0.freq() # get current frequency pwm0.freq(1000) # set PWM frequency from 1Hz to 40MHz duty = pwm0.duty() # get current duty cycle, range 0-1023 (default 512, 50%) @@ -589,7 +641,7 @@ See :ref:`machine.SDCard `. :: # Slot 2 uses pins sck=18, cs=5, miso=19, mosi=23 sd = machine.SDCard(slot=2) - os.mount(sd, "/sd") # mount + os.mount(sd, '/sd') # mount os.listdir('/sd') # list directory contents diff --git a/docs/esp32/tutorial/intro.rst b/docs/esp32/tutorial/intro.rst index 8ed42dbd3dc95..be09599871ce6 100644 --- a/docs/esp32/tutorial/intro.rst +++ b/docs/esp32/tutorial/intro.rst @@ -17,7 +17,7 @@ Requirements The first thing you need is a board with an ESP32 chip. The MicroPython software supports the ESP32 chip itself and any board should work. The main characteristic of a board is how the GPIO pins are connected to the outside -world, and whether it includes a built-in USB-serial convertor to make the +world, and whether it includes a built-in USB-serial converter to make the UART available to your PC. Names of pins will be given in this tutorial using the chip names (eg GPIO2) @@ -59,7 +59,7 @@ bootloader mode, and second you need to copy across the firmware. The exact procedure for these steps is highly dependent on the particular board and you will need to refer to its documentation for details. -Fortunately, most boards have a USB connector, a USB-serial convertor, and the DTR +Fortunately, most boards have a USB connector, a USB-serial converter, and the DTR and RTS pins wired in a special way then deploying the firmware should be easy as all steps can be done automatically. Boards that have such features include the Adafruit Feather HUZZAH32, M5Stack, Wemos LOLIN32, and TinyPICO @@ -104,7 +104,7 @@ Serial prompt Once you have the firmware on the device you can access the REPL (Python prompt) over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial -convertor, depending on your board. The baudrate is 115200. +converter, depending on your board. The baudrate is 115200. From here you can now follow the ESP8266 tutorial, because these two Espressif chips are very similar when it comes to using MicroPython on them. The ESP8266 tutorial @@ -124,7 +124,7 @@ after it, here are troubleshooting recommendations: * The flashing instructions above use flashing speed of 460800 baud, which is good compromise between speed and stability. However, depending on your - module/board, USB-UART convertor, cables, host OS, etc., the above baud + module/board, USB-UART converter, cables, host OS, etc., the above baud rate may be too high and lead to errors. Try a more common 115200 baud rate instead in such cases. diff --git a/docs/esp32/tutorial/pwm.rst b/docs/esp32/tutorial/pwm.rst index 12d10a86b9474..2650284d35f41 100644 --- a/docs/esp32/tutorial/pwm.rst +++ b/docs/esp32/tutorial/pwm.rst @@ -50,7 +50,7 @@ low all of the time. * Example of a smooth frequency change:: - from utime import sleep + from time import sleep from machine import Pin, PWM F_MIN = 500 @@ -75,7 +75,7 @@ low all of the time. * Example of a smooth duty change:: - from utime import sleep + from time import sleep from machine import Pin, PWM DUTY_MAX = 2**16 - 1 diff --git a/docs/esp8266/tutorial/intro.rst b/docs/esp8266/tutorial/intro.rst index ac46e68b5a5cc..0d4bc42e2daba 100644 --- a/docs/esp8266/tutorial/intro.rst +++ b/docs/esp8266/tutorial/intro.rst @@ -18,12 +18,12 @@ The first thing you need is a board with an ESP8266 chip. The MicroPython software supports the ESP8266 chip itself and any board should work. The main characteristic of a board is how much flash it has, how the GPIO pins are connected to the outside world, and whether it includes a built-in USB-serial -convertor to make the UART available to your PC. +converter to make the UART available to your PC. The minimum requirement for flash size is 1Mbyte. There is also a special build for boards with 512KB, but it is highly limited comparing to the normal build: there is no support for filesystem, and thus features which -depend on it won't work (WebREPL, upip, etc.). As such, 512KB build will +depend on it won't work (WebREPL, mip, etc.). As such, 512KB build will be more interesting for users who build from source and fine-tune parameters for their particular application. @@ -70,7 +70,7 @@ need to put your device in boot-loader mode, and second you need to copy across the firmware. The exact procedure for these steps is highly dependent on the particular board and you will need to refer to its documentation for details. -If you have a board that has a USB connector, a USB-serial convertor, and has +If you have a board that has a USB connector, a USB-serial converter, and has the DTR and RTS pins wired in a special way then deploying the firmware should be easy as all steps can be done automatically. Boards that have such features include the Adafruit Feather HUZZAH and NodeMCU boards. @@ -128,7 +128,7 @@ Serial prompt Once you have the firmware on the device you can access the REPL (Python prompt) over UART0 (GPIO1=TX, GPIO3=RX), which might be connected to a USB-serial -convertor, depending on your board. The baudrate is 115200. The next part of +converter, depending on your board. The baudrate is 115200. The next part of the tutorial will discuss the prompt in more detail. WiFi @@ -137,7 +137,7 @@ WiFi After a fresh install and boot the device configures itself as a WiFi access point (AP) that you can connect to. The ESSID is of the form MicroPython-xxxxxx where the x's are replaced with part of the MAC address of your device (so will -be the same everytime, and most likely different for all ESP8266 chips). The +be the same every time, and most likely different for all ESP8266 chips). The password for the WiFi is micropythoN (note the upper-case N). Its IP address will be 192.168.4.1 once you connect to its network. WiFi configuration will be discussed in more detail later in the tutorial. @@ -169,7 +169,7 @@ after it, here are troubleshooting recommendations: * The flashing instructions above use flashing speed of 460800 baud, which is good compromise between speed and stability. However, depending on your - module/board, USB-UART convertor, cables, host OS, etc., the above baud + module/board, USB-UART converter, cables, host OS, etc., the above baud rate may be too high and lead to errors. Try a more common 115200 baud rate instead in such cases. diff --git a/docs/esp8266/tutorial/repl.rst b/docs/esp8266/tutorial/repl.rst index 196541bd02cb6..bc0142aaef5f9 100644 --- a/docs/esp8266/tutorial/repl.rst +++ b/docs/esp8266/tutorial/repl.rst @@ -13,7 +13,7 @@ REPL over the serial port The REPL is always available on the UART0 serial peripheral, which is connected to the pins GPIO1 for TX and GPIO3 for RX. The baudrate of the REPL is 115200. -If your board has a USB-serial convertor on it then you should be able to access +If your board has a USB-serial converter on it then you should be able to access the REPL directly from your PC. Otherwise you will need to have a way of communicating with the UART. diff --git a/docs/index.rst b/docs/index.rst index 9a021b3906d46..64b83618da149 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -17,3 +17,4 @@ MicroPython documentation and references unix/quickref.rst zephyr/quickref.rst renesas-ra/quickref.rst + samd/quickref.rst diff --git a/docs/library/array.rst b/docs/library/array.rst index 88d6d2263ca6b..f417a7046e2ff 100644 --- a/docs/library/array.rst +++ b/docs/library/array.rst @@ -27,3 +27,55 @@ Classes Append new elements as contained in *iterable* to the end of array, growing it. + + .. method:: __getitem__(index) + + Indexed read of the array, called as ``a[index]`` (where ``a`` is an ``array``). + Returns a value if *index* is an ``int`` and an ``array`` if *index* is a slice. + Negative indices count from the end and ``IndexError`` is thrown if the index is + out of range. + + **Note:** ``__getitem__`` cannot be called directly (``a.__getitem__(index)`` fails) and + is not present in ``__dict__``, however ``a[index]`` does work. + + .. method:: __setitem__(index, value) + + Indexed write into the array, called as ``a[index] = value`` (where ``a`` is an ``array``). + ``value`` is a single value if *index* is an ``int`` and an ``array`` if *index* is a slice. + Negative indices count from the end and ``IndexError`` is thrown if the index is out of range. + + **Note:** ``__setitem__`` cannot be called directly (``a.__setitem__(index, value)`` fails) and + is not present in ``__dict__``, however ``a[index] = value`` does work. + + .. method:: __len__() + + Returns the number of items in the array, called as ``len(a)`` (where ``a`` is an ``array``). + + **Note:** ``__len__`` cannot be called directly (``a.__len__()`` fails) and the + method is not present in ``__dict__``, however ``len(a)`` does work. + + .. method:: __add__(other) + + Return a new ``array`` that is the concatenation of the array with *other*, called as + ``a + other`` (where ``a`` and *other* are both ``arrays``). + + **Note:** ``__add__`` cannot be called directly (``a.__add__(other)`` fails) and + is not present in ``__dict__``, however ``a + other`` does work. + + .. method:: __iadd__(other) + + Concatenates the array with *other* in-place, called as ``a += other`` (where ``a`` and *other* + are both ``arrays``). Equivalent to ``extend(other)``. + + **Note:** ``__iadd__`` cannot be called directly (``a.__iadd__(other)`` fails) and + is not present in ``__dict__``, however ``a += other`` does work. + + .. method:: __repr__() + + Returns the string representation of the array, called as ``str(a)`` or ``repr(a)``` + (where ``a`` is an ``array``). Returns the string ``"array(, [])"``, + where ```` is the type code letter for the array and ```` is a comma + separated list of the elements of the array. + + **Note:** ``__repr__`` cannot be called directly (``a.__repr__()`` fails) and + is not present in ``__dict__``, however ``str(a)`` and ``repr(a)`` both work. diff --git a/docs/library/asyncio.rst b/docs/library/asyncio.rst new file mode 100644 index 0000000000000..9a2c14e7e0152 --- /dev/null +++ b/docs/library/asyncio.rst @@ -0,0 +1,360 @@ +:mod:`asyncio` --- asynchronous I/O scheduler +============================================= + +.. module:: asyncio + :synopsis: asynchronous I/O scheduler for writing concurrent code + +|see_cpython_module| +`asyncio `_ + +Example:: + + import asyncio + + async def blink(led, period_ms): + while True: + led.on() + await asyncio.sleep_ms(5) + led.off() + await asyncio.sleep_ms(period_ms) + + async def main(led1, led2): + asyncio.create_task(blink(led1, 700)) + asyncio.create_task(blink(led2, 400)) + await asyncio.sleep_ms(10_000) + + # Running on a pyboard + from pyb import LED + asyncio.run(main(LED(1), LED(2))) + + # Running on a generic board + from machine import Pin + asyncio.run(main(Pin(1), Pin(2))) + +Core functions +-------------- + +.. function:: create_task(coro) + + Create a new task from the given coroutine and schedule it to run. + + Returns the corresponding `Task` object. + +.. function:: current_task() + + Return the `Task` object associated with the currently running task. + +.. function:: run(coro) + + Create a new task from the given coroutine and run it until it completes. + + Returns the value returned by *coro*. + +.. function:: sleep(t) + + Sleep for *t* seconds (can be a float). + + This is a coroutine. + +.. function:: sleep_ms(t) + + Sleep for *t* milliseconds. + + This is a coroutine, and a MicroPython extension. + +Additional functions +-------------------- + +.. function:: wait_for(awaitable, timeout) + + Wait for the *awaitable* to complete, but cancel it if it takes longer + than *timeout* seconds. If *awaitable* is not a task then a task will be + created from it. + + If a timeout occurs, it cancels the task and raises ``asyncio.TimeoutError``: + this should be trapped by the caller. The task receives + ``asyncio.CancelledError`` which may be ignored or trapped using ``try...except`` + or ``try...finally`` to run cleanup code. + + Returns the return value of *awaitable*. + + This is a coroutine. + +.. function:: wait_for_ms(awaitable, timeout) + + Similar to `wait_for` but *timeout* is an integer in milliseconds. + + This is a coroutine, and a MicroPython extension. + +.. function:: gather(*awaitables, return_exceptions=False) + + Run all *awaitables* concurrently. Any *awaitables* that are not tasks are + promoted to tasks. + + Returns a list of return values of all *awaitables*. + + This is a coroutine. + +class Task +---------- + +.. class:: Task() + + This object wraps a coroutine into a running task. Tasks can be waited on + using ``await task``, which will wait for the task to complete and return + the return value of the task. + + Tasks should not be created directly, rather use `create_task` to create them. + +.. method:: Task.cancel() + + Cancel the task by injecting ``asyncio.CancelledError`` into it. The task may + ignore this exception. Cleanup code may be run by trapping it, or via + ``try ... finally``. + +class Event +----------- + +.. class:: Event() + + Create a new event which can be used to synchronise tasks. Events start + in the cleared state. + +.. method:: Event.is_set() + + Returns ``True`` if the event is set, ``False`` otherwise. + +.. method:: Event.set() + + Set the event. Any tasks waiting on the event will be scheduled to run. + + Note: This must be called from within a task. It is not safe to call this + from an IRQ, scheduler callback, or other thread. See `ThreadSafeFlag`. + +.. method:: Event.clear() + + Clear the event. + +.. method:: Event.wait() + + Wait for the event to be set. If the event is already set then it returns + immediately. + + This is a coroutine. + +class ThreadSafeFlag +-------------------- + +.. class:: ThreadSafeFlag() + + Create a new flag which can be used to synchronise a task with code running + outside the asyncio loop, such as other threads, IRQs, or scheduler + callbacks. Flags start in the cleared state. The class does not currently + work under the Unix build of MicroPython. + +.. method:: ThreadSafeFlag.set() + + Set the flag. If there is a task waiting on the flag, it will be scheduled + to run. + +.. method:: ThreadSafeFlag.clear() + + Clear the flag. This may be used to ensure that a possibly previously-set + flag is clear before waiting for it. + +.. method:: ThreadSafeFlag.wait() + + Wait for the flag to be set. If the flag is already set then it returns + immediately. The flag is automatically reset upon return from ``wait``. + + A flag may only be waited on by a single task at a time. + + This is a coroutine. + +class Lock +---------- + +.. class:: Lock() + + Create a new lock which can be used to coordinate tasks. Locks start in + the unlocked state. + + In addition to the methods below, locks can be used in an ``async with`` statement. + +.. method:: Lock.locked() + + Returns ``True`` if the lock is locked, otherwise ``False``. + +.. method:: Lock.acquire() + + Wait for the lock to be in the unlocked state and then lock it in an atomic + way. Only one task can acquire the lock at any one time. + + This is a coroutine. + +.. method:: Lock.release() + + Release the lock. If any tasks are waiting on the lock then the next one in the + queue is scheduled to run and the lock remains locked. Otherwise, no tasks are + waiting an the lock becomes unlocked. + +TCP stream connections +---------------------- + +.. function:: open_connection(host, port) + + Open a TCP connection to the given *host* and *port*. The *host* address will be + resolved using `socket.getaddrinfo`, which is currently a blocking call. + + Returns a pair of streams: a reader and a writer stream. + Will raise a socket-specific ``OSError`` if the host could not be resolved or if + the connection could not be made. + + This is a coroutine. + +.. function:: start_server(callback, host, port, backlog=5) + + Start a TCP server on the given *host* and *port*. The *callback* will be + called with incoming, accepted connections, and be passed 2 arguments: reader + and writer streams for the connection. + + Returns a `Server` object. + + This is a coroutine. + +.. class:: Stream() + + This represents a TCP stream connection. To minimise code this class implements + both a reader and a writer, and both ``StreamReader`` and ``StreamWriter`` alias to + this class. + +.. method:: Stream.get_extra_info(v) + + Get extra information about the stream, given by *v*. The valid values for *v* are: + ``peername``. + +.. method:: Stream.close() + + Close the stream. + +.. method:: Stream.wait_closed() + + Wait for the stream to close. + + This is a coroutine. + +.. method:: Stream.read(n=-1) + + Read up to *n* bytes and return them. If *n* is not provided or -1 then read all + bytes until EOF. The returned value will be an empty bytes object if EOF is + encountered before any bytes are read. + + This is a coroutine. + +.. method:: Stream.readinto(buf) + + Read up to n bytes into *buf* with n being equal to the length of *buf*. + + Return the number of bytes read into *buf*. + + This is a coroutine, and a MicroPython extension. + +.. method:: Stream.readexactly(n) + + Read exactly *n* bytes and return them as a bytes object. + + Raises an ``EOFError`` exception if the stream ends before reading *n* bytes. + + This is a coroutine. + +.. method:: Stream.readline() + + Read a line and return it. + + This is a coroutine. + +.. method:: Stream.write(buf) + + Accumulated *buf* to the output buffer. The data is only flushed when + `Stream.drain` is called. It is recommended to call `Stream.drain` immediately + after calling this function. + +.. method:: Stream.drain() + + Drain (write) all buffered output data out to the stream. + + This is a coroutine. + +.. class:: Server() + + This represents the server class returned from `start_server`. It can be used + in an ``async with`` statement to close the server upon exit. + +.. method:: Server.close() + + Close the server. + +.. method:: Server.wait_closed() + + Wait for the server to close. + + This is a coroutine. + +Event Loop +---------- + +.. function:: get_event_loop() + + Return the event loop used to schedule and run tasks. See `Loop`. + +.. function:: new_event_loop() + + Reset the event loop and return it. + + Note: since MicroPython only has a single event loop this function just + resets the loop's state, it does not create a new one. + +.. class:: Loop() + + This represents the object which schedules and runs tasks. It cannot be + created, use `get_event_loop` instead. + +.. method:: Loop.create_task(coro) + + Create a task from the given *coro* and return the new `Task` object. + +.. method:: Loop.run_forever() + + Run the event loop until `stop()` is called. + +.. method:: Loop.run_until_complete(awaitable) + + Run the given *awaitable* until it completes. If *awaitable* is not a task + then it will be promoted to one. + +.. method:: Loop.stop() + + Stop the event loop. + +.. method:: Loop.close() + + Close the event loop. + +.. method:: Loop.set_exception_handler(handler) + + Set the exception handler to call when a Task raises an exception that is not + caught. The *handler* should accept two arguments: ``(loop, context)``. + +.. method:: Loop.get_exception_handler() + + Get the current exception handler. Returns the handler, or ``None`` if no + custom handler is set. + +.. method:: Loop.default_exception_handler(context) + + The default exception handler that is called. + +.. method:: Loop.call_exception_handler(context) + + Call the current exception handler. The argument *context* is passed through and + is a dictionary containing keys: ``'message'``, ``'exception'``, ``'future'``. diff --git a/docs/library/bluetooth.rst b/docs/library/bluetooth.rst index 052f7a5c78039..78cb4cc281486 100644 --- a/docs/library/bluetooth.rst +++ b/docs/library/bluetooth.rst @@ -44,7 +44,7 @@ Configuration Get or set configuration values of the BLE interface. To get a value the parameter name should be quoted as a string, and just one parameter is - queried at a time. To set values use the keyword syntax, and one ore more + queried at a time. To set values use the keyword syntax, and one or more parameter can be set at a time. Currently supported values are: @@ -166,7 +166,7 @@ Event Handling conn_handle, status = data elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT: # Called for each characteristic found by gattc_discover_services(). - conn_handle, def_handle, value_handle, properties, uuid = data + conn_handle, end_handle, value_handle, properties, uuid = data elif event == _IRQ_GATTC_CHARACTERISTIC_DONE: # Called once service discovery is complete. # Note: Status will be zero on success, implementation-specific value otherwise. @@ -183,12 +183,10 @@ Event Handling conn_handle, value_handle, char_data = data elif event == _IRQ_GATTC_READ_DONE: # A gattc_read() has completed. - # Note: The value_handle will be zero on btstack (but present on NimBLE). # Note: Status will be zero on success, implementation-specific value otherwise. conn_handle, value_handle, status = data elif event == _IRQ_GATTC_WRITE_DONE: # A gattc_write() has completed. - # Note: The value_handle will be zero on btstack (but present on NimBLE). # Note: Status will be zero on success, implementation-specific value otherwise. conn_handle, value_handle, status = data elif event == _IRQ_GATTC_NOTIFY: @@ -514,19 +512,24 @@ writes from a client to a given characteristic, use Sends a notification request to a connected client. - If *data* is not ``None``, then that value is sent to the client as part of - the notification. The local value will not be modified. + If *data* is ``None`` (the default), then the current local value (as set + with :meth:`gatts_write `) will be sent. - Otherwise, if *data* is ``None``, then the current local value (as - set with :meth:`gatts_write `) will be sent. + Otherwise, if *data* is not ``None``, then that value is sent to the client + as part of the notification. The local value will not be modified. **Note:** The notification will be sent regardless of the subscription status of the client to this characteristic. -.. method:: BLE.gatts_indicate(conn_handle, value_handle, /) +.. method:: BLE.gatts_indicate(conn_handle, value_handle, data=None, /) - Sends an indication request containing the characteristic's current value to - a connected client. + Sends a indication request to a connected client. + + If *data* is ``None`` (the default), then the current local value (as set + with :meth:`gatts_write `) will be sent. + + Otherwise, if *data* is not ``None``, then that value is sent to the client + as part of the indication. The local value will not be modified. On acknowledgment (or failure, e.g. timeout), the ``_IRQ_GATTS_INDICATE_DONE`` event will be raised. diff --git a/docs/library/esp32.rst b/docs/library/esp32.rst index f0f0c8ef1f56e..efdd6c1be289c 100644 --- a/docs/library/esp32.rst +++ b/docs/library/esp32.rst @@ -44,10 +44,6 @@ Functions Read the raw value of the internal temperature sensor, returning an integer. -.. function:: hall_sensor() - - Read the raw value of the internal Hall sensor, returning an integer. - .. function:: idf_heap_info(capabilities) Returns information about the ESP-IDF heap memory regions. One of them contains @@ -126,7 +122,7 @@ methods to enable over-the-air (OTA) updates. and an ``OSError(-261)`` is raised if called on firmware that doesn't have the feature enabled. It is OK to call ``mark_app_valid_cancel_rollback`` on every boot and it is not - necessary when booting firmare that was loaded using esptool. + necessary when booting firmware that was loaded using esptool. Constants ~~~~~~~~~ @@ -279,6 +275,14 @@ For more details see Espressif's `ESP-IDF RMT documentation. Ultra-Low-Power co-processor ---------------------------- +This class gives access to the Ultra Low Power (ULP) co-processor on the ESP32, +ESP32-S2 and ESP32-S3 chips. + +.. warning:: + + This class does not provide access to the RISCV ULP co-processor available + on the ESP32-S2 and ESP32-S3 chips. + .. class:: ULP() This class provides access to the Ultra-Low-Power co-processor. diff --git a/docs/library/espnow.rst b/docs/library/espnow.rst new file mode 100644 index 0000000000000..f344983700a13 --- /dev/null +++ b/docs/library/espnow.rst @@ -0,0 +1,936 @@ +:mod:`espnow` --- support for the ESP-NOW wireless protocol +=========================================================== + +.. module:: espnow + :synopsis: ESP-NOW wireless protocol support + +This module provides an interface to the `ESP-NOW `_ protocol provided by Espressif on +ESP32 and ESP8266 devices (`API docs `_). + +Table of Contents: +------------------ + + - `Introduction`_ + - `Configuration`_ + - `Sending and Receiving Data`_ + - `Peer Management`_ + - `Callback Methods`_ + - `Exceptions`_ + - `Constants`_ + - `Wifi Signal Strength (RSSI) - (ESP32 Only)`_ + - `Supporting asyncio`_ + - `Broadcast and Multicast`_ + - `ESPNow and Wifi Operation`_ + - `ESPNow and Sleep Modes`_ + +Introduction +------------ + +ESP-NOW is a connection-less wireless communication protocol supporting: + +- Direct communication between up to 20 registered peers: + + - Without the need for a wireless access point (AP), + +- Encrypted and unencrypted communication (up to 6 encrypted peers), + +- Message sizes up to 250 bytes, + +- Can operate alongside Wifi operation (:doc:`network.WLAN`) on + ESP32 and ESP8266 devices. + +It is especially useful for small IoT networks, latency sensitive or power +sensitive applications (such as battery operated devices) and for long-range +communication between devices (hundreds of metres). + +This module also supports tracking the Wifi signal strength (RSSI) of peer +devices. + +A simple example would be: + +**Sender:** :: + + import network + import espnow + + # A WLAN interface must be active to send()/recv() + sta = network.WLAN(network.STA_IF) # Or network.AP_IF + sta.active(True) + sta.disconnect() # For ESP8266 + + e = espnow.ESPNow() + e.active(True) + peer = b'\xbb\xbb\xbb\xbb\xbb\xbb' # MAC address of peer's wifi interface + e.add_peer(peer) # Must add_peer() before send() + + e.send(peer, "Starting...") + for i in range(100): + e.send(peer, str(i)*20, True) + e.send(peer, b'end') + +**Receiver:** :: + + import network + import espnow + + # A WLAN interface must be active to send()/recv() + sta = network.WLAN(network.STA_IF) + sta.active(True) + sta.disconnect() # Because ESP8266 auto-connects to last Access Point + + e = espnow.ESPNow() + e.active(True) + + while True: + host, msg = e.recv() + if msg: # msg == None if timeout in recv() + print(host, msg) + if msg == b'end': + break + +class ESPNow +------------ + +Constructor +----------- + +.. class:: ESPNow() + + Returns the singleton ESPNow object. As this is a singleton, all calls to + `espnow.ESPNow()` return a reference to the same object. + + .. note:: + Some methods are available only on the ESP32 due to code size + restrictions on the ESP8266 and differences in the Espressif API. + +Configuration +------------- + +.. method:: ESPNow.active([flag]) + + Initialise or de-initialise the ESP-NOW communication protocol depending on + the value of the ``flag`` optional argument. + + .. data:: Arguments: + + - *flag*: Any python value which can be converted to a boolean type. + + - ``True``: Prepare the software and hardware for use of the ESP-NOW + communication protocol, including: + + - initialise the ESPNow data structures, + - allocate the recv data buffer, + - invoke esp_now_init() and + - register the send and recv callbacks. + + - ``False``: De-initialise the Espressif ESP-NOW software stack + (esp_now_deinit()), disable callbacks, deallocate the recv + data buffer and deregister all peers. + + If *flag* is not provided, return the current status of the ESPNow + interface. + + .. data:: Returns: + + ``True`` if interface is currently *active*, else ``False``. + +.. method:: ESPNow.config(param=value, ...) + ESPNow.config('param') (ESP32 only) + + Set or get configuration values of the ESPNow interface. To set values, use + the keyword syntax, and one or more parameters can be set at a time. To get + a value the parameter name should be quoted as a string, and just one + parameter is queried at a time. + + **Note:** *Getting* parameters is not supported on the ESP8266. + + .. data:: Options: + + *rxbuf*: (default=526) Get/set the size in bytes of the internal + buffer used to store incoming ESPNow packet data. The default size is + selected to fit two max-sized ESPNow packets (250 bytes) with associated + mac_address (6 bytes), a message byte count (1 byte) and RSSI data plus + buffer overhead. Increase this if you expect to receive a lot of large + packets or expect bursty incoming traffic. + + **Note:** The recv buffer is allocated by `ESPNow.active()`. Changing + this value will have no effect until the next call of + `ESPNow.active(True)`. + + *timeout_ms*: (default=300,000) Default timeout (in milliseconds) + for receiving ESPNow messages. If *timeout_ms* is less than zero, then + wait forever. The timeout can also be provided as arg to + `recv()`/`irecv()`/`recvinto()`. + + *rate*: (ESP32 only, IDF>=4.3.0 only) Set the transmission speed for + ESPNow packets. Must be set to a number from the allowed numeric values + in `enum wifi_phy_rate_t + `_. + + .. data:: Returns: + + ``None`` or the value of the parameter being queried. + + .. data:: Raises: + + - ``OSError(num, "ESP_ERR_ESPNOW_NOT_INIT")`` if not initialised. + - ``ValueError()`` on invalid configuration options or values. + +Sending and Receiving Data +-------------------------- + +A wifi interface (``network.STA_IF`` or ``network.AP_IF``) must be +`active()` before messages can be sent or received, +but it is not necessary to connect or configure the WLAN interface. +For example:: + + import network + + sta = network.WLAN(network.STA_IF) + sta.active(True) + sta.disconnect() # For ESP8266 + +**Note:** The ESP8266 has a *feature* that causes it to automatically reconnect +to the last wifi Access Point when set `active(True)` (even +after reboot/reset). This reduces the reliability of receiving ESP-NOW messages +(see `ESPNow and Wifi Operation`_). You can avoid this by calling +`disconnect()` after +`active(True)`. + +.. method:: ESPNow.send(mac, msg[, sync]) + ESPNow.send(msg) (ESP32 only) + + Send the data contained in ``msg`` to the peer with given network ``mac`` + address. In the second form, ``mac=None`` and ``sync=True``. The peer must + be registered with `ESPNow.add_peer()` before the + message can be sent. + + .. data:: Arguments: + + - *mac*: byte string exactly ``espnow.ADDR_LEN`` (6 bytes) long or + ``None``. If *mac* is ``None`` (ESP32 only) the message will be sent + to all registered peers, except any broadcast or multicast MAC + addresses. + + - *msg*: string or byte-string up to ``espnow.MAX_DATA_LEN`` (250) + bytes long. + + - *sync*: + + - ``True``: (default) send ``msg`` to the peer(s) and wait for a + response (or not). + + - ``False`` send ``msg`` and return immediately. Responses from the + peers will be discarded. + + .. data:: Returns: + + ``True`` if ``sync=False`` or if ``sync=True`` and *all* peers respond, + else ``False``. + + .. data:: Raises: + + - ``OSError(num, "ESP_ERR_ESPNOW_NOT_INIT")`` if not initialised. + - ``OSError(num, "ESP_ERR_ESPNOW_NOT_FOUND")`` if peer is not registered. + - ``OSError(num, "ESP_ERR_ESPNOW_IF")`` the wifi interface is not + `active()`. + - ``OSError(num, "ESP_ERR_ESPNOW_NO_MEM")`` internal ESP-NOW buffers are + full. + - ``ValueError()`` on invalid values for the parameters. + + **Note**: A peer will respond with success if its wifi interface is + `active()` and set to the same channel as the sender, + regardless of whether it has initialised it's ESP-NOW system or is + actively listening for ESP-NOW traffic (see the Espressif ESP-NOW docs). + +.. method:: ESPNow.recv([timeout_ms]) + + Wait for an incoming message and return the ``mac`` address of the peer and + the message. **Note**: It is **not** necessary to register a peer (using + `add_peer()`) to receive a message from that peer. + + .. data:: Arguments: + + - *timeout_ms*: (Optional): May have the following values. + + - ``0``: No timeout. Return immediately if no data is available; + - ``> 0``: Specify a timeout value in milliseconds; + - ``< 0``: Do not timeout, ie. wait forever for new messages; or + - ``None`` (or not provided): Use the default timeout value set with + `ESPNow.config()`. + + .. data:: Returns: + + - ``(None, None)`` if timeout is reached before a message is received, or + + - ``[mac, msg]``: where: + + - ``mac`` is a bytestring containing the address of the device which + sent the message, and + - ``msg`` is a bytestring containing the message. + + .. data:: Raises: + + - ``OSError(num, "ESP_ERR_ESPNOW_NOT_INIT")`` if not initialised. + - ``OSError(num, "ESP_ERR_ESPNOW_IF")`` if the wifi interface is not + `active()`. + - ``ValueError()`` on invalid *timeout_ms* values. + + `ESPNow.recv()` will allocate new storage for the returned list and the + ``peer`` and ``msg`` bytestrings. This can lead to memory fragmentation if + the data rate is high. See `ESPNow.irecv()` for a memory-friendly + alternative. + + +.. method:: ESPNow.irecv([timeout_ms]) + + Works like `ESPNow.recv()` but will re-use internal bytearrays to store the + return values: ``[mac, msg]``, so that no new memory is allocated on each + call. + + .. data:: Arguments: + + *timeout_ms*: (Optional) Timeout in milliseconds (see `ESPNow.recv()`). + + .. data:: Returns: + + - As for `ESPNow.recv()`, except that ``msg`` is a bytearray, instead of + a bytestring. On the ESP8266, ``mac`` will also be a bytearray. + + .. data:: Raises: + + - See `ESPNow.recv()`. + + **Note:** You may also read messages by iterating over the ESPNow object, + which will use the `irecv()` method for alloc-free reads, eg: :: + + import espnow + e = espnow.ESPNow(); e.active(True) + for mac, msg in e: + print(mac, msg) + if mac is None: # mac, msg will equal (None, None) on timeout + break + +.. method:: ESPNow.recvinto(data[, timeout_ms]) + + Wait for an incoming message and return the length of the message in bytes. + This is the low-level method used by both `recv()` and + `irecv()` to read messages. + + .. data:: Arguments: + + *data*: A list of at least two elements, ``[peer, msg]``. ``msg`` must + be a bytearray large enough to hold the message (250 bytes). On the + ESP8266, ``peer`` should be a bytearray of 6 bytes. The MAC address of + the sender and the message will be stored in these bytearrays (see Note + on ESP32 below). + + *timeout_ms*: (Optional) Timeout in milliseconds (see `ESPNow.recv()`). + + .. data:: Returns: + + - Length of message in bytes or 0 if *timeout_ms* is reached before a + message is received. + + .. data:: Raises: + + - See `ESPNow.recv()`. + + **Note:** On the ESP32: + + - It is unnecessary to provide a bytearray in the first element of the + ``data`` list because it will be replaced by a reference to a unique + ``peer`` address in the **peer device table** (see `ESPNow.peers_table`). + - If the list is at least 4 elements long, the rssi and timestamp values + will be saved as the 3rd and 4th elements. + +.. method:: ESPNow.any() + + Check if data is available to be read with `ESPNow.recv()`. + + For more sophisticated querying of available characters use `select.poll()`:: + + import select + import espnow + + e = espnow.ESPNow() + poll = select.poll() + poll.register(e, select.POLLIN) + poll.poll(timeout) + + .. data:: Returns: + + ``True`` if data is available to be read, else ``False``. + +.. method:: ESPNow.stats() (ESP32 only) + + .. data:: Returns: + + A 5-tuple containing the number of packets sent/received/lost: + + ``(tx_pkts, tx_responses, tx_failures, rx_packets, rx_dropped_packets)`` + + Incoming packets are *dropped* when the recv buffers are full. To reduce + packet loss, increase the ``rxbuf`` config parameters and ensure you are + reading messages as quickly as possible. + + **Note**: Dropped packets will still be acknowledged to the sender as + received. + +Peer Management +--------------- + +On ESP32 devices, the Espressif ESP-NOW software requires that other devices +(peers) must be *registered* using `add_peer()` before we can +`send()` them messages (this is *not* enforced on ESP8266 +devices). It is **not** necessary to register a peer to receive an +un-encrypted message from that peer. + +**Encrypted messages**: To receive an *encrypted* message, the receiving device +must first register the sender and use the same encryption keys as the sender +(PMK and LMK) (see `set_pmk()` and `add_peer()`. + +.. method:: ESPNow.set_pmk(pmk) + + Set the Primary Master Key (PMK) which is used to encrypt the Local Master + Keys (LMK) for encrypting messages. If this is not set, a default PMK is + used by the underlying Espressif ESP-NOW software stack. + + **Note:** messages will only be encrypted if *lmk* is also set in + `ESPNow.add_peer()` (see `Security + `_ in the Espressif API + docs). + + .. data:: Arguments: + + *pmk*: Must be a byte string, bytearray or string of length + `espnow.KEY_LEN` (16 bytes). + + .. data:: Returns: + + ``None`` + + .. data:: Raises: + + ``ValueError()`` on invalid *pmk* values. + +.. method:: ESPNow.add_peer(mac, [lmk], [channel], [ifidx], [encrypt]) + ESPNow.add_peer(mac, param=value, ...) (ESP32 only) + + Add/register the provided *mac* address as a peer. Additional parameters may + also be specified as positional or keyword arguments (any parameter set to + ``None`` will be set to it's default value): + + .. data:: Arguments: + + - *mac*: The MAC address of the peer (as a 6-byte byte-string). + + - *lmk*: The Local Master Key (LMK) key used to encrypt data + transfers with this peer (unless the *encrypt* parameter is set to + ``False``). Must be: + + - a byte-string or bytearray or string of length ``espnow.KEY_LEN`` + (16 bytes), or + + - any non ``True`` python value (default= ``b''``), signifying an + *empty* key which will disable encryption. + + - *channel*: The wifi channel (2.4GHz) to communicate with this peer. + Must be an integer from 0 to 14. If channel is set to 0 the current + channel of the wifi device will be used. (default=0) + + - *ifidx*: (ESP32 only) Index of the wifi interface which will be + used to send data to this peer. Must be an integer set to + ``network.STA_IF`` (=0) or ``network.AP_IF`` (=1). + (default=0/``network.STA_IF``). See `ESPNow and Wifi Operation`_ + below for more information. + + - *encrypt*: (ESP32 only) If set to ``True`` data exchanged with + this peer will be encrypted with the PMK and LMK. (default = + ``True`` if *lmk* is set to a valid key, else ``False``) + + **ESP8266**: Keyword args may not be used on the ESP8266. + + **Note:** The maximum number of peers which may be registered is 20 + (`espnow.MAX_TOTAL_PEER_NUM`), with a maximum of 6 + (`espnow.MAX_ENCRYPT_PEER_NUM`) of those peers with encryption enabled + (see `ESP_NOW_MAX_ENCRYPT_PEER_NUM `_ in the Espressif API + docs). + + .. data:: Raises: + + - ``OSError(num, "ESP_ERR_ESPNOW_NOT_INIT")`` if not initialised. + - ``OSError(num, "ESP_ERR_ESPNOW_EXIST")`` if *mac* is already + registered. + - ``OSError(num, "ESP_ERR_ESPNOW_FULL")`` if too many peers are + already registered. + - ``ValueError()`` on invalid keyword args or values. + +.. method:: ESPNow.del_peer(mac) + + Deregister the peer associated with the provided *mac* address. + + .. data:: Returns: + + ``None`` + + .. data:: Raises: + + - ``OSError(num, "ESP_ERR_ESPNOW_NOT_INIT")`` if not initialised. + - ``OSError(num, "ESP_ERR_ESPNOW_NOT_FOUND")`` if *mac* is not + registered. + - ``ValueError()`` on invalid *mac* values. + +.. method:: ESPNow.get_peer(mac) (ESP32 only) + + Return information on a registered peer. + + .. data:: Returns: + + ``(mac, lmk, channel, ifidx, encrypt)``: a tuple of the "peer + info" associated with the given *mac* address. + + .. data:: Raises: + + - ``OSError(num, "ESP_ERR_ESPNOW_NOT_INIT")`` if not initialised. + - ``OSError(num, "ESP_ERR_ESPNOW_NOT_FOUND")`` if *mac* is not + registered. + - ``ValueError()`` on invalid *mac* values. + +.. method:: ESPNow.peer_count() (ESP32 only) + + Return the number of registered peers: + + - ``(peer_num, encrypt_num)``: where + + - ``peer_num`` is the number of peers which are registered, and + - ``encrypt_num`` is the number of encrypted peers. + +.. method:: ESPNow.get_peers() (ESP32 only) + + Return the "peer info" parameters for all the registered peers (as a tuple + of tuples). + +.. method:: ESPNow.mod_peer(mac, lmk, [channel], [ifidx], [encrypt]) (ESP32 only) + ESPNow.mod_peer(mac, 'param'=value, ...) (ESP32 only) + + Modify the parameters of the peer associated with the provided *mac* + address. Parameters may be provided as positional or keyword arguments + (see `ESPNow.add_peer()`). Any parameter that is not set (or set to + ``None``) will retain the existing value for that parameter. + +Callback Methods +---------------- + +.. method:: ESPNow.irq(callback) (ESP32 only) + + Set a callback function to be called *as soon as possible* after a message has + been received from another ESPNow device. The callback function will be called + with the `ESPNow` instance object as an argument. For more reliable operation, + it is recommended to read out as many messages as are available when the + callback is invoked and to set the read timeout to zero, eg: :: + + def recv_cb(e): + while True: # Read out all messages waiting in the buffer + mac, msg = e.irecv(0) # Don't wait if no messages left + if mac is None: + return + print(mac, msg) + e.irq(recv_cb) + + The `irq()` callback method is an alternative method for + processing incoming messages, especially if the data rate is moderate + and the device is *not too busy* but there are some caveats: + + - The scheduler stack *can* overflow and callbacks will be missed if + packets are arriving at a sufficient rate or if other MicroPython components + (eg, bluetooth, machine.Pin.irq(), machine.timer, i2s, ...) are exercising + the scheduler stack. This method may be less reliable for dealing with + bursts of messages, or high throughput or on a device which is busy dealing + with other hardware operations. + + - For more information on *scheduled* function callbacks see: + `micropython.schedule()`. + +Constants +--------- + +.. data:: espnow.MAX_DATA_LEN(=250) + espnow.KEY_LEN(=16) + espnow.ADDR_LEN(=6) + espnow.MAX_TOTAL_PEER_NUM(=20) + espnow.MAX_ENCRYPT_PEER_NUM(=6) + +Exceptions +---------- + +If the underlying Espressif ESP-NOW software stack returns an error code, +the MicroPython espnow module will raise an ``OSError(errnum, errstring)`` +exception where ``errstring`` is set to the name of one of the error codes +identified in the +`Espressif ESP-NOW docs +`_. For example:: + + try: + e.send(peer, 'Hello') + except OSError as err: + if len(err.args) < 2: + raise err + if err.args[1] == 'ESP_ERR_ESPNOW_NOT_INIT': + e.active(True) + elif err.args[1] == 'ESP_ERR_ESPNOW_NOT_FOUND': + e.add_peer(peer) + elif err.args[1] == 'ESP_ERR_ESPNOW_IF': + network.WLAN(network.STA_IF).active(True) + else: + raise err + +Wifi Signal Strength (RSSI) - (ESP32 only) +------------------------------------------ + +The ESPNow object maintains a **peer device table** which contains the signal +strength and timestamp of the last received message from all hosts. The **peer +device table** can be accessed using `ESPNow.peers_table` and can be used to +track device proximity and identify *nearest neighbours* in a network of peer +devices. This feature is **not** available on ESP8266 devices. + +.. data:: ESPNow.peers_table + + A reference to the **peer device table**: a dict of known peer devices + and rssi values:: + + {peer: [rssi, time_ms], ...} + + where: + + - ``peer`` is the peer MAC address (as `bytes`); + - ``rssi`` is the wifi signal strength in dBm (-127 to 0) of the last + message received from the peer; and + - ``time_ms`` is the time the message was received (in milliseconds since + system boot - wraps every 12 days). + + Example:: + + >>> e.peers_table + {b'\xaa\xaa\xaa\xaa\xaa\xaa': [-31, 18372], + b'\xbb\xbb\xbb\xbb\xbb\xbb': [-43, 12541]} + + **Note**: the ``mac`` addresses returned by `recv()` are references to + the ``peer`` key values in the **peer device table**. + + **Note**: RSSI and timestamp values in the device table are updated only + when the message is read by the application. + +Supporting asyncio +------------------ + +A supplementary module (`aioespnow`) is available to provide +:doc:`asyncio` support. + +**Note:** Asyncio support is available on all ESP32 targets as well as those +ESP8266 boards which include the asyncio module (ie. ESP8266 devices with at +least 2MB flash memory). + +A small async server example:: + + import network + import aioespnow + import asyncio + + # A WLAN interface must be active to send()/recv() + network.WLAN(network.STA_IF).active(True) + + e = aioespnow.AIOESPNow() # Returns AIOESPNow enhanced with async support + e.active(True) + peer = b'\xbb\xbb\xbb\xbb\xbb\xbb' + e.add_peer(peer) + + # Send a periodic ping to a peer + async def heartbeat(e, peer, period=30): + while True: + if not await e.asend(peer, b'ping'): + print("Heartbeat: peer not responding:", peer) + else: + print("Heartbeat: ping", peer) + await asyncio.sleep(period) + + # Echo any received messages back to the sender + async def echo_server(e): + async for mac, msg in e: + print("Echo:", msg) + try: + await e.asend(mac, msg) + except OSError as err: + if len(err.args) > 1 and err.args[1] == 'ESP_ERR_ESPNOW_NOT_FOUND': + e.add_peer(mac) + await e.asend(mac, msg) + + async def main(e, peer, timeout, period): + asyncio.create_task(heartbeat(e, peer, period)) + asyncio.create_task(echo_server(e)) + await asyncio.sleep(timeout) + + asyncio.run(main(e, peer, 120, 10)) + +.. module:: aioespnow + :synopsis: ESP-NOW :doc:`asyncio` support + +.. class:: AIOESPNow() + + The `AIOESPNow` class inherits all the methods of `ESPNow` + and extends the interface with the following async methods. + +.. method:: async AIOESPNow.arecv() + + Asyncio support for `ESPNow.recv()`. Note that this method does not take a + timeout value as argument. + +.. method:: async AIOESPNow.airecv() + + Asyncio support for `ESPNow.irecv()`. Note that this method does not take a + timeout value as argument. + +.. method:: async AIOESPNow.asend(mac, msg, sync=True) + async AIOESPNow.asend(msg) + + Asyncio support for `ESPNow.send()`. + +.. method:: AIOESPNow._aiter__() / async AIOESPNow.__anext__() + + `AIOESPNow` also supports reading incoming messages by asynchronous + iteration using ``async for``; eg:: + + e = AIOESPNow() + e.active(True) + async def recv_till_halt(e): + async for mac, msg in e: + print(mac, msg) + if msg == b'halt': + break + asyncio.run(recv_till_halt(e)) + +Broadcast and Multicast +----------------------- + +All active ESPNow clients will receive messages sent to their MAC address and +all devices (**except ESP8266 devices**) will also receive messages sent to the +*broadcast* MAC address (``b'\xff\xff\xff\xff\xff\xff'``) or any multicast +MAC address. + +All ESPNow devices (including ESP8266 devices) can also send messages to the +broadcast MAC address or any multicast MAC address. + +To `send()` a broadcast message, the broadcast (or +multicast) MAC address must first be registered using +`add_peer()`. `send()` will always return +``True`` for broadcasts, regardless of whether any devices receive the +message. It is not permitted to encrypt messages sent to the broadcast +address or any multicast address. + +**Note**: `ESPNow.send(None, msg)` will send to all registered +peers *except* the broadcast address. To send a broadcast or multicast +message, you must specify the broadcast (or multicast) MAC address as the +peer. For example:: + + bcast = b'\xff' * 6 + e.add_peer(bcast) + e.send(bcast, "Hello World!") + +ESPNow and Wifi Operation +------------------------- + +ESPNow messages may be sent and received on any `active()` +`WLAN` interface (``network.STA_IF`` or ``network.AP_IF``), even +if that interface is also connected to a wifi network or configured as an access +point. When an ESP32 or ESP8266 device connects to a Wifi Access Point (see +`ESP32 Quickref <../esp32/quickref.html#networking>`__) the following things +happen which affect ESPNow communications: + +1. Wifi Power-saving Mode (`network.WLAN.PM_PERFORMANCE`) + is automatically activated and +2. The radio on the esp device changes wifi ``channel`` to match the channel + used by the Access Point. + +**Wifi Power-saving Mode:** (see `Espressif Docs `_) The power saving mode causes the +device to turn off the radio periodically (typically for hundreds of +milliseconds), making it unreliable in receiving ESPNow messages. This can be +resolved by either of: + +1. Disabling the power-saving mode on the STA_IF interface; + + - Use ``sta.config(pm=sta.PM_NONE)`` + +2. Turning on the AP_IF interface, which will disable the power saving mode. + However, the device will then be advertising an active wifi access point. + + - You **may** also choose to send your messages via the AP_IF interface, but + this is not necessary. + - ESP8266 peers must send messages to this AP_IF interface (see below). + +3. Configuring ESPNow clients to retry sending messages. + +**Receiving messages from an ESP8266 device:** Strangely, an ESP32 device +connected to a wifi network using method 1 or 2 above, will receive ESPNow +messages sent to the STA_IF MAC address from another ESP32 device, but will +**reject** messages from an ESP8266 device!!!. To receive messages from an +ESP8266 device, the AP_IF interface must be set to ``active(True)`` **and** +messages must be sent to the AP_IF MAC address. + +**Managing wifi channels:** Any other ESPNow devices wishing to communicate with +a device which is also connected to a Wifi Access Point MUST use the same +channel. A common scenario is where one ESPNow device is connected to a wifi +router and acts as a proxy for messages from a group of sensors connected via +ESPNow: + +**Proxy:** :: + + import network, time, espnow + + sta, ap = wifi_reset() # Reset wifi to AP off, STA on and disconnected + sta.connect('myssid', 'mypassword') + while not sta.isconnected(): # Wait until connected... + time.sleep(0.1) + sta.config(pm=sta.PM_NONE) # ..then disable power saving + + # Print the wifi channel used AFTER finished connecting to access point + print("Proxy running on channel:", sta.config("channel")) + e = espnow.ESPNow(); e.active(True) + for peer, msg in e: + # Receive espnow messages and forward them to MQTT broker over wifi + +**Sensor:** :: + + import network, espnow + + sta, ap = wifi_reset() # Reset wifi to AP off, STA on and disconnected + sta.config(channel=6) # Change to the channel used by the proxy above. + peer = b'0\xaa\xaa\xaa\xaa\xaa' # MAC address of proxy + e = espnow.ESPNow(); e.active(True); + e.add_peer(peer) + while True: + msg = read_sensor() + e.send(peer, msg) + time.sleep(1) + +Other issues to take care with when using ESPNow with wifi are: + +- **Set WIFI to known state on startup:** MicroPython does not reset the wifi + peripheral after a soft reset. This can lead to unexpected behaviour. To + guarantee the wifi is reset to a known state after a soft reset make sure you + deactivate the STA_IF and AP_IF before setting them to the desired state at + startup, eg.:: + + import network, time + + def wifi_reset(): # Reset wifi to AP_IF off, STA_IF on and disconnected + sta = network.WLAN(network.STA_IF); sta.active(False) + ap = network.WLAN(network.AP_IF); ap.active(False) + sta.active(True) + while not sta.active(): + time.sleep(0.1) + sta.disconnect() # For ESP8266 + while sta.isconnected(): + time.sleep(0.1) + return sta, ap + + sta, ap = wifi_reset() + + Remember that a soft reset occurs every time you connect to the device REPL + and when you type ``ctrl-D``. + +- **STA_IF and AP_IF always operate on the same channel:** the AP_IF will change + channel when you connect to a wifi network; regardless of the channel you set + for the AP_IF (see `Attention Note 3 + `_ + ). After all, there is really only one wifi radio on the device, which is + shared by the STA_IF and AP_IF virtual devices. + +- **Disable automatic channel assignment on your wifi router:** If the wifi + router for your wifi network is configured to automatically assign the wifi + channel, it may change the channel for the network if it detects interference + from other wifi routers. When this occurs, the ESP devices connected to the + wifi network will also change channels to match the router, but other + ESPNow-only devices will remain on the previous channel and communication will + be lost. To mitigate this, either set your wifi router to use a fixed wifi + channel or configure your devices to re-scan the wifi channels if they are + unable to find their expected peers on the current channel. + +- **MicroPython re-scans wifi channels when trying to reconnect:** If the esp + device is connected to a Wifi Access Point that goes down, MicroPython will + automatically start scanning channels in an attempt to reconnect to the + Access Point. This means ESPNow messages will be lost while scanning for the + AP. This can be disabled by ``sta.config(reconnects=0)``, which will also + disable the automatic reconnection after losing connection. + +- Some versions of the ESP IDF only permit sending ESPNow packets from the + STA_IF interface to peers which have been registered on the same wifi + channel as the STA_IF:: + + ESPNOW: Peer channel is not equal to the home channel, send fail! + +ESPNow and Sleep Modes +---------------------- + +The `machine.lightsleep([time_ms])` and +`machine.deepsleep([time_ms])` functions can be used to put +the ESP32 and peripherals (including the WiFi and Bluetooth radios) to sleep. +This is useful in many applications to conserve battery power. However, +applications must disable the WLAN peripheral (using +`active(False)`) before entering light or deep sleep (see +`Sleep Modes `_). +Otherwise the WiFi radio may not be initialised properly after wake from +sleep. If the ``STA_IF`` and ``AP_IF`` interfaces have both been set +`active(True)` then both interfaces should be set +`active(False)` before entering any sleep mode. + +**Example:** deep sleep:: + + import network, machine, espnow + + sta, ap = wifi_reset() # Reset wifi to AP off, STA on and disconnected + peer = b'0\xaa\xaa\xaa\xaa\xaa' # MAC address of peer + e = espnow.ESPNow() + e.active(True) + e.add_peer(peer) # Register peer on STA_IF + + print('Sending ping...') + if not e.send(peer, b'ping'): + print('Ping failed!') + e.active(False) + sta.active(False) # Disable the wifi before sleep + print('Going to sleep...') + machine.deepsleep(10000) # Sleep for 10 seconds then reboot + +**Example:** light sleep:: + + import network, machine, espnow + + sta, ap = wifi_reset() # Reset wifi to AP off, STA on and disconnected + sta.config(channel=6) + peer = b'0\xaa\xaa\xaa\xaa\xaa' # MAC address of peer + e = espnow.ESPNow() + e.active(True) + e.add_peer(peer) # Register peer on STA_IF + + while True: + print('Sending ping...') + if not e.send(peer, b'ping'): + print('Ping failed!') + sta.active(False) # Disable the wifi before sleep + print('Going to sleep...') + machine.lightsleep(10000) # Sleep for 10 seconds + sta.active(True) + sta.config(channel=6) # Wifi loses config after lightsleep() + diff --git a/docs/library/framebuf.rst b/docs/library/framebuf.rst index 098ada8153847..149f4d6609be9 100644 --- a/docs/library/framebuf.rst +++ b/docs/library/framebuf.rst @@ -11,8 +11,8 @@ class FrameBuffer ----------------- The FrameBuffer class provides a pixel buffer which can be drawn upon with -pixels, lines, rectangles, text and even other FrameBuffer's. It is useful -when generating output for displays. +pixels, lines, rectangles, ellipses, polygons, text and even other +FrameBuffers. It is useful when generating output for displays. For example:: @@ -77,12 +77,37 @@ The following methods draw shapes onto the FrameBuffer. methods draw horizontal and vertical lines respectively up to a given length. -.. method:: FrameBuffer.rect(x, y, w, h, c) -.. method:: FrameBuffer.fill_rect(x, y, w, h, c) +.. method:: FrameBuffer.rect(x, y, w, h, c[, f]) - Draw a rectangle at the given location, size and color. The `rect` - method draws only a 1 pixel outline whereas the `fill_rect` method - draws both the outline and interior. + Draw a rectangle at the given location, size and color. + + The optional *f* parameter can be set to ``True`` to fill the rectangle. + Otherwise just a one pixel outline is drawn. + +.. method:: FrameBuffer.ellipse(x, y, xr, yr, c[, f, m]) + + Draw an ellipse at the given location. Radii *xr* and *yr* define the + geometry; equal values cause a circle to be drawn. The *c* parameter + defines the color. + + The optional *f* parameter can be set to ``True`` to fill the ellipse. + Otherwise just a one pixel outline is drawn. + + The optional *m* parameter enables drawing to be restricted to certain + quadrants of the ellipse. The LS four bits determine which quadrants are + to be drawn, with bit 0 specifying Q1, b1 Q2, b2 Q3 and b3 Q4. Quadrants + are numbered counterclockwise with Q1 being top right. + +.. method:: FrameBuffer.poly(x, y, coords, c[, f]) + + Given a list of coordinates, draw an arbitrary (convex or concave) closed + polygon at the given x, y location using the given color. + + The *coords* must be specified as a :mod:`array` of integers, e.g. + ``array('h', [x0, y0, x1, y1, ... xn, yn])``. + + The optional *f* parameter can be set to ``True`` to fill the polygon. + Otherwise just a one pixel outline is drawn. Drawing text ------------ @@ -108,7 +133,9 @@ Other methods Draw another FrameBuffer on top of the current one at the given coordinates. If *key* is specified then it should be a color integer and the corresponding color will be considered transparent: all pixels with that - color value will not be drawn. + color value will not be drawn. (If the *palette* is specified then the *key* + is compared to the value from *palette*, not to the value directly from + *fbuf*.) The *palette* argument enables blitting between FrameBuffers with differing formats. Typical usage is to render a monochrome or grayscale glyph/icon to diff --git a/docs/library/index.rst b/docs/library/index.rst index ffd373a4df25b..69bc81ade5e14 100644 --- a/docs/library/index.rst +++ b/docs/library/index.rst @@ -8,15 +8,17 @@ MicroPython libraries Important summary of this section * MicroPython provides built-in modules that mirror the functionality of the - Python standard library (e.g. :mod:`os`, :mod:`time`), as well as - MicroPython-specific modules (e.g. :mod:`bluetooth`, :mod:`machine`). - * Most standard library modules implement a subset of the functionality of - the equivalent Python module, and in a few cases provide some - MicroPython-specific extensions (e.g. :mod:`array`, :mod:`os`) + :ref:`Python standard library ` (e.g. :mod:`os`, + :mod:`time`), as well as :ref:`MicroPython-specific modules ` + (e.g. :mod:`bluetooth`, :mod:`machine`). + * Most Python standard library modules implement a subset of the + functionality of the equivalent Python module, and in a few cases provide + some MicroPython-specific extensions (e.g. :mod:`array`, :mod:`os`) * Due to resource constraints or other limitations, some ports or firmware versions may not include all the functionality documented here. - * To allow for extensibility, the built-in modules can be extended from - Python code loaded onto the device. + * To allow for extensibility, some built-in modules can be + :ref:`extended from Python code ` loaded onto + the device filesystem. This chapter describes modules (function and class libraries) which are built into MicroPython. This documentation in general aspires to describe all modules @@ -41,6 +43,8 @@ Beyond the built-in libraries described in this documentation, many more modules from the Python standard library, as well as further MicroPython extensions to it, can be found in :term:`micropython-lib`. +.. _micropython_lib_python: + Python standard libraries and micro-libraries --------------------------------------------- @@ -53,6 +57,7 @@ library. :maxdepth: 1 array.rst + asyncio.rst binascii.rst builtins.rst cmath.rst @@ -73,10 +78,10 @@ library. struct.rst sys.rst time.rst - uasyncio.rst zlib.rst _thread.rst +.. _micropython_lib_micropython: MicroPython-specific libraries ------------------------------ @@ -155,6 +160,11 @@ The following libraries are specific to the ESP8266 and ESP32. esp.rst esp32.rst +.. toctree:: + :maxdepth: 1 + + espnow.rst + Libraries specific to the RP2040 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -176,23 +186,60 @@ The following libraries are specific to the Zephyr port. zephyr.rst +.. _micropython_lib_extending: + Extending built-in libraries from Python ---------------------------------------- -In most cases, the above modules are actually named ``umodule`` rather than -``module``, but MicroPython will alias any module prefixed with a ``u`` to the -non-``u`` version. However a file (or :term:`frozen module`) named -``module.py`` will take precedence over this alias. +A subset of the built-in modules are able to be extended by Python code by +providing a module of the same name in the filesystem. This extensibility +applies to the following Python standard library modules which are built-in to +the firmware: ``array``, ``binascii``, ``collections``, ``errno``, ``hashlib``, +``heapq``, ``io``, ``json``, ``os``, ``platform``, ``random``, ``re``, +``select``, ``socket``, ``ssl``, ``struct``, ``time`` ``zlib``, as well as the +MicroPython-specific ``machine`` module. All other built-in modules cannot be +extended from the filesystem. This allows the user to provide an extended implementation of a built-in library -(perhaps to provide additional CPython compatibility). The user-provided module -(in ``module.py``) can still use the built-in functionality by importing -``umodule`` directly. This is used extensively in :term:`micropython-lib`. See -:ref:`packages` for more information. - -This applies to both the Python standard libraries (e.g. ``os``, ``time``, etc), -but also the MicroPython libraries too (e.g. ``machine``, ``bluetooth``, etc). -The main exception is the port-specific libraries (``pyb``, ``esp``, etc). - -*Other than when you specifically want to force the use of the built-in module, -we recommend always using ``import module`` rather than ``import umodule``.* +(perhaps to provide additional CPython compatibility or missing functionality). +This is used extensively in :term:`micropython-lib`, see :ref:`packages` for +more information. The filesystem module will typically do a wildcard import of +the built-in module in order to inherit all the globals (classes, functions and +variables) from the built-in. + +In MicroPython v1.21.0 and higher, to prevent the filesystem module from +importing itself, it can force an import of the built-in module it by +temporarily clearing ``sys.path`` during the import. For example, to extend the +``time`` module from Python, a file named ``time.py`` on the filesystem would +do the following:: + + _path = sys.path + sys.path = () + try: + from time import * + finally: + sys.path = _path + del _path + + def extra_method(): + pass + +The result is that ``time.py`` contains all the globals of the built-in ``time`` +module, but adds ``extra_method``. + +In earlier versions of MicroPython, you can force an import of a built-in module +by appending a ``u`` to the start of its name. For example, ``import utime`` +instead of ``import time``. For example, ``time.py`` on the filesystem could +look like:: + + from utime import * + + def extra_method(): + pass + +This way is still supported, but the ``sys.path`` method described above is now +preferred as the ``u``-prefix will be removed from the names of built-in +modules in a future version of MicroPython. + +*Other than when it specifically needs to force the use of the built-in module, +code should always use* ``import module`` *rather than* ``import umodule``. diff --git a/docs/library/machine.ADC.rst b/docs/library/machine.ADC.rst index eb538a4424f6f..65225ea8788da 100644 --- a/docs/library/machine.ADC.rst +++ b/docs/library/machine.ADC.rst @@ -4,7 +4,7 @@ class ADC -- analog to digital conversion ========================================= -The ADC class provides an interface to analog-to-digital convertors, and +The ADC class provides an interface to analog-to-digital converters, and represents a single endpoint that can sample a continuous voltage and convert it to a discretised value. diff --git a/docs/library/machine.I2C.rst b/docs/library/machine.I2C.rst index 82a88390c3fb3..635d5873444b5 100644 --- a/docs/library/machine.I2C.rst +++ b/docs/library/machine.I2C.rst @@ -20,6 +20,17 @@ Software I2C is implemented by bit-banging and can be used on any pin but is not as efficient. These classes have the same methods available and differ primarily in the way they are constructed. +.. Note:: + + The I2C bus requires pull-up circuitry on both SDA and SCL for it's operation. + Usually these are resistors in the range of 1 - 10 kOhm, connected from each SDA/SCL + to Vcc. Without these, the behaviour is undefined and may range from blocking, + unexpected watchdog reset to just wrong values. Often, this pull-up circuitry + is built-in already to the MCU board or sensor breakout boards, but there is + no rule for that. So please check in case of trouble. See also this excellent + `learning guide `_ + by Adafruit about I2C wiring. + Example usage:: from machine import I2C @@ -41,7 +52,7 @@ Example usage:: Constructors ------------ -.. class:: I2C(id, *, scl, sda, freq=400000) +.. class:: I2C(id, *, scl, sda, freq=400000, timeout=50000) Construct and return a new I2C object using the following parameters: @@ -51,6 +62,8 @@ Constructors - *sda* should be a pin object specifying the pin to use for SDA. - *freq* should be an integer which sets the maximum frequency for SCL. + - *timeout* is the maximum time in microseconds to allow for I2C + transactions. This parameter is not allowed on some ports. Note that some ports/boards will have default values of *scl* and *sda* that can be changed in this constructor. Others will have fixed values @@ -80,6 +93,10 @@ General Methods - *sda* is a pin object for the SDA line - *freq* is the SCL clock rate + In the case of hardware I2C the actual clock frequency may be lower than the + requested frequency. This is dependent on the platform hardware. The actual + rate may be determined by printing the I2C object. + .. method:: I2C.deinit() Turn off the I2C bus. diff --git a/docs/library/machine.I2S.rst b/docs/library/machine.I2S.rst index b602ac6504d3c..84edb94e78dbf 100644 --- a/docs/library/machine.I2S.rst +++ b/docs/library/machine.I2S.rst @@ -47,7 +47,7 @@ I2S objects can be created and initialized using:: 3 modes of operation are supported: - blocking - non-blocking - - uasyncio + - asyncio blocking:: @@ -63,13 +63,13 @@ non-blocking:: audio_in.irq(i2s_callback) # i2s_callback is called when buf is filled num_read = audio_in.readinto(buf) # returns immediately -uasyncio:: +asyncio:: - swriter = uasyncio.StreamWriter(audio_out) + swriter = asyncio.StreamWriter(audio_out) swriter.write(buf) await swriter.drain() - sreader = uasyncio.StreamReader(audio_in) + sreader = asyncio.StreamReader(audio_in) num_read = await sreader.readinto(buf) Some codec devices like the WM8960 or SGTL5000 require separate initialization @@ -103,7 +103,7 @@ Constructor - ``ibuf`` specifies internal buffer length (bytes) For all ports, DMA runs continuously in the background and allows user applications to perform other operations while - sample data is transfered between the internal buffer and the I2S peripheral unit. + sample data is transferred between the internal buffer and the I2S peripheral unit. Increasing the size of the internal buffer has the potential to increase the time that user applications can perform non-I2S operations before underflow (e.g. ``write`` method) or overflow (e.g. ``readinto`` method). diff --git a/docs/library/machine.PWM.rst b/docs/library/machine.PWM.rst index 4b74355775602..b9cf00240314c 100644 --- a/docs/library/machine.PWM.rst +++ b/docs/library/machine.PWM.rst @@ -10,7 +10,8 @@ Example usage:: from machine import PWM - pwm = PWM(pin) # create a PWM object on a pin + pwm = PWM(pin, freq=50, duty_u16=8192) # create a PWM object on a pin + # and set freq and duty pwm.duty_u16(32768) # set duty to 50% # reinitialise with a period of 200us, duty of 5us @@ -23,7 +24,7 @@ Example usage:: Constructors ------------ -.. class:: PWM(dest, *, freq, duty_u16, duty_ns) +.. class:: PWM(dest, *, freq, duty_u16, duty_ns, invert) Construct and return a new PWM object using the following parameters: @@ -34,10 +35,12 @@ Constructors PWM cycle. - *duty_u16* sets the duty cycle as a ratio ``duty_u16 / 65535``. - *duty_ns* sets the pulse width in nanoseconds. + - *invert* inverts the respective output if the value is True Setting *freq* may affect other PWM objects if the objects share the same underlying PWM generator (this is hardware specific). Only one of *duty_u16* and *duty_ns* should be specified at a time. + *invert* is not available at all ports. Methods ------- diff --git a/docs/library/machine.SPI.rst b/docs/library/machine.SPI.rst index 7b0e8cf40689f..7c3c4b583265a 100644 --- a/docs/library/machine.SPI.rst +++ b/docs/library/machine.SPI.rst @@ -98,7 +98,7 @@ Methods specify them as a tuple of ``pins`` parameter. In the case of hardware SPI the actual clock frequency may be lower than the - requested baudrate. This is dependant on the platform hardware. The actual + requested baudrate. This is dependent on the platform hardware. The actual rate may be determined by printing the SPI object. .. method:: SPI.deinit() diff --git a/docs/library/machine.Timer.rst b/docs/library/machine.Timer.rst index 424a49bcba488..44e6594080558 100644 --- a/docs/library/machine.Timer.rst +++ b/docs/library/machine.Timer.rst @@ -38,13 +38,16 @@ Constructors Methods ------- -.. method:: Timer.init(*, mode=Timer.PERIODIC, period=-1, callback=None) +.. method:: Timer.init(*, mode=Timer.PERIODIC, freq=-1, period=-1, callback=None) Initialise the timer. Example:: def mycallback(t): pass + # periodic at 1kHz + tim.init(mode=Timer.PERIODIC, freq=1000, callback=mycallback) + # periodic with 100ms period tim.init(period=100, callback=mycallback) @@ -60,12 +63,17 @@ Methods - ``Timer.PERIODIC`` - The timer runs periodically at the configured frequency of the channel. + - ``freq`` - The timer frequency, in units of Hz. The upper bound of + the frequency is dependent on the port. When both the ``freq`` and + ``period`` arguments are given, ``freq`` has a higher priority and + ``period`` is ignored. + - ``period`` - The timer period, in milliseconds. - ``callback`` - The callable to call upon expiration of the timer period. The callback must take one argument, which is passed the Timer object. The ``callback`` argument shall be specified. Otherwise an exception - will occurr upon timer expiration: + will occur upon timer expiration: ``TypeError: 'NoneType' object isn't callable`` .. method:: Timer.deinit() diff --git a/docs/library/machine.UART.rst b/docs/library/machine.UART.rst index e239525736983..072bdb7188a3d 100644 --- a/docs/library/machine.UART.rst +++ b/docs/library/machine.UART.rst @@ -87,10 +87,22 @@ Methods When no pins are given, then the default set of TX and RX pins is taken, and hardware flow control will be disabled. If *pins* is ``None``, no pin assignment will be made. + .. note:: + It is possible to call ``init()`` multiple times on the same object in + order to reconfigure UART on the fly. That allows using single UART + peripheral to serve different devices attached to different GPIO pins. + Only one device can be served at a time in that case. + Also do not call ``deinit()`` as it will prevent calling ``init()`` + again. + .. method:: UART.deinit() Turn off the UART bus. + .. note:: + You will not be able to call ``init()`` on the object after ``deinit()``. + A new instance needs to be created in that case. + .. method:: UART.any() Returns an integer counting the number of characters that can be read without @@ -165,6 +177,32 @@ Methods Availability: WiPy. +.. method:: UART.flush() + + Waits until all data has been sent. In case of a timeout, an exception is raised. The timeout + duration depends on the tx buffer size and the baud rate. Unless flow control is enabled, a timeout + should not occur. + + .. note:: + + For the rp2, esp8266 and nrf ports the call returns while the last byte is sent. + If required, a one character wait time has to be added in the calling script. + + Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra + +.. method:: UART.txdone() + + Tells whether all data has been sent or no data transfer is happening. In this case, + it returns ``True``. If a data transmission is ongoing it returns ``False``. + + .. note:: + + For the rp2, esp8266 and nrf ports the call may return ``True`` even if the last byte + of a transfer is still being sent. If required, a one character wait time has to be + added in the calling script. + + Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra + Constants --------- diff --git a/docs/library/machine.WDT.rst b/docs/library/machine.WDT.rst index 8c81e10ea5817..cf77df9632088 100644 --- a/docs/library/machine.WDT.rst +++ b/docs/library/machine.WDT.rst @@ -15,7 +15,7 @@ Example usage:: wdt = WDT(timeout=2000) # enable it with a timeout of 2s wdt.feed() -Availability of this class: pyboard, WiPy, esp8266, esp32. +Availability of this class: pyboard, WiPy, esp8266, esp32, rp2040, mimxrt. Constructors ------------ @@ -25,8 +25,8 @@ Constructors Create a WDT object and start it. The timeout must be given in milliseconds. Once it is running the timeout cannot be changed and the WDT cannot be stopped either. - Notes: On the esp32 the minimum timeout is 1 second. On the esp8266 a timeout - cannot be specified, it is determined by the underlying system. + Notes: On the esp8266 a timeout cannot be specified, it is determined by the underlying system. + On rp2040 devices, the maximum timeout is 8388 ms. Methods ------- diff --git a/docs/library/machine.rst b/docs/library/machine.rst index c3bf43896136b..3f5cd6f13c72b 100644 --- a/docs/library/machine.rst +++ b/docs/library/machine.rst @@ -19,6 +19,44 @@ This is true for both physical devices with IDs >= 0 and "virtual" devices with negative IDs like -1 (these "virtual" devices are still thin shims on top of real hardware and real hardware interrupts). See :ref:`isr_rules`. +Memory access +------------- + +The module exposes three objects used for raw memory access. + +.. data:: mem8 + + Read/write 8 bits of memory. + +.. data:: mem16 + + Read/write 16 bits of memory. + +.. data:: mem32 + + Read/write 32 bits of memory. + +Use subscript notation ``[...]`` to index these objects with the address of +interest. Note that the address is the byte address, regardless of the size of +memory being accessed. + +Example use (registers are specific to an stm32 microcontroller): + +.. code-block:: python3 + + import machine + from micropython import const + + GPIOA = const(0x48000000) + GPIO_BSRR = const(0x18) + GPIO_IDR = const(0x10) + + # set PA2 high + machine.mem32[GPIOA + GPIO_BSRR] = 1 << 2 + + # read PA3 + value = (machine.mem32[GPIOA + GPIO_IDR] >> 3) & 1 + Reset related functions ----------------------- diff --git a/docs/library/micropython.rst b/docs/library/micropython.rst index 7106a1a2ff16d..b17dfa9a75a48 100644 --- a/docs/library/micropython.rst +++ b/docs/library/micropython.rst @@ -9,7 +9,7 @@ Functions .. function:: const(expr) - Used to declare that the expression is a constant so that the compile can + Used to declare that the expression is a constant so that the compiler can optimise it. The use of this function should be as follows:: from micropython import const diff --git a/docs/library/neopixel.rst b/docs/library/neopixel.rst index 1b37f088baa71..543f2588125e0 100644 --- a/docs/library/neopixel.rst +++ b/docs/library/neopixel.rst @@ -6,9 +6,11 @@ This module provides a driver for WS2818 / NeoPixel LEDs. -.. note:: This module is only included by default on the ESP8266 and ESP32 - ports. On STM32 / Pyboard, you can `download the module - `_ +.. note:: This module is only included by default on the ESP8266, ESP32 and RP2 + ports. On STM32 / Pyboard and others, you can either install the + ``neopixel`` package using :term:`mip`, or you can download the module + directly from + `_ and copy it to the filesystem. class NeoPixel diff --git a/docs/library/network.CC3K.rst b/docs/library/network.CC3K.rst deleted file mode 100644 index 41d3fb437e992..0000000000000 --- a/docs/library/network.CC3K.rst +++ /dev/null @@ -1,89 +0,0 @@ -.. currentmodule:: network -.. _network.CC3K: - -class CC3K -- control CC3000 WiFi modules -========================================= - -This class provides a driver for CC3000 WiFi modules. Example usage:: - - import network - nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3) - nic.connect('your-ssid', 'your-password') - while not nic.isconnected(): - pyb.delay(50) - print(nic.ifconfig()) - - # now use socket as usual - ... - -For this example to work the CC3000 module must have the following connections: - - - MOSI connected to Y8 - - MISO connected to Y7 - - CLK connected to Y6 - - CS connected to Y5 - - VBEN connected to Y4 - - IRQ connected to Y3 - -It is possible to use other SPI buses and other pins for CS, VBEN and IRQ. - -Constructors ------------- - -.. class:: CC3K(spi, pin_cs, pin_en, pin_irq) - - Create a CC3K driver object, initialise the CC3000 module using the given SPI bus - and pins, and return the CC3K object. - - Arguments are: - - - *spi* is an :ref:`SPI object ` which is the SPI bus that the CC3000 is - connected to (the MOSI, MISO and CLK pins). - - *pin_cs* is a :ref:`Pin object ` which is connected to the CC3000 CS pin. - - *pin_en* is a :ref:`Pin object ` which is connected to the CC3000 VBEN pin. - - *pin_irq* is a :ref:`Pin object ` which is connected to the CC3000 IRQ pin. - - All of these objects will be initialised by the driver, so there is no need to - initialise them yourself. For example, you can use:: - - nic = network.CC3K(pyb.SPI(2), pyb.Pin.board.Y5, pyb.Pin.board.Y4, pyb.Pin.board.Y3) - -Methods -------- - -.. method:: CC3K.connect(ssid, key=None, *, security=WPA2, bssid=None) - - Connect to a WiFi access point using the given SSID, and other security - parameters. - -.. method:: CC3K.disconnect() - - Disconnect from the WiFi access point. - -.. method:: CC3K.isconnected() - - Returns True if connected to a WiFi access point and has a valid IP address, - False otherwise. - -.. method:: CC3K.ifconfig() - - Returns a 7-tuple with (ip, subnet mask, gateway, DNS server, DHCP server, - MAC address, SSID). - -.. method:: CC3K.patch_version() - - Return the version of the patch program (firmware) on the CC3000. - -.. method:: CC3K.patch_program('pgm') - - Upload the current firmware to the CC3000. You must pass 'pgm' as the first - argument in order for the upload to proceed. - -Constants ---------- - -.. data:: CC3K.WEP -.. data:: CC3K.WPA -.. data:: CC3K.WPA2 - - security type to use diff --git a/docs/library/network.LAN.rst b/docs/library/network.LAN.rst index 58bd61ebbd873..375e02cefecd0 100644 --- a/docs/library/network.LAN.rst +++ b/docs/library/network.LAN.rst @@ -19,7 +19,7 @@ Example usage:: Constructors ------------ -.. class:: LAN(id, *, phy_type=, phy_addr=, phy_clock=) +.. class:: LAN(id, *, phy_type=, phy_addr=, ref_clk_mode=) Create a LAN driver object, initialise the LAN module using the given PHY driver name, and return the LAN object. @@ -31,13 +31,15 @@ Constructors is the default. Suitable values are port specific. - *phy_addr* specifies the address of the PHY interface. As with *phy_type*, the hardwired value has to be used for most boards and that value is the default. - - *phy_clock* specifies, whether the data clock is provided by the Ethernet controller or the PYH interface. - The default value is the one that matches the board. If set to ``True``, the clock is driven by the - Ethernet controller, otherwise by the PHY interface. + - *ref_clk_mode* specifies, whether the data clock is provided by the Ethernet controller or + the PYH interface. + The default value is the one that matches the board. If set to ``LAN.OUT`` or ``Pin.OUT`` + or ``True``, the clock is driven by the Ethernet controller, if set to ``LAN.IN`` + or ``Pin.IN`` or ``False``, the clock is driven by the PHY interface. For example, with the Seeed Arch Mix board you can use:: - nic = LAN(0, phy_type=LAN.PHY_LAN8720, phy_addr=2, phy_clock=False) + nic = LAN(0, phy_type=LAN.PHY_LAN8720, phy_addr=1, ref_clk_mode=Pin.IN) Methods ------- diff --git a/docs/library/network.WLAN.rst b/docs/library/network.WLAN.rst index bc416d1c2edde..68cd49769afff 100644 --- a/docs/library/network.WLAN.rst +++ b/docs/library/network.WLAN.rst @@ -130,7 +130,23 @@ Methods hidden Whether SSID is hidden (boolean) security Security protocol supported (enumeration, see module constants) key Access key (string) - dhcp_hostname The DHCP hostname to use + hostname The hostname that will be sent to DHCP (STA interfaces) and mDNS (if supported, both STA and AP). (Deprecated, use :func:`network.hostname` instead) reconnects Number of reconnect attempts to make (integer, 0=none, -1=unlimited) txpower Maximum transmit power in dBm (integer or float) + pm WiFi Power Management setting (see below for allowed values) ============= =========== + +Constants +--------- + +.. data:: WLAN.PM_PERFORMANCE + WLAN.PM_POWERSAVE + WLAN.PM_NONE + + Allowed values for the ``WLAN.config(pm=...)`` network interface parameter: + + * ``PM_PERFORMANCE``: enable WiFi power management to balance power + savings and WiFi performance + * ``PM_POWERSAVE``: enable WiFi power management with additional power + savings and reduced WiFi performance + * ``PM_NONE``: disable wifi power management diff --git a/docs/library/network.rst b/docs/library/network.rst index 6742a2e0733db..b13c84123ce7f 100644 --- a/docs/library/network.rst +++ b/docs/library/network.rst @@ -150,7 +150,6 @@ provide a way to control networking interfaces of various kinds. network.WLAN.rst network.WLANWiPy.rst - network.CC3K.rst network.WIZNET5K.rst network.LAN.rst @@ -159,12 +158,39 @@ Network functions The following are functions available in the network module. +.. function:: country([code]) + + Get or set the two-letter ISO 3166-1 Alpha-2 country code to be used for + radio compliance. + + If the *code* parameter is provided, the country will be set to this value. + If the function is called without parameters, it returns the current + country. + + The default code ``"XX"`` represents the "worldwide" region. + +.. function:: hostname([name]) + + Get or set the hostname that will identify this device on the network. It is + applied to all interfaces. + + This hostname is used for: + * Sending to the DHCP server in the client request. (If using DHCP) + * Broadcasting via mDNS. (If enabled) + + If the *name* parameter is provided, the hostname will be set to this value. + If the function is called without parameters, it returns the current + hostname. + + The default hostname is typically the name of the board. + .. function:: phy_mode([mode]) Get or set the PHY mode. - If the *mode* parameter is provided, sets the mode to its value. If - the function is called without parameters, returns the current mode. + If the *mode* parameter is provided, the PHY mode will be set to this value. + If the function is called without parameters, it returns the current PHY + mode. The possible modes are defined as constants: * ``MODE_11B`` -- IEEE 802.11b, diff --git a/docs/library/os.rst b/docs/library/os.rst index 19652ee2bc5ef..27a7d2d44a05b 100644 --- a/docs/library/os.rst +++ b/docs/library/os.rst @@ -86,7 +86,7 @@ Filesystem access .. function:: statvfs(path) - Get the status of a fileystem. + Get the status of a filesystem. Returns a tuple with the filesystem information in the following order: diff --git a/docs/library/pyb.CAN.rst b/docs/library/pyb.CAN.rst index 54377091db2b1..57a85d54b7714 100644 --- a/docs/library/pyb.CAN.rst +++ b/docs/library/pyb.CAN.rst @@ -252,7 +252,7 @@ Methods For example:: buf = bytearray(8) - lst = [0, 0, 0, memoryview(buf)] + lst = [0, 0, 0, 0, memoryview(buf)] # No heap memory is allocated in the following call can.recv(0, lst) @@ -272,7 +272,7 @@ Methods - *fdf* for CAN FD controllers, if set to True, the frame will have an FD frame format, which supports data payloads up to 64 bytes. - *brs* for CAN FD controllers, if set to True, the bitrate switching mode - is enabled, in which the data phase is transmitted at a differet bitrate. + is enabled, in which the data phase is transmitted at a different bitrate. See :meth:`CAN.init` for the data bit timing configuration parameters. If timeout is 0 the message is placed in a buffer in one of three hardware diff --git a/docs/library/pyb.I2C.rst b/docs/library/pyb.I2C.rst index 24b9cb8c3aaf3..71d043aa6d4f9 100644 --- a/docs/library/pyb.I2C.rst +++ b/docs/library/pyb.I2C.rst @@ -96,6 +96,10 @@ Methods that DMA transfers have more precise timing but currently do not handle bus errors properly) + The actual clock frequency may be lower than the requested frequency. + This is dependent on the platform hardware. The actual rate may be determined + by printing the I2C object. + .. method:: I2C.is_ready(addr) Check if an I2C device responds to the given address. Only valid when in controller mode. diff --git a/docs/library/pyb.Pin.rst b/docs/library/pyb.Pin.rst index d13cb9741cd22..b93924508b943 100644 --- a/docs/library/pyb.Pin.rst +++ b/docs/library/pyb.Pin.rst @@ -58,16 +58,6 @@ an ordinal pin number: You can set ``pyb.Pin.debug(True)`` to get some debug information about how a particular object gets mapped to a pin. -When a pin has the ``Pin.PULL_UP`` or ``Pin.PULL_DOWN`` pull-mode enabled, -that pin has an effective 40k Ohm resistor pulling it to 3V3 or GND -respectively (except pin Y5 which has 11k Ohm resistors). - -Now every time a falling edge is seen on the gpio pin, the callback will be -executed. Caution: mechanical push buttons have "bounce" and pushing or -releasing a switch will often generate multiple edges. -See: http://www.eng.utah.edu/~cs5780/debouncing.pdf for a detailed -explanation, along with various techniques for debouncing. - All pin objects go through the pin mapper to come up with one of the gpio pins. @@ -107,7 +97,8 @@ Methods - ``Pin.IN`` - configure the pin for input; - ``Pin.OUT_PP`` - configure the pin for output, with push-pull control; - ``Pin.OUT_OD`` - configure the pin for output, with open-drain control; - - ``Pin.AF_PP`` - configure the pin for alternate function, pull-pull; + - ``Pin.ALT`` - configure the pin for alternate function, input or output; + - ``Pin.AF_PP`` - configure the pin for alternate function, push-pull; - ``Pin.AF_OD`` - configure the pin for alternate function, open-drain; - ``Pin.ANALOG`` - configure the pin for analog. @@ -117,10 +108,14 @@ Methods - ``Pin.PULL_UP`` - enable the pull-up resistor; - ``Pin.PULL_DOWN`` - enable the pull-down resistor. + When a pin has the ``Pin.PULL_UP`` or ``Pin.PULL_DOWN`` pull-mode enabled, + that pin has an effective 40k Ohm resistor pulling it to 3V3 or GND + respectively (except pin Y5 which has 11k Ohm resistors). + - *value* if not None will set the port output value before enabling the pin. - - *alt* can be used when mode is ``Pin.AF_PP`` or ``Pin.AF_OD`` to set the - index or name of one of the alternate functions associated with a pin. + - *alt* can be used when mode is ``Pin.ALT`` , ``Pin.AF_PP`` or ``Pin.AF_OD`` to + set the index or name of one of the alternate functions associated with a pin. This arg was previously called *af* which can still be used if needed. Returns: ``None``. @@ -183,6 +178,10 @@ Methods Constants --------- +.. data:: Pin.ALT + + initialise the pin to alternate-function mode for input or output + .. data:: Pin.AF_OD initialise the pin to alternate-function mode with an open-drain drive @@ -243,11 +242,11 @@ control is desired. To configure X3 to expose TIM2_CH3, you could use:: - pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, alt=pyb.Pin.AF1_TIM2) + pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.ALT, alt=pyb.Pin.AF1_TIM2) or:: - pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.AF_PP, alt=1) + pin = pyb.Pin(pyb.Pin.board.X3, mode=pyb.Pin.ALT, alt=1) Methods ------- diff --git a/docs/library/pyb.Timer.rst b/docs/library/pyb.Timer.rst index 53213666ba87b..1749efce2d508 100644 --- a/docs/library/pyb.Timer.rst +++ b/docs/library/pyb.Timer.rst @@ -111,7 +111,9 @@ Methods the PWM when the ``BRK_IN`` input is asserted. The value of this argument determines if break is enabled and what the polarity is, and can be one of ``Timer.BRK_OFF``, ``Timer.BRK_LOW`` or - ``Timer.BRK_HIGH``. + ``Timer.BRK_HIGH``. To select the ``BRK_IN`` pin construct a Pin object with + ``mode=Pin.ALT, alt=Pin.AFn_TIMx``. The pin's GPIO input features are + available in alt mode - ``pull=`` , ``value()`` and ``irq()``. You must either specify freq or both of period and prescaler. @@ -204,6 +206,17 @@ Methods ch2 = timer.channel(2, pyb.Timer.PWM, pin=pyb.Pin.board.X2, pulse_width=8000) ch3 = timer.channel(3, pyb.Timer.PWM, pin=pyb.Pin.board.X3, pulse_width=16000) + PWM Motor Example with complementary outputs, dead time, break input and break callback:: + + from pyb import Timer + from machine import Pin # machine.Pin supports alt mode and irq on the same pin. + pin_t8_1 = Pin(Pin.board.Y1, mode=Pin.ALT, af=Pin.AF3_TIM8) # Pin PC6, TIM8_CH1 + pin_t8_1n = Pin(Pin.board.X8, mode=Pin.ALT, af=Pin.AF3_TIM8) # Pin PA7, TIM8_CH1N + pin_bkin = Pin(Pin.board.X7, mode=Pin.ALT, af=Pin.AF3_TIM8) # Pin PA6, TIM8_BKIN + pin_bkin.irq(handler=break_callabck, trigger=Pin.IRQ_FALLING) + timer = pyb.Timer(8, freq=1000, deadtime=1008, brk=Timer.BRK_LOW) + ch1 = timer.channel(1, pyb.Timer.PWM, pulse_width_percent=30) + .. method:: Timer.counter([value]) Get or set the timer counter. diff --git a/docs/library/random.rst b/docs/library/random.rst index dd8b47c80f084..be56eb088eae7 100644 --- a/docs/library/random.rst +++ b/docs/library/random.rst @@ -24,7 +24,7 @@ This module implements a pseudo-random number generator (PRNG). .. note:: The :func:`randrange`, :func:`randint` and :func:`choice` functions are only - available if the ``MICROPY_PY_URANDOM_EXTRA_FUNCS`` configuration option is + available if the ``MICROPY_PY_RANDOM_EXTRA_FUNCS`` configuration option is enabled. @@ -73,7 +73,7 @@ Other Functions supported by the port) initialise the PRNG with a true random number (usually a hardware generated random number). - The ``None`` case only works if ``MICROPY_PY_URANDOM_SEED_INIT_FUNC`` is + The ``None`` case only works if ``MICROPY_PY_RANDOM_SEED_INIT_FUNC`` is enabled by the port, otherwise it raises ``ValueError``. .. function:: choice(sequence) diff --git a/docs/library/rp2.StateMachine.rst b/docs/library/rp2.StateMachine.rst index 8d73ccf772a7f..ee16ce3c513da 100644 --- a/docs/library/rp2.StateMachine.rst +++ b/docs/library/rp2.StateMachine.rst @@ -55,8 +55,8 @@ Methods `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. - *push_thresh* is the threshold in bits before auto-push or conditional re-pushing is triggered. - - *pull_thresh* is the threshold in bits before auto-push or conditional - re-pushing is triggered. + - *pull_thresh* is the threshold in bits before auto-pull or conditional + re-pulling is triggered. .. method:: StateMachine.active([value]) @@ -82,11 +82,18 @@ Methods .. method:: StateMachine.exec(instr) - Execute a single PIO instruction. Uses `asm_pio_encode` to encode the - instruction from the given string *instr*. + Execute a single PIO instruction. + + If *instr* is a string then uses `asm_pio_encode` to encode the instruction + from the given string. >>> sm.exec("set(0, 1)") + If *instr* is an integer then it is treated as an already encoded PIO + machine code instruction to be executed. + + >>> sm.exec(rp2.asm_pio_encode("out(y, 8)", 0)) + .. method:: StateMachine.get(buf=None, shift=0) Pull a word from the state machine's RX FIFO. @@ -99,13 +106,17 @@ Methods .. method:: StateMachine.put(value, shift=0) - Push a word onto the state machine's TX FIFO. + Push words onto the state machine's TX FIFO. + + *value* can be an integer, an array of type ``B``, ``H`` or ``I``, or a + `bytearray`. - If the FIFO is full, it blocks until there is space (i.e. the state machine - pulls a word). + This method will block until all words have been written to the FIFO. If + the FIFO is, or becomes, full, the method will block until the state machine + pulls enough words to complete the write. - The value is first shifted left by *shift* bits, i.e. the state machine - receives ``value << shift``. + Each word is first shifted left by *shift* bits, i.e. the state machine + receives ``word << shift``. .. method:: StateMachine.rx_fifo() diff --git a/docs/library/rp2.rst b/docs/library/rp2.rst index 06affaae8cac5..7a473387b4a81 100644 --- a/docs/library/rp2.rst +++ b/docs/library/rp2.rst @@ -47,8 +47,8 @@ For running PIO programs, see :class:`rp2.StateMachine`. `PIO.SHIFT_LEFT` or `PIO.SHIFT_RIGHT`. - *push_thresh* is the threshold in bits before auto-push or conditional re-pushing is triggered. - - *pull_thresh* is the threshold in bits before auto-push or conditional - re-pushing is triggered. + - *pull_thresh* is the threshold in bits before auto-pull or conditional + re-pulling is triggered. The remaining parameters are: @@ -66,6 +66,17 @@ For running PIO programs, see :class:`rp2.StateMachine`. >>> rp2.asm_pio_encode("set(0, 1)", 0) 57345 +.. function:: bootsel_button() + + Temporarily turns the QSPI_SS pin into an input and reads its value, + returning 1 for low and 0 for high. + On a typical RP2040 board with a BOOTSEL button, a return value of 1 + indicates that the button is pressed. + + Since this function temporarily disables access to the external flash + memory, it also temporarily disables interrupts and the other core to + prevent them from trying to execute code from flash. + .. class:: PIOASMError This exception is raised from `asm_pio()` or `asm_pio_encode()` if there is diff --git a/docs/library/socket.rst b/docs/library/socket.rst index 1d1c23abd1976..944e7e631ac76 100644 --- a/docs/library/socket.rst +++ b/docs/library/socket.rst @@ -29,7 +29,7 @@ returned by `getaddrinfo` function, which must be used to resolve textual addres # You must use getaddrinfo() even for numeric addresses sockaddr = socket.getaddrinfo('127.0.0.1', 80)[0][-1] # Now you can use that address - sock.connect(addr) + sock.connect(sockaddr) Using `getaddrinfo` is the most efficient (both in terms of memory and processing power) and portable way to work with addresses. diff --git a/docs/library/ssl.rst b/docs/library/ssl.rst index 4726daa59b4ae..e3dfa9d993668 100644 --- a/docs/library/ssl.rst +++ b/docs/library/ssl.rst @@ -13,26 +13,54 @@ facilities for network sockets, both client-side and server-side. Functions --------- -.. function:: ssl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, ca_certs=None, do_handshake=True) +.. function:: ssl.wrap_socket(sock, server_side=False, keyfile=None, certfile=None, cert_reqs=CERT_NONE, cadata=None, server_hostname=None, do_handshake=True) + + Wrap the given *sock* and return a new wrapped-socket object. The implementation + of this function is to first create an `SSLContext` and then call the `SSLContext.wrap_socket` + method on that context object. The arguments *sock*, *server_side* and *server_hostname* are + passed through unchanged to the method call. The argument *do_handshake* is passed through as + *do_handshake_on_connect*. The remaining arguments have the following behaviour: + + - *cert_reqs* determines whether the peer (server or client) must present a valid certificate. + Note that for mbedtls based ports, ``ssl.CERT_NONE`` and ``ssl.CERT_OPTIONAL`` will not + validate any certificate, only ``ssl.CERT_REQUIRED`` will. + + - *cadata* is a bytes object containing the CA certificate chain (in DER format) that will + validate the peer's certificate. Currently only a single DER-encoded certificate is supported. + + Depending on the underlying module implementation in a particular + :term:`MicroPython port`, some or all keyword arguments above may be not supported. + +class SSLContext +---------------- + +.. class:: SSLContext(protocol, /) + + Create a new SSLContext instance. The *protocol* argument must be one of the ``PROTOCOL_*`` + constants. + +.. method:: SSLContext.wrap_socket(sock, *, server_side=False, do_handshake_on_connect=True, server_hostname=None) Takes a `stream` *sock* (usually socket.socket instance of ``SOCK_STREAM`` type), - and returns an instance of ssl.SSLSocket, which wraps the underlying stream in - an SSL context. Returned object has the usual `stream` interface methods like + and returns an instance of ssl.SSLSocket, wrapping the underlying stream. + The returned object has the usual `stream` interface methods like ``read()``, ``write()``, etc. - A server-side SSL socket should be created from a normal socket returned from - :meth:`~socket.socket.accept()` on a non-SSL listening server socket. - - *do_handshake* determines whether the handshake is done as part of the ``wrap_socket`` + - *server_side* selects whether the wrapped socket is on the server or client side. + A server-side SSL socket should be created from a normal socket returned from + :meth:`~socket.socket.accept()` on a non-SSL listening server socket. + + - *do_handshake_on_connect* determines whether the handshake is done as part of the ``wrap_socket`` or whether it is deferred to be done as part of the initial reads or writes - (there is no ``do_handshake`` method as in CPython). For blocking sockets doing the handshake immediately is standard. For non-blocking sockets (i.e. when the *sock* passed into ``wrap_socket`` is in non-blocking mode) the handshake should generally be deferred because otherwise ``wrap_socket`` blocks until it completes. Note that in AXTLS the handshake can be deferred until the first read or write but it then blocks until completion. - Depending on the underlying module implementation in a particular - :term:`MicroPython port`, some or all keyword arguments above may be not supported. + - *server_hostname* is for use as a client, and sets the hostname to check against the received + server certificate. It also sets the name for Server Name Indication (SNI), allowing the server + to present the proper certificate. .. warning:: @@ -44,6 +72,11 @@ Functions returns an object more similar to CPython's ``SSLObject`` which does not have these socket methods. +.. attribute:: SSLContext.verify_mode + + Set or get the behaviour for verification of peer certificates. Must be one of the + ``CERT_*`` constants. + Exceptions ---------- @@ -54,8 +87,14 @@ Exceptions Constants --------- +.. data:: ssl.PROTOCOL_TLS_CLIENT + ssl.PROTOCOL_TLS_SERVER + + Supported values for the *protocol* parameter. + .. data:: ssl.CERT_NONE ssl.CERT_OPTIONAL ssl.CERT_REQUIRED - Supported values for *cert_reqs* parameter. + Supported values for *cert_reqs* parameter, and the :attr:`SSLContext.verify_mode` + attribute. diff --git a/docs/library/struct.rst b/docs/library/struct.rst index 92757aba8d50a..026cb5e8ac3b4 100644 --- a/docs/library/struct.rst +++ b/docs/library/struct.rst @@ -6,11 +6,58 @@ |see_cpython_module| :mod:`python:struct`. -Supported size/byte order prefixes: ``@``, ``<``, ``>``, ``!``. - -Supported format codes: ``b``, ``B``, ``h``, ``H``, ``i``, ``I``, ``l``, -``L``, ``q``, ``Q``, ``s``, ``P``, ``f``, ``d`` (the latter 2 depending -on the floating-point support). +The following byte orders are supported: + ++-----------+------------------------+----------+-----------+ +| Character | Byte order | Size | Alignment | ++===========+========================+==========+===========+ +| @ | native | native | native | ++-----------+------------------------+----------+-----------+ +| < | little-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| > | big-endian | standard | none | ++-----------+------------------------+----------+-----------+ +| ! | network (= big-endian) | standard | none | ++-----------+------------------------+----------+-----------+ + +The following data types are supported: + ++--------+--------------------+-------------------+---------------+ +| Format | C Type | Python type | Standard size | ++========+====================+===================+===============+ +| b | signed char | integer | 1 | ++--------+--------------------+-------------------+---------------+ +| B | unsigned char | integer | 1 | ++--------+--------------------+-------------------+---------------+ +| h | short | integer | 2 | ++--------+--------------------+-------------------+---------------+ +| H | unsigned short | integer | 2 | ++--------+--------------------+-------------------+---------------+ +| i | int | integer (`1`) | 4 | ++--------+--------------------+-------------------+---------------+ +| I | unsigned int | integer (`1`) | 4 | ++--------+--------------------+-------------------+---------------+ +| l | long | integer (`1`) | 4 | ++--------+--------------------+-------------------+---------------+ +| L | unsigned long | integer (`1`) | 4 | ++--------+--------------------+-------------------+---------------+ +| q | long long | integer (`1`) | 8 | ++--------+--------------------+-------------------+---------------+ +| Q | unsigned long long | integer (`1`) | 8 | ++--------+--------------------+-------------------+---------------+ +| f | float | float (`2`) | 4 | ++--------+--------------------+-------------------+---------------+ +| d | double | float (`2`) | 8 | ++--------+--------------------+-------------------+---------------+ +| s | char[] | bytes | | ++--------+--------------------+-------------------+---------------+ +| P | void * | integer | | ++--------+--------------------+-------------------+---------------+ + +.. _fn: + +(1) Requires long support when used with values larger than 30 bits. +(2) Requires floating point support. .. admonition:: Difference to CPython :class: attention @@ -43,5 +90,5 @@ Functions .. function:: unpack_from(fmt, data, offset=0, /) Unpack from the *data* starting at *offset* according to the format string - *fmt*. *offset* may be negative to count from the end of *buffer*. The return + *fmt*. *offset* may be negative to count from the end of *data*. The return value is a tuple of the unpacked values. diff --git a/docs/library/sys.rst b/docs/library/sys.rst index 3efdce964ce05..c8eb4b5c502b9 100644 --- a/docs/library/sys.rst +++ b/docs/library/sys.rst @@ -46,7 +46,7 @@ Functions .. function:: settrace(tracefunc) Enable tracing of bytecode execution. For details see the `CPython - documentaion `_. + documentation `_. This function requires a custom MicroPython build as it is typically not present in pre-built firmware (due to it affecting performance). The relevant diff --git a/docs/library/time.rst b/docs/library/time.rst index 6ca172f22128e..8c1c1d4d6fb23 100644 --- a/docs/library/time.rst +++ b/docs/library/time.rst @@ -10,8 +10,8 @@ The ``time`` module provides functions for getting the current time and date, measuring time intervals, and for delays. **Time Epoch**: Unix port uses standard for POSIX systems epoch of -1970-01-01 00:00:00 UTC. However, embedded ports use epoch of -2000-01-01 00:00:00 UTC. +1970-01-01 00:00:00 UTC. However, some embedded ports use epoch of +2000-01-01 00:00:00 UTC. Epoch year may be determined with ``gmtime(0)[0]``. **Maintaining actual calendar date/time**: This requires a Real Time Clock (RTC). On systems with underlying OS (including some @@ -163,8 +163,8 @@ Functions However, values returned by `ticks_ms()`, etc. functions may wrap around, so directly using subtraction on them will produce incorrect result. That is why `ticks_diff()` is needed, it implements modular (or more specifically, ring) - arithmetics to produce correct result even for wrap-around values (as long as they not - too distant inbetween, see below). The function returns **signed** value in the range + arithmetic to produce correct result even for wrap-around values (as long as they not + too distant in between, see below). The function returns **signed** value in the range [*-TICKS_PERIOD/2* .. *TICKS_PERIOD/2-1*] (that's a typical range definition for two's-complement signed binary integers). If the result is negative, it means that *ticks1* occurred earlier in time than *ticks2*. Otherwise, it means that @@ -183,7 +183,7 @@ Functions has passed. To avoid this mistake, just look at the clock regularly. Your application should do the same. "Too long sleep" metaphor also maps directly to application behaviour: don't let your application run any single task for too long. Run tasks - in steps, and do time-keeping inbetween. + in steps, and do time-keeping in between. `ticks_diff()` is designed to accommodate various usage patterns, among them: diff --git a/docs/library/uasyncio.rst b/docs/library/uasyncio.rst deleted file mode 100644 index 0abbf8dd8d7d2..0000000000000 --- a/docs/library/uasyncio.rst +++ /dev/null @@ -1,354 +0,0 @@ -:mod:`uasyncio` --- asynchronous I/O scheduler -============================================== - -.. module:: uasyncio - :synopsis: asynchronous I/O scheduler for writing concurrent code - -|see_cpython_module| -`asyncio `_ - -Example:: - - import uasyncio - - async def blink(led, period_ms): - while True: - led.on() - await uasyncio.sleep_ms(5) - led.off() - await uasyncio.sleep_ms(period_ms) - - async def main(led1, led2): - uasyncio.create_task(blink(led1, 700)) - uasyncio.create_task(blink(led2, 400)) - await uasyncio.sleep_ms(10_000) - - # Running on a pyboard - from pyb import LED - uasyncio.run(main(LED(1), LED(2))) - - # Running on a generic board - from machine import Pin - uasyncio.run(main(Pin(1), Pin(2))) - -Core functions --------------- - -.. function:: create_task(coro) - - Create a new task from the given coroutine and schedule it to run. - - Returns the corresponding `Task` object. - -.. function:: current_task() - - Return the `Task` object associated with the currently running task. - -.. function:: run(coro) - - Create a new task from the given coroutine and run it until it completes. - - Returns the value returned by *coro*. - -.. function:: sleep(t) - - Sleep for *t* seconds (can be a float). - - This is a coroutine. - -.. function:: sleep_ms(t) - - Sleep for *t* milliseconds. - - This is a coroutine, and a MicroPython extension. - -Additional functions --------------------- - -.. function:: wait_for(awaitable, timeout) - - Wait for the *awaitable* to complete, but cancel it if it takes longer - than *timeout* seconds. If *awaitable* is not a task then a task will be - created from it. - - If a timeout occurs, it cancels the task and raises ``uasyncio.TimeoutError``: - this should be trapped by the caller. The task receives - ``uasyncio.CancelledError`` which may be ignored or trapped using ``try...except`` - or ``try...finally`` to run cleanup code. - - Returns the return value of *awaitable*. - - This is a coroutine. - -.. function:: wait_for_ms(awaitable, timeout) - - Similar to `wait_for` but *timeout* is an integer in milliseconds. - - This is a coroutine, and a MicroPython extension. - -.. function:: gather(*awaitables, return_exceptions=False) - - Run all *awaitables* concurrently. Any *awaitables* that are not tasks are - promoted to tasks. - - Returns a list of return values of all *awaitables*. - - This is a coroutine. - -class Task ----------- - -.. class:: Task() - - This object wraps a coroutine into a running task. Tasks can be waited on - using ``await task``, which will wait for the task to complete and return - the return value of the task. - - Tasks should not be created directly, rather use `create_task` to create them. - -.. method:: Task.cancel() - - Cancel the task by injecting ``uasyncio.CancelledError`` into it. The task may - ignore this exception. Cleanup code may be run by trapping it, or via - ``try ... finally``. - -class Event ------------ - -.. class:: Event() - - Create a new event which can be used to synchronise tasks. Events start - in the cleared state. - -.. method:: Event.is_set() - - Returns ``True`` if the event is set, ``False`` otherwise. - -.. method:: Event.set() - - Set the event. Any tasks waiting on the event will be scheduled to run. - - Note: This must be called from within a task. It is not safe to call this - from an IRQ, scheduler callback, or other thread. See `ThreadSafeFlag`. - -.. method:: Event.clear() - - Clear the event. - -.. method:: Event.wait() - - Wait for the event to be set. If the event is already set then it returns - immediately. - - This is a coroutine. - -class ThreadSafeFlag --------------------- - -.. class:: ThreadSafeFlag() - - Create a new flag which can be used to synchronise a task with code running - outside the uasyncio loop, such as other threads, IRQs, or scheduler - callbacks. Flags start in the cleared state. - -.. method:: ThreadSafeFlag.set() - - Set the flag. If there is a task waiting on the event, it will be scheduled - to run. - -.. method:: ThreadSafeFlag.wait() - - Wait for the flag to be set. If the flag is already set then it returns - immediately. The flag is automatically reset upon return from ``wait``. - - A flag may only be waited on by a single task at a time. - - This is a coroutine. - -class Lock ----------- - -.. class:: Lock() - - Create a new lock which can be used to coordinate tasks. Locks start in - the unlocked state. - - In addition to the methods below, locks can be used in an ``async with`` statement. - -.. method:: Lock.locked() - - Returns ``True`` if the lock is locked, otherwise ``False``. - -.. method:: Lock.acquire() - - Wait for the lock to be in the unlocked state and then lock it in an atomic - way. Only one task can acquire the lock at any one time. - - This is a coroutine. - -.. method:: Lock.release() - - Release the lock. If any tasks are waiting on the lock then the next one in the - queue is scheduled to run and the lock remains locked. Otherwise, no tasks are - waiting an the lock becomes unlocked. - -TCP stream connections ----------------------- - -.. function:: open_connection(host, port) - - Open a TCP connection to the given *host* and *port*. The *host* address will be - resolved using `socket.getaddrinfo`, which is currently a blocking call. - - Returns a pair of streams: a reader and a writer stream. - Will raise a socket-specific ``OSError`` if the host could not be resolved or if - the connection could not be made. - - This is a coroutine. - -.. function:: start_server(callback, host, port, backlog=5) - - Start a TCP server on the given *host* and *port*. The *callback* will be - called with incoming, accepted connections, and be passed 2 arguments: reader - and writer streams for the connection. - - Returns a `Server` object. - - This is a coroutine. - -.. class:: Stream() - - This represents a TCP stream connection. To minimise code this class implements - both a reader and a writer, and both ``StreamReader`` and ``StreamWriter`` alias to - this class. - -.. method:: Stream.get_extra_info(v) - - Get extra information about the stream, given by *v*. The valid values for *v* are: - ``peername``. - -.. method:: Stream.close() - - Close the stream. - -.. method:: Stream.wait_closed() - - Wait for the stream to close. - - This is a coroutine. - -.. method:: Stream.read(n=-1) - - Read up to *n* bytes and return them. If *n* is not provided or -1 then read all - bytes until EOF. The returned value will be an empty bytes object if EOF is - encountered before any bytes are read. - - This is a coroutine. - -.. method:: Stream.readinto(buf) - - Read up to n bytes into *buf* with n being equal to the length of *buf*. - - Return the number of bytes read into *buf*. - - This is a coroutine, and a MicroPython extension. - -.. method:: Stream.readexactly(n) - - Read exactly *n* bytes and return them as a bytes object. - - Raises an ``EOFError`` exception if the stream ends before reading *n* bytes. - - This is a coroutine. - -.. method:: Stream.readline() - - Read a line and return it. - - This is a coroutine. - -.. method:: Stream.write(buf) - - Accumulated *buf* to the output buffer. The data is only flushed when - `Stream.drain` is called. It is recommended to call `Stream.drain` immediately - after calling this function. - -.. method:: Stream.drain() - - Drain (write) all buffered output data out to the stream. - - This is a coroutine. - -.. class:: Server() - - This represents the server class returned from `start_server`. It can be used - in an ``async with`` statement to close the server upon exit. - -.. method:: Server.close() - - Close the server. - -.. method:: Server.wait_closed() - - Wait for the server to close. - - This is a coroutine. - -Event Loop ----------- - -.. function:: get_event_loop() - - Return the event loop used to schedule and run tasks. See `Loop`. - -.. function:: new_event_loop() - - Reset the event loop and return it. - - Note: since MicroPython only has a single event loop this function just - resets the loop's state, it does not create a new one. - -.. class:: Loop() - - This represents the object which schedules and runs tasks. It cannot be - created, use `get_event_loop` instead. - -.. method:: Loop.create_task(coro) - - Create a task from the given *coro* and return the new `Task` object. - -.. method:: Loop.run_forever() - - Run the event loop until `stop()` is called. - -.. method:: Loop.run_until_complete(awaitable) - - Run the given *awaitable* until it completes. If *awaitable* is not a task - then it will be promoted to one. - -.. method:: Loop.stop() - - Stop the event loop. - -.. method:: Loop.close() - - Close the event loop. - -.. method:: Loop.set_exception_handler(handler) - - Set the exception handler to call when a Task raises an exception that is not - caught. The *handler* should accept two arguments: ``(loop, context)``. - -.. method:: Loop.get_exception_handler() - - Get the current exception handler. Returns the handler, or ``None`` if no - custom handler is set. - -.. method:: Loop.default_exception_handler(context) - - The default exception handler that is called. - -.. method:: Loop.call_exception_handler(context) - - Call the current exception handler. The argument *context* is passed through and - is a dictionary containing keys: ``'message'``, ``'exception'``, ``'future'``. diff --git a/docs/library/zephyr.DiskAccess.rst b/docs/library/zephyr.DiskAccess.rst index d19d81a962e23..3e5fa9a3575a0 100644 --- a/docs/library/zephyr.DiskAccess.rst +++ b/docs/library/zephyr.DiskAccess.rst @@ -34,5 +34,5 @@ Methods These methods implement the simple and extended :ref:`block protocol ` defined by - :class:`uos.AbstractBlockDev`. + :class:`os.AbstractBlockDev`. diff --git a/docs/library/zephyr.FlashArea.rst b/docs/library/zephyr.FlashArea.rst index 306347d449eab..9cd4dd59d6852 100644 --- a/docs/library/zephyr.FlashArea.rst +++ b/docs/library/zephyr.FlashArea.rst @@ -37,4 +37,4 @@ Methods These methods implement the simple and extended :ref:`block protocol ` defined by - :class:`uos.AbstractBlockDev`. + :class:`os.AbstractBlockDev`. diff --git a/docs/library/zephyr.rst b/docs/library/zephyr.rst index da3d14a093ecf..10676d9085289 100644 --- a/docs/library/zephyr.rst +++ b/docs/library/zephyr.rst @@ -32,7 +32,7 @@ Functions * *CPU utilization is only printed if runtime statistics are configured via the ``CONFIG_THREAD_RUNTIME_STATS`` kconfig* This function can only be accessed if ``CONFIG_THREAD_ANALYZER`` is configured for the port in ``zephyr/prj.conf``. - For more infomation, see documentation for Zephyr `thread analyzer + For more information, see documentation for Zephyr `thread analyzer `_. .. function:: shell_exec(cmd_in) diff --git a/docs/mimxrt/pinout.rst b/docs/mimxrt/pinout.rst index b82c153fc3ea4..b5a7fbbfe08ce 100644 --- a/docs/mimxrt/pinout.rst +++ b/docs/mimxrt/pinout.rst @@ -14,9 +14,9 @@ The pin assignment of UARTs to pins is fixed. The UARTs are numbered 0..8. The rx/tx pins are assigned according to the tables below: -================ =========== =========== =========== =========== +================= =========== =========== =========== =========== Board / Pin UART0 UART1 UART2 UART3 -================ =========== =========== =========== =========== +================= =========== =========== =========== =========== Teensy 4.0 - 0/1 7/8 14/15 Teensy 4.1 - 0/1 7/8 14/15 MIMXRT1010-EVK Debug USB D0/D1 D7/D6 - @@ -27,9 +27,10 @@ MIMXRT1050-EVKB Debug USB D0/D1 D7/D6 D8/D9 MIMXRT1060-EVK Debug USB D0/D1 D7/D6 D8/D9 MIMXRT1064-EVK Debug USB D0/D1 D7/D6 D8/D9 MIMXRT1170-EVK Debug USB D0/D1 D12/D11 D10/D13 +Adafruit Metro M7 - D0/D1 D7/D3 A1/A0 Olimex RT1010Py - RxD/TxD D5/D6 - -Seeed ARCH MIX - J3_19/J3_20 J4_16/J4_17 J4_06/J4_07 -================ =========== =========== =========== =========== +Seeed ARCH MIX - J3_19/J3_20 J4_16/J4_17 J4_06/J4_07 +================= =========== =========== =========== =========== | @@ -61,38 +62,38 @@ PWM pin assignment Pins are specified in the same way as for the Pin class. The following tables show the assignment of the board Pins to PWM modules: -=========== ========== ========== ====== ============== ====== -Pin/ MIMXRT 1010 1015 1020 1050/1060/1064 1170 -=========== ========== ========== ====== ============== ====== -D0 - Q1/1 F1/1/B - - -D1 - Q1/0 F1/1/A - - -D2 F1/3/B F1/3/A - F1/3/B - -D3 F1/3/A F1/0/A F2/3/B F4/0/A F1/2/A -D4 F1/3/A (*) Q1/2 Q2/1 F2/3/A Q4/2 -D5 F1/0/B (*) F1/0/B F2/3/A F1/3/A F1/2/B -D6 - F1/2/B F2/0/A Q3/2 F1/0/A -D7 - - F1/0/A Q3/3 - -D8 F1/0/A F1/1/B F1/0/B F1/1/X Q4/3 -D9 F1/1/B (*) F1/2/A F2/0/B F1/0/X F1/0/B -D10 F1/3/B - F2/2/B F1/0/B (*) F2/2/B -D11 F1/2/A - F2/1/A F1/1/A (*) - -D12 F1/2/B - F2/1/B F1/1/B (*) - -D13 F1/3/A - F2/2/A F1/0/A (*) F2/2/A -D14 F1/0/B - - F2/3/B - -D15 F1/0/A - - F2/3/A - -A0 - - F1/2/A - - -A1 F1/3/X F1/3/B F1/2/B - - -A2 F1/2/X F1/3/A F1/3/A - - -A3 - F1/2/A F1/3/B - - -A4 - - - Q3/1 - -A5 - - - Q3/0 - -D31 - - - - F1/2/B -D32 - - - - F1/2/A -D33 - - - - F1/1/B -D34 - - - - F1/1/A -D35 - - - - F1/0/B -D36 - - - - F1/0/A -=========== ========== ========== ====== ============== ====== +=========== ========== ========== ====== ========== ====== ======== +Pin/ MIMXRT 1010 1015 1020 1050/60/64 1170 Metro M7 +=========== ========== ========== ====== ========== ====== ======== +D0 - Q1/1 F1/1/B - - - +D1 - Q1/0 F1/1/A - - - +D2 F1/3/B F1/3/A - F1/3/B - - +D3 F1/3/A F1/0/A F2/3/B F4/0/A F1/2/A - +D4 F1/3/A (*) Q1/2 Q2/1 F2/3/A Q4/2 F1/0/B +D5 F1/0/B (*) F1/0/B F2/3/A F1/3/A F1/2/B F1/0/A +D6 - F1/2/B F2/0/A Q3/2 F1/0/A - +D7 - - F1/0/A Q3/3 - - +D8 F1/0/A F1/1/B F1/0/B F1/1/X Q4/3 F1/3/A +D9 F1/1/B (*) F1/2/A F2/0/B F1/0/X F1/0/B F1/3/B +D10 F1/3/B - F2/2/B F1/0/B (*) F2/2/B F1/2/A +D11 F1/2/A - F2/1/A F1/1/A (*) - F1/2/B +D12 F1/2/B - F2/1/B F1/1/B (*) - F1/1/A +D13 F1/3/A - F2/2/A F1/0/A (*) F2/2/A F1/1/B +D14 F1/0/B - - F2/3/B - F1/0/B +D15 F1/0/A - - F2/3/A - F1/0/A +A0 - - F1/2/A - - - +A1 F1/3/X F1/3/B F1/2/B - - - +A2 F1/2/X F1/3/A F1/3/A - - - +A3 - F1/2/A F1/3/B - - F1/3/B +A4 - - - Q3/1 - F1/2/X +A5 - - - Q3/0 - - +D31 - - - - F1/2/B - +D32 - - - - F1/2/A - +D33 - - - - F1/1/B - +D34 - - - - F1/1/A - +D35 - - - - F1/0/B - +D36 - - - - F1/0/A - +=========== ========== ========== ====== ========== ====== ======== Pins denoted with (*) are by default not wired at the board. @@ -318,11 +319,13 @@ MIXMXRT1050-EVKB D10/-/D11/D12/D13 (*) - - MIXMXRT1060-EVK D10/-/D11/D12/D13 (*) - - MIXMXRT1064-EVK D10/-/D11/D12/D13 (*) - - MIXMXRT1170-EVK D10/-/D11/D12/D13 D28/-/D25/D24/D26 -/-/D14/D15/D24 +Adafruit Metro M7 -/-/MOSI/MISO/SCK - - Olimex RT1010Py - CS0/-/SDO/SDI/SCK SDCARD with CS1 Seeed ARCH MIX J4_12/-/J4_14/J4_13/J4_15 J3_09/J3_05/J3_08_J3_11 ================= ========================= ======================= =============== -Pins denoted with (*) are by default not wired at the board. +Pins denoted with (*) are by default not wired at the board. The CS0 and CS1 signals +are enabled with the keyword option cs=0 or cs=1 of the SPI object constructor. .. _mimxrt_i2c_pinout: @@ -349,6 +352,7 @@ MIXMXRT1050-EVKB A4/A5 D1/D0 - - - MIXMXRT1060-EVK A4/A5 D1/D0 - - - MIXMXRT1064-EVK A4/A5 D1/D0 - - - MIXMXRT1170-EVK D14/D15 D1/D0 A4/A5 D26/D25 D19/D18 +Adafruit Metro M7 D14/D15 D0/D1 Olimex RT1010Py - SDA1/SCL1 SDA2/SCL2 - - Seeed ARCH MIX J3_17/J3_16 J4_06/J4_07 J5_05/J5_04 - - ================= =========== =========== =========== ======= ======= @@ -363,18 +367,19 @@ Hardware I2S pin assignment Pin assignments for a few MIMXRT boards: -=============== == ===== ======== ======= ======= ======== ======= ======= -Board ID MCK SCK_TX WS_TX SD_TX SCK_RX WS_RX SD_RX -=============== == ===== ======== ======= ======= ======== ======= ======= -Teensy 4.0 1 23 26 27 7 21 20 8 -Teensy 4.0 2 33 4 3 2 - - 5 -Teensy 4.1 1 23 26 27 7 21 20 8 -Teensy 4.1 2 33 4 3 2 - - 5 -Seeed Arch MIX 1 J4_09 J4_14 J4_15 J14_13 J4_11 J4_10 J4_10 -Olimex RT1010Py 1 D8 D6 D7 D4 D1 D2 D3 -Olimex RT1010Py 3 - D10 D9 D11 - - - -MIMXRT_DEV 1 "MCK" "SCK_TX" "WS_TX" "SD_TX" "SCK_RX" "WS_RX" "SD_RX" -=============== == ===== ======== ======= ======= ======== ======= ======= +================= == ===== ======== ======= ======= ======== ======= ======= +Board ID MCK SCK_TX WS_TX SD_TX SCK_RX WS_RX SD_RX +================= == ===== ======== ======= ======= ======== ======= ======= +Teensy 4.0 1 23 26 27 7 21 20 8 +Teensy 4.0 2 33 4 3 2 - - 5 +Teensy 4.1 1 23 26 27 7 21 20 8 +Teensy 4.1 2 33 4 3 2 - - 5 +Seeed Arch MIX 1 J4_09 J4_14 J4_15 J14_13 J4_11 J4_10 J4_10 +Adafruit Metro M7 1 D8 D10 D9 D12 D14 D15 D13 +Olimex RT1010Py 1 D8 D6 D7 D4 D1 D2 D3 +Olimex RT1010Py 3 - D10 D9 D11 - - - +MIMXRT_DEV 1 "MCK" "SCK_TX" "WS_TX" "SD_TX" "SCK_RX" "WS_RX" "SD_RX" +================= == ===== ======== ======= ======= ======== ======= ======= Symbolic pin names are provided for the MIMXRT_10xx_DEV boards. -These are provided for the other boards as well. \ No newline at end of file +These are provided for the other boards as well. diff --git a/docs/mimxrt/quickref.rst b/docs/mimxrt/quickref.rst index 0a14c632aafe5..ab8bf8831bbb0 100644 --- a/docs/mimxrt/quickref.rst +++ b/docs/mimxrt/quickref.rst @@ -56,21 +56,18 @@ Use the :mod:`time