Compare commits

..

No commits in common. "master" and "v1.17" have entirely different histories.

4594 changed files with 112736 additions and 247881 deletions

View File

@ -1,36 +1,3 @@
# all: Prune trailing whitespace.
dda9b9c6da5d3c31fa8769e581a753e95a270803
# all: Remove the "STATIC" macro and just use "static" instead.
decf8e6a8bb940d5829ca3296790631fcece7b21
# renesas-ra: Fix spelling mistakes found by codespell.
b3f2f18f927fa2fad10daf63d8c391331f5edf58
# all: Update Python formatting to ruff-format.
bbd8760bd9a2302e5abee29db279102bb11d7732
# all: Fix various spelling mistakes found by codespell 2.2.6.
cf490a70917a1b2d38ba9b58e763e0837d0f7ca7
# 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.
5c32111fa0e31e451b0f1666bdf926be2fdfd82c
# all: Update Python formatting to latest Black version 22.1.0.
ab2923dfa1174dc177f0a90cb00a7e4ff87958d2
# all: Update Python formatting to latest Black version 21.12b0.
3770fab33449a5dadf8eb06edfae0767e75320a6
# tools/gen-cpydiff.py: Fix formatting of doc strings for new Black.
0f78c36c5aa458a954eed39a46942209107a553e

2
.gitattributes vendored
View File

@ -8,12 +8,10 @@
# These are binary so should never be modified by git.
*.a binary
*.ico binary
*.png binary
*.jpg binary
*.dxf binary
*.mpy binary
*.der binary
# These should also not be modified by git.
tests/basics/string_cr_conversion.py -text

View File

@ -1,109 +0,0 @@
name: Bug report
description: Report a bug or unexpected behaviour
labels: ["bug"]
body:
- type: markdown
attributes:
value: |
Please provide as much detail as you can, it really helps us find and fix bugs faster.
#### Not a bug report?
* If you have a question \"How Do I ...?\", please post it on [GitHub Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead of here.
* For missing or incorrect documentation, or feature requests, then please [choose a different issue type](https://github.com/micropython/micropython/issues/new/choose).
#### Existing issue?
* Please search for [existing issues](https://github.com/micropython/micropython/issues) matching this bug before reporting.
- type: input
id: port-board-hw
attributes:
label: Port, board and/or hardware
description: |
Which MicroPython port(s) and board(s) are you using?
placeholder: |
esp32 port, ESP32-Fantastic board.
validations:
required: true
- type: textarea
id: version
attributes:
label: MicroPython version
description: |
To find the version:
1. Open a serial REPL.
2. Type Ctrl-B to see the startup message.
3. Copy-paste that output here.
If the issue is about building MicroPython, please provide output of `git describe --dirty` and as much information as possible about the build environment.
If the version or configuration is modified from the official MicroPython releases or the master branch, please tell us the details of this as well.
placeholder: |
MicroPython v6.28.3 on 2029-01-23; PyBoard 9 with STM32F9
validations:
required: true
- type: textarea
id: steps-reproduce
attributes:
label: Reproduction
description: |
What steps will reproduce the problem? Please include all details that could be relevant about the environment, configuration, etc.
If there is Python code to reproduce this issue then please either:
a. Type it into a code block below ([code block guide](https://docs.github.com/en/get-started/writing-on-github/working-with-advanced-formatting/creating-and-highlighting-code-blocks)), or
b. Post longer code to a [GitHub gist](https://gist.github.com/), or
c. Create a sample project on GitHub.
For build issues, please provide the exact build commands that you ran.
placeholder: |
1. Copy paste the code provided below into a new file
2. Use `mpremote run` to execute it on the board.
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected behaviour
description: |
What did you expect MicroPython to do? If comparing output with CPython or a different MicroPython port/version then please provide that output here.
placeholder: |
Expected to print "Hello World".
Here is the correct output, seen with previous MicroPython version v3.14.159:
> [...]
- type: textarea
id: what-happened
attributes:
label: Observed behaviour
description: |
What actually happened? Where possible please paste exact output, or the complete build log, etc. Very long output can be linked in a [GitHub gist](https://gist.github.com/).
placeholder: |
This unexpected exception appears:
> [...]
validations:
required: true
- type: textarea
id: additional
attributes:
label: Additional Information
description: |
Is there anything else that might help to resolve this issue?
value: No, I've provided everything above.
- type: dropdown
id: code-of-conduct
attributes:
label: Code of Conduct
description: |
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
options:
- "Yes, I agree"
multiple: true
validations:
required: true
- type: markdown
attributes:
value: |
Thanks for taking the time to help improve MicroPython.

View File

@ -1,11 +0,0 @@
blank_issues_enabled: false
contact_links:
- 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/
about: Documentation for using and working with MicroPython and libraries.
- name: MicroPython Downloads
url: https://micropython.org/download/
about: Pre-built firmware and information for most supported boards.

View File

@ -1,46 +0,0 @@
name: Documentation issue
description: Report areas of the documentation or examples that need improvement
title: "docs: "
labels: ["documentation"]
body:
- type: markdown
attributes:
value: |
This form is for reporting issues with the documentation or examples provided with MicroPython.
If you have a general question \"How Do I ...?\", please post it on [GitHub Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead of here.
#### Existing issue?
* Please search for [existing issues](https://github.com/micropython/micropython/issues) before reporting a new one.
- type: input
id: page
attributes:
label: Documentation URL
description: |
Does this issue relate to a particular page in the [online documentation](https://docs.micropython.org/en/latest/)? If yes, please paste the URL of the page:
placeholder: |
https://docs.micropython.org/en/latest/
- type: textarea
id: version
attributes:
label: Description
description: |
Please describe what was missing from the documentation and/or what was incorrect/incomplete.
validations:
required: true
- type: dropdown
id: code-of-conduct
attributes:
label: Code of Conduct
description: |
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
options:
- "Yes, I agree"
multiple: true
validations:
required: true
- type: markdown
attributes:
value: |
Thanks for taking the time to help improve MicroPython.

View File

@ -1,74 +0,0 @@
name: Feature request
description: Request a feature or improvement
labels: ['enhancement']
body:
- type: markdown
attributes:
value: |
This form is for requesting features or improvements in MicroPython.
#### Get feedback first
Before submitting a new feature idea here, suggest starting a discussion on [Discord](https://discord.gg/RB8HZSAExQ) or [GitHub Discussions](https://github.com/orgs/micropython/discussions/) to get early feedback from the community and maintainers.
#### Not a MicroPython core feature?
* If you have a question \"How Do I ...?\", please post it on GitHub Discussions or Discord instead of here.
* Could this feature be implemented as a pure Python library? If so, please open the request on the [micropython-lib repository](https://github.com/micropython/micropython-lib/issues) instead.
#### Existing issue?
* Please search for [existing issues](https://github.com/micropython/micropython/issues) before opening a new one.
- type: textarea
id: feature
attributes:
label: Description
description: |
Describe the feature you'd like to see added to MicroPython. What does this feature enable and why is it useful?
* For core Python features, where possible please include a link to the relevant PEP or CPython documentation.
* For new architectures / ports / boards, please provide links to relevant documentation, specifications, and toolchains. Any information about the popularity and unique features about this hardware would also be useful.
* For features for existing ports (e.g. new peripherals or microcontroller features), please describe which port(s) it applies to, and whether this is could be an extension to the machine API or a port-specific module?
* For drivers (e.g. for external hardware), please link to datasheets and/or existing drivers from other sources.
If there is an existing discussion somewhere about this feature, please add a link to it as well.
validations:
required: true
- type: textarea
id: size
attributes:
label: Code Size
description: |
MicroPython aims to strike a balance between functionality and code size. Can this feature be optionally enabled?
If you believe the usefulness of this feature would outweigh the additional code size, please explain. (It's OK to say you're unsure here, we're happy to discuss this with you.)
- type: dropdown
id: implementation
attributes:
label: Implementation
description: |
What is your suggestion for implementing this feature?
(See also: [How to sponsor](https://github.com/sponsors/micropython#sponsors), [How to submit a Pull Request](https://github.com/micropython/micropython/wiki/ContributorGuidelines).)
options:
- I hope the MicroPython maintainers or community will implement this feature
- I intend to implement this feature and would submit a Pull Request if desirable
- I would like to sponsor development of this feature
multiple: true
validations:
required: true
- type: dropdown
id: code-of-conduct
attributes:
label: Code of Conduct
description: |
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
options:
- "Yes, I agree"
multiple: true
validations:
required: true
- type: markdown
attributes:
value: |
Thanks for taking the time to suggest improvements for MicroPython.

View File

@ -1,60 +0,0 @@
name: Security report
description: Report a security issue or vulnerability in MicroPython
labels: ["security"]
body:
- type: markdown
attributes:
value: |
This form is for reporting security issues in MicroPython that are not readily exploitable.
1. For issues that are readily exploitable or have high impact, please email contact@micropython.org instead.
1. If this is a question about security, please ask it in [Discussions](https://github.com/orgs/micropython/discussions/) or [Discord](https://discord.gg/RB8HZSAExQ) instead.
#### Existing issue?
* Please search for [existing issues](https://github.com/micropython/micropython/issues) before reporting a new one.
- type: input
id: port-board-hw
attributes:
label: Port, board and/or hardware
description: |
Which MicroPython port(s) and board(s) are you using?
placeholder: |
esp32 port, ESP32-Duper board.
- type: textarea
id: version
attributes:
label: MicroPython version
description: |
To find the version:
1. Open a serial REPL.
2. Type Ctrl-B to see the startup message.
3. Copy-paste that output here.
If the version or configuration is modified from the official MicroPython releases or the master branch, please tell us the details of this as well.
placeholder: |
MicroPython v6.28.3 on 2029-01-23; PyBoard 9 with STM32F9
- type: textarea
id: report
attributes:
label: Issue Report
description: |
Please provide a clear and concise description of the security issue.
* What does this issue allow an attacker to do?
* How does the attacker exploit this issue?
validations:
required: true
- type: dropdown
id: code-of-conduct
attributes:
label: Code of Conduct
description: |
Do you agree to follow the MicroPython [Code of Conduct](https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md) to ensure a safe and respectful space for everyone?
options:
- "Yes, I agree"
multiple: true
validations:
required: true

View File

@ -1,12 +0,0 @@
# Comment to a new issue.
pullRequestOpened: |
Thank you for raising your pull request.
To ensure that all licensing criteria is met all repositories of the LVGL project apply a process called DCO (Developer's Certificate of Origin).
The text of DCO can be read here: https://developercertificate.org/
For a more detailed description see the [Documentation](https://docs.lvgl.io/latest/en/html/contributing/index.html#developer-certification-of-origin-dco) site.
By contributing to any repositories of the LVGL project you state that your contribution corresponds with the DCO.
No further action is required if your contribution fulfills the DCO. If you are not sure about it feel free to ask us in a comment.

View File

@ -1,7 +0,0 @@
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "daily"

View File

@ -1,33 +0,0 @@
<!-- Thanks for submitting a Pull Request! We appreciate you spending the
time to improve MicroPython. Please provide enough information so that
others can review your Pull Request.
Before submitting, please read:
https://github.com/micropython/micropython/blob/master/CODEOFCONDUCT.md
https://github.com/micropython/micropython/wiki/ContributorGuidelines
Please check any CI failures that appear after your Pull Request is opened.
-->
### Summary
<!-- Explain the reason for making this change. What problem does the pull request
solve, or what improvement does it add? Add links if relevant. -->
### Testing
<!-- Explain what testing you did, and on which boards/ports. If there are
boards or ports that you couldn't test, please mention this here as well.
If you leave this empty then your Pull Request may be closed. -->
### Trade-offs and Alternatives
<!-- If the Pull Request has some negative impact (i.e. increased code size)
then please explain why you think the trade-off improvement is worth it.
If you can think of alternative ways to do this, please explain that here too.
Delete this heading if not relevant (i.e. small fixes) -->

17
.github/stale.yml vendored
View File

@ -1,17 +0,0 @@
# Number of days of inactivity before an issue becomes stale
daysUntilStale: 21
# Number of days of inactivity before a stale issue is closed
daysUntilClose: 7
# Issues with these labels will never be considered stale
exemptLabels:
- architecture
- pinned
# Label to use when marking an issue as stale
staleLabel: stale
# Comment to post when marking an issue as stale. Set to `false` to disable
markComment: >
This issue or pull request has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. Thank you
for your contributions.
# Comment to post when closing a stale issue. Set to `false` to disable
closeComment: false

View File

@ -1,16 +0,0 @@
name: JavaScript code lint and formatting with Biome
on: [push, pull_request]
jobs:
eslint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Biome
uses: biomejs/setup-biome@v2
with:
version: 1.5.3
- name: Run Biome
run: biome ci --indent-style=space --indent-width=4 tests/ ports/webassembly

View File

@ -2,19 +2,15 @@ name: Check code formatting
on: [push, pull_request]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
code-formatting:
runs-on: ubuntu-22.04
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
- name: Install packages
run: source tools/ci.sh && ci_c_code_formatting_setup
run: source tools/ci.sh && ci_code_formatting_setup
- name: Run code formatting
run: source tools/ci.sh && ci_c_code_formatting_run
run: source tools/ci.sh && ci_code_formatting_run
- name: Check code formatting
run: git diff --exit-code

View File

@ -8,25 +8,15 @@ on:
- 'tools/**'
- 'py/**'
- 'extmod/**'
- 'shared/**'
- 'lib/**'
- 'ports/bare-arm/**'
- 'ports/mimxrt/**'
- 'ports/minimal/**'
- 'ports/rp2/**'
- 'ports/samd/**'
- 'ports/stm32/**'
- 'ports/unix/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-22.04
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
with:
fetch-depth: 100
- name: Install packages
@ -34,18 +24,4 @@ jobs:
- name: Build
run: source tools/ci.sh && ci_code_size_build
- name: Compute code size difference
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@v4
with:
name: code-size-report
path: |
diff
pr_number
retention-days: 1
run: tools/metrics.py diff --error-threshold 0 ~/size0 ~/size1

View File

@ -1,105 +0,0 @@
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-22.04
steps:
- name: 'Download artifact'
id: download-artifact
uses: actions/github-script@v7
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@v7
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,
});
}

View File

@ -1,13 +0,0 @@
name: Check spelling with codespell
on: [push, pull_request]
jobs:
codespell:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
# codespell version should be kept in sync with .pre-commit-config.yml
- run: pip install --user codespell==2.2.6 tomli
- run: codespell

View File

@ -2,17 +2,13 @@ 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@v4
- uses: actions/checkout@v2
with:
fetch-depth: '100'
- uses: actions/setup-python@v5
- uses: actions/setup-python@v1
- name: Check commit message formatting
run: source tools/ci.sh && ci_commit_formatting_run

View File

@ -1,23 +1,18 @@
name: Build docs
on:
push:
pull_request:
paths:
- docs/**
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
- name: Install Python packages
run: pip install -r docs/requirements.txt
run: pip install Sphinx
- name: Build docs
run: make -C docs/ html

View File

@ -1,25 +0,0 @@
name: Check examples
on:
push:
pull_request:
paths:
- '.github/workflows/*.yml'
- 'examples/**'
- 'ports/unix/**'
- 'py/**'
- 'shared/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
embedding:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build
run: make -C examples/embedding -f micropython_embed.mk && make -C examples/embedding
- name: Run
run: ./examples/embedding/embed | grep "hello world"

View File

@ -1,68 +0,0 @@
name: Build Javascript v9 port
env:
EM_VERSION: 2.0.31
EM_CACHE_FOLDER: 'emsdk-cache'
on:
push:
branches: [ lvgl_javascript_v9 ]
workflow_dispatch:
jobs:
build-and-deploy:
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v2
with:
persist-credentials: false
ref: 'lvgl_javascript_v9'
fetch-depth: 0
- name: Setup cache
id: cache-system-libraries
uses: actions/cache@v2
with:
path: ${{env.EM_CACHE_FOLDER}}
key: ${{env.EM_VERSION}}-${{ runner.os }}
- uses: mymindstorm/setup-emsdk@v10
with:
version: ${{env.EM_VERSION}}
actions-cache-folder: ${{env.EM_CACHE_FOLDER}}
- name: Build SDL2
run: embuilder build sdl2
- name: Build FreeType
run: ./build_freetype.sh
working-directory: ports/javascript/scripts
- name: Build Rlottie
run: ./build_rlottie.sh
working-directory: ports/javascript/scripts
- name: Update submodules
run: make -j $(nproc) -C ports/javascript submodules
- name: Build mpy-cross
run: make -j $(nproc) -C mpy-cross
- name: Install node modules
run: npm install
working-directory: ports/javascript
- name: Build workers
run: npm run clean
working-directory: ports/javascript
- name: Build the javascript port
run: make -j $(nproc) -C ports/javascript
- name: Build frontend
run: npm run bundle
working-directory: ports/javascript
- name: Clean up unneeded files
run: rm -rf build .cache node_modules
working-directory: ports/javascript
- name: Retrieve version
run: |
echo "::set-output name=VERSION_NAME::$(user_modules/lv_binding_micropython/lvgl/scripts/find_version.sh)"
id: version
- name: Deploy
uses: JamesIves/github-pages-deploy-action@4.1.3
with:
token: ${{ secrets.LVGL_BOT_TOKEN }}
commit-message: ${{ env.GITHUB_SHA }}
branch: master
folder: ports/javascript/bundle_out
repository-name: lvgl/sim
target-folder: v${{ steps.version.outputs.VERSION_NAME }}/micropython/ports/javascript

View File

@ -1,33 +0,0 @@
name: Merge master branch to lvgl_javascript
on:
push:
branches:
- 'master'
jobs:
merge-branch:
runs-on: ubuntu-20.04
steps:
- name: Wait for Unix port build to succeed
uses: fountainhead/action-wait-for-check@v1.0.0
id: wait-for-build
with:
token: ${{ secrets.GITHUB_TOKEN }}
checkName: build
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Skip merge
run: exit 1
if: steps.wait-for-build.outputs.conclusion == 'failure'
- uses: actions/checkout@master
- name: Merge to lvgl_javascript branch
uses: devmasx/merge-branch@v1.1.0
with:
type: now
target_branch: 'lvgl_javascript_v9'
env:
GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
- name: Trigger Javascript port build
uses: benc-uk/workflow-dispatch@a69ac85ea87587e76bb4f262eb868205dfcab8e8
with:
workflow: Build Javascript v9 port
ref: ${{ github.event.ref }}
token: ${{ secrets.LVGL_BOT_TOKEN }}

View File

@ -1,29 +0,0 @@
name: Package mpremote
on:
push:
pull_request:
paths:
- '.github/workflows/*.yml'
- 'tools/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
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@v5
- 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@v4
with:
name: mpremote
path: |
tools/mpremote/dist/mpremote*.whl

View File

@ -1,24 +0,0 @@
name: .mpy file format and tools
on:
push:
pull_request:
paths:
- '.github/workflows/*.yml'
- 'examples/**'
- 'tests/**'
- 'tools/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test:
runs-on: ubuntu-20.04 # use 20.04 to get python2
steps:
- uses: actions/checkout@v4
- name: Install packages
run: source tools/ci.sh && ci_mpy_format_setup
- name: Test mpy-tool.py
run: source tools/ci.sh && ci_mpy_format_test

View File

@ -1,22 +0,0 @@
name: Build ports metadata
on:
push:
pull_request:
paths:
- '.github/workflows/*.yml'
- 'tools/**'
- ports/**
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build ports download metadata
run: mkdir boards && ./tools/autobuild/build-downloads.py . ./boards

View File

@ -8,20 +8,15 @@ 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@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_cc3200_setup
- name: Build

View File

@ -8,50 +8,25 @@ on:
- 'tools/**'
- 'py/**'
- 'extmod/**'
- 'shared/**'
- 'lib/**'
- 'drivers/**'
- 'ports/esp32/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build_idf:
strategy:
fail-fast: false
matrix:
ci_func: # names are functions in ci.sh
- esp32_build_cmod_spiram_s2
- esp32_build_s3_c3
build_idf402:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- 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
- id: idf_ver
name: Read the ESP-IDF version
run: source tools/ci.sh && echo "IDF_VER=$IDF_VER" | tee "$GITHUB_OUTPUT"
- name: Cached ESP-IDF install
id: cache_esp_idf
uses: actions/cache@v4
with:
path: |
./esp-idf/
~/.espressif/
!~/.espressif/dist/
~/.cache/pip/
key: esp-idf-${{ steps.idf_ver.outputs.IDF_VER }}
- name: Install ESP-IDF packages
if: steps.cache_esp_idf.outputs.cache-hit != 'true'
run: source tools/ci.sh && ci_esp32_idf_setup
- name: ccache
uses: hendrikmuhs/ccache-action@v1.2
with:
key: esp32-${{ matrix.ci_func }}
- name: Build ci_${{matrix.ci_func }}
run: source tools/ci.sh && ci_${{ matrix.ci_func }}
build_idf43:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_esp32_idf43_setup
- name: Build
run: source tools/ci.sh && ci_esp32_build

View File

@ -8,20 +8,15 @@ 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@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_esp8266_setup && ci_esp8266_path >> $GITHUB_PATH
- name: Build

24
.github/workflows/ports_javascript.yml vendored Normal file
View File

@ -0,0 +1,24 @@
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

View File

@ -8,25 +8,15 @@ 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
defaults:
run:
working-directory: 'micropython repo' # test build with space in path
steps:
- uses: actions/checkout@v4
with:
path: 'micropython repo'
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_mimxrt_setup
- name: Build

View File

@ -8,20 +8,15 @@ 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@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_nrf_setup
- name: Build

View File

@ -8,20 +8,15 @@ 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@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_powerpc_setup
- name: Build

27
.github/workflows/ports_qemu-arm.yml vendored Normal file
View File

@ -0,0 +1,27 @@
name: qemu-arm port
on:
push:
pull_request:
paths:
- '.github/workflows/*.yml'
- 'tools/**'
- 'py/**'
- 'extmod/**'
- 'lib/**'
- 'drivers/**'
- 'ports/qemu-arm/**'
- 'tests/**'
jobs:
build_and_test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_qemu_arm_setup
- name: Build and run test suite
run: source tools/ci.sh && ci_qemu_arm_build
- name: Print failures
if: failure()
run: grep --text "FAIL" ports/qemu-arm/build/console.out

View File

@ -1,44 +0,0 @@
name: qemu port
on:
push:
pull_request:
paths:
- '.github/workflows/*.yml'
- 'tools/**'
- 'py/**'
- 'extmod/**'
- 'shared/**'
- 'lib/**'
- 'drivers/**'
- 'ports/qemu/**'
- 'tests/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build_and_test_arm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install packages
run: source tools/ci.sh && ci_qemu_setup_arm
- name: Build and run test suite
run: source tools/ci.sh && ci_qemu_build_arm
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
build_and_test_rv32:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install packages
run: source tools/ci.sh && ci_qemu_setup_rv32
- name: Build and run test suite
run: source tools/ci.sh && ci_qemu_build_rv32
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures

View File

@ -1,29 +0,0 @@
name: renesas-ra port
on:
push:
pull_request:
paths:
- '.github/workflows/*.yml'
- '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@v4
- name: Install packages
run: source tools/ci.sh && ci_renesas_ra_setup
- name: Build
run: source tools/ci.sh && ci_renesas_ra_board_build

View File

@ -8,25 +8,15 @@ 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
defaults:
run:
working-directory: 'micropython repo' # test build with space in path
steps:
- uses: actions/checkout@v4
with:
path: 'micropython repo'
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_rp2_setup
- name: Build

View File

@ -8,20 +8,15 @@ 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@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_samd_setup
- name: Build

View File

@ -8,29 +8,25 @@ on:
- 'tools/**'
- 'py/**'
- 'extmod/**'
- 'shared/**'
- 'lib/**'
- 'drivers/**'
- 'ports/stm32/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build_stm32:
strategy:
fail-fast: false
matrix:
ci_func: # names are functions in ci.sh
- stm32_pyb_build
- stm32_nucleo_build
- stm32_misc_build
build_pyb:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_stm32_setup
- name: Build ci_${{matrix.ci_func }}
run: source tools/ci.sh && ci_${{ matrix.ci_func }}
- name: Build
run: source tools/ci.sh && ci_stm32_pyb_build
build_nucleo:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_stm32_setup
- name: Build
run: source tools/ci.sh && ci_stm32_nucleo_build

23
.github/workflows/ports_teensy.yml vendored Normal file
View File

@ -0,0 +1,23 @@
name: teensy port
on:
push:
pull_request:
paths:
- '.github/workflows/*.yml'
- 'tools/**'
- 'py/**'
- 'extmod/**'
- 'lib/**'
- 'drivers/**'
- 'ports/teensy/**'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_teensy_setup
- name: Build
run: source tools/ci.sh && ci_teensy_build

View File

@ -8,22 +8,16 @@ 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@v4
- uses: actions/checkout@v2
- name: Build
run: source tools/ci.sh && ci_unix_minimal_build
- name: Run main test suite
@ -35,34 +29,36 @@ jobs:
reproducible:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- 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/build-minimal/micropython -i | grep 'on 2009-02-13;'
run: echo | ports/unix/micropython-minimal -i | grep 'on 2009-02-13;'
standard:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Build
run: source tools/ci.sh && ci_unix_standard_build
- name: Run main test suite
run: source tools/ci.sh && ci_unix_standard_run_tests
- name: Run performance benchmarks
run: source tools/ci.sh && ci_unix_standard_run_perfbench
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
standard_v2:
dev:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Build
run: source tools/ci.sh && ci_unix_standard_v2_build
run: source tools/ci.sh && ci_unix_dev_build
- name: Run main test suite
run: source tools/ci.sh && ci_unix_standard_v2_run_tests
run: source tools/ci.sh && ci_unix_dev_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
@ -70,15 +66,13 @@ jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_unix_coverage_setup
- name: Build
run: source tools/ci.sh && ci_unix_coverage_build
- name: Run main test suite
run: source tools/ci.sh && ci_unix_coverage_run_tests
- name: Test merging .mpy files
run: source tools/ci.sh && ci_unix_coverage_run_mpy_merge_tests
- name: Build native mpy modules
run: source tools/ci.sh && ci_native_mpy_modules_build
- name: Test importing .mpy generated by mpy_ld.py
@ -88,19 +82,18 @@ 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@v4
uses: codecov/codecov-action@v1
with:
fail_ci_if_error: true
verbose: true
token: ${{ secrets.CODECOV_TOKEN }}
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
coverage_32bit:
runs-on: ubuntu-20.04 # use 20.04 to get libffi-dev:i386
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_unix_32bit_setup
- name: Build
@ -116,9 +109,9 @@ jobs:
run: tests/run-tests.py --print-failures
nanbox:
runs-on: ubuntu-20.04 # use 20.04 to get python2, and libffi-dev:i386
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_unix_32bit_setup
- name: Build
@ -132,7 +125,7 @@ jobs:
float:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Build
run: source tools/ci.sh && ci_unix_float_build
- name: Run main test suite
@ -144,7 +137,7 @@ jobs:
stackless_clang:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_unix_clang_setup
- name: Build
@ -158,7 +151,7 @@ jobs:
float_clang:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_unix_clang_setup
- name: Build
@ -172,7 +165,7 @@ jobs:
settrace:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Build
run: source tools/ci.sh && ci_unix_settrace_build
- name: Run main test suite
@ -184,7 +177,7 @@ jobs:
settrace_stackless:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Build
run: source tools/ci.sh && ci_unix_settrace_stackless_build
- name: Run main test suite
@ -194,12 +187,10 @@ jobs:
run: tests/run-tests.py --print-failures
macos:
runs-on: macos-latest
runs-on: macos-11.0
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.8'
- uses: actions/checkout@v2
- uses: actions/setup-python@v1
- name: Build
run: source tools/ci.sh && ci_unix_macos_build
- name: Run tests
@ -211,7 +202,7 @@ jobs:
qemu_mips:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_unix_qemu_mips_setup
- name: Build
@ -225,7 +216,7 @@ jobs:
qemu_arm:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_unix_qemu_arm_setup
- name: Build
@ -235,17 +226,3 @@ jobs:
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures
qemu_riscv64:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install packages
run: source tools/ci.sh && ci_unix_qemu_riscv64_setup
- name: Build
run: source tools/ci.sh && ci_unix_qemu_riscv64_build
- name: Run main test suite
run: source tools/ci.sh && ci_unix_qemu_riscv64_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures

View File

@ -1,32 +0,0 @@
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@v4
- 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

View File

@ -8,138 +8,15 @@ on:
- 'tools/**'
- 'py/**'
- 'extmod/**'
- 'shared/**'
- 'lib/**'
- 'ports/unix/**'
- 'ports/windows/**'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-vs:
strategy:
fail-fast: false
matrix:
platform: [x86, x64]
configuration: [Debug, Release]
variant: [dev, standard]
visualstudio: ['2017', '2019', '2022']
include:
- visualstudio: '2017'
runner: windows-latest
vs_version: '[15, 16)'
- visualstudio: '2019'
runner: windows-2019
vs_version: '[16, 17)'
- visualstudio: '2022'
runner: windows-2022
vs_version: '[17, 18)'
# trim down the number of jobs in the matrix
exclude:
- variant: standard
configuration: Debug
- visualstudio: '2019'
configuration: Debug
env:
CI_BUILD_CONFIGURATION: ${{ matrix.configuration }}
runs-on: ${{ matrix.runner }}
steps:
- name: Install Visual Studio 2017
if: matrix.visualstudio == '2017'
run: |
choco install visualstudio2017buildtools
choco install visualstudio2017-workload-vctools
choco install windows-sdk-8.1
- uses: microsoft/setup-msbuild@v2
with:
vs-version: ${{ matrix.vs_version }}
- uses: actions/setup-python@v5
if: matrix.runner == 'windows-2019'
with:
python-version: '3.9'
- uses: actions/checkout@v4
- name: Build mpy-cross.exe
run: msbuild mpy-cross\mpy-cross.vcxproj -maxcpucount -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }}
- name: Update submodules
run: git submodule update --init lib/micropython-lib
- name: Build micropython.exe
run: msbuild ports\windows\micropython.vcxproj -maxcpucount -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }} -property:PyVariant=${{ matrix.variant }}
- name: Get micropython.exe path
id: get_path
run: |
$exePath="$(msbuild ports\windows\micropython.vcxproj -nologo -v:m -t:ShowTargetPath -property:Configuration=${{ matrix.configuration }} -property:Platform=${{ matrix.platform }} -property:PyVariant=${{ matrix.variant }})"
echo ("micropython=" + $exePath.Trim()) >> $env:GITHUB_OUTPUT
- name: Run tests
id: test
env:
MICROPY_MICROPYTHON: ${{ steps.get_path.outputs.micropython }}
working-directory: tests
run: python run-tests.py
- name: Print failures
if: failure() && steps.test.conclusion == 'failure'
working-directory: tests
run: python run-tests.py --print-failures
- name: Run mpy tests
id: test_mpy
env:
MICROPY_MICROPYTHON: ${{ steps.get_path.outputs.micropython }}
working-directory: tests
run: python run-tests.py --via-mpy -d basics float micropython
- name: Print mpy failures
if: failure() && steps.test_mpy.conclusion == 'failure'
working-directory: tests
run: python run-tests.py --print-failures
build-mingw:
strategy:
fail-fast: false
matrix:
variant: [dev, standard]
sys: [mingw32, mingw64]
include:
- sys: mingw32
env: i686
- sys: mingw64
env: x86_64
runs-on: windows-2022
env:
CHERE_INVOKING: enabled_from_arguments
defaults:
run:
shell: msys2 {0}
steps:
- uses: msys2/setup-msys2@v2
with:
msystem: ${{ matrix.sys }}
update: true
install: >-
make
mingw-w64-${{ matrix.env }}-gcc
pkg-config
mingw-w64-${{ matrix.env }}-python3
git
diffutils
- uses: actions/checkout@v4
- name: Build mpy-cross.exe
run: make -C mpy-cross -j2
- name: Update submodules
run: make -C ports/windows VARIANT=${{ matrix.variant }} submodules
- name: Build micropython.exe
run: make -C ports/windows -j2 VARIANT=${{ matrix.variant }}
- name: Run tests
id: test
run: make -C ports/windows test_full VARIANT=${{ matrix.variant }}
- name: Print failures
if: failure() && steps.test.conclusion == 'failure'
working-directory: tests
run: python run-tests.py --print-failures
cross-build-on-linux:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_windows_setup
- name: Build

View File

@ -8,36 +8,17 @@ 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: jlumbroso/free-disk-space@main
with:
# Only free up a few things so this step runs quickly.
android: false
dotnet: true
haskell: true
large-packages: false
docker-images: false
swap-storage: false
- uses: actions/checkout@v4
- uses: actions/checkout@v2
- name: Install packages
run: source tools/ci.sh && ci_zephyr_setup
- name: Install Zephyr
run: source tools/ci.sh && ci_zephyr_install
- name: Build
run: source tools/ci.sh && ci_zephyr_build
- name: Run main test suite
run: source tools/ci.sh && ci_zephyr_run_tests
- name: Print failures
if: failure()
run: tests/run-tests.py --print-failures

View File

@ -1,31 +0,0 @@
name: rp2 port
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-20.04
strategy:
matrix:
board: [PICO]
steps:
- uses: actions/checkout@v2
- name: arm-none-eabi-gcc
uses: carlosperate/arm-none-eabi-gcc-action@v1.3.0
with:
release: '9-2019-q4' # The arm-none-eabi-gcc release to use.
- name: Initialize lv_bindings submodule
run: git submodule update --init --recursive user_modules/lv_binding_micropython
- name: Initialize Micropython submodules
run: make -C ports/rp2 BOARD=${{ matrix.board }} USER_C_MODULES=../../user_modules/lv_binding_micropython/bindings.cmake submodules
- name: Build mpy-cross
run: make -j $(nproc) -C mpy-cross
- name: Build ${{ matrix.board }}
run: make -j $(nproc) -C ports/rp2 BOARD=${{ matrix.board }} USER_C_MODULES=../../user_modules/lv_binding_micropython/bindings.cmake
- uses: actions/upload-artifact@v2
if: ${{ env.GITHUB_EVENT_NAME }} == 'push'
with:
name: ${{ matrix.board }}.hex
path: ports/rp2/build-${{ matrix.board }}/firmware.elf

View File

@ -1,15 +0,0 @@
name: Python code lint and formatting with ruff
on: [push, pull_request]
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Initialize lv_bindings submodule
run: git submodule update --init --recursive user_modules/lv_binding_micropython
# ruff version should be kept in sync with .pre-commit-config.yaml
- run: pip install --user ruff==0.1.3
- run: ruff check --output-format=github .
- run: ruff format --diff .

View File

@ -1,29 +0,0 @@
name: stm32 port
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-20.04
strategy:
matrix:
board: [STM32F7DISC]
steps:
- uses: actions/checkout@v2
- name: arm-none-eabi-gcc
uses: carlosperate/arm-none-eabi-gcc-action@v1.3.0
with:
release: '9-2019-q4' # The arm-none-eabi-gcc release to use.
- name: Update submodules
run: git submodule update --init --recursive
- name: Build mpy-cross
run: make -j $(nproc) -C mpy-cross
- name: Build ${{ matrix.board }}
run: make -j $(nproc) -C ports/stm32 BOARD=${{ matrix.board }}
- uses: actions/upload-artifact@v2
if: ${{ env.GITHUB_EVENT_NAME }} == 'push'
with:
name: ${{ matrix.board }}.hex
path: ports/stm32/build-${{ matrix.board }}/firmware.hex

View File

@ -1,31 +0,0 @@
name: unix port
on:
push:
pull_request:
jobs:
build:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: |
sudo add-apt-repository -y "deb http://archive.ubuntu.com/ubuntu `lsb_release -sc` main universe restricted multiverse"
sudo apt-get update -y -qq
sudo apt-get install libsdl2-dev parallel libfreetype-dev librlottie-dev libavformat-dev libavcodec-dev libswscale-dev libavutil-dev
- name: Initialize lv_bindings submodule
run: git submodule update --init --recursive user_modules/lv_binding_micropython
- name: Update submodules
run: make -C ports/unix DEBUG=1 submodules
- name: Build mpy-cross
run: make -j $(nproc) -C mpy-cross
- name: Build the unix port
run: make -j $(nproc) -C ports/unix DEBUG=1
- name: Run tests
run: |
export XDG_RUNTIME_DIR=/tmp
user_modules/lv_binding_micropython/tests/run.sh

64
.gitignore vendored
View File

@ -1,30 +1,3 @@
# 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 and intermediate artefacts
tests/results/*
tests/ports/unix/ffi_lib.so
# Python cache files
__pycache__/
# Customized Makefile/project overrides
GNUmakefile
user.props
# MacOS desktop metadata files
.DS_Store
# Compiled Sources
###################
*.o
@ -36,9 +9,6 @@ user.props
*.dis
*.exe
lextab.py
yacctab.py
# Packages
############
@ -49,24 +19,30 @@ yacctab.py
# VIM Swap Files
######################
*.swp
*.swo
*.swn
*.swi
*.swj
*.swk
*.swl
*.swm
# VIM Session Files
# Build directories
######################
Session.vim
build/
build-*/
# CTags files
# Test failure outputs
######################
tags
TAGS
tests/results/*
# Python cache files
######################
__pycache__/
*.pyc
ports/javascript/node_modules
.vscode/
# Customized Makefile/project overrides
######################
GNUmakefile
user.props
# Generated rst files
######################
genrst/
# MacOS desktop metadata files
######################
.DS_Store

38
.gitmodules vendored
View File

@ -3,17 +3,17 @@
url = https://github.com/micropython/axtls.git
[submodule "lib/libffi"]
path = lib/libffi
url = https://github.com/libffi/libffi
url = https://github.com/atgreen/libffi
[submodule "lib/lwip"]
path = lib/lwip
url = https://github.com/lwip-tcpip/lwip.git
[submodule "lib/berkeley-db-1.xx"]
path = lib/berkeley-db-1.xx
url = https://github.com/micropython/berkeley-db-1.xx
url = https://github.com/pfalcon/berkeley-db-1.xx
[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+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
branch = work-F4-1.13.1+F7-1.5.0+L4-1.3.0
[submodule "lib/nrfx"]
path = lib/nrfx
url = https://github.com/NordicSemiconductor/nrfx.git
@ -23,13 +23,12 @@
[submodule "lib/asf4"]
path = lib/asf4
url = https://github.com/adafruit/asf4
branch = circuitpython
[submodule "lib/tinyusb"]
path = lib/tinyusb
url = https://github.com/hathach/tinyusb
[submodule "lib/mynewt-nimble"]
path = lib/mynewt-nimble
url = https://github.com/micropython/mynewt-nimble.git
url = https://github.com/apache/mynewt-nimble.git
[submodule "lib/btstack"]
path = lib/btstack
url = https://github.com/bluekitchen/btstack.git
@ -42,32 +41,3 @@
[submodule "lib/pico-sdk"]
path = lib/pico-sdk
url = https://github.com/raspberrypi/pico-sdk.git
[submodule "lib/fsp"]
path = lib/fsp
url = https://github.com/renesas/fsp.git
[submodule "lib/wiznet"]
path = lib/wiznet5k
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
[submodule "lib/protobuf-c"]
path = lib/protobuf-c
url = https://github.com/protobuf-c/protobuf-c.git
[submodule "lib/open-amp"]
path = lib/open-amp
url = https://github.com/OpenAMP/open-amp.git
[submodule "lib/libmetal"]
path = lib/libmetal
url = https://github.com/OpenAMP/libmetal.git
[submodule "lib/arduino-lib"]
path = lib/arduino-lib
url = https://github.com/arduino/arduino-lib-mpy.git
[submodule "user_modules/lv_binding_micropython"]
path = user_modules/lv_binding_micropython
url = https://github.com/lvgl/lv_binding_micropython.git

35
.gitpod
View File

@ -1,35 +0,0 @@
image:
file: .gitpod.Dockerfile
ports:
- port: 6080
protocol: "http"
onOpen: open-preview
- port: 5900
onOpen: ignore
tasks:
- init: |
make -C ports/unix DEBUG=1 submodules
make -j $(nproc) -C mpy-cross DEBUG=1
make -j $(nproc) -C ports/unix DEBUG=1
command: |
xrandr --fb 500x500 # Fix resolution for LVGL screens which are smaller
ports/unix/build-lvgl/micropython -i user_modules/lv_binding_micropython/examples/advanced_demo.py
vscode:
extensions:
- ms-vscode.cpptools
github:
prebuilds:
# enable for the master/default branch (defaults to true)
master: true
# enable for all branches in this repo (defaults to false)
branches: true
# enable for pull requests coming from this repo (defaults to true)
pullRequests: true
# enable for pull requests coming from forks (defaults to false)
pullRequestsFromForks: true
# add a "Review in Gitpod" button as a comment to pull requests (defaults to true)
addComment: true
# add a "Review in Gitpod" button to pull requests (defaults to false)
addBadge: false
# add a label once the prebuild is ready to pull requests (defaults to false)
addLabel: prebuilt-in-gitpod

9
.gitpod.Dockerfile vendored
View File

@ -1,9 +0,0 @@
FROM gitpod/workspace-full-vnc
# https://community.gitpod.io/t/long-startup-times/3299/9
ENV GITPOD_TRIGGER_REBUILD=1
# Install dependencies
RUN sudo apt-get update && \
sudo apt-get install -y libgtk-3-dev libsdl2-dev x11-xserver-utils parallel libfreetype-dev librlottie-dev libusb-1.0-0

View File

@ -1,27 +0,0 @@
repos:
- repo: local
hooks:
- id: codeformat
name: MicroPython codeformat.py for changed C files
entry: tools/codeformat.py -v -c -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
# Version should be kept in sync with .github/workflows/ruff.yml
rev: v0.1.3
hooks:
- id: ruff
- id: ruff-format
- repo: https://github.com/codespell-project/codespell
# Version should be kept in sync with .github/workflows/codespell.yml
rev: v2.2.6
hooks:
- id: codespell
name: Spellcheck for changed files (codespell)
additional_dependencies:
- tomli

View File

@ -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 must fit within 72 characters. Examples
final full stop. First line should fit within 72 characters. Examples
of good first line of commit messages:
py/objstr: Add splitlines() method.
@ -27,9 +27,12 @@ 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 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:
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:
* 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
@ -46,146 +49,28 @@ are then certifying and signing off 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,
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
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.
Code auto-formatting
====================
Both C and Python code formatting are controlled for consistency across the
MicroPython codebase. C code is formatted using the `tools/codeformat.py`
script which uses [uncrustify](https://github.com/uncrustify/uncrustify).
Python code is linted and formatted using
[ruff & ruff format](https://github.com/astral-sh/ruff).
After making changes, and before committing, run `tools/codeformat.py` to
reformat your C code and `ruff format` for any Python code. 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
```
Code spell checking
===================
Code spell checking is done using [codespell](https://github.com/codespell-project/codespell#codespell)
and runs in a GitHub action in CI. Codespell is configured via `pyproject.toml`
to avoid false positives. It is recommended run codespell before submitting a
PR. To simplify this, codespell is configured as a pre-commit hook and will be
installed if you run `pre-commit install` (see below).
If you want to install and run codespell manually, you can do so by running:
```
$ pip install codespell tomli
$ codespell
```
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").
Running pre-commit manually
===========================
Once pre-commit is installed as per the previous section it can be manually
run against the MicroPython python codebase to update file formatting on
demand, with either:
* `pre-commit run --all-files` to fix all files in the MicroPython codebase
* `pre-commit run --file ./path/to/my/file` to fix just one file
* `pre-commit run --file ./path/to/my/folder/*` to fix just one folder
Both C and Python code are auto-formatted using the `tools/codeformat.py`
script. This uses [uncrustify](https://github.com/uncrustify/uncrustify) to
format C code and [black](https://github.com/psf/black) to format Python code.
After making changes, and before committing, run this tool to reformat your
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.
Python code conventions
=======================
Python code follows [PEP 8](https://legacy.python.org/dev/peps/pep-0008/) and
is auto-formatted using [ruff format](https://docs.astral.sh/ruff/formatter)
with a line-length of 99 characters.
is auto-formatted using [black](https://github.com/psf/black) with a line-length
of 99 characters.
Naming conventions:
- Module names are short and all lowercase; eg pyb, stm.
@ -280,7 +165,7 @@ Documentation conventions
=========================
MicroPython generally follows CPython in documentation process and
conventions. reStructuredText syntax is used for the documentation.
conventions. reStructuredText syntax is used for the documention.
Specific conventions/suggestions:

15
LICENSE
View File

@ -1,6 +1,6 @@
The MIT License (MIT)
Copyright (c) 2013-2024 Damien P. George
Copyright (c) 2013-2021 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,7 +35,9 @@ 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)
@ -48,31 +50,24 @@ used during the build process and is not part of the compiled source code.
/cmsis (BSD-3-clause)
/crypto-algorithms (NONE)
/libhydrogen (ISC)
/libmetal (BSD-3-clause)
/littlefs (BSD-3-clause)
/lwip (BSD-3-clause)
/mynewt-nimble (Apache-2.0)
/nrfx (BSD-3-clause)
/nxp_driver (BSD-3-Clause)
/oofatfs (BSD-1-clause)
/open-amp (BSD-3-clause)
/pico-sdk (BSD-3-clause)
/re15 (BSD-3-clause)
/stm32lib (BSD-3-clause)
/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)
/rp2
/mutex_extra.c (BSD-3-clause)
/clocks_extra.c (BSD-3-clause)
/stm32
/usbd*.c (MCD-ST Liberty SW License Agreement V2)
/stm32_it.* (MIT + BSD-3-clause)
@ -82,6 +77,8 @@ used during the build process and is not part of the compiled source code.
/*/stm32*.h (BSD-3-clause)
/usbdev (MCD-ST Liberty SW License Agreement V2)
/usbhost (MCD-ST Liberty SW License Agreement V2)
/teensy
/core (PJRC.COM)
/zephyr
/src (Apache-2.0)
/tools

View File

@ -1,237 +0,0 @@
# Micropython + lvgl
**Micropython bindings to LVGL for Embedded devices, Unix and JavaScript**
[![Build lv_micropython unix port](https://github.com/lvgl/lv_micropython/actions/workflows/unix_port.yml/badge.svg)](https://github.com/lvgl/lv_micropython/actions/workflows/unix_port.yml)
[![Build lv_micropython stm32 port](https://github.com/lvgl/lv_micropython/actions/workflows/stm32_port.yml/badge.svg)](https://github.com/lvgl/lv_micropython/actions/workflows/stm32_port.yml)
[![esp32 port](https://github.com/lvgl/lv_micropython/actions/workflows/ports_esp32.yml/badge.svg)](https://github.com/lvgl/lv_micropython/actions/workflows/ports_esp32.yml) [![Build lv_micropython rp2 port](https://github.com/lvgl/lv_micropython/actions/workflows/rp2_port.yml/badge.svg)](https://github.com/lvgl/lv_micropython/actions/workflows/rp2_port.yml)
[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/lvgl/lv_micropython)
To quickly run Micropython + LVGL from your web browser you can also use the [Online Simulator](https://sim.lvgl.io/).
**For information about Micropython lvgl bindings please refer to [lv_binding_micropython/README.md](https://github.com/lvgl/lv_binding_micropython/blob/master/README.md)**
See also [Micropython + LittlevGL](https://blog.lvgl.io/2019-02-20/micropython-bindings) blog post. (LittlevGL is LVGL's previous name.)
For questions and discussions - please use the forum: https://forum.lvgl.io/c/micropython
Original micropython README: https://github.com/micropython/micropython/blob/master/README.md
## Relationship between `lv_micropython` and `lv_binding_micropython`
Originally, `lv_micropython` was created as an example of how to use [lv_binding_micropython](https://github.com/lvgl/lv_binding_micropython) on a Micropython fork.
As such, we try to keep changes here as minimal as possible and we try to keep it in sync with Micropython upstream releases. We also try to add changes to `lv_binding_micropython` instead of to `lv_micropython`, when possible. (for example we keep all drivers in `lv_binding_micropython`, etc.)
Eventually it turned out that many people prefer using `lv_micropython` directly and only a few use it as a reference to support LVGL on their own Micropython fork.
If you are only starting with Micropython+LVGL, it's recommended that you use `lv_micropython`, while porting a Micropython fork to LVGL is for advanced users.
Actual `lv_micropython` repo is using [LVGL binding](https://github.com/lvgl/lv_binding_micropython) as MicroPython C module.
More details: https://docs.micropython.org/en/latest/develop/cmodules.html
## Build Instructions
First step is always to clone `lv_micropython` and update its submodules recursively:
```
git clone https://github.com/lvgl/lv_micropython.git
cd lv_micropython
git submodule update --init --recursive user_modules/lv_binding_micropython
```
Next step is to build the port you want to use.
Some basic build and deploy scripts are added to `scripts` folder, to easily build and deploy firmware to your device (or use unix port).
You can of course build firmwares manually with `make` commands, if build script is missing for the port or you want to override some build parameters.
### Unix (Linux) port
Using build script:
```
cd scripts
./build-unix.sh
cd ..
./ports/unix/build-lvgl/micropython
```
Manual build:
1. `sudo apt-get install build-essential libreadline-dev libffi-dev git pkg-config libsdl2-2.0-0 libsdl2-dev python3.8 parallel`
Python 3 is required, but you can install some other version of python3 instead of 3.8, if needed.
2. `git clone https://github.com/lvgl/lv_micropython.git`
3. `cd lv_micropython`
4. `git submodule update --init --recursive user_modules/lv_binding_micropython`
5. `make -C mpy-cross`
6. `make -C ports/unix submodules`
7. `make -C ports/unix`
8. `./ports/unix/build-lvgl/micropython`
## Unix (MAC OS) port
1. `brew install sdl2 pkg-config`
2. `sdl2-config --version` Get the sdl2 version
3. `git clone https://github.com/lvgl/lv_micropython.git`
4. `cd lv_micropython`
5. `git submodule update --init --recursive user_modules/lv_binding_micropython`
6. `sudo mkdir -p /usr/local/lib/`
7. `sudo cp /opt/homebrew/Cellar/sdl2/<YOUR_SDL_VERSION>/lib/libSDL2.dylib /usr/local/lib/`
8. `sudo cp -r /opt/homebrew/Cellar/sdl2/<YOUR_SDL_VERSION>/include /usr/local/`
9. `sed -i '' 's/ -Werror//' ports/unix/Makefile mpy-cross/Makefile` Remove -Werror from compiler parameters as Mac fails compilation otherwise
10. `make -C mpy-cross`
11. `make -C ports/unix submodules`
12. `make -C ports/unix VARIANT=lvgl`
13. `./ports/unix/build-lvgl/micropython`
### ESP32 port
Install ESP-IDF v5.x: https://docs.espressif.com/projects/esp-idf/en/v5.2.3/esp32/get-started/index.html#manual-installation
(you can configure ESP-IDF path in [scripts/env-variables-esp32.sh](./scripts/env-variables-esp32.sh) file)
Build and deploy with scripts:
```
cd scripts
./build-esp32.sh
./deploy-esp32.sh
```
Manual build:
Please run `esp-idf/export.sh` from your ESP-IDF installation directory as explained in the [Micropython ESP32 Getting Started documentation](https://docs.espressif.com/projects/esp-idf/en/stable/esp32/get-started/#get-started-export)
ESP-IDF version needs to match Micropython expected esp-idf, otherwise a warning will be displayed (and build will probably fail)
For more details refer to [Setting up the toolchain and ESP-IDF](https://github.com/lvgl/lv_micropython/blob/master/ports/esp32/README.md#setting-up-the-toolchain-and-esp-idf)
When using IL9341 driver, the color depth need to be set to match ILI9341. This can be done from the command line.
Here is the command to build ESP32 + LVGL which is compatible with ILI9341 driver:
```
make -C mpy-cross
make -C ports/esp32 LV_CFLAGS="-DLV_COLOR_DEPTH=16" BOARD=ESP32_GENERIC BOARD_VARIANT=SPIRAM deploy
```
Explanation about the parameters:
- `LV_CFLAGS` are used to override color depth, for ILI9341 compatibility.
- `LV_COLOR_DEPTH=16` is needed if you plan to use the ILI9341 driver.
- `BOARD` - I use WROVER board with SPIRAM. You can choose other boards from `ports/esp32/boards/` directory.
- `deploy` - make command will create ESP32 port of Micropython, and will try to deploy it through USB-UART bridge.
For more details please refer to [Micropython ESP32 README](https://github.com/micropython/micropython/blob/master/ports/esp32/README.md).
### JavaScript port
Refer to the README of the `lvgl_javascript` branch: https://github.com/lvgl/lv_micropython/tree/lvgl_javascript_v8#javascript-port
### Raspberry Pi Pico port
This port uses [Micropython infrastructure for C modules](https://docs.micropython.org/en/latest/develop/cmodules.html#compiling-the-cmodule-into-micropython) and `USER_C_MODULES` must be given:
1. `git clone https://github.com/lvgl/lv_micropython.git`
2. `cd lv_micropython`
3. `git submodule update --init --recursive user_modules/lv_binding_micropython`
4. `make -C ports/rp2 BOARD=PICO submodules`
5. `make -j -C mpy-cross`
6. `make -j -C ports/rp2 BOARD=PICO USER_C_MODULES=../../user_modules/lv_binding_micropython/bindings.cmake`
#### Troubleshooting
If you experience unstable behaviour, it is worth checking the value of *MICROPY_HW_FLASH_STORAGE_BASE* against the value of *__flash_binary_end* from the firmware.elf.map file.
If the storage base is lower than the binary end, parts of the firmware will be overwritten when the micropython filesystem is initialised.
## Super Simple Example
First, LVGL needs to be imported and initialized
```python
import lvgl as lv
lv.init()
```
Then event loop, display driver and input driver needs to be registered.
Refer to [Porting the library](https://docs.lvgl.io/8.0/porting/index.html) for more information.
Here is an example of registering SDL drivers on Micropython unix port:
```python
# Create an event loop and Register SDL display/mouse/keyboard drivers.
from lv_utils import event_loop
WIDTH = 480
HEIGHT = 320
event_loop = event_loop()
disp_drv = lv.sdl_window_create(WIDTH, HEIGHT)
disp_drv.set_default()
display = lv.display_get_default()
group = lv.group_create()
group.set_default()
mouse = lv.sdl_mouse_create()
mouse.set_display(display)
mouse.set_group(group)
keyboard = lv.sdl_keyboard_create()
keyboard.set_display(display)
keyboard.set_group(group)
```
Here is an alternative example, for registering ILI9341 drivers on Micropython ESP32 port:
```python
import lvgl as lv
# Import ILI9341 driver and initialized it
from ili9341 import ili9341
disp = ili9341()
# Import XPT2046 driver and initialize it
from xpt2046 import xpt2046
touch = xpt2046()
```
By default, both ILI9341 and XPT2046 are initialized on the same SPI bus with the following parameters:
- ILI9341: `miso=5, mosi=18, clk=19, cs=13, dc=12, rst=4, power=14, backlight=15, spihost=esp.HSPI_HOST, mhz=40, factor=4, hybrid=True`
- XPT2046: `cs=25, spihost=esp.HSPI_HOST, mhz=5, max_cmds=16, cal_x0 = 3783, cal_y0 = 3948, cal_x1 = 242, cal_y1 = 423, transpose = True, samples = 3`
You can change any of these parameters on ili9341/xpt2046 constructor.
You can also initialize them on different SPI buses if you want, by providing miso/mosi/clk parameters. Set them to -1 to use existing (initialized) spihost bus.
Now you can create the GUI itself:
```python
# Create a screen with a button and a label
scr = lv.obj()
btn = lv.button(scr)
btn.align_to(lv.scr_act(), lv.ALIGN.CENTER, 0, 0)
label = lv.label(btn)
label.set_text("Hello World!")
# Load the screen
lv.screen_load(scr)
```
## More information
More info about LVGL:
- Website https://lvgl.io
- GitHub: https://github.com/lvgl/lvgl
- Documentation: https://docs.lvgl.io/master/get-started/bindings/micropython.html
- Examples: https://docs.lvgl.io/master/examples.html
- More examples: https://github.com/lvgl/lv_binding_micropython/tree/master/examples
More info about lvgl Micropython bindings:
- https://github.com/lvgl/lv_binding_micropython/blob/master/README.md
Discussions about the Micropython binding: https://github.com/lvgl/lvgl/issues/557
More info about the unix port: https://github.com/micropython/micropython/wiki/Getting-Started#debian-ubuntu-mint-and-variants

275
README.md
View File

@ -1,10 +1,4 @@
# Micropython + LVGL
**Micropython bindings to LVGL for Embedded devices, Unix and JavaScript**
More information about MicroPython-LVGL binding and how to build it, see: [README-LVGL.md](README-LVGL.md)
---
[![CI badge](https://github.com/micropython/micropython/workflows/unix%20port/badge.svg)](https://github.com/micropython/micropython/actions?query=branch%3Amaster+event%3Apush) [![codecov](https://codecov.io/gh/micropython/micropython/branch/master/graph/badge.svg?token=I92PfD05sD)](https://codecov.io/gh/micropython/micropython)
The MicroPython project
=======================
@ -21,43 +15,167 @@ 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 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. Some 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.
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 (.py files) or from
precompiled bytecode (.mpy files), in both cases either from an on-device
filesystem or "frozen" into the MicroPython executable.
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.
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.
See the repository http://github.com/micropython/pyboard for the MicroPython
board (PyBoard), the officially supported reference electronic circuit board.
Getting started
---------------
Major components in this repository:
- py/ -- the core Python implementation, including compiler, runtime, and
core library.
- 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.
See the [online documentation](https://docs.micropython.org/) for the API
reference and information about using MicroPython and information about how
it is implemented.
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.
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.
The subdirectories above may include READMEs with additional info.
For bugs and feature requests, please [raise an issue](https://github.com/micropython/micropython/issues/new/choose)
and follow the templates there.
"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`).
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).
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:
$ 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:
$ 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://launchpad.net/gcc-arm-embedded
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
------------
@ -68,86 +186,3 @@ productive, please be sure to follow the
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/](mpy-cross/) -- the MicroPython cross-compiler which is used to turn scripts
into precompiled bytecode.
- [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`). 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, ESP32C6).
- [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](ports/qemu) -- 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)
- [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](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
External dependencies
---------------------
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
to ensure that all required submodules are initialised.

View File

@ -3,7 +3,7 @@
# You can set these variables from the command line.
PYTHON = python3
SPHINXOPTS = -W --keep-going -j auto
SPHINXOPTS = -W --keep-going
SPHINXBUILD = sphinx-build
PAPER =
BUILDDIR = build/$(MICROPY_PORT)

View File

@ -47,7 +47,7 @@ This can be achieved with:
make latexpdf
but requires a rather complete install of LaTeX with various extensions. On
Debian/Ubuntu, try (1GB+ download):
but require rather complete install of LaTeX with various extensions. On
Debian/Ubuntu, try (500MB+ download):
apt install texlive-latex-recommended texlive-latex-extra texlive-xetex texlive-fonts-extra cm-super xindy
apt-get install texlive-latex-recommended texlive-latex-extra

View File

@ -19,56 +19,54 @@ import os
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
sys.path.insert(0, os.path.abspath("."))
# The MICROPY_VERSION env var should be "vX.Y.Z" (or unset).
micropy_version = os.getenv("MICROPY_VERSION") or "latest"
micropy_all_versions = (os.getenv("MICROPY_ALL_VERSIONS") or "latest").split(",")
url_pattern = "%s/en/%%s" % (os.getenv("MICROPY_URL_PREFIX") or "/",)
sys.path.insert(0, os.path.abspath('.'))
# The members of the html_context dict are available inside topindex.html
micropy_version = os.getenv('MICROPY_VERSION') or 'latest'
micropy_all_versions = (os.getenv('MICROPY_ALL_VERSIONS') or 'latest').split(',')
url_pattern = '%s/en/%%s' % (os.getenv('MICROPY_URL_PREFIX') or '/',)
html_context = {
"cur_version": micropy_version,
"all_versions": [(ver, url_pattern % ver) for ver in micropy_all_versions],
"downloads": [
("PDF", url_pattern % micropy_version + "/micropython-docs.pdf"),
'cur_version':micropy_version,
'all_versions':[
(ver, url_pattern % ver) for ver in micropy_all_versions
],
'downloads':[
('PDF', url_pattern % micropy_version + '/micropython-docs.pdf'),
],
"is_release": micropy_version != "latest",
}
# -- General configuration ------------------------------------------------
# If your documentation needs a minimal Sphinx version, state it here.
# needs_sphinx = '1.0'
#needs_sphinx = '1.0'
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx.ext.autodoc",
"sphinx.ext.doctest",
"sphinx.ext.intersphinx",
"sphinx.ext.todo",
"sphinx.ext.coverage",
"sphinxcontrib.jquery",
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.todo',
'sphinx.ext.coverage',
]
# Add any paths that contain templates here, relative to this directory.
templates_path = ["templates"]
templates_path = ['templates']
# The suffix of source filenames.
source_suffix = ".rst"
source_suffix = '.rst'
# The encoding of source files.
# source_encoding = 'utf-8-sig'
#source_encoding = 'utf-8-sig'
# The master toctree document.
master_doc = "index"
master_doc = 'index'
# General information about the project.
project = "MicroPython"
copyright = "- The MicroPython Documentation is Copyright © 2014-2024, Damien P. George, Paul Sokolovsky, and contributors"
project = 'MicroPython'
copyright = '- The MicroPython Documentation is Copyright © 2014-2021, 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
@ -76,45 +74,45 @@ copyright = "- The MicroPython Documentation is Copyright © 2014-2024, Damien P
#
# 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 = micropy_version
version = release = '1.17'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
# language = None
#language = None
# There are two options for replacing |today|: either, you set today to some
# non-false value, then it is used:
# today = ''
#today = ''
# Else, today_fmt is used as the format for a strftime call.
# today_fmt = '%B %d, %Y'
#today_fmt = '%B %d, %Y'
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
exclude_patterns = ["build", ".venv"]
exclude_patterns = ['build', '.venv']
# The reST default role (used for this markup: `text`) to use for all
# documents.
default_role = "any"
default_role = 'any'
# If true, '()' will be appended to :func: etc. cross-reference text.
# add_function_parentheses = True
#add_function_parentheses = True
# If true, the current module name will be prepended to all description
# unit titles (such as .. function::).
# add_module_names = True
#add_module_names = True
# If true, sectionauthor and moduleauthor directives will be shown in the
# output. They are ignored by default.
# show_authors = False
#show_authors = False
# The name of the Pygments (syntax highlighting) style to use.
pygments_style = "sphinx"
pygments_style = 'sphinx'
# A list of ignored prefixes for module index sorting.
# modindex_common_prefix = []
#modindex_common_prefix = []
# If true, keep warnings as "system message" paragraphs in the built documents.
# keep_warnings = False
#keep_warnings = False
# Global include files. Sphinx docs suggest using rst_epilog in preference
# of rst_prolog, so we follow. Absolute paths below mean "from the base
@ -126,168 +124,153 @@ rst_epilog = """
# -- Options for HTML output ----------------------------------------------
# on_rtd is whether we are on readthedocs.org
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
on_rtd = os.environ.get('READTHEDOCS', None) == 'True'
if not on_rtd: # only import and set the theme if we're building docs locally
try:
import sphinx_rtd_theme
html_theme = "sphinx_rtd_theme"
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), "."]
html_theme = 'sphinx_rtd_theme'
html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), '.']
except:
html_theme = "default"
html_theme_path = ["."]
html_theme = 'default'
html_theme_path = ['.']
else:
html_theme_path = ["."]
html_theme_path = ['.']
# Theme options are theme-specific and customize the look and feel of a theme
# further. For a list of options available for each theme, see the
# documentation.
# html_theme_options = {}
#html_theme_options = {}
# Add any paths that contain custom themes here, relative to this directory.
# html_theme_path = ['.']
# The name for this set of Sphinx documents. If None, it defaults to
# "<project> v<release> documentation".
# html_title = None
#html_title = None
# A shorter title for the navigation bar. Default is the same as html_title.
# html_short_title = None
#html_short_title = None
# The name of an image file (relative to this directory) to place at the top
# of the sidebar.
# html_logo = '../../logo/trans-logo.png'
#html_logo = '../../logo/trans-logo.png'
# The name of an image file (within the static path) to use as favicon of the
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
# pixels large.
html_favicon = "static/favicon.ico"
html_favicon = 'static/favicon.ico'
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["static"]
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.
# html_extra_path = []
#html_extra_path = []
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
# using the given strftime format.
html_last_updated_fmt = "%d %b %Y"
html_last_updated_fmt = '%d %b %Y'
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
# html_use_smartypants = True
#html_use_smartypants = True
# Custom sidebar templates, maps document names to template names.
# html_sidebars = {}
#html_sidebars = {}
# Additional templates that should be rendered to pages, maps page names to
# template names.
html_additional_pages = {"index": "topindex.html"}
# If false, no module index is generated.
# html_domain_indices = True
#html_domain_indices = True
# If false, no index is generated.
# html_use_index = True
#html_use_index = True
# If true, the index is split into individual pages for each letter.
# html_split_index = False
#html_split_index = False
# If true, links to the reST sources are added to the pages.
# html_show_sourcelink = True
#html_show_sourcelink = True
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
# html_show_sphinx = True
#html_show_sphinx = True
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
# html_show_copyright = True
#html_show_copyright = True
# If true, an OpenSearch description file will be output, and all pages will
# contain a <link> tag referring to it. The value of this option must be the
# base URL from which the finished HTML is served.
# html_use_opensearch = ''
#html_use_opensearch = ''
# This is the file name suffix for HTML files (e.g. ".xhtml").
# html_file_suffix = None
#html_file_suffix = None
# Output file base name for HTML help builder.
htmlhelp_basename = "MicroPythondoc"
htmlhelp_basename = 'MicroPythondoc'
# -- Options for LaTeX output ---------------------------------------------
latex_elements = {
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Include 3 levels of headers in PDF ToC
"preamble": r"\setcounter{tocdepth}{2}",
# The paper size ('letterpaper' or 'a4paper').
#'papersize': 'letterpaper',
# The font size ('10pt', '11pt' or '12pt').
#'pointsize': '10pt',
# Additional stuff for the LaTeX preamble.
#'preamble': '',
# Include 3 levels of headers in PDF ToC
'preamble': '\setcounter{tocdepth}{2}',
}
# Grouping the document tree into LaTeX files. List of tuples
# (source start file, target name, title,
# author, documentclass [howto, manual, or own class]).
latex_documents = [
(
master_doc,
"MicroPython.tex",
"MicroPython Documentation",
"Damien P. George, Paul Sokolovsky, and contributors",
"manual",
),
(master_doc, 'MicroPython.tex', 'MicroPython Documentation',
'Damien P. George, Paul Sokolovsky, and contributors', 'manual'),
]
# The name of an image file (relative to this directory) to place at the top of
# the title page.
# latex_logo = None
#latex_logo = None
# For "manual" documents, if this is true, then toplevel headings are parts,
# not chapters.
# latex_use_parts = False
#latex_use_parts = False
# If true, show page references after internal links.
# latex_show_pagerefs = False
#latex_show_pagerefs = False
# If true, show URL addresses after external links.
# latex_show_urls = False
#latex_show_urls = False
# Documents to append as an appendix to all manuals.
# latex_appendices = []
#latex_appendices = []
# If false, no module index is generated.
# latex_domain_indices = True
#latex_domain_indices = True
# Enable better Unicode support so that `make latexpdf` doesn't fail
latex_engine = "xelatex"
# -- Options for manual page output ---------------------------------------
# One entry per manual page. List of tuples
# (source start file, name, description, authors, manual section).
man_pages = [
(
"index",
"micropython",
"MicroPython Documentation",
["Damien P. George, Paul Sokolovsky, and contributors"],
1,
),
('index', 'micropython', 'MicroPython Documentation',
['Damien P. George, Paul Sokolovsky, and contributors'], 1),
]
# If true, show URL addresses after external links.
# man_show_urls = False
#man_show_urls = False
# -- Options for Texinfo output -------------------------------------------
@ -296,29 +279,23 @@ man_pages = [
# (source start file, target name, title, author,
# dir menu entry, description, category)
texinfo_documents = [
(
master_doc,
"MicroPython",
"MicroPython Documentation",
"Damien P. George, Paul Sokolovsky, and contributors",
"MicroPython",
"One line description of project.",
"Miscellaneous",
),
(master_doc, 'MicroPython', 'MicroPython Documentation',
'Damien P. George, Paul Sokolovsky, and contributors', 'MicroPython', 'One line description of project.',
'Miscellaneous'),
]
# Documents to append as an appendix to all manuals.
# texinfo_appendices = []
#texinfo_appendices = []
# If false, no module index is generated.
# texinfo_domain_indices = True
#texinfo_domain_indices = True
# How to display URL addresses: 'footnote', 'no', or 'inline'.
# texinfo_show_urls = 'footnote'
#texinfo_show_urls = 'footnote'
# If true, do not generate a @detailmenu in the "Top" node's menu.
# texinfo_no_detailmenu = False
#texinfo_no_detailmenu = False
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {"python": ("https://docs.python.org/3.5", None)}
intersphinx_mapping = {'python': ('https://docs.python.org/3.5', None)}

View File

@ -49,17 +49,9 @@ 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 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 want to include assembly files use ``SRC_USERMOD_LIB_ASM``.
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``
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
@ -95,12 +87,9 @@ A MicroPython user C module is a directory with the following files:
Basic example
-------------
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
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
`in the examples directory <https://github.com/micropython/micropython/tree/master/examples/usercmodule/cexample>`_
and has a source file and a Makefile fragment with content as described above::
@ -232,25 +221,23 @@ as described above.
If a module is not enabled by default then the corresponding C preprocessor macro
must be enabled. This macro name can be found by searching for the ``MP_REGISTER_MODULE``
line in the module's source code (it usually appears at the end of the main source file).
This macro should be surrounded by a ``#if X`` / ``#endif`` pair, and the configuration
option ``X`` must be set to 1 using ``CFLAGS_EXTRA`` to make the module available. If
there is no ``#if X`` / ``#endif`` pair then the module is enabled by default.
The third argument to ``MP_REGISTER_MODULE`` is the macro name, and this must be set
to 1 using ``CFLAGS_EXTRA`` to make the module available. If the third argument is just
the number 1 then the module is enabled by default.
For example, the ``examples/usercmodule/cexample`` module is enabled by default so
has the following line in its source code:
.. code-block:: c
MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule);
MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule, 1);
Alternatively, to make this module disabled by default but selectable through
a preprocessor configuration option, it would be:
.. code-block:: c
#if MODULE_CEXAMPLE_ENABLED
MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule);
#endif
MP_REGISTER_MODULE(MP_QSTR_cexample, example_user_cmodule, MODULE_CEXAMPLE_ENABLED);
In this case the module is enabled by adding ``CFLAGS_EXTRA=-DMODULE_CEXAMPLE_ENABLED=1``
to the ``make`` command, or editing ``mpconfigport.h`` or ``mpconfigboard.h`` to add
@ -275,13 +262,3 @@ 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

View File

@ -98,7 +98,7 @@ Then also edit ``py/lexer.c`` to add the new keyword literal text:
.. code-block:: c
:emphasize-lines: 12
static const char *const tok_kw[] = {
STATIC const char *const tok_kw[] = {
...
"or",
"pass",
@ -147,17 +147,10 @@ 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_compiled_module_t cm;
cm.context = context;
mp_compile_to_raw_code(parse_tree, source_file, is_repl, &cm);
mp_raw_code_t *rc = mp_compile_to_raw_code(parse_tree, source_file, is_repl);
// Create and return a function object that executes the outer module.
return mp_make_function_from_proto_fun(cm.rc, cm.context, NULL);
return mp_make_function_from_raw_code(rc, MP_OBJ_NULL, MP_OBJ_NULL);
}
The compiler compiles the code in four passes: scope, stack size, code size and emit.
@ -301,7 +294,7 @@ code statement:
.. code-block:: c
static void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) {
STATIC void emit_native_unary_op(emit_t *emit, mp_unary_op_t op) {
vtype_kind_t vtype;
emit_pre_pop_reg(emit, &vtype, REG_ARG_2);
if (vtype == VTYPE_PYOBJ) {

View File

@ -16,3 +16,4 @@ live in the main MicroPython repository.
cmodules.rst
natmod.rst

View File

@ -60,10 +60,10 @@ After the above configuration, your setup should be similar to this:
.. code-block:: bash
$ git remote -v
origin https://github.com/<your-user-name>/micropython (fetch)
origin https://github.com/<your-user-name>/micropython (push)
upstream https://github.com/micropython/micropython (fetch)
upstream https://github.com/micropython/micropython (push)
origin https://github.com/<your-user-name>/micropython (fetch)
origin https://github.com/<your-user-name>/micropython (push)
upstream https://github.com/micropython/micropython (fetch)
upstream https://github.com/micropython/micropython (push)
You should now have a copy of the source code. By default, you are pointing
to the master branch. To prepare for further development, it is recommended
@ -100,10 +100,10 @@ For the stm32 port, the ARM cross-compiler is required:
.. code-block:: bash
$ sudo apt-get install gcc-arm-none-eabi libnewlib-arm-none-eabi
$ sudo apt-get install arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-newlib
See the `ARM GCC
toolchain <https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads>`_
toolchain <https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm>`_
for the latest details.
Python is also required. Python 2 is supported for now, but we recommend using Python 3.
@ -140,8 +140,8 @@ If it built successfully, you should see a message similar to this:
.. code-block:: bash
LINK mpy-cross
text data bss dec hex filename
279328 776 880 280984 44998 mpy-cross
text data bss dec hex filename
279328 776 880 280984 44998 mpy-cross
.. note::
@ -181,8 +181,8 @@ If MicroPython built correctly, you should see the following:
.. code-block:: bash
LINK micropython
text data bss dec hex filename
412033 5680 2496 420209 66971 micropython
text data bss dec hex filename
412033 5680 2496 420209 66971 micropython
Now run it:
@ -228,7 +228,7 @@ You can also specify which board to use:
.. code-block:: bash
$ cd ports/stm32
$ make BOARD=<board> submodules
$ make submodules
$ make BOARD=<board>
See `ports/stm32/boards <https://github.com/micropython/micropython/tree/master/ports/stm32/boards>`_
@ -245,7 +245,7 @@ that you use a virtual environment:
$ python3 -m venv env
$ source env/bin/activate
$ pip install -r docs/requirements.txt
$ pip install sphinx
Navigate to the ``docs`` directory:
@ -322,8 +322,7 @@ tests
tools
Contains scripts used by the build and CI process, as well as user tools such
as ``pyboard.py`` and ``mpremote``.
Contains helper tools including the ``upip`` and the ``pyboard.py`` module.
examples

View File

@ -24,3 +24,4 @@ MicroPython to a new platform and implementing a core MicroPython library.
publiccapi.rst
extendingmicropython.rst
porting.rst

View File

@ -48,23 +48,23 @@ hypothetical new module ``subsystem`` in the file ``modsubsystem.c``:
#if MICROPY_PY_SUBSYSTEM
// info()
static mp_obj_t py_subsystem_info(void) {
STATIC mp_obj_t py_subsystem_info(void) {
return MP_OBJ_NEW_SMALL_INT(42);
}
MP_DEFINE_CONST_FUN_OBJ_0(subsystem_info_obj, py_subsystem_info);
static const mp_rom_map_elem_t mp_module_subsystem_globals_table[] = {
STATIC const mp_rom_map_elem_t mp_module_subsystem_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_subsystem) },
{ MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&subsystem_info_obj) },
};
static MP_DEFINE_CONST_DICT(mp_module_subsystem_globals, mp_module_subsystem_globals_table);
STATIC MP_DEFINE_CONST_DICT(mp_module_subsystem_globals, mp_module_subsystem_globals_table);
const mp_obj_module_t mp_module_subsystem = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&mp_module_subsystem_globals,
};
MP_REGISTER_MODULE(MP_QSTR_subsystem, mp_module_subsystem);
MP_REGISTER_MODULE(MP_QSTR_subsystem, mp_module_subsystem, MICROPY_PY_SUBSYSTEM);
#endif

View File

@ -34,7 +34,6 @@ options for the ``ARCH`` variable, see below):
* ``x86`` (32 bit)
* ``x64`` (64 bit x86)
* ``armv6m`` (ARM Thumb, eg Cortex-M0)
* ``armv7m`` (ARM Thumb 2, eg Cortex-M3)
* ``armv7emsp`` (ARM Thumb 2, single precision float, eg Cortex-M4F, Cortex-M7)
* ``armv7emdp`` (ARM Thumb 2, double precision float, eg Cortex-M7)
@ -128,7 +127,7 @@ The file ``factorial.c`` contains:
#include "py/dynruntime.h"
// Helper function to compute factorial
static mp_int_t factorial_helper(mp_int_t x) {
STATIC mp_int_t factorial_helper(mp_int_t x) {
if (x == 0) {
return 1;
}
@ -136,7 +135,7 @@ The file ``factorial.c`` contains:
}
// This is the function which will be called from Python, as factorial(x)
static mp_obj_t factorial(mp_obj_t x_obj) {
STATIC mp_obj_t factorial(mp_obj_t x_obj) {
// Extract the integer from the MicroPython input object
mp_int_t x = mp_obj_get_int(x_obj);
// Calculate the factorial
@ -145,7 +144,7 @@ The file ``factorial.c`` contains:
return mp_obj_new_int(result);
}
// Define a Python reference to the function above
static MP_DEFINE_CONST_FUN_OBJ_1(factorial_obj, factorial);
STATIC MP_DEFINE_CONST_FUN_OBJ_1(factorial_obj, factorial);
// This is the entry point and is called when the module is imported
mp_obj_t mpy_init(mp_obj_fun_bc_t *self, size_t n_args, size_t n_kw, mp_obj_t *args) {
@ -172,7 +171,7 @@ The file ``Makefile`` contains:
# Source files (.c or .py)
SRC = factorial.c
# Architecture to build for (x86, x64, armv6m, armv7m, xtensa, xtensawin)
# Architecture to build for (x86, x64, armv7m, xtensa, xtensawin)
ARCH = x64
# Include to get the rules for compiling and linking the module

View File

@ -25,15 +25,13 @@ 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
---------
MicroPython processes local and global variables differently. Global variables
are stored and looked up from a global dictionary that is allocated on the heap
(note that each module has its own separate dict, so separate namespace).
Local variables on the other hand are stored on the Python value stack, which may
Local variables on the other hand are are stored on the Python value stack, which may
live on the C stack or on the heap. They are accessed directly by their offset
within the Python stack, which is more efficient than a global lookup in a dict.

View File

@ -38,7 +38,6 @@ 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"
@ -54,6 +53,8 @@ The basic MicroPython firmware is implemented in the main port file, e.g ``main.
mp_stack_ctrl_init();
gc_init(heap, heap + sizeof(heap));
mp_init();
mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_path), 0);
mp_obj_list_init(MP_OBJ_TO_PTR(mp_sys_argv), 0);
// Start a normal REPL; will exit when ctrl-D is entered on a blank line.
pyexec_friendly_repl();
@ -83,7 +84,7 @@ The basic MicroPython firmware is implemented in the main port file, e.g ``main.
}
// There is no filesystem so opening a file raises an exception.
mp_lexer_t *mp_lexer_new_from_file(qstr filename) {
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
mp_raise_OSError(MP_ENOENT);
}
@ -96,11 +97,10 @@ We also need a Makefile at this point for the port:
# Include py core make definitions.
include $(TOP)/py/py.mk
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 = \
@ -111,9 +111,6 @@ 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))
@ -175,6 +172,9 @@ 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.
@ -262,24 +262,29 @@ To add a custom module like ``myport``, first add the module definition in a fil
#include "py/runtime.h"
static mp_obj_t myport_info(void) {
STATIC mp_obj_t myport_info(void) {
mp_printf(&mp_plat_print, "info about my port\n");
return mp_const_none;
}
static MP_DEFINE_CONST_FUN_OBJ_0(myport_info_obj, myport_info);
STATIC MP_DEFINE_CONST_FUN_OBJ_0(myport_info_obj, myport_info);
static const mp_rom_map_elem_t myport_module_globals_table[] = {
STATIC const mp_rom_map_elem_t myport_module_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_myport) },
{ MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&myport_info_obj) },
};
static MP_DEFINE_CONST_DICT(myport_module_globals, myport_module_globals_table);
STATIC MP_DEFINE_CONST_DICT(myport_module_globals, myport_module_globals_table);
const mp_obj_module_t myport_module = {
.base = { &mp_type_module },
.globals = (mp_obj_dict_t *)&myport_module_globals,
};
MP_REGISTER_MODULE(MP_QSTR_myport, myport_module);
MP_REGISTER_MODULE(MP_QSTR_myport, myport_module, 1);
Note: the "1" as the third argument in ``MP_REGISTER_MODULE`` enables this new module
unconditionally. To allow it to be conditionally enabled, replace the "1" by
``MICROPY_PY_MYPORT`` and then add ``#define MICROPY_PY_MYPORT (1)`` in ``mpconfigport.h``
accordingly.
You will also need to edit the Makefile to add ``modmyport.c`` to the ``SRC_C`` list, and
a new line adding the same file to ``SRC_QSTR`` (so qstrs are searched for in this new file),
@ -293,7 +298,7 @@ like this:
mphalport.c \
...
SRC_QSTR += modmyport.c
SRC_QSTR += modport.c
If all went correctly then, after rebuilding, you should be able to import the new module:

View File

@ -3,22 +3,8 @@
MicroPython differences from CPython
====================================
MicroPython implements Python 3.4 and some select features of Python 3.5 and
above. The sections below describe the current status of these features.
.. toctree::
../differences/python_35.rst
../differences/python_36.rst
../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
operations listed in the sections below produce conflicting results in
MicroPython when compared to standard Python.
The operations listed in this section produce conflicting results in MicroPython when compared to standard Python.
MicroPython implements Python 3.4 and some select features of Python 3.5.
.. toctree::
:maxdepth: 2

View File

@ -1,33 +0,0 @@
.. Preamble section inserted into generated output
Positional-only Parameters
--------------------------
To save code size, many functions that accept keyword arguments in CPython only accept positional arguments in MicroPython.
MicroPython marks positional-only parameters in the same way as CPython, by inserting a ``/`` to mark the end of the positional parameters. Any function whose signature ends in ``/`` takes *only* positional arguments. For more details, see `PEP 570 <https://peps.python.org/pep-0570/>`_.
Example
~~~~~~~
For example, in CPython 3.4 this is the signature of the constructor ``socket.socket``::
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)
However, the signature documented in :func:`MicroPython<socket.socket>` is::
socket(af=AF_INET, type=SOCK_STREAM, proto=IPPROTO_TCP, /)
The ``/`` at the end of the parameters indicates that they are all positional-only in MicroPython. The following code works in CPython but not in most MicroPython ports::
import socket
s = socket.socket(type=socket.SOCK_DGRAM)
MicroPython will raise an exception::
TypeError: function doesn't take keyword arguments
The following code will work in both CPython and MicroPython::
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

View File

@ -1,238 +0,0 @@
.. _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 <https://www.python.org/dev/peps/pep-0619/#features-for-3-10>`_
and a detailed description of the changes can be found in
`What's New in Python 3.10 <https://docs.python.org/3/whatsnew/3.10.html>`_.
.. table::
:widths: 20 60 20
+--------------------------------------------------------+----------------------------------------------------+--------------+
| **New syntax features** | **Status** |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 634 <https://www.python.org/dev/peps/pep-0634/>`_ | Structural Pattern Matching: Specification | [#spm]_ |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 635 <https://www.python.org/dev/peps/pep-0635/>`_ | Structural Pattern Matching: Motivation and | [#spm]_ |
| | Rationale | |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 636 <https://www.python.org/dev/peps/pep-0636/>`_ | Structural Pattern Matching: Tutorial | [#spm]_ |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `bpo-12782 | Parenthesized context managers are now officially | |
| <https://github.com/python/cpython/issues/56991>`_ | allowed | |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| **New features in the standard library** |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 618 <https://www.python.org/dev/peps/pep-0618/>`_ | Add Optional Length-Checking To zip | |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| **Interpreter improvements** |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 626 <https://www.python.org/dev/peps/pep-0626/>`_ | Precise line numbers for debugging and other tools | |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| **New typing features** |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 604 <https://www.python.org/dev/peps/pep-0604/>`_ | Allow writing union types as X | Y | |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 613 <https://www.python.org/dev/peps/pep-0613/>`_ | Explicit Type Aliases | |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 612 <https://www.python.org/dev/peps/pep-0612/>`_ | Parameter Specification Variables | |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| **Important deprecations, removals or restrictions** |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 644 <https://www.python.org/dev/peps/pep-0644/>`_ | Require OpenSSL 1.1.1 or newer | |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 632 <https://www.python.org/dev/peps/pep-0632/>`_ | Deprecate distutils module. | Not relevant |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 623 <https://www.python.org/dev/peps/pep-0623/>`_ | Deprecate and prepare for the removal of the wstr | Not relevant |
| | member in PyUnicodeObject. | |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 624 <https://www.python.org/dev/peps/pep-0624/>`_ | Remove Py_UNICODE encoder APIs | Not relevant |
+--------------------------------------------------------+----------------------------------------------------+--------------+
| `PEP 597 <https://www.python.org/dev/peps/pep-0597/>`_ | 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 <staticmethod>`) and class methods | |
| (:func:`@classmethod <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 objects ``__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 <https://docs.python.org/3/whatsnew/3.10.html#asyncio>`_ |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Add missing :meth:`~asyncio.events.AbstractEventLoop.connect_accepted_socket` | |
| method. | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| `array <https://docs.python.org/3/whatsnew/3.10.html#array>`_ |
+---------------------------------------------------------------------------------------------------------------+---------------+
| The :meth:`~array.array.index` method of :class:`array.array` now has | |
| optional *start* and *stop* parameters. | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| `gc <https://docs.python.org/3/whatsnew/3.10.html#gc>`_ |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Add audit hooks for :func:`gc.get_objects`, :func:`gc.get_referrers` and | |
| :func:`gc.get_referents`. | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| `hashlib <https://docs.python.org/3/whatsnew/3.10.html#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 <https://docs.python.org/3/whatsnew/3.10.html#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 <https://docs.python.org/3/whatsnew/3.10.html#platform>`_ |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Add :func:`platform.freedesktop_os_release()` to retrieve operation system | |
| identification from `freedesktop.org os-release | |
| <https://www.freedesktop.org/software/systemd/man/os-release.html>`_ standard file. | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| `socket <https://docs.python.org/3/whatsnew/3.10.html#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 <https://docs.python.org/3/whatsnew/3.10.html#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 <https://docs.python.org/3/whatsnew/3.10.html#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 <https://docs.python.org/3/whatsnew/3.10.html#_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 <https://github.com/micropython/micropython/issues/7847>`_.

View File

@ -1,193 +0,0 @@
.. _python_35:
Python 3.5
==========
Below is a list of finalised/accepted PEPs for Python 3.5 grouped into their impact to MicroPython.
.. table::
:widths: 30 50 20
+--------------------------------------------------------------------------------------------------------------+--------------------+
| **Extensions to the syntax** | **Status** |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 448 <https://www.python.org/dev/peps/pep-0448/>`_ | Additional unpacking generalizations | Partial |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 465 <https://www.python.org/dev/peps/pep-0465/>`_ | A new matrix multiplication operator | Complete |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 492 <https://www.python.org/dev/peps/pep-0492/>`_ | Coroutines with ``async`` and ``await`` syntax | Complete |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| **Extensions and changes to runtime** |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 461 <https://www.python.org/dev/peps/pep-0461/>`_ | % formatting for binary strings | Complete |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 475 <https://www.python.org/dev/peps/pep-0475/>`_ | Retrying system calls that fail with ``EINTR`` | Complete |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 479 <https://www.python.org/dev/peps/pep-0479/>`_ | Change ``StopIteration`` handling inside generators | Complete |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| **Standard library changes** |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 471 <https://www.python.org/dev/peps/pep-0471/>`_ | ``os.scandir()`` | |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 485 <https://www.python.org/dev/peps/pep-0485/>`_ | ``math.isclose()``, a function for testing | Complete |
| | approximate equality | |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| **Miscellaneous changes** |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 441 <https://www.python.org/dev/peps/pep-0441/>`_ | Improved Python zip application support | |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 486 <https://www.python.org/dev/peps/pep-0486/>`_ | Make the Python Launcher aware of virtual | Not relevant |
| | environments | |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 484 <https://www.python.org/dev/peps/pep-0484/>`_ | Type hints (advisory only) | Complete [#fth]_ |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 488 <https://www.python.org/dev/peps/pep-0488/>`_ | Elimination of PYO files | Not relevant |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
| `PEP 489 <https://www.python.org/dev/peps/pep-0489/>`_ | Redesigning extension module loading | |
+--------------------------------------------------------+-----------------------------------------------------+--------------------+
Other Language Changes:
.. 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:
* `typing <https://docs.python.org/3/whatsnew/3.5.html#typing>`_
* `zipzap <https://docs.python.org/3/whatsnew/3.5.html#zipapp>`_
Changes to built-in modules:
.. table::
:widths: 90 10
+-----------------------------------------------------------------------------------------------------------+---------------+
| `collections <https://docs.python.org/3/whatsnew/3.5.html#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 <https://docs.python.org/3/whatsnew/3.5.html#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 <https://docs.python.org/3/whatsnew/3.5.html#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 <https://docs.python.org/3/whatsnew/3.5.html#json>`_ | |
+-----------------------------------------------------------------------------------------------------------+---------------+
| JSON decoder now raises JSONDecodeError instead of ValueError to provide better context information about | |
| the error. | |
+-----------------------------------------------------------------------------------------------------------+---------------+
| `math <https://docs.python.org/3/whatsnew/3.5.html#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 <https://docs.python.org/3/whatsnew/3.5.html#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 <https://docs.python.org/3/whatsnew/3.5.html#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 <https://docs.python.org/3/whatsnew/3.5.html#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 <https://docs.python.org/3/whatsnew/3.5.html#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 <https://docs.python.org/3/whatsnew/3.5.html#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 <https://docs.python.org/3/whatsnew/3.5.html#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.

View File

@ -1,200 +0,0 @@
.. _python_36:
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:
.. table::
:widths: 30 50 20
+-----------------------------------------------------------------------------------------------------------+-----------------+
| **New Syntax Features** | **Status** |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 498 <https://www.python.org/dev/peps/pep-0498/>`_ | Literal String Formatting | Complete |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 515 <https://www.python.org/dev/peps/pep-0515/>`_ | Underscores in Numeric Literals | Complete |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 525 <https://www.python.org/dev/peps/pep-0525/>`_ | Asynchronous Generators | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 526 <https://www.python.org/dev/peps/pep-0526/>`_ | Syntax for Variable Annotations (provisional) | Complete |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 530 <https://www.python.org/dev/peps/pep-0530/>`_ | Asynchronous Comprehensions | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| **New Built-in Features** |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 468 <https://www.python.org/dev/peps/pep-0468/>`_ | Preserving the order of *kwargs* in a function | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 487 <https://www.python.org/dev/peps/pep-0487/>`_ | Simpler customization of class creation | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 520 <https://www.python.org/dev/peps/pep-0520/>`_ | Preserving Class Attribute Definition Order | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| **Standard Library Changes** |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 495 <https://www.python.org/dev/peps/pep-0495/>`_ | Local Time Disambiguation | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 506 <https://www.python.org/dev/peps/pep-0506/>`_ | Adding A Secrets Module To The Standard Library | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 519 <https://www.python.org/dev/peps/pep-0519/>`_ | Adding a file system path protocol | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| **CPython Internals** |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 509 <https://www.python.org/dev/peps/pep-0509/>`_ | Add a private version to dict | Won't do |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 523 <https://www.python.org/dev/peps/pep-0523/>`_ | Adding a frame evaluation API to CPython | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| **Linux/Window Changes** |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 524 <https://www.python.org/dev/peps/pep-0524/>`_ | Make ``os.urandom()`` blocking on Linux | |
| | (during system startup) | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 528 <https://www.python.org/dev/peps/pep-0528/>`_ | Change Windows console encoding to UTF-8 | |
+--------------------------------------------------------+--------------------------------------------------+-----------------+
| `PEP 529 <https://www.python.org/dev/peps/pep-0529/>`_ | 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. | |
+-------------------------------------------------------------------------------------------------------------+---------------+
| It is now possible to set a special method to None to indicate that the corresponding operation is not | |
| available. For example, if a class sets *__iter__()* to *None* , the class is not iterable. | |
+-------------------------------------------------------------------------------------------------------------+---------------+
| Long sequences of repeated traceback lines are now abbreviated as *[Previous line repeated {count} more | |
| times]* | |
+-------------------------------------------------------------------------------------------------------------+---------------+
| Import now raises the new exception *ModuleNotFoundError* when it cannot find a module. Code that currently | |
| checks for ImportError (in try-except) will still work. | |
+-------------------------------------------------------------------------------------------------------------+---------------+
| Class methods relying on zero-argument *super()* will now work correctly when called from metaclass methods | |
| during class creation. | |
+-------------------------------------------------------------------------------------------------------------+---------------+
Changes to built-in modules:
.. table::
:widths: 90 10
+--------------------------------------------------------------------------------------------------------------+----------------+
| `array <https://docs.python.org/3.6/whatsnew/3.6.html#array>`_ | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| Exhausted iterators of *array.array* will now stay exhausted even if the iterated array is extended. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `binascii <https://docs.python.org/3.6/whatsnew/3.6.html#binascii>`_ | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| 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 <https://docs.python.org/3.6/whatsnew/3.6.html#cmath>`_ | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The new cmath.tau (τ) constant has been added | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| New constants: *cmath.inf* and *cmath.nan* to match *math.inf* and *math.nan* , and also *cmath.infj* and | |
| *cmath.nanj* to match the format used by complex repr | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `collections <https://docs.python.org/3.6/whatsnew/3.6.html#collections>`_ |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The new Collection abstract base class has been added to represent sized iterable container classes | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The new *Reversible* abstract base class represents iterable classes that also provide the *__reversed__()* | |
| method. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The new *AsyncGenerator* abstract base class represents asynchronous generators. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The *namedtuple()* function now accepts an optional keyword argument module, which, when specified, is used | |
| for the *__module__* attribute of the returned named tuple class. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The verbose and rename arguments for *namedtuple()* are now keyword-only. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| Recursive *collections.deque* instances can now be pickled. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `hashlib <https://docs.python.org/3.6/whatsnew/3.6.html#hashlib>`_ |
+--------------------------------------------------------------------------------------------------------------+----------------+
| BLAKE2 hash functions were added to the module. *blake2b()* and *blake2s()* are always available and support | |
| the full feature set of BLAKE2. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The SHA-3 hash functions *sha3_224()*, *sha3_256()*, *sha3_384()*, *sha3_512()*, and *SHAKE* hash functions | |
| *shake_128()* and *shake_256()* were added. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The password-based key derivation function *scrypt()* is now available with OpenSSL 1.1.0 and newer. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `json <https://docs.python.org/3.6/whatsnew/3.6.html#json>`_ |
+--------------------------------------------------------------------------------------------------------------+----------------+
| *json.load()* and *json.loads()* now support binary input. Encoded JSON should be represented using either | |
| UTF-8, UTF-16, or UTF-32. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `math <https://docs.python.org/3.6/whatsnew/3.6.html#math>`_ |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The new math.tau (τ) constant has been added | Complete |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `os <https://docs.python.org/3.6/whatsnew/3.6.html#os>`_ |
+--------------------------------------------------------------------------------------------------------------+----------------+
| A new *close()* method allows explicitly closing a *scandir()* iterator. The *scandir()* iterator now | |
| supports the context manager protocol. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| On Linux, *os.urandom()* now blocks until the system urandom entropy pool is initialized to increase the | |
| security. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The Linux *getrandom()* syscall (get random bytes) is now exposed as the new *os.getrandom()* function. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `re <https://docs.python.org/3.6/whatsnew/3.6.html#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'*. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| Match object groups can be accessed by *__getitem__*, which is equivalent to *group()*. So *mo['name']* is | |
| now equivalent to *mo.group('name')*. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| Match objects now support index-like objects as group indices. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `socket <https://docs.python.org/3.6/whatsnew/3.6.html#socket>`_ |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The *ioctl()* function now supports the *SIO_LOOPBACK_FAST_PATH* control code. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The *getsockopt()* constants *SO_DOMAIN* , *SO_PROTOCOL*, *SO_PEERSEC* , and *SO_PASSSEC* are now supported. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The *setsockopt()* now supports the *setsockopt(level, optname, None, optlen: int)* form. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The socket module now supports the address family *AF_ALG* to interface with Linux Kernel crypto API. | |
| *ALG_*, *SOL_ALG* and *sendmsg_afalg()* were added. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| New Linux constants *TCP_USER_TIMEOUT* and *TCP_CONGESTION* were added. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `ssl <https://docs.python.org/3.6/whatsnew/3.6.html#ssl>`_ |
+--------------------------------------------------------------------------------------------------------------+----------------+
| ssl supports OpenSSL 1.1.0. The minimum recommend version is 1.0.2. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| 3DES has been removed from the default cipher suites and ChaCha20 Poly1305 cipher suites have been added. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| *SSLContext* has better default configuration for options and ciphers. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| SSL session can be copied from one client-side connection to another with the new *SSLSession* class. TLS | |
| session resumption can speed up the initial handshake, reduce latency and improve performance. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The new *get_ciphers()* method can be used to get a list of enabled ciphers in order of cipher priority. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| All constants and flags have been converted to *IntEnum* and *IntFlags*. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| Server and client-side specific TLS protocols for *SSLContext* were added. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| Added *SSLContext.post_handshake_auth* to enable and *ssl.SSLSocket.verify_client_post_handshake()* to | |
| initiate TLS 1.3 post-handshake authentication. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `struct <https://docs.python.org/3.6/whatsnew/3.6.html#struct>`_ | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| now supports IEEE 754 half-precision floats via the 'e' format specifier. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `sys <https://docs.python.org/3.6/whatsnew/3.6.html#sys>`_ | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The new *getfilesystemencodeerrors()* function returns the name of the error mode used to convert between | |
| Unicode filenames and bytes filenames. | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| `zlib <https://docs.python.org/3.6/whatsnew/3.6.html#zlib>`_ | |
+--------------------------------------------------------------------------------------------------------------+----------------+
| The *compress()* and *decompress()* functions now accept keyword arguments | |
+--------------------------------------------------------------------------------------------------------------+----------------+

View File

@ -1,108 +0,0 @@
.. _python_37:
Python 3.7
==========
New Features:
.. table::
:widths: 20 60 20
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| **Feature** | **Status** |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 538 <https://www.python.org/dev/peps/pep-0538/>`_ | Coercing the legacy C locale to a UTF-8 based | |
| | locale | |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 539 <https://www.python.org/dev/peps/pep-0539/>`_ | A New C-API for Thread-Local Storage in CPython | |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 540 <https://www.python.org/dev/peps/pep-0540/>`_ | UTF-8 mode | |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 552 <https://www.python.org/dev/peps/pep-0552/>`_ | Deterministic pyc | |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 553 <https://www.python.org/dev/peps/pep-0553/>`_ | Built-in ``breakpoint()`` | |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 557 <https://www.python.org/dev/peps/pep-0557/>`_ | Data Classes | |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 560 <https://www.python.org/dev/peps/pep-0560/>`_ | Core support for typing module and generic types | |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 562 <https://www.python.org/dev/peps/pep-0562/>`_ | Module ``__getattr__`` and ``__dir__`` | Partial |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 563 <https://www.python.org/dev/peps/pep-0563/>`_ | Postponed Evaluation of Annotations | |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 564 <https://www.python.org/dev/peps/pep-0564/>`_ | Time functions with nanosecond resolution | Partial [#ftimenanosec]_ |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 565 <https://www.python.org/dev/peps/pep-0565/>`_ | Show DeprecationWarning in ``__main__`` | |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
| `PEP 567 <https://www.python.org/dev/peps/pep-0567/>`_ | Context Variables | |
+--------------------------------------------------------+--------------------------------------------------+--------------------------------------+
Other Language Changes:
.. 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 <https://docs.python.org/3/whatsnew/3.7.html#asyncio>`_ | |
+------------------------------------------------------------------------------------------------------------+----------------+
| Too many to list | |
+------------------------------------------------------------------------------------------------------------+----------------+
| `gc <https://docs.python.org/3/whatsnew/3.7.html#gc>`_ | |
+------------------------------------------------------------------------------------------------------------+----------------+
| New features include *gc.freeze()*, *gc.unfreeze()*, *gc-get_freeze_count* | |
+------------------------------------------------------------------------------------------------------------+----------------+
| `math <https://docs.python.org/3/whatsnew/3.7.html#math>`_ | |
+------------------------------------------------------------------------------------------------------------+----------------+
| math.remainder() added to implement IEEE 754-style remainder | |
+------------------------------------------------------------------------------------------------------------+----------------+
| `re <https://docs.python.org/3/whatsnew/3.7.html#re>`_ | |
+------------------------------------------------------------------------------------------------------------+----------------+
| A number of tidy up features including better support for splitting on empty strings and copy support for | |
| compiled expressions and match objects | |
+------------------------------------------------------------------------------------------------------------+----------------+
| `sys <https://docs.python.org/3/whatsnew/3.7.html#sys>`_ | |
+------------------------------------------------------------------------------------------------------------+----------------+
| sys.breakpointhook() added. sys.get(/set)_coroutine_origin_tracking_depth() added | |
+------------------------------------------------------------------------------------------------------------+----------------+
| `time <https://docs.python.org/3/whatsnew/3.7.html#time>`_ | |
+------------------------------------------------------------------------------------------------------------+----------------+
| Mostly updates to support nanosecond resolution in PEP564, see above | |
+------------------------------------------------------------------------------------------------------------+----------------+
.. rubric:: Notes
.. [#ftimenanosec] Only :func:`time.time_ns` is implemented.

View File

@ -1,127 +0,0 @@
.. _python_38:
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 <https://www.python.org/dev/peps/pep-0569/#id9>`_ and
a detailed description of the changes can be found in `What's New in Python
3.8. <https://docs.python.org/3/whatsnew/3.8.html>`_
.. table::
:widths: 20 60 20
+--------------------------------------------------------+---------------------------------------------------+---------------+
| **Features** | **Status** |
+--------------------------------------------------------+---------------------------------------------------+---------------+
| `PEP 570 <https://www.python.org/dev/peps/pep-0570/>`_ | Positional-only arguments | |
+--------------------------------------------------------+---------------------------------------------------+---------------+
| `PEP 572 <https://www.python.org/dev/peps/pep-0572/>`_ | Assignment Expressions | Complete |
+--------------------------------------------------------+---------------------------------------------------+---------------+
| `PEP 574 <https://www.python.org/dev/peps/pep-0574/>`_ | Pickle protocol 5 with out-of-band data | |
+--------------------------------------------------------+---------------------------------------------------+---------------+
| `PEP 578 <https://www.python.org/dev/peps/pep-0578/>`_ | Runtime audit hooks | |
+--------------------------------------------------------+---------------------------------------------------+---------------+
| `PEP 587 <https://www.python.org/dev/peps/pep-0587/>`_ | Python Initialization Configuration | |
+--------------------------------------------------------+---------------------------------------------------+---------------+
| `PEP 590 <https://www.python.org/dev/peps/pep-0590/>`_ | Vectorcall: a fast calling protocol for CPython | |
+--------------------------------------------------------+---------------------------------------------------+---------------+
| **Miscellaneous** |
+------------------------------------------------------------------------------------------------------------+---------------+
| 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 | 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 | |
| in *float* and *decimal.Decimal* | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Constructors of *int*, *float* and *complex* will now use the *__index__()* special method, if available | |
| and the corresponding method *__int__()*, *__float__()* or *__complex__()* is not available | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Added support of *\N{name}* escapes in regular expressions | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Dict and dictviews are now iterable in reversed insertion order using *reversed()* | |
+------------------------------------------------------------------------------------------------------------+-------------+
| The syntax allowed for keyword names in function calls was further restricted. In particular, | |
| f((keyword)=arg) is no longer allowed | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Generalized iterable unpacking in yield and return statements no longer requires enclosing parentheses | |
+------------------------------------------------------------------------------------------------------------+-------------+
| When a comma is missed in code such as [(10, 20) (30, 40)], the compiler displays a SyntaxWarning with a | |
| helpful suggestion | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Arithmetic operations between subclasses of *datetime.date* or *datetime.datetime* and *datetime.timedelta*| |
| objects now return an instance of the subclass, rather than the base class | |
+------------------------------------------------------------------------------------------------------------+-------------+
| When the Python interpreter is interrupted by *Ctrl-C (SIGINT)* and the resulting *KeyboardInterrupt* | |
| exception is not caught, the Python process now exits via a SIGINT signal or with the correct exit code | |
| such that the calling process can detect that it died due to a *Ctrl-C* | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Some advanced styles of programming require updating the *types.CodeType* object for an existing function | |
+------------------------------------------------------------------------------------------------------------+-------------+
| For integers, the three-argument form of the pow() function now permits the exponent to be negative in the | |
| case where the base is relatively prime to the modulus | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Dict comprehensions have been synced-up with dict literals so that the key is computed first and the value | |
| second | |
+------------------------------------------------------------------------------------------------------------+-------------+
| The *object.__reduce__()* method can now return a tuple from two to six elements long | |
+------------------------------------------------------------------------------------------------------------+-------------+
Changes to built-in modules:
.. table::
:widths: 90 10
+------------------------------------------------------------------------------------------------------------+-------------+
| `asyncio <https://docs.python.org/3/whatsnew/3.8.html#asyncio>`_ |
+------------------------------------------------------------------------------------------------------------+-------------+
| *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 | Complete |
| longer inherits from *concurrent.futures.CancelledError* | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Added *asyncio.Task.get_coro()* for getting the wrapped coroutine within an *asyncio.Task* | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Asyncio tasks can now be named, either by passing the name keyword argument to *asyncio.create_task()* or | |
| the *create_task()* event loop method, or by calling the *set_name()* method on the task object | |
+------------------------------------------------------------------------------------------------------------+-------------+
| 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 <https://docs.python.org/3/whatsnew/3.8.html#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 <https://docs.python.org/3/whatsnew/3.8.html#math>`_ |
+------------------------------------------------------------------------------------------------------------+-------------+
| Added new function *math.dist()* for computing Euclidean distance between two points | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Expanded the *math.hypot()* function to handle multiple dimensions | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Added new function, *math.prod()*, as analogous function to *sum()* that returns the product of a "start" | |
| value (default: 1) times an iterable of numbers | |
+------------------------------------------------------------------------------------------------------------+-------------+
| Added two new combinatoric functions *math.perm()* and *math.comb()* | |
+------------------------------------------------------------------------------------------------------------+-------------+
| 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 | Complete |
+------------------------------------------------------------------------------------------------------------+-------------+
| `sys <https://docs.python.org/3/whatsnew/3.8.html#sys>`_ |
+------------------------------------------------------------------------------------------------------------+-------------+
| Add new *sys.unraisablehook()* function which can be overridden to control how "unraisable exceptions" | |
| are handled | |
+------------------------------------------------------------------------------------------------------------+-------------+

View File

@ -1,134 +0,0 @@
.. _python_39:
Python 3.9
==========
Python 3.9.0 (final) was released on the 5th October 2020. The Features for 3.9 are
defined in `PEP 596 <https://www.python.org/dev/peps/pep-0596/#features-for-3-9>`_
and a detailed description of the changes can be found in
`What's New in Python 3.9 <https://docs.python.org/3/whatsnew/3.9.html>`_
.. table::
:widths: 20 60 20
+--------------------------------------------------------+----------------------------------------------------+----------------------+
| **Features** | | **Status** |
+--------------------------------------------------------+----------------------------------------------------+----------------------+
| `PEP 573 <https://www.python.org/dev/peps/pep-0573/>`_ | Fast access to module state from methods of C | Not relevant |
| | extension types | |
+--------------------------------------------------------+----------------------------------------------------+----------------------+
| `PEP 584 <https://www.python.org/dev/peps/pep-0584/>`_ | Union operators added to dict | Complete [#pep584]_ |
+--------------------------------------------------------+----------------------------------------------------+----------------------+
| `PEP 585 <https://www.python.org/dev/peps/pep-0584/>`_ | Type hinting generics in standard collections | |
+--------------------------------------------------------+----------------------------------------------------+----------------------+
| `PEP 593 <https://www.python.org/dev/peps/pep-0593/>`_ | Flexible function and variable annotations | |
+--------------------------------------------------------+----------------------------------------------------+----------------------+
| `PEP 602 <https://www.python.org/dev/peps/pep-0602/>`_ | CPython adopts an annual release cycle. Instead of | Not relevant |
| | annual, aiming for two month release cycle | |
+--------------------------------------------------------+----------------------------------------------------+----------------------+
| `PEP 614 <https://www.python.org/dev/peps/pep-0614/>`_ | Relaxed grammar restrictions on decorators | |
+--------------------------------------------------------+----------------------------------------------------+----------------------+
| `PEP 615 <https://www.python.org/dev/peps/pep-0615/>`_ | The IANA Time Zone Database is now present in the | |
| | standard library in the zoneinfo module | |
+--------------------------------------------------------+----------------------------------------------------+----------------------+
| `PEP 616 <https://www.python.org/dev/peps/pep-0616/>`_ | String methods to remove prefixes and suffixes | |
+--------------------------------------------------------+----------------------------------------------------+----------------------+
| `PEP 617 <https://www.python.org/dev/peps/pep-0617/>`_ | 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* | 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 | |
| relative path | |
+-------------------------------------------------------------------------------------------------------------+---------------+
| By default, for best performance, the errors argument is only checked at the first encoding/decoding error | |
| and the encoding argument is sometimes ignored for empty strings | |
+-------------------------------------------------------------------------------------------------------------+---------------+
| *"".replace("", s, n)* now returns *s* instead of an empty string for all non-zero n. It is now consistent | |
| with *"".replace("", s)* | |
+-------------------------------------------------------------------------------------------------------------+---------------+
| Any valid expression can now be used as a decorator. Previously, the grammar was much more restrictive | |
+-------------------------------------------------------------------------------------------------------------+---------------+
| Parallel running of *aclose()* / *asend()* / *athrow()* is now prohibited, and *ag_running* now reflects | |
| the actual running status of the async generator | |
+-------------------------------------------------------------------------------------------------------------+---------------+
| Unexpected errors in calling the *__iter__* method are no longer masked by TypeError in the in operator and | |
| functions contains(), indexOf() and countOf() of the operator module | |
+-------------------------------------------------------------------------------------------------------------+---------------+
| Unparenthesized lambda expressions can no longer be the expression part in an if clause in comprehensions | |
| and generator expressions | |
+-------------------------------------------------------------------------------------------------------------+---------------+
Changes to built-in modules:
.. table::
:widths: 90 10
+---------------------------------------------------------------------------------------------------------------+---------------+
| `asyncio <https://docs.python.org/3/whatsnew/3.9.html#asyncio>`_ |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Due to significant security concerns, the reuse_address parameter of *asyncio.loop.create_datagram_endpoint()*| |
| is no longer supported | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Added a new coroutine *shutdown_default_executor()* that schedules a shutdown for the default executor that | |
| waits on the *ThreadPoolExecutor* to finish closing. Also, *asyncio.run()* has been updated to use the new | |
| coroutine. | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Added *asyncio.PidfdChildWatcher*, a Linux-specific child watcher implementation that polls process file | |
| descriptors | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| added a new *coroutine asyncio.to_thread()* | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| When cancelling the task due to a timeout, *asyncio.wait_for()* will now wait until the cancellation is | |
| complete also in the case when timeout is <= 0, like it does with positive timeouts | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| *asyncio* now raises *TyperError* when calling incompatible methods with an *ssl.SSLSocket* socket | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| `gc <https://docs.python.org/3/whatsnew/3.9.html#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 <https://docs.python.org/3/whatsnew/3.9.html#math>`_ |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Expanded the *math.gcd()* function to handle multiple arguments. Formerly, it only supported two arguments | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Added *math.lcm()*: return the least common multiple of specified arguments | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Added *math.nextafter()*: return the next floating-point value after x towards y | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Added *math.ulp()*: return the value of the least significant bit of a float | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| `os <https://docs.python.org/3/whatsnew/3.9.html#os>`_ |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Exposed the Linux-specific *os.pidfd_open()* and *os.P_PIDFD* | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| The *os.unsetenv()* function is now also available on Windows | Complete |
+---------------------------------------------------------------------------------------------------------------+---------------+
| 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 <https://docs.python.org/3/whatsnew/3.9.html#random>`_ |
+---------------------------------------------------------------------------------------------------------------+---------------+
| Added a new *random.Random.randbytes* method: generate random bytes | |
+---------------------------------------------------------------------------------------------------------------+---------------+
| `sys <https://docs.python.org/3/whatsnew/3.9.html#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.

View File

@ -16,10 +16,7 @@ working with this board it may be useful to get an overview of the microcontroll
:maxdepth: 1
general.rst
tutorial/index.rst
Note that there are several varieties of ESP32 -- ESP32, ESP32C3, ESP32C6, ESP32S2, ESP32S3 --
supported by MicroPython, with some differences in functionality between them.
tutorial/intro.rst
Installing MicroPython
----------------------
@ -60,25 +57,17 @@ 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, not on ESP32C3/C6
esp32.ULP() # access to the Ultra-Low-Power Co-processor
Note that the temperature sensor in the ESP32 will typically read higher than
ambient due to the IC getting warm while it runs. This effect can be minimised
by reading the temperature sensor immediately after waking up from sleep.
ESP32C3, ESP32C6, ESP32S2, and ESP32S3 also have an internal temperature sensor available.
It is implemented a bit differently to the ESP32 and returns the temperature in
Celsius::
esp32.mcu_temperature() # read the internal temperature of the MCU, in Celsius
Networking
----------
WLAN
^^^^
The :mod:`network` module::
import network
@ -87,12 +76,12 @@ The :mod:`network` module::
wlan.active(True) # activate the interface
wlan.scan() # scan for access points
wlan.isconnected() # check if the station is connected to an AP
wlan.connect('ssid', 'key') # connect to an AP
wlan.connect('essid', 'password') # connect to an AP
wlan.config('mac') # get the interface's MAC address
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
ap = network.WLAN(network.AP_IF) # create access-point interface
ap.config(ssid='ESP-AP') # set the SSID of the access point
ap.config(essid='ESP-AP') # set the ESSID of the access point
ap.config(max_clients=10) # set how many clients can connect to the network
ap.active(True) # activate the interface
@ -104,13 +93,13 @@ A useful function for connecting to your local WiFi network is::
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('ssid', 'key')
wlan.connect('essid', 'password')
while not wlan.isconnected():
pass
print('network config:', wlan.ipconfig('addr4'))
print('network config:', wlan.ifconfig())
Once the network is established the :mod:`socket <socket>` module can be used
to create and use TCP/UDP sockets as usual, and the ``requests`` module for
to create and use TCP/UDP sockets as usual, and the ``urequests`` module for
convenient HTTP requests.
After a call to ``wlan.connect()``, the device will by default retry to connect
@ -121,56 +110,6 @@ 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.ipconfig('addr4') # get the interface's IPv4 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
- reset=pin-object # set the reset pin of the PHY device.
- power=pin-object # set the pin which switches the power of the PHY device.
- phy_type=<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
----------------
@ -221,7 +160,6 @@ Use the :ref:`machine.Pin <machine.Pin>` class::
p4 = Pin(4, Pin.IN, Pin.PULL_UP) # enable internal pull-up resistor
p5 = Pin(5, Pin.OUT, value=1) # set pin high on creation
p6 = Pin(6, Pin.OUT, drive=Pin.DRIVE_3) # set maximum drive strength
Available Pins are from the following ranges (inclusive): 0-19, 21-23, 25-27, 32-39.
These correspond to the actual GPIO pin numbers of ESP32 chip. Note that many
@ -229,23 +167,6 @@ end-user boards use their own adhoc pin numbering (marked e.g. D0, D1, ...).
For mapping between board logical pins and physical chip pins consult your board
documentation.
Four drive strengths are supported, using the ``drive`` keyword argument to the
``Pin()`` constructor or ``Pin.init()`` method, with different corresponding
safe maximum source/sink currents and approximate internal driver resistances:
- ``Pin.DRIVE_0``: 5mA / 130 ohm
- ``Pin.DRIVE_1``: 10mA / 60 ohm
- ``Pin.DRIVE_2``: 20mA / 30 ohm (default strength if not configured)
- ``Pin.DRIVE_3``: 40mA / 15 ohm
The ``hold=`` keyword argument to ``Pin()`` and ``Pin.init()`` will enable the
ESP32 "pad hold" feature. When set to ``True``, the pin configuration
(direction, pull resistors and output value) will be held and any further
changes (including changing the output level) will not be applied. Setting
``hold=False`` will immediately apply any outstanding pin configuration changes
and release the pin. Using ``hold=True`` while a pin is already held will apply
any configuration changes and then immediately reapply the hold.
Notes:
* Pins 1 and 3 are REPL UART TX and RX respectively
@ -255,7 +176,8 @@ Notes:
* Pins 34-39 are input only, and also do not have internal pull-up resistors
* See :ref:`Deep_sleep_Mode` for a discussion of pin behaviour during sleep
* The pull value of some pins can be set to ``Pin.PULL_HOLD`` to reduce power
consumption during deepsleep.
There's a higher-level abstraction :ref:`machine.Signal <machine.Signal>`
which can be used to invert a pin. Useful for illuminating active-low LEDs
@ -277,10 +199,9 @@ 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, 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.
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.
===== ===== ===== =====
\ UART0 UART1 UART2
@ -297,158 +218,72 @@ range from 1Hz to 40MHz but there is a tradeoff; as the base frequency
*increases* the duty resolution *decreases*. See
`LED Control <https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/peripherals/ledc.html>`_
for more details.
Currently the duty cycle has to be in the range of 0-1023.
Use the :ref:`machine.PWM <machine.PWM>` class::
Use the ``machine.PWM`` class::
from machine import Pin, PWM
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
pwm0 = PWM(Pin(0)) # create PWM object from a pin
pwm0.freq() # get current frequency
pwm0.freq(1000) # set frequency
pwm0.duty() # get current duty cycle
pwm0.duty(200) # set duty cycle
pwm0.deinit() # turn off PWM on the pin
duty = pwm0.duty() # get current duty cycle, range 0-1023 (default 512, 50%)
pwm0.duty(256) # set duty cycle from 0 to 1023 as a ratio duty/1023, (now 25%)
duty_u16 = pwm0.duty_u16() # get current duty cycle, range 0-65535
pwm0.duty_u16(2**16*3//4) # set duty cycle from 0 to 65535 as a ratio duty_u16/65535, (now 75%)
duty_ns = pwm0.duty_ns() # get current pulse width in ns
pwm0.duty_ns(250_000) # set pulse width in nanoseconds from 0 to 1_000_000_000/freq, (now 25%)
pwm0.deinit() # turn off PWM on the pin
pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go
print(pwm2) # view PWM settings
ESP chips have different hardware peripherals:
===================================================== ======== ======== ========
Hardware specification ESP32 ESP32-S2 ESP32-C3
----------------------------------------------------- -------- -------- --------
Number of groups (speed modes) 2 1 1
Number of timers per group 4 4 4
Number of channels per group 8 8 6
----------------------------------------------------- -------- -------- --------
Different PWM frequencies (groups * timers) 8 4 4
Total PWM channels (Pins, duties) (groups * channels) 16 8 6
===================================================== ======== ======== ========
A maximum number of PWM channels (Pins) are available on the ESP32 - 16 channels,
but only 8 different PWM frequencies are available, the remaining 8 channels must
have the same frequency. On the other hand, 16 independent PWM duty cycles are
possible at the same frequency.
See more examples in the :ref:`esp32_pwm` tutorial.
DAC (digital to analog conversion)
----------------------------------
On the ESP32, DAC functionality is available on pins 25, 26.
On the ESP32S2, DAC functionality is available on pins 17, 18.
Use the DAC::
from machine import DAC, Pin
dac = DAC(Pin(25)) # create an DAC object acting on a pin
dac.write(128) # set a raw analog value in the range 0-255, 50% now
pwm2 = PWM(Pin(2), freq=20000, duty=512) # create and configure in one go
ADC (analog to digital conversion)
----------------------------------
On the ESP32, ADC functionality is available on pins 32-39 (ADC block 1) and
pins 0, 2, 4, 12-15 and 25-27 (ADC block 2).
On the ESP32 ADC functionality is available on Pins 32-39. Note that, when
using the default configuration, input voltages on the ADC pin must be between
0.0v and 1.0v (anything above 1.0v will just read as 4095). Attenuation must
be applied in order to increase this usable voltage range.
Use the :ref:`machine.ADC <machine.ADC>` class::
from machine import ADC
adc = ADC(pin) # create an ADC object acting on a pin
val = adc.read_u16() # read a raw analog value in the range 0-65535
val = adc.read_uv() # read an analog value in microvolts
adc = ADC(Pin(32)) # create ADC object on ADC pin
adc.read() # read value, 0-4095 across voltage range 0.0v - 1.0v
ADC block 2 is also used by WiFi and so attempting to read analog values from
block 2 pins when WiFi is active will raise an exception.
adc.atten(ADC.ATTN_11DB) # set 11dB input attenuation (voltage range roughly 0.0v - 3.6v)
adc.width(ADC.WIDTH_9BIT) # set 9 bit return values (returned range 0-511)
adc.read() # read value using the newly configured attenuation and width
The internal ADC reference voltage is typically 1.1V, but varies slightly from
package to package. The ADC is less linear close to the reference voltage
(particularly at higher attenuations) and has a minimum measurement voltage
around 100mV, voltages at or below this will read as 0. To read voltages
accurately, it is recommended to use the ``read_uv()`` method (see below).
ESP32 specific ADC class method reference:
ESP32-specific ADC class method reference:
.. method:: ADC.atten(attenuation)
.. class:: ADC(pin, *, atten)
This method allows for the setting of the amount of attenuation on the
input of the ADC. This allows for a wider possible input voltage range,
at the cost of accuracy (the same number of bits now represents a wider
range). The possible attenuation options are:
Return the ADC object for the specified pin. ESP32 does not support
different timings for ADC sampling and so the ``sample_ns`` keyword argument
is not supported.
To read voltages above the reference voltage, apply input attenuation with
the ``atten`` keyword argument. Valid values (and approximate linear
measurement ranges) are:
- ``ADC.ATTN_0DB``: No attenuation (100mV - 950mV)
- ``ADC.ATTN_2_5DB``: 2.5dB attenuation (100mV - 1250mV)
- ``ADC.ATTN_6DB``: 6dB attenuation (150mV - 1750mV)
- ``ADC.ATTN_11DB``: 11dB attenuation (150mV - 2450mV)
- ``ADC.ATTN_0DB``: 0dB attenuation, gives a maximum input voltage
of 1.00v - this is the default configuration
- ``ADC.ATTN_2_5DB``: 2.5dB attenuation, gives a maximum input voltage
of approximately 1.34v
- ``ADC.ATTN_6DB``: 6dB attenuation, gives a maximum input voltage
of approximately 2.00v
- ``ADC.ATTN_11DB``: 11dB attenuation, gives a maximum input voltage
of approximately 3.6v
.. Warning::
Note that the absolute maximum voltage rating for input pins is 3.6V. Going
near to this boundary risks damage to the IC!
Despite 11dB attenuation allowing for up to a 3.6v range, note that the
absolute maximum voltage rating for the input pins is 3.6v, and so going
near this boundary may be damaging to the IC!
.. method:: ADC.read_uv()
.. method:: ADC.width(width)
This method uses the known characteristics of the ADC and per-package eFuse
values - set during manufacture - to return a calibrated input voltage
(before attenuation) in microvolts. The returned value has only millivolt
resolution (i.e., will always be a multiple of 1000 microvolts).
The calibration is only valid across the linear range of the ADC. In
particular, an input tied to ground will read as a value above 0 microvolts.
Within the linear range, however, more accurate and consistent results will
be obtained than using `read_u16()` and scaling the result with a constant.
The ESP32 port also supports the :ref:`machine.ADC <machine.ADCBlock>` API:
.. class:: ADCBlock(id, *, bits)
Return the ADC block object with the given ``id`` (1 or 2) and initialize
it to the specified resolution (9 to 12-bits depending on the ESP32 series)
or the highest supported resolution if not specified.
.. method:: ADCBlock.connect(pin)
ADCBlock.connect(channel)
ADCBlock.connect(channel, pin)
Return the ``ADC`` object for the specified ADC pin or channel number.
Arbitrary connection of ADC channels to GPIO is not supported and so
specifying a pin that is not connected to this block, or specifying a
mismatched channel and pin, will raise an exception.
Legacy methods:
.. method:: ADC.read()
This method returns the raw ADC value ranged according to the resolution of
the block, e.g., 0-4095 for 12-bit resolution.
.. method:: ADC.atten(atten)
Equivalent to ``ADC.init(atten=atten)``.
.. method:: ADC.width(bits)
Equivalent to ``ADC.block().init(bits=bits)``.
For compatibility, the ``ADC`` object also provides constants matching the
supported ADC resolutions:
- ``ADC.WIDTH_9BIT`` = 9
- ``ADC.WIDTH_10BIT`` = 10
- ``ADC.WIDTH_11BIT`` = 11
- ``ADC.WIDTH_12BIT`` = 12
This method allows for the setting of the number of bits to be utilised
and returned during ADC reads. Possible width options are:
- ``ADC.WIDTH_9BIT``: 9 bit data
- ``ADC.WIDTH_10BIT``: 10 bit data
- ``ADC.WIDTH_11BIT``: 11 bit data
- ``ADC.WIDTH_12BIT``: 12 bit data - this is the default configuration
Software SPI bus
----------------
@ -590,8 +425,6 @@ See :ref:`machine.WDT <machine.WDT>`. ::
wdt = WDT(timeout=5000)
wdt.feed()
.. _Deep_sleep_mode:
Deep-sleep mode
---------------
@ -611,64 +444,30 @@ Notes:
* Calling ``deepsleep()`` without an argument will put the device to sleep
indefinitely
* A software reset does not change the reset cause
* There may be some leakage current flowing through enabled internal pullups.
To further reduce power consumption it is possible to disable the internal pullups::
Some ESP32 pins (0, 2, 4, 12-15, 25-27, 32-39) are connected to the RTC during
deep-sleep and can be used to wake the device with the ``wake_on_`` functions in
the :mod:`esp32` module. The output-capable RTC pins (all except 34-39) will
also retain their pull-up or pull-down resistor configuration when entering
deep-sleep.
p1 = Pin(4, Pin.IN, Pin.PULL_HOLD)
If the pull resistors are not actively required during deep-sleep and are likely
to cause current leakage (for example a pull-up resistor is connected to ground
through a switch), then they should be disabled to save power before entering
deep-sleep mode::
After leaving deepsleep it may be necessary to un-hold the pin explicitly (e.g. if
it is an output pin) via::
from machine import Pin, deepsleep
# configure input RTC pin with pull-up on boot
pin = Pin(2, Pin.IN, Pin.PULL_UP)
# disable pull-up and put the device to sleep for 10 seconds
pin.init(pull=None)
machine.deepsleep(10000)
Output-configured RTC pins will also retain their output direction and level in
deep-sleep if pad hold is enabled with the ``hold=True`` argument to
``Pin.init()``.
Non-RTC GPIO pins will be disconnected by default on entering deep-sleep.
Configuration of non-RTC pins - including output level - can be retained by
enabling pad hold on the pin and enabling GPIO pad hold during deep-sleep::
from machine import Pin, deepsleep
import esp32
opin = Pin(19, Pin.OUT, value=1, hold=True) # hold output level
ipin = Pin(21, Pin.IN, Pin.PULL_UP, hold=True) # hold pull-up
# enable pad hold in deep-sleep for non-RTC GPIO
esp32.gpio_deep_sleep_hold(True)
# put the device to sleep for 10 seconds
deepsleep(10000)
The pin configuration - including the pad hold - will be retained on wake from
sleep. See :ref:`Pins_and_GPIO` above for a further discussion of pad holding.
p1 = Pin(4, Pin.OUT, None)
SD card
-------
See :ref:`machine.SDCard <machine.SDCard>`. ::
import machine, os, vfs
import machine, os
# Slot 2 uses pins sck=18, cs=5, miso=19, mosi=23
sd = machine.SDCard(slot=2)
vfs.mount(sd, '/sd') # mount
os.mount(sd, "/sd") # mount
os.listdir('/sd') # list directory contents
vfs.umount('/sd') # eject
os.umount('/sd') # eject
RMT
---
@ -682,7 +481,7 @@ The RMT is ESP32-specific and allows generation of accurate digital pulses with
r = esp32.RMT(0, pin=Pin(18), clock_div=8)
r # RMT(channel=0, pin=18, source_freq=80000000, clock_div=8)
# The channel resolution is 100ns (1/(source_freq/clock_div)).
r.write_pulses((1, 20, 2, 40), 0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns
r.write_pulses((1, 20, 2, 40), start=0) # Send 0 for 100ns, 1 for 2000ns, 0 for 200ns, 1 for 4000ns
OneWire driver
--------------
@ -735,16 +534,17 @@ The APA106 driver extends NeoPixel, but internally uses a different colour order
ap = APA106(pin, 8)
r, g, b = ap[0]
For low-level driving of a NeoPixel::
import esp
esp.neopixel_write(pin, grb_buf, is800khz)
.. Warning::
By default ``NeoPixel`` is configured to control the more popular *800kHz*
units. It is possible to use alternative timing to control other (typically
400kHz) devices by passing ``timing=0`` when constructing the
``NeoPixel`` object.
For low-level driving of a NeoPixel see `machine.bitstream`.
This low-level driver uses an RMT channel by default. To configure this see
`RMT.bitstream_channel`.
APA102 (DotStar) uses a different driver as it has an additional clock pin.
Capacitive touch

Binary file not shown.

Before

Width:  |  Height:  |  Size: 200 KiB

View File

@ -1,23 +0,0 @@
.. _esp32_tutorial:
MicroPython tutorial for ESP32
==============================
This tutorial is intended to get you started using MicroPython on the ESP32
system-on-a-chip. If it is your first time it is recommended to follow the
tutorial through in the order below. Otherwise the sections are mostly self
contained, so feel free to skip to those that interest you.
The tutorial does not assume that you know Python, but it also does not attempt
to explain any of the details of the Python language. Instead it provides you
with commands that are ready to run, and hopes that you will gain a bit of
Python knowledge along the way. To learn more about Python itself please refer
to `<https://www.python.org>`__.
.. toctree::
:maxdepth: 1
:numbered:
intro.rst
pwm.rst
peripheral_access.rst

View File

@ -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 converter to make the
world, and whether it includes a built-in USB-serial convertor 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 converter, and the DTR
Fortunately, most boards have a USB connector, a USB-serial convertor, 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
converter, depending on your board. The baudrate is 115200.
convertor, 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 converter, cables, host OS, etc., the above baud
module/board, USB-UART convertor, 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.

View File

@ -1,136 +0,0 @@
Accessing peripherals directly via registers
============================================
The ESP32's peripherals can be controlled via direct register reads and writes.
This requires reading the datasheet to know what registers to use and what
values to write to them. The following example shows how to turn on and change
the prescaler of the MCPWM0 peripheral.
.. code-block:: python3
from micropython import const
from machine import mem32
# Define the register addresses that will be used.
DR_REG_DPORT_BASE = const(0x3FF00000)
DPORT_PERIP_CLK_EN_REG = const(DR_REG_DPORT_BASE + 0x0C0)
DPORT_PERIP_RST_EN_REG = const(DR_REG_DPORT_BASE + 0x0C4)
DPORT_PWM0_CLK_EN = const(1 << 17)
MCPWM0 = const(0x3FF5E000)
MCPWM1 = const(0x3FF6C000)
# Enable CLK and disable RST.
print(hex(mem32[DPORT_PERIP_CLK_EN_REG] & 0xffffffff))
print(hex(mem32[DPORT_PERIP_RST_EN_REG] & 0xffffffff))
mem32[DPORT_PERIP_CLK_EN_REG] |= DPORT_PWM0_CLK_EN
mem32[DPORT_PERIP_RST_EN_REG] &= ~DPORT_PWM0_CLK_EN
print(hex(mem32[DPORT_PERIP_CLK_EN_REG] & 0xffffffff))
print(hex(mem32[DPORT_PERIP_RST_EN_REG] & 0xffffffff))
# Change the MCPWM0 prescaler.
print(hex(mem32[MCPWM0])) # read PWM_CLK_CFG_REG (reset value = 0)
mem32[MCPWM0] = 0x55 # change PWM_CLK_PRESCALE
print(hex(mem32[MCPWM0])) # read PWM_CLK_CFG_REG
The specific addresses will be different on different ESP32
models. For example, ESP32-S3 uses these values:
.. code-block:: python3
DR_REG_DPORT_BASE = const(0x600C_0000)
DPORT_PERIP_CLK_EN0_REG = const(DR_REG_DPORT_BASE + 0x0018)
DPORT_PERIP_RST_EN0_REG = const(DR_REG_DPORT_BASE + 0x0020)
DPORT_PWM0_CLK_EN = const(1 << 17)
MCPWM0 = const(0x6001_E000 + 0x0004)
...
Note that before a peripheral can be used its clock must be enabled and it must
be taken out of reset. In the above example the following registers are used
for this:
- ``DPORT_PERI_CLK_EN_REG``: used to enable a peripheral clock
- ``DPORT_PERI_RST_EN_REG``: used to reset (or take out of reset) a peripheral
The MCPWM0 peripheral is in bit position 17 of the above two registers, hence
the value of ``DPORT_PWM0_CLK_EN``.
Synchronous access to pins directly via registers
-------------------------------------------------
The following code shows how to access pins directly via registers. It has been
tested on a generic ESP32 board. It configures pins 16, 17, 32 and 33 in output
mode via registers, and switches pin output values via registers. Pins 16 and
17 are switched simultaneously.
.. code-block:: python3
from micropython import const
from machine import mem32, Pin
GPIO_OUT_REG = const(0x3FF44004) # GPIO 0-31 output register
GPIO_OUT1_REG = const(0x3FF44010) # GPIO 32-39 output register
GPIO_ENABLE_REG = const(0x3FF44020) # GPIO 0-31 output enable register
GPIO_ENABLE1_REG = const(0x3FF4402C) # GPIO 32-39 output enable register
M16 = 1 << 16 # Pin(16) bit mask
M17 = 1 << 17 # Pin(17) bit mask
M32 = 1 << (32-32) # Pin(32) bit mask
M33 = 1 << (33-32) # Pin(33) bit mask
# Enable pin output mode like
# p16 = Pin(16, mode=Pin.OUT)
# p17 = Pin(17, mode=Pin.OUT)
# p32 = Pin(32, mode=Pin.OUT)
# p33 = Pin(33, mode=Pin.OUT)
mem32[GPIO_ENABLE_REG] = mem32[GPIO_ENABLE_REG] | M16 | M17
mem32[GPIO_ENABLE1_REG] = mem32[GPIO_ENABLE1_REG] | M32 | M33
print(hex(mem32[GPIO_OUT_REG]), hex(mem32[GPIO_OUT1_REG]))
# Set outputs to 1 like
# p16(1)
# p17(1)
# p32(1)
# p33(1)
mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] | M16 | M17
mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] | M32 | M33
print(hex(mem32[GPIO_OUT_REG]), hex(mem32[GPIO_OUT1_REG]))
# Set outputs to 0 like
# p16(0)
# p17(0)
# p32(0)
# p33(0)
mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] & ~(M16 | M17)
mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] & ~(M32 | M33)
print(hex(mem32[GPIO_OUT_REG]), hex(mem32[GPIO_OUT1_REG]))
while True:
# Set outputs to 1
mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] | M16 | M17
mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] | M32 | M33
# Set outputs to 0
mem32[GPIO_OUT_REG] = mem32[GPIO_OUT_REG] & ~(M16 | M17)
mem32[GPIO_OUT1_REG] = mem32[GPIO_OUT1_REG] & ~(M32 | M33)
Output is::
0x0 0x0
0x30000 0x3
0x0 0x0
Pins 16 and 17 are switched synchronously:
.. image:: img/mem32_gpio_output.jpg
Same image on pins 32 and 33.
Note that pins 34-36 and 39 are inputs only. Also pins 1 and 3 are Tx, Rx of the REPL UART,
pins 6-11 are connected to the built-in SPI flash.

View File

@ -1,115 +0,0 @@
.. _esp32_pwm:
Pulse Width Modulation
======================
Pulse width modulation (PWM) is a way to get an artificial analog output on a
digital pin. It achieves this by rapidly toggling the pin from low to high.
There are two parameters associated with this: the frequency of the toggling,
and the duty cycle. The duty cycle is defined to be how long the pin is high
compared with the length of a single period (low plus high time). Maximum
duty cycle is when the pin is high all of the time, and minimum is when it is
low all of the time.
* More comprehensive example with all 16 PWM channels and 8 timers::
from machine import Pin, PWM
try:
f = 100 # Hz
d = 1024 // 16 # 6.25%
pins = (15, 2, 4, 16, 18, 19, 22, 23, 25, 26, 27, 14 , 12, 13, 32, 33)
pwms = []
for i, pin in enumerate(pins):
pwms.append(PWM(Pin(pin), freq=f * (i // 2 + 1), duty= 1023 if i==15 else d * (i + 1)))
print(pwms[i])
finally:
for pwm in pwms:
try:
pwm.deinit()
except:
pass
Output is::
PWM(Pin(15), freq=100, duty=64, resolution=10, mode=0, channel=0, timer=0)
PWM(Pin(2), freq=100, duty=128, resolution=10, mode=0, channel=1, timer=0)
PWM(Pin(4), freq=200, duty=192, resolution=10, mode=0, channel=2, timer=1)
PWM(Pin(16), freq=200, duty=256, resolution=10, mode=0, channel=3, timer=1)
PWM(Pin(18), freq=300, duty=320, resolution=10, mode=0, channel=4, timer=2)
PWM(Pin(19), freq=300, duty=384, resolution=10, mode=0, channel=5, timer=2)
PWM(Pin(22), freq=400, duty=448, resolution=10, mode=0, channel=6, timer=3)
PWM(Pin(23), freq=400, duty=512, resolution=10, mode=0, channel=7, timer=3)
PWM(Pin(25), freq=500, duty=576, resolution=10, mode=1, channel=0, timer=0)
PWM(Pin(26), freq=500, duty=640, resolution=10, mode=1, channel=1, timer=0)
PWM(Pin(27), freq=600, duty=704, resolution=10, mode=1, channel=2, timer=1)
PWM(Pin(14), freq=600, duty=768, resolution=10, mode=1, channel=3, timer=1)
PWM(Pin(12), freq=700, duty=832, resolution=10, mode=1, channel=4, timer=2)
PWM(Pin(13), freq=700, duty=896, resolution=10, mode=1, channel=5, timer=2)
PWM(Pin(32), freq=800, duty=960, resolution=10, mode=1, channel=6, timer=3)
PWM(Pin(33), freq=800, duty=1023, resolution=10, mode=1, channel=7, timer=3)
* Example of a smooth frequency change::
from time import sleep
from machine import Pin, PWM
F_MIN = 500
F_MAX = 1000
f = F_MIN
delta_f = 1
p = PWM(Pin(5), f)
print(p)
while True:
p.freq(f)
sleep(10 / F_MIN)
f += delta_f
if f >= F_MAX or f <= F_MIN:
delta_f = -delta_f
See PWM wave at Pin(5) with an oscilloscope.
* Example of a smooth duty change::
from time import sleep
from machine import Pin, PWM
DUTY_MAX = 2**16 - 1
duty_u16 = 0
delta_d = 16
p = PWM(Pin(5), 1000, duty_u16=duty_u16)
print(p)
while True:
p.duty_u16(duty_u16)
sleep(1 / 1000)
duty_u16 += delta_d
if duty_u16 >= DUTY_MAX:
duty_u16 = DUTY_MAX
delta_d = -delta_d
elif duty_u16 <= 0:
duty_u16 = 0
delta_d = -delta_d
See PWM wave at Pin(5) with an oscilloscope.
Note: the Pin.OUT mode does not need to be specified. The channel is initialized
to PWM mode internally once for each Pin that is passed to the PWM constructor.
The following code is wrong::
pwm = PWM(Pin(5, Pin.OUT), freq=1000, duty=512) # Pin(5) in PWM mode here
pwm = PWM(Pin(5, Pin.OUT), freq=500, duty=256) # Pin(5) in OUT mode here, PWM is off
Use this code instead::
pwm = PWM(Pin(5), freq=1000, duty=512)
pwm.init(freq=500, duty=256)

View File

@ -57,13 +57,13 @@ The :mod:`network` module::
wlan.active(True) # activate the interface
wlan.scan() # scan for access points
wlan.isconnected() # check if the station is connected to an AP
wlan.connect('ssid', 'key') # connect to an AP
wlan.connect('essid', 'password') # connect to an AP
wlan.config('mac') # get the interface's MAC address
wlan.ipconfig('addr4') # get the interface's IPv4 addresses
wlan.ifconfig() # get the interface's IP/netmask/gw/DNS addresses
ap = network.WLAN(network.AP_IF) # create access-point interface
ap.active(True) # activate the interface
ap.config(ssid='ESP-AP') # set the SSID of the access point
ap.config(essid='ESP-AP') # set the ESSID of the access point
A useful function for connecting to your local WiFi network is::
@ -73,10 +73,10 @@ A useful function for connecting to your local WiFi network is::
wlan.active(True)
if not wlan.isconnected():
print('connecting to network...')
wlan.connect('ssid', 'key')
wlan.connect('essid', 'password')
while not wlan.isconnected():
pass
print('network config:', wlan.ipconfig('addr4'))
print('network config:', wlan.ifconfig())
Once the network is established the :mod:`socket <socket>` module can be used
to create and use TCP/UDP sockets as usual.
@ -374,13 +374,17 @@ Use the ``neopixel`` module::
np.write() # write data to all pixels
r, g, b = np[0] # get first pixel colour
For low-level driving of a NeoPixel::
import esp
esp.neopixel_write(pin, grb_buf, is800khz)
.. Warning::
By default ``NeoPixel`` is configured to control the more popular *800kHz*
units. It is possible to use alternative timing to control other (typically
400kHz) devices by passing ``timing=0`` when constructing the
``NeoPixel`` object.
For low-level driving of a NeoPixel see `machine.bitstream`.
APA102 driver
-------------

View File

@ -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
converter to make the UART available to your PC.
convertor 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, mip, etc.). As such, 512KB build will
depend on it won't work (WebREPL, upip, 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 converter, and has
If you have a board that has a USB connector, a USB-serial convertor, 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
converter, depending on your board. The baudrate is 115200. The next part of
convertor, 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 every time, and most likely different for all ESP8266 chips). The
be the same everytime, 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 converter, cables, host OS, etc., the above baud
module/board, USB-UART convertor, 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.

View File

@ -19,10 +19,10 @@ You can check if the interfaces are active by::
You can also check the network settings of the interface by::
>>> ap_if.ipconfig('addr4')
('192.168.4.1', '255.255.255.0')
>>> ap_if.ifconfig()
('192.168.4.1', '255.255.255.0', '192.168.4.1', '8.8.8.8')
The returned values are: IP address and netmask.
The returned values are: IP address, netmask, gateway, DNS.
Configuration of the WiFi
-------------------------
@ -37,7 +37,7 @@ First activate the station interface::
Then connect to your WiFi network::
>>> sta_if.connect('<your SSID>', '<your key>')
>>> sta_if.connect('<your ESSID>', '<your password>')
To check if the connection is established use::
@ -45,8 +45,8 @@ To check if the connection is established use::
Once established you can check the IP address::
>>> sta_if.ipconfig('addr4')
('192.168.0.2', '255.255.255.0')
>>> sta_if.ifconfig()
('192.168.0.2', '255.255.255.0', '192.168.0.1', '8.8.8.8')
You can then disable the access-point interface if you no longer need it::
@ -61,10 +61,10 @@ connect to your WiFi network::
if not sta_if.isconnected():
print('connecting to network...')
sta_if.active(True)
sta_if.connect('<ssid>', '<key>')
sta_if.connect('<essid>', '<password>')
while not sta_if.isconnected():
pass
print('network config:', sta_if.ipconfig('addr4'))
print('network config:', sta_if.ifconfig())
Sockets
-------

View File

@ -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 converter on it then you should be able to access
If your board has a USB-serial convertor 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.

View File

@ -66,8 +66,8 @@ Subclassing FrameBuffer provides support for graphics primitives::
display.hline(0, 8, 4, 1) # draw horizontal line x=0, y=8, width=4, colour=1
display.vline(0, 8, 4, 1) # draw vertical line x=0, y=8, height=4, colour=1
display.line(0, 0, 127, 63, 1) # draw a line from 0,0 to 127,63
display.rect(10, 10, 107, 43, 1) # draw a rectangle outline 10,10 to 117,53, colour=1
display.fill_rect(10, 10, 107, 43, 1) # draw a solid rectangle 10,10 to 117,53, colour=1
display.rect(10, 10, 107, 43, 1) # draw a rectangle outline 10,10 to 107,43, colour=1
display.fill_rect(10, 10, 107, 43, 1) # draw a solid rectangle 10,10 to 107,43, colour=1
display.text('Hello World', 0, 0, 1) # draw some text at x=0, y=0, colour=1
display.scroll(20, 0) # scroll 20 pixels to the right

View File

@ -12,9 +12,6 @@ MicroPython documentation and references
esp8266/quickref.rst
esp32/quickref.rst
rp2/quickref.rst
mimxrt/quickref.rst
wipy/quickref.rst
unix/quickref.rst
zephyr/quickref.rst
renesas-ra/quickref.rst
samd/quickref.rst

View File

@ -27,55 +27,3 @@ 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(<type>, [<elements>])"``,
where ``<type>`` is the type code letter for the array and ``<elements>`` 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.

View File

@ -1,363 +0,0 @@
:mod:`asyncio` --- asynchronous I/O scheduler
=============================================
.. module:: asyncio
:synopsis: asynchronous I/O scheduler for writing concurrent code
|see_cpython_module|
`asyncio <https://docs.python.org/3.8/library/asyncio.html>`_
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.
.. 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, ssl=None)
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.
If *ssl* is a `ssl.SSLContext` object, this context is used to create the transport;
if *ssl* is ``True``, a default context is used.
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, ssl=None)
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.
If *ssl* is a `ssl.SSLContext` object, this context is used to create the transport.
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'``.

View File

@ -31,8 +31,8 @@ Functions
Conforms to `RFC 2045 s.6.8 <https://tools.ietf.org/html/rfc2045#section-6.8>`_.
Returns a bytes object.
.. function:: b2a_base64(data, *, newline=True)
.. function:: b2a_base64(data)
Encode binary data in base64 format, as in `RFC 3548
<https://tools.ietf.org/html/rfc3548.html>`_. Returns the encoded data
followed by a newline character if newline is true, as a bytes object.
followed by a newline character, as a bytes object.

View File

@ -13,9 +13,6 @@ concurrently. Pairing (and bonding) is supported on some ports.
This API is intended to match the low-level Bluetooth protocol and provide
building-blocks for higher-level abstractions such as specific device types.
.. note:: For most applications, we recommend using the higher-level
`aioble library <https://github.com/micropython/micropython-lib/tree/master/micropython/bluetooth/aioble>`_.
.. note:: This module is still under development and its classes, functions,
methods and constants are subject to change.
@ -44,7 +41,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 or more
queried at a time. To set values use the keyword syntax, and one ore more
parameter can be set at a time.
Currently supported values are:
@ -52,7 +49,7 @@ Configuration
- ``'mac'``: The current address in use, depending on the current address mode.
This returns a tuple of ``(addr_type, addr)``.
See :meth:`gatts_write <BLE.gatts_write>` for details about address type.
See :meth:`gatts_write <BLE.gap_scan>` for details about address type.
This may only be queried while the interface is currently active.
@ -166,7 +163,7 @@ Event Handling
conn_handle, status = data
elif event == _IRQ_GATTC_CHARACTERISTIC_RESULT:
# Called for each characteristic found by gattc_discover_services().
conn_handle, end_handle, value_handle, properties, uuid = data
conn_handle, def_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,10 +180,12 @@ 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:
@ -312,7 +311,7 @@ Broadcaster Role (Advertiser)
in all broadcasts, and *resp_data* is send in reply to an active scan.
**Note:** if *adv_data* (or *resp_data*) is ``None``, then the data passed
to the previous call to ``gap_advertise`` will be reused. This allows a
to the previous call to ``gap_advertise`` will be re-used. This allows a
broadcaster to resume advertising with just ``gap_advertise(interval_us)``.
To clear the advertising payload pass an empty ``bytes``, i.e. ``b''``.
@ -360,27 +359,13 @@ Central Role
A central device can connect to peripherals that it has discovered using the observer role (see :meth:`gap_scan<BLE.gap_scan>`) or with a known address.
.. method:: BLE.gap_connect(addr_type, addr, scan_duration_ms=2000, min_conn_interval_us=None, max_conn_interval_us=None, /)
.. method:: BLE.gap_connect(addr_type, addr, scan_duration_ms=2000, /)
Connect to a peripheral.
See :meth:`gap_scan <BLE.gap_scan>` for details about address types.
To cancel an outstanding connection attempt early, call
``gap_connect(None)``.
On success, the ``_IRQ_PERIPHERAL_CONNECT`` event will be raised. If
cancelling a connection attempt, the ``_IRQ_PERIPHERAL_DISCONNECT`` event
will be raised.
The device will wait up to *scan_duration_ms* to receive an advertising
payload from the device.
The connection interval can be configured in **micro**\ seconds using either
or both of *min_conn_interval_us* and *max_conn_interval_us*. Otherwise a
default interval will be chosen, typically between 30000 and 50000
microseconds. A shorter interval will increase throughput, at the expense
of power usage.
On success, the ``_IRQ_PERIPHERAL_CONNECT`` event will be raised.
Peripheral Role
@ -512,24 +497,19 @@ writes from a client to a given characteristic, use
Sends a notification request to a connected client.
If *data* is ``None`` (the default), then the current local value (as set
with :meth:`gatts_write <BLE.gatts_write>`) will be sent.
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.
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.
Otherwise, if *data* is ``None``, then the current local value (as
set with :meth:`gatts_write <BLE.gatts_write>`) will be sent.
**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, data=None, /)
.. method:: BLE.gatts_indicate(conn_handle, value_handle, /)
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 <BLE.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.
Sends an indication request containing the characteristic's current value to
a connected client.
On acknowledgment (or failure, e.g. timeout), the
``_IRQ_GATTS_INDICATE_DONE`` event will be raised.
@ -722,7 +702,7 @@ Pairing and bonding
and ``_IRQ_SET_SECRET`` events.
**Note:** This is currently only supported when using the NimBLE stack on
ESP32, STM32 and Unix.
STM32 and Unix (not ESP32).
.. method:: BLE.gap_pair(conn_handle, /)

View File

@ -11,9 +11,8 @@ value, a database also supports efficient ordered range scans (retrieval
of values with the keys in a given range). On the application interface
side, BTree database work as close a possible to a way standard `dict`
type works, one notable difference is that both keys and values must
be `bytes`-like objects (so, if you want to store objects of other types, you
need to first serialize them to `str` or `bytes` or another type that supports
the buffer protocol).
be `bytes` objects (so, if you want to store objects of other types, you
need to serialize them to `bytes` first).
The module is based on the well-known BerkelyDB library, version 1.xx.

View File

@ -82,10 +82,6 @@ Functions and types
In MicroPython, `byteorder` parameter must be positional (this is
compatible with CPython).
.. note:: The optional ``signed`` kwarg from CPython is not supported.
MicroPython currently converts negative integers as signed,
and positive as unsigned. (:ref:`Details <cpydiff_types_int_to_bytes>`.)
.. function:: isinstance()
.. function:: issubclass()

View File

@ -12,15 +12,13 @@ hold/accumulate various objects.
Classes
-------
.. class:: deque(iterable, maxlen[, flags])
.. function:: deque(iterable, maxlen[, flags])
Deques (double-ended queues) are a list-like container that support O(1)
appends and pops from either side of the deque. New deques are created
using the following arguments:
- *iterable* is an iterable used to populate the deque when it is
created. It can be an empty tuple or list to create a deque that
is initially empty.
- *iterable* must be the empty tuple, and the new deque is created empty.
- *maxlen* must be specified and the deque will be bounded to this
maximum length. Once the deque is full, any new items added will
@ -28,37 +26,18 @@ Classes
- The optional *flags* can be 1 to check for overflow when adding items.
Deque objects support `bool`, `len`, iteration and subscript load and store.
They also have the following methods:
As well as supporting `bool` and `len`, deque objects have the following
methods:
.. method:: deque.append(x)
Add *x* to the right side of the deque.
Raises ``IndexError`` if overflow checking is enabled and there is
no more room in the queue.
.. method:: deque.appendleft(x)
Add *x* to the left side of the deque.
Raises ``IndexError`` if overflow checking is enabled and there is
no more room in the queue.
.. method:: deque.pop()
Remove and return an item from the right side of the deque.
Raises ``IndexError`` if no items are present.
Raises IndexError if overflow checking is enabled and there is no more room left.
.. method:: deque.popleft()
Remove and return an item from the left side of the deque.
Raises ``IndexError`` if no items are present.
.. method:: deque.extend(iterable)
Extend the deque by appending all the items from *iterable* to
the right of the deque.
Raises ``IndexError`` if overflow checking is enabled and there is
no more room in the deque.
Raises IndexError if no items are present.
.. function:: namedtuple(name, fields)
@ -78,7 +57,7 @@ Classes
print(t1.name)
assert t2.name == t2[1]
.. class:: OrderedDict(...)
.. function:: OrderedDict(...)
``dict`` type subclass which remembers and preserves the order of keys
added. When ordered dict is iterated over, keys/items are returned in

View File

@ -1,182 +0,0 @@
:mod:`deflate` -- deflate compression & decompression
=====================================================
.. module:: deflate
:synopsis: deflate compression & decompression
This module allows compression and decompression of binary data with the
`DEFLATE algorithm <https://en.wikipedia.org/wiki/DEFLATE>`_
(commonly used in the zlib library and gzip archiver).
**Availability:**
* Added in MicroPython v1.21.
* Decompression: Enabled via the ``MICROPY_PY_DEFLATE`` build option, on by default
on ports with the "extra features" level or higher (which is most boards).
* Compression: Enabled via the ``MICROPY_PY_DEFLATE_COMPRESS`` build option, on
by default on ports with the "full features" level or higher (generally this means
you need to build your own firmware to enable this).
Classes
-------
.. class:: DeflateIO(stream, format=AUTO, wbits=0, close=False, /)
This class can be used to wrap a *stream* which is any
:term:`stream-like <stream>` object such as a file, socket, or stream
(including :class:`io.BytesIO`). It is itself a stream and implements the
standard read/readinto/write/close methods.
The *stream* must be a blocking stream. Non-blocking streams are currently
not supported.
The *format* can be set to any of the constants defined below, and defaults
to ``AUTO`` which for decompressing will auto-detect gzip or zlib streams,
and for compressing it will generate a raw stream.
The *wbits* parameter sets the base-2 logarithm of the DEFLATE dictionary
window size. So for example, setting *wbits* to ``10`` sets the window size
to 1024 bytes. Valid values are ``5`` to ``15`` inclusive (corresponding to
window sizes of 32 to 32k bytes).
If *wbits* is set to ``0`` (the default), then for compression a window size
of 256 bytes will be used (as if *wbits* was set to 8). For decompression, it
depends on the format:
* ``RAW`` will use 256 bytes (corresponding to *wbits* set to 8).
* ``ZLIB`` (or ``AUTO`` with zlib detected) will use the value from the zlib
header.
* ``GZIP`` (or ``AUTO`` with gzip detected) will use 32 kilobytes
(corresponding to *wbits* set to 15).
See the :ref:`window size <deflate_wbits>` notes below for more information
about the window size, zlib, and gzip streams.
If *close* is set to ``True`` then the underlying stream will be closed
automatically when the :class:`deflate.DeflateIO` stream is closed. This is
useful if you want to return a :class:`deflate.DeflateIO` stream that wraps
another stream and not have the caller need to know about managing the
underlying stream.
If compression is enabled, a given :class:`deflate.DeflateIO` instance
supports both reading and writing. For example, a bidirectional stream like
a socket can be wrapped, which allows for compression/decompression in both
directions.
Constants
---------
.. data:: deflate.AUTO
deflate.RAW
deflate.ZLIB
deflate.GZIP
Supported values for the *format* parameter.
Examples
--------
A typical use case for :class:`deflate.DeflateIO` is to read or write a compressed
file from storage:
.. code:: python
import deflate
# Writing a zlib-compressed stream (uses the default window size of 256 bytes).
with open("data.gz", "wb") as f:
with deflate.DeflateIO(f, deflate.ZLIB) as d:
# Use d.write(...) etc
# Reading a zlib-compressed stream (auto-detect window size).
with open("data.z", "rb") as f:
with deflate.DeflateIO(f, deflate.ZLIB) as d:
# Use d.read(), d.readinto(), etc.
Because :class:`deflate.DeflateIO` is a stream, it can be used for example
with :meth:`json.dump` and :meth:`json.load` (and any other places streams can
be used):
.. code:: python
import deflate, json
# Write a dictionary as JSON in gzip format, with a
# small (64 byte) window size.
config = { ... }
with open("config.gz", "wb") as f:
with deflate.DeflateIO(f, deflate.GZIP, 6) as f:
json.dump(config, f)
# Read back that dictionary.
with open("config.gz", "rb") as f:
with deflate.DeflateIO(f, deflate.GZIP, 6) as f:
config = json.load(f)
If your source data is not in a stream format, you can use :class:`io.BytesIO`
to turn it into a stream suitable for use with :class:`deflate.DeflateIO`:
.. code:: python
import deflate, io
# Decompress a bytes/bytearray value.
compressed_data = get_data_z()
with deflate.DeflateIO(io.BytesIO(compressed_data), deflate.ZLIB) as d:
decompressed_data = d.read()
# Compress a bytes/bytearray value.
uncompressed_data = get_data()
stream = io.BytesIO()
with deflate.DeflateIO(stream, deflate.ZLIB) as d:
d.write(uncompressed_data)
compressed_data = stream.getvalue()
.. _deflate_wbits:
Deflate window size
-------------------
The window size limits how far back in the stream the (de)compressor can
reference. Increasing the window size will improve compression, but will require
more memory and make the compressor slower.
If an input stream was compressed a given window size, then `DeflateIO`
using a smaller window size will fail mid-way during decompression with
:exc:`OSError`, but only if a back-reference actually refers back further
than the decompressor's window size. This means it may be possible to decompress
with a smaller window size. For example, this would trivially be the case if the
original uncompressed data is shorter than the window size.
Decompression
~~~~~~~~~~~~~
The zlib format includes a header which specifies the window size that was used
to compress the data. This indicates the maximum window size required to
decompress this stream. If this header value is less than the specified *wbits*
value (or if *wbits* is unset), then the header value will be used.
The gzip format does not include the window size in the header, and assumes that
all gzip compressors (e.g. the ``gzip`` utility, or CPython's implementation of
:class:`gzip.GzipFile`) use the maximum window size of 32kiB. For this reason,
if the *wbits* parameter is not set, the decompressor will use a 32 kiB window
size (corresponding to *wbits* set to 15). This means that to be able to
decompress an arbitrary gzip stream, you must have at least this much RAM
available. If you control the source data, consider instead using the zlib
format with a smaller window size.
The raw format has no header and therefore does not include any information
about the window size. If *wbits* is not set, then it will default to a window
size of 256 bytes, which may not be large enough for a given stream. Therefore
it is recommended that you should always explicitly set *wbits* if using the raw
format.
Compression
~~~~~~~~~~~
For compression, MicroPython will default to a window size of 256 bytes for all
formats. This provides a reasonable amount of compression with minimal memory
usage and fast compression time, and will generate output that will work with
any decompressor.

View File

@ -62,53 +62,6 @@ Functions
.. function:: flash_erase(sector_no)
.. function:: osdebug(uart_no)
.. note:: This is the ESP8266 form of this function.
Change the level of OS serial debug log messages. On boot,
OS serial debug log messages are disabled.
``uart_no`` is the number of the UART peripheral which should receive
OS-level output, or ``None`` to disable OS serial debug log messages.
.. function:: osdebug(uart_no, [level])
:no-index:
.. note:: This is the ESP32 form of this function.
Change the level of OS serial debug log messages. On boot, OS
serial debug log messages are limited to Error output only.
The behaviour of this function depends on the arguments passed to it. The
following combinations are supported:
``osdebug(None)`` restores the default OS debug log message level
(``LOG_ERROR``).
``osdebug(0)`` enables all available OS debug log messages (in the
default build configuration this is ``LOG_INFO``).
``osdebug(0, level)`` sets the OS debug log message level to the
specified value. The log levels are defined as constants:
* ``LOG_NONE`` -- No log output
* ``LOG_ERROR`` -- Critical errors, software module can not recover on its own
* ``LOG_WARN`` -- Error conditions from which recovery measures have been taken
* ``LOG_INFO`` -- Information messages which describe normal flow of events
* ``LOG_DEBUG`` -- Extra information which is not necessary for normal use (values, pointers, sizes, etc)
* ``LOG_VERBOSE`` -- Bigger chunks of debugging information, or frequent messages
which can potentially flood the output
.. note:: ``LOG_DEBUG`` and ``LOG_VERBOSE`` are not compiled into the
MicroPython binary by default, to save size. A custom build with a
modified "``sdkconfig``" source file is needed to see any output
at these log levels.
.. note:: Log output on ESP32 is automatically suspended in "Raw REPL" mode,
to prevent communications issues. This means OS level logging is never
seen when using ``mpremote run`` and similar tools.
.. function:: set_native_code_location(start, length)
**Note**: ESP8266 only

View File

@ -18,11 +18,6 @@ Functions
Configure whether or not a touch will wake the device from sleep.
*wake* should be a boolean value.
.. function:: wake_on_ulp(wake)
Configure whether or not the Ultra-Low-Power co-processor can wake the
device from sleep. *wake* should be a boolean value.
.. function:: wake_on_ext0(pin, level)
Configure how EXT0 wakes the device from sleep. *pin* can be ``None``
@ -35,15 +30,14 @@ Functions
or a tuple/list of valid Pin objects. *level* should be ``esp32.WAKEUP_ALL_LOW``
or ``esp32.WAKEUP_ANY_HIGH``.
.. function:: gpio_deep_sleep_hold(enable)
Configure whether non-RTC GPIO pin configuration is retained during
deep-sleep mode for held pads. *enable* should be a boolean value.
.. function:: raw_temperature()
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
@ -51,6 +45,8 @@ Functions
buffers and other data. This data is useful to get a sense of how much memory
is available to ESP-IDF and the networking stack in particular. It may shed
some light on situations where ESP-IDF operations fail due to allocation failures.
The information returned is *not* useful to troubleshoot Python allocation failures,
use `micropython.mem_info()` instead.
The capabilities parameter corresponds to ESP-IDF's ``MALLOC_CAP_XXX`` values but the
two most useful ones are predefined as `esp32.HEAP_DATA` for data heap regions and
@ -66,42 +62,23 @@ Functions
[(240, 0, 0, 0), (7288, 0, 0, 0), (16648, 4, 4, 4), (79912, 35712, 35512, 35108),
(15072, 15036, 15036, 15036), (113840, 0, 0, 0)]
.. note:: Free IDF heap memory in the `esp32.HEAP_DATA` region is available
to be automatically added to the MicroPython heap to prevent a
MicroPython allocation from failing. However, the information returned
here is otherwise *not* useful to troubleshoot Python allocation
failures. :func:`micropython.mem_info()` and :func:`gc.mem_free()` should
be used instead:
The "max new split" value in :func:`micropython.mem_info()` output
corresponds to the largest free block of ESP-IDF heap that could be
automatically added on demand to the MicroPython heap.
The result of :func:`gc.mem_free()` is the total of the current "free"
and "max new split" values printed by :func:`micropython.mem_info()`.
Flash partitions
----------------
This class gives access to the partitions in the device's flash memory and includes
methods to enable over-the-air (OTA) updates.
.. class:: Partition(id, block_size=4096, /)
.. class:: Partition(id)
Create an object representing a partition. *id* can be a string which is the label
of the partition to retrieve, or one of the constants: ``BOOT`` or ``RUNNING``.
*block_size* specifies the byte size of an individual block.
.. classmethod:: Partition.find(type=TYPE_APP, subtype=0xff, label=None, block_size=4096)
.. classmethod:: Partition.find(type=TYPE_APP, subtype=0xff, label=None)
Find a partition specified by *type*, *subtype* and *label*. Returns a
(possibly empty) list of Partition objects. Note: ``subtype=0xff`` matches any subtype
and ``label=None`` matches any label.
*block_size* specifies the byte size of an individual block used by the returned
objects.
.. method:: Partition.info()
Returns a 6-tuple ``(type, subtype, addr, size, label, encrypted)``.
@ -114,17 +91,12 @@ methods to enable over-the-air (OTA) updates.
These methods implement the simple and :ref:`extended
<block-device-interface>` block protocol defined by
:class:`vfs.AbstractBlockDev`.
:class:`os.AbstractBlockDev`.
.. method:: Partition.set_boot()
Sets the partition as the boot partition.
.. note:: Do not enter :func:`deepsleep<machine.deepsleep>` after changing
the OTA boot partition, without first performing a hard
:func:`reset<machine.reset>` or power cycle. This ensures the bootloader
will validate the new image before booting.
.. method:: Partition.get_next_update()
Gets the next update partition after this one, and returns a new Partition object.
@ -140,7 +112,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 firmware that was loaded using esptool.
necessary when booting firmare that was loaded using esptool.
Constants
~~~~~~~~~
@ -193,7 +165,7 @@ numbers specified in ``write_pulses`` are multiplied by the resolution to
define the pulses.
``clock_div`` is an 8-bit divider (0-255) and each pulse can be defined by
multiplying the resolution by a 15-bit (1-``PULSE_MAX``) number. There are eight
multiplying the resolution by a 15-bit (0-32,768) number. There are eight
channels (0-7) and each can have a different clock divider.
So, in the example above, the 80MHz clock is divided by 8. Thus the
@ -226,7 +198,7 @@ For more details see Espressif's `ESP-IDF RMT documentation.
``100``) and the output level to apply the carrier to (a boolean as per
*idle_level*).
.. classmethod:: RMT.source_freq()
.. method:: RMT.source_freq()
Returns the source clock frequency. Currently the source clock is not
configurable so this will always return 80MHz.
@ -264,10 +236,10 @@ For more details see Espressif's `ESP-IDF RMT documentation.
**Mode 3:** *duration* and *data* are lists or tuples of equal length,
specifying individual durations and the output level for each.
Durations are in integer units of the channel resolution (as
described above), between 1 and ``PULSE_MAX`` units. Output levels
are any value that can be converted to a boolean, with ``True``
representing high voltage and ``False`` representing low.
Durations are in integer units of the channel resolution (as described
above), between 1 and 32767 units. Output levels are any value that can
be converted to a boolean, with ``True`` representing high voltage and
``False`` representing low.
If transmission of an earlier sequence is in progress then this method will
block until that transmission is complete before beginning the new sequence.
@ -278,36 +250,10 @@ For more details see Espressif's `ESP-IDF RMT documentation.
new sequence of pulses. Looping sequences longer than 126 pulses is not
supported by the hardware.
.. staticmethod:: RMT.bitstream_channel([value])
Select which RMT channel is used by the `machine.bitstream` implementation.
*value* can be ``None`` or a valid RMT channel number. The default RMT
channel is the highest numbered one.
Passing in ``None`` disables the use of RMT and instead selects a bit-banging
implementation for `machine.bitstream`.
Passing in no argument will not change the channel. This function returns
the current channel number.
Constants
---------
.. data:: RMT.PULSE_MAX
Maximum integer that can be set for a pulse duration.
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.

View File

@ -1,936 +0,0 @@
: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 <https://www.espressif.com/
en/products/software/esp-now/overview>`_ protocol provided by Espressif on
ESP32 and ESP8266 devices (`API docs <https://docs.espressif.com/
projects/esp-idf/en/latest/api-reference/network/esp_now.html>`_).
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<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)<ESPNow.active()>`.
*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
<https://docs.espressif.com/projects/esp-idf/en/v4.4.1/esp32/
api-reference/network/esp_wifi.html#_CPPv415wifi_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()<network.WLAN.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)<network.WLAN.active>` (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()<network.WLAN.disconnect>` after
`active(True)<network.WLAN.active>`.
.. 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()<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()<network.WLAN.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()<network.WLAN.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()<ESPNow.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()<network.WLAN.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 reuse 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()<ESPNow.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()<ESPNow.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
<https://docs.espressif.com/projects/esp-idf/en/latest/
esp32/api-reference/network/esp_now.html#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 <https://docs.espressif.com/
projects/esp-idf/en/latest/esp32/api-reference/network/
esp_now.html#c.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()<ESPNow.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()<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
<https://docs.espressif.com/projects/esp-idf/en/latest/
api-reference/network/esp_now.html#api-reference>`_. 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<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<espnow.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()<ESPNow.send()>` a broadcast message, the broadcast (or
multicast) MAC address must first be registered using
`add_peer()<ESPNow.add_peer()>`. `send()<ESPNow.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)<ESPNow.send()>` 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()<network.WLAN.active>`
`WLAN<network.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 <https://docs.espressif.com/
projects/esp-idf/en/latest/esp32/api-guides/
wifi.html#esp32-wi-fi-power-saving-mode>`_) 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
<https://docs.espressif.com/
projects/esp-idf/en/latest/esp32/api-reference/network/esp_wifi.html
#_CPPv419esp_wifi_set_config16wifi_interface_tP13wifi_config_t>`_
). 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])<machine.lightsleep>` and
`machine.deepsleep([time_ms])<machine.deepsleep>` 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)<network.WLAN.active>`) before entering light or deep sleep (see
`Sleep Modes <https://docs.espressif.com/
projects/esp-idf/en/latest/esp32/api-reference/system/sleep_modes.html>`_).
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)<network.WLAN.active()>` then both interfaces should be set
`active(False)<network.WLAN.active()>` 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()

View File

@ -11,19 +11,19 @@ class FrameBuffer
-----------------
The FrameBuffer class provides a pixel buffer which can be drawn upon with
pixels, lines, rectangles, ellipses, polygons, text and even other
FrameBuffers. It is useful when generating output for displays.
pixels, lines, rectangles, text and even other FrameBuffer's. It is useful
when generating output for displays.
For example::
import framebuf
# FrameBuffer needs 2 bytes for every RGB565 pixel
fbuf = framebuf.FrameBuffer(bytearray(100 * 10 * 2), 100, 10, framebuf.RGB565)
fbuf = framebuf.FrameBuffer(bytearray(10 * 100 * 2), 10, 100, framebuf.RGB565)
fbuf.fill(0)
fbuf.text('MicroPython!', 0, 0, 0xffff)
fbuf.hline(0, 9, 96, 0xffff)
fbuf.hline(0, 10, 96, 0xffff)
Constructors
------------
@ -77,37 +77,12 @@ 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[, f])
.. method:: FrameBuffer.rect(x, y, w, h, c)
.. method:: FrameBuffer.fill_rect(x, y, w, h, c)
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.
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.
Drawing text
------------
@ -133,9 +108,7 @@ 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. (If the *palette* is specified then the *key*
is compared to the value from *palette*, not to the value directly from
*fbuf*.)
color value will not be drawn.
The *palette* argument enables blitting between FrameBuffers with differing
formats. Typical usage is to render a monochrome or grayscale glyph/icon to

View File

@ -24,7 +24,7 @@ Functions
.. function:: mem_alloc()
Return the number of bytes of heap RAM that are allocated by Python code.
Return the number of bytes of heap RAM that are allocated.
.. admonition:: Difference to CPython
:class: attention
@ -33,8 +33,8 @@ Functions
.. function:: mem_free()
Return the number of bytes of heap RAM that is available for Python
code to allocate, or -1 if this amount is not known.
Return the number of bytes of available heap RAM, or -1 if this amount
is not known.
.. admonition:: Difference to CPython
:class: attention

Some files were not shown because too many files have changed in this diff Show More