diff --git a/.github/dangerjs/.gitignore b/.github/dangerjs/.gitignore deleted file mode 100644 index 0471eff2c21a..000000000000 --- a/.github/dangerjs/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Transpiled JavaScript (if any) -dist - -# Installed dependencies -node_modules diff --git a/.github/dangerjs/README.md b/.github/dangerjs/README.md deleted file mode 100644 index fc027a455144..000000000000 --- a/.github/dangerjs/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# DangerJS pull request automatic review tool - GitHub - -## Implementation -The main development is done in Espressif Gitlab project. -Espressif [GitHub project espressif/esp-idf](https://github.com/espressif/esp-idf) is only a public mirror. - -Therefore, all changes and updates to DangerJS files (`.github/dangerjs`) must be made via MR in the **Gitlab** repository by Espressif engineer. - -When adding a new Danger rule or updating existing one, might be a good idea to test it on the developer's fork of GitHub project. This way, the new feature can be tested using a GitHub action without concern of damaging Espressif's GitHub repository. - -Danger for Espressif GitHub is implemented in TypeScript. This makes the code more readable and robust than plain JavaScript. -Compilation to JavaScript code (using `tsc`) is not necessary; Danger handles TypeScript natively. - -A good practice is to store each Danger rule in a separate module, and then import these modules into the main Danger file `.github/dangerjs/dangerfile.ts` (see how this is done for currently present modules when adding a new one). - -If the Danger module (new check/rule) uses an external NPM module (e.g. `axios`), be sure to add this dependency to `.github/dangerjs/package.json` and also update `.github/dangerjs/package-lock.json`. - -In the GitHub action, `danger` is not installed globally (nor are its dependencies) and the `npx` call is used to start the `danger` checks in CI. - - -## Adding new Danger rule -For local development you can use following strategy - -#### Install dependencies -```sh -cd .github/dangerjs -npm install -``` -(If the IDE still shows compiler/typing errors, reload the IDE window.) - -#### Add new code as needed or make updates - -#### Test locally -Danger rules can be tested locally (without running the GitHub action pipeline). -To do this, you have to first export the ENV variables used by Danger in the local terminal: - -```sh -export GITHUB_TOKEN='**************************************' -``` - -Then you can call Danger by: -```sh -cd .github/dangerjs - -danger pr https://github.com/espressif/esp-idf/pull/ -``` -The result will be displayed in your terminal. diff --git a/.github/dangerjs/dangerfile.ts b/.github/dangerjs/dangerfile.ts deleted file mode 100644 index fbb6efe6d6bb..000000000000 --- a/.github/dangerjs/dangerfile.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { DangerResults } from "danger"; -declare const results: DangerResults; -declare const message: (message: string, results?: DangerResults) => void; -declare const markdown: (message: string, results?: DangerResults) => void; - -// Import modules with danger rules -// (Modules with checks are stored in ".github/dangerjs/.ts". To import them, use path relative to "dangerfile.ts") -import prCommitsTooManyCommits from "./prCommitsTooManyCommits"; -import prDescription from "./prDescription"; -import prTargetBranch from "./prTargetBranch"; -import prInfoContributor from "./prInfoContributor"; -import prCommitMessage from "./prCommitMessage"; - -async function runDangerRules(): Promise { - // Message to contributor about review and merge process - const prInfoContributorMessage: string = await prInfoContributor(); - markdown(prInfoContributorMessage); - - // Run danger checks - prCommitsTooManyCommits(); - prDescription(); - prTargetBranch(); - prCommitMessage(); - - // Add success log if no issues - const dangerFails: number = results.fails.length; - const dangerWarns: number = results.warnings.length; - const dangerInfos: number = results.messages.length; - if (!dangerFails && !dangerWarns && !dangerInfos) { - return message("Good Job! All checks are passing!"); - } - - // Add retry link - addRetryLink(); -} - -runDangerRules(); - -function addRetryLink(): void { - const serverUrl: string | undefined = process.env.GITHUB_SERVER_URL; - const repoName: string | undefined = process.env.GITHUB_REPOSITORY; - const runId: string | undefined = process.env.GITHUB_RUN_ID; - - const retryLinkUrl: string = `${serverUrl}/${repoName}/actions/runs/${runId}`; - const retryLink: string = `:repeat: You can re-run automatic PR checks by retrying the DangerJS action`; - - markdown(retryLink); -} diff --git a/.github/dangerjs/package-lock.json b/.github/dangerjs/package-lock.json deleted file mode 100644 index 5229aed3f921..000000000000 --- a/.github/dangerjs/package-lock.json +++ /dev/null @@ -1,1999 +0,0 @@ -{ - "name": "dangerjs-github", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "dangerjs-github", - "license": "ISC", - "dependencies": { - "axios": "^1.3.3", - "danger": "^11.2.3", - "request": "^2.88.2", - "sync-request": "^6.1.0", - "typescript": "^5.0.3" - }, - "devDependencies": { - "@types/node": "^18.15.11" - } - }, - "node_modules/@gitbeaker/core": { - "version": "21.7.0", - "resolved": "https://registry.npmjs.org/@gitbeaker/core/-/core-21.7.0.tgz", - "integrity": "sha512-cw72rE7tA27wc6JJe1WqeAj9v/6w0S7XJcEji+bRNjTlUfE1zgfW0Gf1mbGUi7F37SOABGCosQLfg9Qe63aIqA==", - "dependencies": { - "@gitbeaker/requester-utils": "^21.7.0", - "form-data": "^3.0.0", - "li": "^1.3.0", - "xcase": "^2.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@gitbeaker/core/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@gitbeaker/node": { - "version": "21.7.0", - "resolved": "https://registry.npmjs.org/@gitbeaker/node/-/node-21.7.0.tgz", - "integrity": "sha512-OdM3VcTKYYqboOsnbiPcO0XimXXpYK4gTjARBZ6BWc+1LQXKmqo+OH6oUbyxOoaFu9hHECafIt3WZU3NM4sZTg==", - "dependencies": { - "@gitbeaker/core": "^21.7.0", - "@gitbeaker/requester-utils": "^21.7.0", - "form-data": "^3.0.0", - "got": "^11.1.4", - "xcase": "^2.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@gitbeaker/node/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@gitbeaker/requester-utils": { - "version": "21.7.0", - "resolved": "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-21.7.0.tgz", - "integrity": "sha512-eLTaVXlBnh8Qimj6QuMMA06mu/mLcJm3dy8nqhhn/Vm/D25sPrvpGwmbfFyvzj6QujPqtHvFfsCHtyZddL01qA==", - "dependencies": { - "form-data": "^3.0.0", - "query-string": "^6.12.1", - "xcase": "^2.0.1" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@gitbeaker/requester-utils/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/@octokit/auth-token": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-token/-/auth-token-2.5.0.tgz", - "integrity": "sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==", - "dependencies": { - "@octokit/types": "^6.0.3" - } - }, - "node_modules/@octokit/core": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/@octokit/core/-/core-3.6.0.tgz", - "integrity": "sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==", - "dependencies": { - "@octokit/auth-token": "^2.4.4", - "@octokit/graphql": "^4.5.8", - "@octokit/request": "^5.6.3", - "@octokit/request-error": "^2.0.5", - "@octokit/types": "^6.0.3", - "before-after-hook": "^2.2.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/endpoint": { - "version": "6.0.12", - "resolved": "https://registry.npmjs.org/@octokit/endpoint/-/endpoint-6.0.12.tgz", - "integrity": "sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==", - "dependencies": { - "@octokit/types": "^6.0.3", - "is-plain-object": "^5.0.0", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/graphql": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/@octokit/graphql/-/graphql-4.8.0.tgz", - "integrity": "sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==", - "dependencies": { - "@octokit/request": "^5.6.0", - "@octokit/types": "^6.0.3", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/openapi-types": { - "version": "12.11.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-12.11.0.tgz", - "integrity": "sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==" - }, - "node_modules/@octokit/plugin-paginate-rest": { - "version": "2.21.3", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-2.21.3.tgz", - "integrity": "sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==", - "dependencies": { - "@octokit/types": "^6.40.0" - }, - "peerDependencies": { - "@octokit/core": ">=2" - } - }, - "node_modules/@octokit/plugin-request-log": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz", - "integrity": "sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==", - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "5.16.2", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-5.16.2.tgz", - "integrity": "sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==", - "dependencies": { - "@octokit/types": "^6.39.0", - "deprecation": "^2.3.1" - }, - "peerDependencies": { - "@octokit/core": ">=3" - } - }, - "node_modules/@octokit/request": { - "version": "5.6.3", - "resolved": "https://registry.npmjs.org/@octokit/request/-/request-5.6.3.tgz", - "integrity": "sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==", - "dependencies": { - "@octokit/endpoint": "^6.0.1", - "@octokit/request-error": "^2.1.0", - "@octokit/types": "^6.16.1", - "is-plain-object": "^5.0.0", - "node-fetch": "^2.6.7", - "universal-user-agent": "^6.0.0" - } - }, - "node_modules/@octokit/request-error": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/@octokit/request-error/-/request-error-2.1.0.tgz", - "integrity": "sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==", - "dependencies": { - "@octokit/types": "^6.0.3", - "deprecation": "^2.0.0", - "once": "^1.4.0" - } - }, - "node_modules/@octokit/rest": { - "version": "18.12.0", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-18.12.0.tgz", - "integrity": "sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==", - "dependencies": { - "@octokit/core": "^3.5.1", - "@octokit/plugin-paginate-rest": "^2.16.8", - "@octokit/plugin-request-log": "^1.0.4", - "@octokit/plugin-rest-endpoint-methods": "^5.12.0" - } - }, - "node_modules/@octokit/types": { - "version": "6.41.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-6.41.0.tgz", - "integrity": "sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==", - "dependencies": { - "@octokit/openapi-types": "^12.11.0" - } - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "engines": { - "node": ">= 10" - } - }, - "node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, - "node_modules/@types/concat-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-1.6.1.tgz", - "integrity": "sha512-eHE4cQPoj6ngxBZMvVf6Hw7Mh4jMW4U9lpGmS5GBPB9RYxlFg+CHaVN7ErNY4W9XfLIEn20b4VDYaIrbq0q4uA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/form-data": { - "version": "0.0.33", - "resolved": "https://registry.npmjs.org/@types/form-data/-/form-data-0.0.33.tgz", - "integrity": "sha512-8BSvG1kGm83cyJITQMZSulnl6QV8jqAGreJsc5tPu1Jq0vTSOiY/k24Wx82JRpWwZSqrala6sd5rWi6aNXvqcw==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==" - }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/node": { - "version": "18.15.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.15.11.tgz", - "integrity": "sha512-E5Kwq2n4SbMzQOn6wnmBjuK9ouqlURrcZDVfbo9ftDDTFt3nk7ZKK4GMOzoYgnpQJKcxwQw+lGaBvvlMo0qN/Q==" - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==" - }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==" - }, - "node_modules/asn1": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz", - "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==", - "dependencies": { - "safer-buffer": "~2.1.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "engines": { - "node": ">=0.8" - } - }, - "node_modules/async-retry": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.2.3.tgz", - "integrity": "sha512-tfDb02Th6CE6pJUF2gjW5ZVjsgwlucVXOEQMvEX9JgSJMs9gAX+Nz3xRuJBKuUYjTSYORqvDBORdAQ3LU59g7Q==", - "dependencies": { - "retry": "0.12.0" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "node_modules/aws-sign2": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", - "integrity": "sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==", - "engines": { - "node": "*" - } - }, - "node_modules/aws4": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.12.0.tgz", - "integrity": "sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==" - }, - "node_modules/axios": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.3.5.tgz", - "integrity": "sha512-glL/PvG/E+xCWwV8S6nCHcrfg1exGx7vxyUIivIA1iL7BIh6bePylCfVHwp6k13ao7SATxB6imau2kqY+I67kw==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/bcrypt-pbkdf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", - "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==", - "dependencies": { - "tweetnacl": "^0.14.3" - } - }, - "node_modules/before-after-hook": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", - "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==" - }, - "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/buffer-equal-constant-time": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==" - }, - "node_modules/buffer-from": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", - "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" - }, - "node_modules/cacheable-lookup": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", - "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==" - }, - "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" - }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/core-js": { - "version": "3.30.0", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.0.tgz", - "integrity": "sha512-hQotSSARoNh1mYPi9O2YaWeiq/cEB95kOrFb4NCrO4RIFt1qqNpKsaE+vy/L3oiqvND5cThqXzUU3r9F7Efztg==", - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==" - }, - "node_modules/danger": { - "version": "11.2.6", - "resolved": "https://registry.npmjs.org/danger/-/danger-11.2.6.tgz", - "integrity": "sha512-EEeuDmUcxPGJ166q7Zzz1WEiV+e0qbPopaX4sXxds8U5doGMdw/8oOUOVye7JiHIBuss3KvQWt4YHZeD3jSCfw==", - "dependencies": { - "@gitbeaker/node": "^21.3.0", - "@octokit/rest": "^18.12.0", - "async-retry": "1.2.3", - "chalk": "^2.3.0", - "commander": "^2.18.0", - "core-js": "^3.8.2", - "debug": "^4.1.1", - "fast-json-patch": "^3.0.0-1", - "get-stdin": "^6.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "hyperlinker": "^1.0.0", - "json5": "^2.1.0", - "jsonpointer": "^5.0.0", - "jsonwebtoken": "^9.0.0", - "lodash.find": "^4.6.0", - "lodash.includes": "^4.3.0", - "lodash.isobject": "^3.0.2", - "lodash.keys": "^4.0.8", - "lodash.mapvalues": "^4.6.0", - "lodash.memoize": "^4.1.2", - "memfs-or-file-map-to-github-branch": "^1.2.1", - "micromatch": "^4.0.4", - "node-cleanup": "^2.1.2", - "node-fetch": "^2.6.7", - "override-require": "^1.1.1", - "p-limit": "^2.1.0", - "parse-diff": "^0.7.0", - "parse-git-config": "^2.0.3", - "parse-github-url": "^1.0.2", - "parse-link-header": "^2.0.0", - "pinpoint": "^1.1.0", - "prettyjson": "^1.2.1", - "readline-sync": "^1.4.9", - "regenerator-runtime": "^0.13.9", - "require-from-string": "^2.0.2", - "supports-hyperlinks": "^1.0.1" - }, - "bin": { - "danger": "distribution/commands/danger.js", - "danger-ci": "distribution/commands/danger-ci.js", - "danger-init": "distribution/commands/danger-init.js", - "danger-js": "distribution/commands/danger.js", - "danger-local": "distribution/commands/danger-local.js", - "danger-pr": "distribution/commands/danger-pr.js", - "danger-process": "distribution/commands/danger-process.js", - "danger-reset-status": "distribution/commands/danger-reset-status.js", - "danger-runner": "distribution/commands/danger-runner.js" - }, - "engines": { - "node": ">=14.13.1" - } - }, - "node_modules/dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==", - "dependencies": { - "assert-plus": "^1.0.0" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/decompress-response/node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "engines": { - "node": ">=10" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/deprecation": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/deprecation/-/deprecation-2.3.1.tgz", - "integrity": "sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==" - }, - "node_modules/ecc-jsbn": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", - "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==", - "dependencies": { - "jsbn": "~0.1.0", - "safer-buffer": "^2.1.0" - } - }, - "node_modules/ecdsa-sig-formatter": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", - "dependencies": { - "safe-buffer": "^5.0.1" - } - }, - "node_modules/end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", - "dependencies": { - "homedir-polyfill": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" - }, - "node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extsprintf": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", - "integrity": "sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==", - "engines": [ - "node >=0.6.0" - ] - }, - "node_modules/fast-deep-equal": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "node_modules/fast-json-patch": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", - "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==" - }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/filter-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-1.1.0.tgz", - "integrity": "sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==", - "engines": { - "node": "*" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/fs-exists-sync": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz", - "integrity": "sha512-cR/vflFyPZtrN6b38ZyWxpWdhlXrzZEBawlpBQMq7033xVY7/kg0GDMBK5jg8lDYQckdJ5x/YC88lM3C7VMsLg==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/get-port": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", - "integrity": "sha512-x5UJKlgeUiNT8nyo/AcnwLnZuZNcSjSw0kogRB+Whd1fjjFq4B1hySFxSFWWSn4mIBzg3sRNUDFYc4g5gjPoLg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "engines": { - "node": ">=4" - } - }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==", - "dependencies": { - "assert-plus": "^1.0.0" - } - }, - "node_modules/git-config-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-1.0.1.tgz", - "integrity": "sha512-KcJ2dlrrP5DbBnYIZ2nlikALfRhKzNSX0stvv3ImJ+fvC4hXKoV+U+74SV0upg+jlQZbrtQzc0bu6/Zh+7aQbg==", - "dependencies": { - "extend-shallow": "^2.0.1", - "fs-exists-sync": "^0.1.0", - "homedir-polyfill": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=10.19.0" - }, - "funding": { - "url": "https://github.com/sindresorhus/got?sponsor=1" - } - }, - "node_modules/har-schema": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", - "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", - "engines": { - "node": ">=4" - } - }, - "node_modules/har-validator": { - "version": "5.1.5", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", - "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", - "deprecated": "this library is no longer supported", - "dependencies": { - "ajv": "^6.12.3", - "har-schema": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "engines": { - "node": ">=4" - } - }, - "node_modules/homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dependencies": { - "parse-passwd": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/http-basic": { - "version": "8.1.3", - "resolved": "https://registry.npmjs.org/http-basic/-/http-basic-8.1.3.tgz", - "integrity": "sha512-/EcDMwJZh3mABI2NhGfHOGOeOZITqfkEO4p/xK+l3NpyncIHUQBoMvCSF/b5GqvKtySC2srL/GGG3+EtlqlmCw==", - "dependencies": { - "caseless": "^0.12.0", - "concat-stream": "^1.6.2", - "http-response-object": "^3.0.1", - "parse-cache-control": "^1.0.1" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/http-cache-semantics": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", - "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==" - }, - "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-response-object": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/http-response-object/-/http-response-object-3.0.2.tgz", - "integrity": "sha512-bqX0XTF6fnXSQcEJ2Iuyr75yVakyjIDCqroJQ/aHfSdlM743Cwqoi2nDYMzLGWUcuTWGWy8AAvOKXTfiv6q9RA==", - "dependencies": { - "@types/node": "^10.0.3" - } - }, - "node_modules/http-response-object/node_modules/@types/node": { - "version": "10.17.60", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.60.tgz", - "integrity": "sha512-F0KIgDJfy2nA3zMLmWGKxcH2ZVEtCZXHHdOQs2gSaQ27+lNeEfGxzkIw90aXswATX7AZ33tahPbzy6KAfUreVw==" - }, - "node_modules/http-signature": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", - "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", - "dependencies": { - "assert-plus": "^1.0.0", - "jsprim": "^1.2.2", - "sshpk": "^1.7.0" - }, - "engines": { - "node": ">=0.8", - "npm": ">=1.3.7" - } - }, - "node_modules/http2-wrapper": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", - "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", - "dependencies": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - }, - "engines": { - "node": ">=10.19.0" - } - }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/hyperlinker": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", - "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" - }, - "node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==" - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" - }, - "node_modules/isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==" - }, - "node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==" - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "node_modules/json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==" - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonpointer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", - "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/jsonwebtoken": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", - "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", - "dependencies": { - "jws": "^3.2.2", - "lodash": "^4.17.21", - "ms": "^2.1.1", - "semver": "^7.3.8" - }, - "engines": { - "node": ">=12", - "npm": ">=6" - } - }, - "node_modules/jsprim": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", - "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", - "dependencies": { - "assert-plus": "1.0.0", - "extsprintf": "1.3.0", - "json-schema": "0.4.0", - "verror": "1.10.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/jwa": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", - "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", - "dependencies": { - "buffer-equal-constant-time": "1.0.1", - "ecdsa-sig-formatter": "1.0.11", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/jws": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", - "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", - "dependencies": { - "jwa": "^1.4.1", - "safe-buffer": "^5.0.1" - } - }, - "node_modules/keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/li": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/li/-/li-1.3.0.tgz", - "integrity": "sha512-z34TU6GlMram52Tss5mt1m//ifRIpKH5Dqm7yUVOdHI+BQCs9qGPHFaCUTIzsWX7edN30aa2WrPwR7IO10FHaw==" - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.find": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", - "integrity": "sha512-yaRZoAV3Xq28F1iafWN1+a0rflOej93l1DQUejs3SZ41h2O9UJBoS9aueGjPDgAl4B6tPC0NuuchLKaDQQ3Isg==" - }, - "node_modules/lodash.includes": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==" - }, - "node_modules/lodash.isobject": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz", - "integrity": "sha512-3/Qptq2vr7WeJbB4KHUSKlq8Pl7ASXi3UG6CMbBm8WRtXi8+GHm7mKaU3urfpSEzWe2wCIChs6/sdocUsTKJiA==" - }, - "node_modules/lodash.keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-4.2.0.tgz", - "integrity": "sha512-J79MkJcp7Df5mizHiVNpjoHXLi4HLjh9VLS/M7lQSGoQ+0oQ+lWEigREkqKyizPB1IawvQLLKY8mzEcm1tkyxQ==" - }, - "node_modules/lodash.mapvalues": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz", - "integrity": "sha512-JPFqXFeZQ7BfS00H58kClY7SPVeHertPE0lNuCyZ26/XlN8TvakYD7b9bGyNmXbT/D3BbtPAAmq90gPWqLkxlQ==" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag==" - }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/memfs-or-file-map-to-github-branch": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/memfs-or-file-map-to-github-branch/-/memfs-or-file-map-to-github-branch-1.2.1.tgz", - "integrity": "sha512-I/hQzJ2a/pCGR8fkSQ9l5Yx+FQ4e7X6blNHyWBm2ojeFLT3GVzGkTj7xnyWpdclrr7Nq4dmx3xrvu70m3ypzAQ==", - "dependencies": { - "@octokit/rest": "^16.43.0 || ^17.11.0 || ^18.12.0" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/node-cleanup": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz", - "integrity": "sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw==" - }, - "node_modules/node-fetch": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.9.tgz", - "integrity": "sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/oauth-sign": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", - "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", - "engines": { - "node": "*" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/override-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/override-require/-/override-require-1.1.1.tgz", - "integrity": "sha512-eoJ9YWxFcXbrn2U8FKT6RV+/Kj7fiGAB1VvHzbYKt8xM5ZuKZgCGvnHzDxmreEjcBH28ejg5MiOH4iyY1mQnkg==" - }, - "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "engines": { - "node": ">=8" - } - }, - "node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-cache-control": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-cache-control/-/parse-cache-control-1.0.1.tgz", - "integrity": "sha512-60zvsJReQPX5/QP0Kzfd/VrpjScIQ7SHBW6bFCYfEP+fp0Eppr1SHhIO5nd1PjZtvclzSzES9D/p5nFJurwfWg==" - }, - "node_modules/parse-diff": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/parse-diff/-/parse-diff-0.7.1.tgz", - "integrity": "sha512-1j3l8IKcy4yRK2W4o9EYvJLSzpAVwz4DXqCewYyx2vEwk2gcf3DBPqc8Fj4XV3K33OYJ08A8fWwyu/ykD/HUSg==" - }, - "node_modules/parse-git-config": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-2.0.3.tgz", - "integrity": "sha512-Js7ueMZOVSZ3tP8C7E3KZiHv6QQl7lnJ+OkbxoaFazzSa2KyEHqApfGbU3XboUgUnq4ZuUmskUpYKTNx01fm5A==", - "dependencies": { - "expand-tilde": "^2.0.2", - "git-config-path": "^1.0.1", - "ini": "^1.3.5" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-github-url": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz", - "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==", - "bin": { - "parse-github-url": "cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/parse-link-header": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/parse-link-header/-/parse-link-header-2.0.0.tgz", - "integrity": "sha512-xjU87V0VyHZybn2RrCX5TIFGxTVZE6zqqZWMPlIKiSKuWh/X5WZdt+w1Ki1nXB+8L/KtL+nZ4iq+sfI6MrhhMw==", - "dependencies": { - "xtend": "~4.0.1" - } - }, - "node_modules/parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/performance-now": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pinpoint": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pinpoint/-/pinpoint-1.1.0.tgz", - "integrity": "sha512-+04FTD9x7Cls2rihLlo57QDCcHoLBGn5Dk51SwtFBWkUWLxZaBXyNVpCw1S+atvE7GmnFjeaRZ0WLq3UYuqAdg==" - }, - "node_modules/prettyjson": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/prettyjson/-/prettyjson-1.2.5.tgz", - "integrity": "sha512-rksPWtoZb2ZpT5OVgtmy0KHVM+Dca3iVwWY9ifwhcexfjebtgjg3wmrUt9PvJ59XIYBcknQeYHD8IAnVlh9lAw==", - "dependencies": { - "colors": "1.4.0", - "minimist": "^1.2.0" - }, - "bin": { - "prettyjson": "bin/prettyjson" - } - }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" - }, - "node_modules/promise": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/promise/-/promise-8.3.0.tgz", - "integrity": "sha512-rZPNPKTOYVNEEKFaq1HqTgOwZD+4/YHS5ukLzQCypkj+OkYx7iv0mA91lJlpPPZ8vMau3IIGj5Qlwrx+8iiSmg==", - "dependencies": { - "asap": "~2.0.6" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/psl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==" - }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/punycode": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz", - "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", - "engines": { - "node": ">=0.6" - } - }, - "node_modules/query-string": { - "version": "6.14.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-6.14.1.tgz", - "integrity": "sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==", - "dependencies": { - "decode-uri-component": "^0.2.0", - "filter-obj": "^1.1.0", - "split-on-first": "^1.0.0", - "strict-uri-encode": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/readline-sync": { - "version": "1.4.10", - "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", - "integrity": "sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw==", - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/regenerator-runtime": { - "version": "0.13.11", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" - }, - "node_modules/request": { - "version": "2.88.2", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", - "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", - "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", - "dependencies": { - "aws-sign2": "~0.7.0", - "aws4": "^1.8.0", - "caseless": "~0.12.0", - "combined-stream": "~1.0.6", - "extend": "~3.0.2", - "forever-agent": "~0.6.1", - "form-data": "~2.3.2", - "har-validator": "~5.1.3", - "http-signature": "~1.2.0", - "is-typedarray": "~1.0.0", - "isstream": "~0.1.2", - "json-stringify-safe": "~5.0.1", - "mime-types": "~2.1.19", - "oauth-sign": "~0.9.0", - "performance-now": "^2.1.0", - "qs": "~6.5.2", - "safe-buffer": "^5.1.2", - "tough-cookie": "~2.5.0", - "tunnel-agent": "^0.6.0", - "uuid": "^3.3.2" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/request/node_modules/form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==" - }, - "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "engines": { - "node": ">= 4" - } - }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/semver": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.3.tgz", - "integrity": "sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/split-on-first": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-1.1.0.tgz", - "integrity": "sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==", - "engines": { - "node": ">=6" - } - }, - "node_modules/sshpk": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz", - "integrity": "sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==", - "dependencies": { - "asn1": "~0.2.3", - "assert-plus": "^1.0.0", - "bcrypt-pbkdf": "^1.0.0", - "dashdash": "^1.12.0", - "ecc-jsbn": "~0.1.1", - "getpass": "^0.1.1", - "jsbn": "~0.1.0", - "safer-buffer": "^2.0.2", - "tweetnacl": "~0.14.0" - }, - "bin": { - "sshpk-conv": "bin/sshpk-conv", - "sshpk-sign": "bin/sshpk-sign", - "sshpk-verify": "bin/sshpk-verify" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/strict-uri-encode": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz", - "integrity": "sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-hyperlinks": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz", - "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==", - "dependencies": { - "has-flag": "^2.0.0", - "supports-color": "^5.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/supports-hyperlinks/node_modules/has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha512-P+1n3MnwjR/Epg9BBo1KT8qbye2g2Ou4sFumihwt6I4tsUX7jnLcX4BTOSKg/B1ZrIYMN9FcEnG4x5a7NB8Eng==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/sync-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sync-request/-/sync-request-6.1.0.tgz", - "integrity": "sha512-8fjNkrNlNCrVc/av+Jn+xxqfCjYaBoHqCsDz6mt030UMxJGr+GSfCV1dQt2gRtlL63+VPidwDVLr7V2OcTSdRw==", - "dependencies": { - "http-response-object": "^3.0.1", - "sync-rpc": "^1.2.1", - "then-request": "^6.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/sync-rpc": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/sync-rpc/-/sync-rpc-1.3.6.tgz", - "integrity": "sha512-J8jTXuZzRlvU7HemDgHi3pGnh/rkoqR/OZSjhTyyZrEkkYQbk7Z33AXp37mkPfPpfdOuj7Ex3H/TJM1z48uPQw==", - "dependencies": { - "get-port": "^3.1.0" - } - }, - "node_modules/then-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/then-request/-/then-request-6.0.2.tgz", - "integrity": "sha512-3ZBiG7JvP3wbDzA9iNY5zJQcHL4jn/0BWtXIkagfz7QgOL/LqjCEOBQuJNZfu0XYnv5JhKh+cDxCPM4ILrqruA==", - "dependencies": { - "@types/concat-stream": "^1.6.0", - "@types/form-data": "0.0.33", - "@types/node": "^8.0.0", - "@types/qs": "^6.2.31", - "caseless": "~0.12.0", - "concat-stream": "^1.6.0", - "form-data": "^2.2.0", - "http-basic": "^8.1.1", - "http-response-object": "^3.0.1", - "promise": "^8.0.0", - "qs": "^6.4.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/then-request/node_modules/@types/node": { - "version": "8.10.66", - "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.66.tgz", - "integrity": "sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw==" - }, - "node_modules/then-request/node_modules/form-data": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", - "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.6", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 0.12" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/tough-cookie": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", - "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", - "dependencies": { - "psl": "^1.1.28", - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, - "node_modules/tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==" - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" - }, - "node_modules/typescript": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz", - "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=12.20" - } - }, - "node_modules/universal-user-agent": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.0.tgz", - "integrity": "sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==" - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, - "node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "bin": { - "uuid": "bin/uuid" - } - }, - "node_modules/verror": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", - "integrity": "sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==", - "engines": [ - "node >=0.6.0" - ], - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==" - }, - "node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/xcase": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/xcase/-/xcase-2.0.1.tgz", - "integrity": "sha512-UmFXIPU+9Eg3E9m/728Bii0lAIuoc+6nbrNUKaRPJOFp91ih44qqGlWtxMB6kXFrRD6po+86ksHM5XHCfk6iPw==" - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - } - } -} diff --git a/.github/dangerjs/package.json b/.github/dangerjs/package.json deleted file mode 100644 index 9f70ec73ad62..000000000000 --- a/.github/dangerjs/package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "name": "dangerjs-github", - "description": "GitHub PR reviewing with DangerJS", - "main": "dangerfile.ts", - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "axios": "^1.3.3", - "danger": "^11.2.3", - "request": "^2.88.2", - "sync-request": "^6.1.0", - "typescript": "^5.0.3" - }, - "devDependencies": { - "@types/node": "^18.15.11" - } -} diff --git a/.github/dangerjs/prCommitMessage.ts b/.github/dangerjs/prCommitMessage.ts deleted file mode 100644 index 86250ddd62a7..000000000000 --- a/.github/dangerjs/prCommitMessage.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { DangerDSLType, DangerResults } from "danger"; -declare const danger: DangerDSLType; -declare const warn: (message: string, results?: DangerResults) => void; - -interface Commit { - message: string; -} - -/** - * Check if commit messages are sufficiently descriptive (not too short). - * - * Search for commit messages that appear to be automatically generated or temporary messages and report them. - * - * @dangerjs WARN - */ -export default function (): void { - const prCommits: Commit[] = danger.git.commits; - - const detectRegexes: RegExp[] = [ - /^Merge pull request #\d+ from .*/i, // Automatically generated message by GitHub - /^Merged .+:.+ into .+/i, // Automatically generated message by GitHub - /^Automatic merge by GitHub Action/i, // Automatically generated message by GitHub - /^Merge branch '.*' of .+ into .+/i, // Automatically generated message by GitHub - /^Create\s[a-zA-Z0-9_.-]+(\.[a-zA-Z0-9]{1,4})?(?=\s|$)/, // Automatically generated message by GitHub using UI - /^Delete\s[a-zA-Z0-9_.-]+(\.[a-zA-Z0-9]{1,4})?(?=\s|$)/, // Automatically generated message by GitHub using UI - /^Update\s[a-zA-Z0-9_.-]+(\.[a-zA-Z0-9]{1,4})?(?=\s|$)/, // Automatically generated message by GitHub using UI - /^Initial commit/i, // Automatically generated message by GitHub - /^WIP.*/i, // Message starts with prefix "WIP" - /^Cleaned.*/i, // Message starts "Cleaned", , probably temporary - /^Test:.*/i, // Message starts with "test" prefix, probably temporary - /clean ?up/i, // Message contains "clean up", probably temporary - /^[^A-Za-z0-9\s].*/, // Message starts with special characters - ]; - - let partMessages: string[] = []; - - for (const commit of prCommits) { - const commitMessage: string = commit.message; - const commitMessageTitle: string = commit.message.split("\n")[0]; - - // Check if the commit message matches any regex from "detectRegexes" - if (detectRegexes.some((regex) => commitMessage.match(regex))) { - partMessages.push( - `- the commit message \`${commitMessageTitle}\` appears to be a temporary or automatically generated message` - ); - continue; - } - - // Check if the commit message is not too short - const shortCommitMessageThreshold: number = 20; // commit message is considered too short below this number of characters - if (commitMessage.length < shortCommitMessageThreshold) { - partMessages.push( - `- the commit message \`${commitMessageTitle}\` may not be sufficiently descriptive` - ); - } - } - - // Create report - if (partMessages.length) { - partMessages.sort(); - let dangerMessage = `\nSome issues found for the commit messages in this MR:\n${partMessages.join( - "\n" - )} - \nPlease consider updating these commit messages.`; - warn(dangerMessage); - } -} diff --git a/.github/dangerjs/prCommitsTooManyCommits.ts b/.github/dangerjs/prCommitsTooManyCommits.ts deleted file mode 100644 index a973752a063f..000000000000 --- a/.github/dangerjs/prCommitsTooManyCommits.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { DangerDSLType, DangerResults } from "danger"; -declare const danger: DangerDSLType; -declare const message: (message: string, results?: DangerResults) => void; - -/** - * Check if pull request has not an excessive numbers of commits (if squashed) - * - * @dangerjs INFO - */ -export default function (): void { - const tooManyCommitThreshold: number = 2; // above this number of commits, squash commits is suggested - const prCommits: number = danger.github.commits.length; - - if (prCommits > tooManyCommitThreshold) { - return message( - `You might consider squashing your ${prCommits} commits (simplifying branch history).` - ); - } -} diff --git a/.github/dangerjs/prDescription.ts b/.github/dangerjs/prDescription.ts deleted file mode 100644 index 06fe2780a0b4..000000000000 --- a/.github/dangerjs/prDescription.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { DangerDSLType, DangerResults } from "danger"; -declare const danger: DangerDSLType; -declare const warn: (message: string, results?: DangerResults) => void; - -/** - * Check if pull request has has a sufficiently accurate description - * - * @dangerjs WARN - */ -export default function (): void { - const prDescription: string = danger.github.pr.body; - const shortPrDescriptionThreshold: number = 100; // Description is considered too short below this number of characters - - if (prDescription.length < shortPrDescriptionThreshold) { - return warn( - "The PR description looks very brief, please check if more details can be added." - ); - } -} diff --git a/.github/dangerjs/prInfoContributor.ts b/.github/dangerjs/prInfoContributor.ts deleted file mode 100644 index 1d4f9be56a13..000000000000 --- a/.github/dangerjs/prInfoContributor.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { DangerDSLType } from "danger"; -declare const danger: DangerDSLType; - -interface Contributor { - login?: string; -} - -const authorLogin = danger.github.pr.user.login; -const messageKnownContributor: string = ` -*** -👋 **Hi ${authorLogin}**, thank you for your another contribution to \`espressif/esp-idf\` project! - -If the change is approved and passes the tests in our internal git repository, it will appear in this public Github repository on the next sync. -*** -`; - -const messageFirstContributor: string = ` -*** -👋 **Welcome ${authorLogin}**, thank you for your first contribution to \`espressif/esp-idf\` project! - -📘 Please check [Contributions Guide](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/contribute/index.html#contributions-guide) for the contribution checklist, information regarding code and documentation style, testing and other topics. - -🖊️ Please also make sure you have **read and signed** the [Contributor License Agreement for espressif/esp-idf project](https://cla-assistant.io/espressif/esp-idf). - -#### Pull request review and merge process you can expect -Espressif develops the ESP-IDF project in an internal repository (Gitlab). We do welcome contributions in the form of bug reports, feature requests and pull requests via this public GitHub repository. - -1. An internal issue has been created for the PR, we assign it to the relevant engineer -2. They review the PR and either approve it or ask you for changes or clarifications -3. Once the Github PR is approved, we synchronize it into our internal git repository -4. In the internal git repository we do the final review, collect approvals from core owners and make sure all the automated tests are passing - - At this point we may do some adjustments to the proposed change, or extend it by adding tests or documentation. -5. If the change is approved and passes the tests it is merged into the \`master\` branch -6. On next sync from the internal git repository merged change will appear in this public Github repository - -*** -`; - -/** - * Check whether the author of the pull request is known or a first-time contributor, and add a message to the PR with information about the review and merge process. - */ -export default async function (): Promise { - const contributors = await danger.github.api.repos.listContributors({ - owner: danger.github.thisPR.owner, - repo: danger.github.thisPR.repo, - }); - - const contributorsData: Contributor[] = contributors.data; - const knownContributors: (string | undefined)[] = contributorsData.map( - (contributor: Contributor) => contributor.login - ); - - if (knownContributors.includes(authorLogin)) { - return messageKnownContributor; - } else { - return messageFirstContributor; - } -} diff --git a/.github/dangerjs/prTargetBranch.ts b/.github/dangerjs/prTargetBranch.ts deleted file mode 100644 index 93b9bd81030c..000000000000 --- a/.github/dangerjs/prTargetBranch.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { DangerDSLType, DangerResults } from "danger"; -declare const danger: DangerDSLType; -declare const fail: (message: string, results?: DangerResults) => void; - -/** - * Check if the target branch is "master" - * - * @dangerjs FAIL - */ -export default function (): void { - const prTargetBranch: string = danger.github?.pr?.base?.ref; - - if (prTargetBranch !== "master") { - return fail(` - The target branch for this pull request should be \`master\`.\n - If you would like to add this feature to the release branch, please state this in the PR description and we will consider backporting it. - `); - } -} diff --git a/.github/dangerjs/tsconfig.json b/.github/dangerjs/tsconfig.json deleted file mode 100644 index d09fc72a690a..000000000000 --- a/.github/dangerjs/tsconfig.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "moduleResolution": "node", - "esModuleInterop": true, - "target": "es6", - "noImplicitAny": true, - "noUnusedParameters": true, - "strictNullChecks": true, - "sourceMap": true, - "removeComments": true, - "outDir": "./dist" - }, - "include": [ - "./*.ts" - ] -} diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index a34982945ac1..000000000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,15 +0,0 @@ -version: 2 -updates: - - package-ecosystem: "all" - directory: "/" - schedule: - interval: "weekly" - ignore: - - directory: ".gitlab/dangerjs" - patterns: - - "package-lock.json" - - directory: ".github/dangerjs" - patterns: - - "package-lock.json" - # Disable "version updates" (keep only "security updates") - open-pull-requests-limit: 0 diff --git a/.github/workflows/dangerjs.yml b/.github/workflows/dangerjs.yml index b2c078ae1dde..07871a79a9a0 100644 --- a/.github/workflows/dangerjs.yml +++ b/.github/workflows/dangerjs.yml @@ -9,28 +9,19 @@ permissions: contents: write jobs: - danger-check: + pull-request-style-linter: runs-on: ubuntu-latest - defaults: - run: - working-directory: .github/dangerjs steps: - name: Check out PR head - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} - - name: Setup NodeJS environment - uses: actions/setup-node@v3 - with: - node-version: 18 - cache: npm - cache-dependency-path: .github/dangerjs/package-lock.json - - - name: Install DangerJS dependencies - run: npm install - - - name: Run DangerJS - run: npx danger ci --failOnErrors -v + - name: DangerJS pull request linter + uses: espressif/shared-github-dangerjs@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + instructions-gitlab-mirror: 'true' + instructions-contributions-file: 'CONTRIBUTING.md' + instructions-cla-link: 'https://cla-assistant.io/espressif/esp-idf' diff --git a/.gitlab/CODEOWNERS b/.gitlab/CODEOWNERS index 3324f54c9e51..4cc21ca35c8d 100644 --- a/.gitlab/CODEOWNERS +++ b/.gitlab/CODEOWNERS @@ -47,8 +47,6 @@ * @esp-idf-codeowners/other /.* @esp-idf-codeowners/tools -/.github/dangerjs/ @esp-idf-codeowners/ci @esp-idf-codeowners/tools -/.github/dependabot.yml @esp-idf-codeowners/ci /.github/workflows/ @esp-idf-codeowners/ci /.gitlab-ci.yml @esp-idf-codeowners/ci /.gitlab/ci/ @esp-idf-codeowners/ci diff --git a/.gitlab/ci/build.yml b/.gitlab/ci/build.yml index 6cbfa370ca14..b58a008f3928 100644 --- a/.gitlab/ci/build.yml +++ b/.gitlab/ci/build.yml @@ -569,7 +569,7 @@ pytest_build_system_macos: pytest_build_system_win: extends: - .test_build_system_template_win - - .rules:test:windows_pytest_build_system + - .rules:labels:windows_pytest_build_system needs: [] tags: - windows-target diff --git a/.gitlab/ci/dependencies/dependencies.yml b/.gitlab/ci/dependencies/dependencies.yml index e0e0face19e0..217e701db58c 100644 --- a/.gitlab/ci/dependencies/dependencies.yml +++ b/.gitlab/ci/dependencies/dependencies.yml @@ -175,15 +175,15 @@ patterns: - submodule -"test:windows_pytest_build_system": - labels: - - windows - specific_rules: - - if-schedule-test-build-system-windows - ################################# # Triggered Only By Labels Jobs # ################################# "labels:nvs_coverage": # host_test labels: - nvs_coverage + +"labels:windows_pytest_build_system": + labels: + - windows + specific_rules: + - if-schedule-test-build-system-windows diff --git a/.gitlab/ci/host-test.yml b/.gitlab/ci/host-test.yml index ec6988e31487..b43855f70c7a 100644 --- a/.gitlab/ci/host-test.yml +++ b/.gitlab/ci/host-test.yml @@ -214,8 +214,6 @@ test_tools: - pytest --noconftest test_idf_qemu.py --junitxml=${IDF_PATH}/XUNIT_IDF_PY_QEMU.xml || stat=1 - cd ${IDF_PATH}/tools/test_mkdfu - pytest --noconftest test_mkdfu.py --junitxml=${IDF_PATH}/XUNIT_MKDFU.xml || stat=1 - - cd ${IDF_PATH}/tools/test_sbom - - pytest --junitxml=${IDF_PATH}/XUNIT_SBOM.xml || stat=1 - cd ${IDF_PATH} - shellcheck -s sh tools/detect_python.sh || stat=1 - shellcheck -s bash tools/detect_python.sh || stat=1 diff --git a/.gitlab/ci/rules.yml b/.gitlab/ci/rules.yml index 76f471adad03..ae688f66b516 100644 --- a/.gitlab/ci/rules.yml +++ b/.gitlab/ci/rules.yml @@ -147,8 +147,6 @@ - "tools/test_idf_tools/**/*" - "tools/install_util.py" - - "tools/test_sbom/*" - - "tools/requirements/*" - "tools/requirements.json" - "tools/requirements_schema.json" @@ -1617,6 +1615,13 @@ when: never - <<: *if-label-nvs_coverage +.rules:labels:windows_pytest_build_system: + rules: + - <<: *if-revert-branch + when: never + - <<: *if-schedule-test-build-system-windows + - <<: *if-label-windows + .rules:test:component_ut-esp32: rules: - <<: *if-revert-branch @@ -2581,13 +2586,3 @@ - <<: *if-label-submodule - <<: *if-dev-push changes: *patterns-submodule - -.rules:test:windows_pytest_build_system: - rules: - - <<: *if-revert-branch - when: never - - <<: *if-protected - - <<: *if-label-build-only - when: never - - <<: *if-schedule-test-build-system-windows - - <<: *if-label-windows diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 9b522cc4d97b..92d7d9d5d32f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -177,12 +177,6 @@ repos: always_run: true pass_filenames: false require_serial: true - - id: submodule-sbom-hash-check - name: Check if sbom-hash values for submodules in .gitmodules match submodules checkout hash in git tree - entry: python tools/test_sbom/test_submodules.py - language: python - always_run: true - pass_filenames: false - id: cleanup-ignore-lists name: Remove non-existing patterns from ignore lists entry: tools/ci/cleanup_ignore_lists.py @@ -221,3 +215,7 @@ repos: name: shellcheck dash (export.sh) args: ['--shell', 'dash', '-x'] files: 'export.sh' + - repo: https://github.com/espressif/esp-idf-sbom.git + rev: v0.11.0 + hooks: + - id: validate-sbom-manifest diff --git a/components/bootloader/Kconfig.projbuild b/components/bootloader/Kconfig.projbuild index 2855441d6a96..6ffbf68aacc9 100644 --- a/components/bootloader/Kconfig.projbuild +++ b/components/bootloader/Kconfig.projbuild @@ -832,7 +832,6 @@ menu "Security features" bool "Enable flash encryption on boot (READ DOCS FIRST)" default N select SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE - select NVS_ENCRYPTION help If this option is set, flash contents will be encrypted by the bootloader on first boot. diff --git a/components/bootloader_support/src/flash_encrypt.c b/components/bootloader_support/src/flash_encrypt.c index 40f70a865885..27f10317cb91 100644 --- a/components/bootloader_support/src/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encrypt.c @@ -137,16 +137,14 @@ esp_flash_enc_mode_t esp_get_flash_encryption_mode(void) } #else if (esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT) -#if CONFIG_IDF_TARGET_ESP32P4 - //TODO: IDF-7545 +#if SOC_EFUSE_DIS_DOWNLOAD_MSPI && esp_efuse_read_field_bit(ESP_EFUSE_SPI_DOWNLOAD_MSPI_DIS) -#else +#endif #if SOC_EFUSE_DIS_DOWNLOAD_ICACHE && esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE) #endif #if SOC_EFUSE_DIS_DOWNLOAD_DCACHE && esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_DCACHE) -#endif #endif ) { mode = ESP_FLASH_ENC_MODE_RELEASE; @@ -192,17 +190,15 @@ void esp_flash_encryption_set_release_mode(void) esp_efuse_write_field_bit(ESP_EFUSE_DISABLE_DL_DECRYPT); #else esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT); -#if CONFIG_IDF_TARGET_ESP32P4 - //TODO: IDF-7545 +#if SOC_EFUSE_DIS_DOWNLOAD_MSPI esp_efuse_write_field_bit(ESP_EFUSE_SPI_DOWNLOAD_MSPI_DIS); -#else +#endif #if SOC_EFUSE_DIS_DOWNLOAD_ICACHE esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE); #endif #if SOC_EFUSE_DIS_DOWNLOAD_DCACHE esp_efuse_write_field_bit(ESP_EFUSE_DIS_DOWNLOAD_DCACHE); #endif -#endif #ifdef CONFIG_SOC_FLASH_ENCRYPTION_XTS_AES_128_DERIVED // For AES128_DERIVED, FE key is 16 bytes and XTS_KEY_LENGTH_256 is 0. // It is important to protect XTS_KEY_LENGTH_256 from further changing it to 1. Set write protection for this bit. @@ -345,14 +341,13 @@ bool esp_flash_encryption_cfg_verify_release_mode(void) } #endif -#if CONFIG_IDF_TARGET_ESP32P4 - //TODO: IDF-7545 +#if SOC_EFUSE_DIS_DOWNLOAD_MSPI secure = esp_efuse_read_field_bit(ESP_EFUSE_SPI_DOWNLOAD_MSPI_DIS); result &= secure; if (!secure) { ESP_LOGW(TAG, "Not disabled UART bootloader download mspi (set DIS_DOWNLOAD_MSPI->1)"); } -#else +#endif #if SOC_EFUSE_DIS_DOWNLOAD_ICACHE secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_DOWNLOAD_ICACHE); result &= secure; @@ -360,7 +355,6 @@ bool esp_flash_encryption_cfg_verify_release_mode(void) ESP_LOGW(TAG, "Not disabled UART bootloader cache (set DIS_DOWNLOAD_ICACHE->1)"); } #endif -#endif #if SOC_EFUSE_DIS_PAD_JTAG secure = esp_efuse_read_field_bit(ESP_EFUSE_DIS_PAD_JTAG); diff --git a/components/bootloader_support/src/flash_encryption/flash_encrypt.c b/components/bootloader_support/src/flash_encryption/flash_encrypt.c index daf920564a07..145fb23e6d9c 100644 --- a/components/bootloader_support/src/flash_encryption/flash_encrypt.c +++ b/components/bootloader_support/src/flash_encryption/flash_encrypt.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -15,6 +15,11 @@ #include "esp_efuse_table.h" #include "esp_log.h" #include "hal/wdt_hal.h" + +#if CONFIG_IDF_TARGET_ESP32P4 //TODO-IDF-7925 +#include "soc/keymng_reg.h" +#endif + #ifdef CONFIG_SOC_EFUSE_CONSISTS_OF_ONE_KEY_BLOCK #include "soc/sensitive_reg.h" #endif @@ -209,6 +214,12 @@ static esp_err_t check_and_generate_encryption_keys(void) } ESP_LOGI(TAG, "Using pre-loaded flash encryption key in efuse"); } + +#if CONFIG_IDF_TARGET_ESP32P4 //TODO - IDF-7925 + // Force Key Manager to use eFuse key for XTS-AES operation + REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY, 2); +#endif + return ESP_OK; } diff --git a/components/bt/controller/lib_esp32 b/components/bt/controller/lib_esp32 index 06ad44e581b3..d1d4b7635d01 160000 --- a/components/bt/controller/lib_esp32 +++ b/components/bt/controller/lib_esp32 @@ -1 +1 @@ -Subproject commit 06ad44e581b3141929850cd705c735d0bd3207b0 +Subproject commit d1d4b7635d01edc40cbd0605376afd804ba4afb9 diff --git a/components/bt/esp_ble_mesh/Kconfig.in b/components/bt/esp_ble_mesh/Kconfig.in index 6efcb1ea0ddb..b324df84764d 100644 --- a/components/bt/esp_ble_mesh/Kconfig.in +++ b/components/bt/esp_ble_mesh/Kconfig.in @@ -6,6 +6,15 @@ if BLE_MESH help It is a temporary solution and needs further modifications. + config BLE_MESH_RANDOM_ADV_INTERVAL + bool "Support using random adv interval for mesh packets" + select BT_BLE_HIGH_DUTY_ADV_INTERVAL if BT_BLUEDROID_ENABLED + default n + help + Enable this option to allow using random advertising interval + for mesh packets. And this could help avoid collision of + advertising packets. + config BLE_MESH_USE_DUPLICATE_SCAN bool "Support Duplicate Scan in BLE Mesh" select BTDM_BLE_SCAN_DUPL if IDF_TARGET_ESP32 diff --git a/components/bt/esp_ble_mesh/common/common.c b/components/bt/esp_ble_mesh/common/common.c index 87f0c6a7bc36..7257db930c7c 100644 --- a/components/bt/esp_ble_mesh/common/common.c +++ b/components/bt/esp_ble_mesh/common/common.c @@ -85,3 +85,8 @@ int bt_mesh_rand(void *buf, size_t len) return 0; } + +uint32_t bt_mesh_get_rand(void) +{ + return esp_random(); +} diff --git a/components/bt/esp_ble_mesh/common/include/mesh/common.h b/components/bt/esp_ble_mesh/common/include/mesh/common.h index db6c1d372a7a..a1cfa673a2fd 100644 --- a/components/bt/esp_ble_mesh/common/include/mesh/common.h +++ b/components/bt/esp_ble_mesh/common/include/mesh/common.h @@ -53,6 +53,8 @@ void bt_mesh_free_buf(struct net_buf_simple *buf); int bt_mesh_rand(void *buf, size_t len); +uint32_t bt_mesh_get_rand(void); + #ifdef __cplusplus } #endif diff --git a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c index 68a768c79419..0e5769ba7d09 100644 --- a/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/bluedroid_host/adapter.c @@ -324,6 +324,7 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, tBLE_ADDR_TYPE addr_type_own = 0U; tBLE_BD_ADDR p_dir_bda = {0}; tBTM_BLE_AFP adv_fil_pol = 0U; + uint16_t interval = 0U; uint8_t adv_type = 0U; int err = 0; @@ -387,9 +388,24 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, adv_fil_pol = BLE_MESH_AP_SCAN_CONN_ALL; p_start_adv_cb = start_adv_completed_cb; + interval = param->interval_min; + +#if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL + /* If non-connectable mesh packets are transmitted with an adv interval + * not smaller than 10ms, then we will use a random adv interval between + * [interval / 2, interval] for them. + */ + if (adv_type == BLE_MESH_ADV_NONCONN_IND && interval >= 16) { + interval >>= 1; + interval += (bt_mesh_get_rand() % (interval + 1)); + + BT_INFO("%u->%u", param->interval_min, interval); + } +#endif + /* Check if we can start adv using BTM_BleSetAdvParamsStartAdvCheck */ BLE_MESH_BTM_CHECK_STATUS( - BTM_BleSetAdvParamsAll(param->interval_min, param->interval_max, adv_type, + BTM_BleSetAdvParamsAll(interval, interval, adv_type, addr_type_own, &p_dir_bda, channel_map, adv_fil_pol, p_start_adv_cb)); BLE_MESH_BTM_CHECK_STATUS(BTM_BleStartAdv()); diff --git a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c index 8df06e4dd7cd..510352ce15d0 100644 --- a/components/bt/esp_ble_mesh/core/nimble_host/adapter.c +++ b/components/bt/esp_ble_mesh/core/nimble_host/adapter.c @@ -758,15 +758,17 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, const struct bt_mesh_adv_data *ad, size_t ad_len, const struct bt_mesh_adv_data *sd, size_t sd_len) { + struct ble_gap_adv_params adv_params; + uint8_t buf[BLE_HS_ADV_MAX_SZ]; + uint16_t interval = 0; + uint8_t buf_len = 0; + int err; + #if BLE_MESH_DEV if (bt_mesh_atomic_test_bit(bt_mesh_dev.flags, BLE_MESH_DEV_ADVERTISING)) { return -EALREADY; } #endif - uint8_t buf[BLE_HS_ADV_MAX_SZ]; - uint8_t buf_len = 0; - int err; - struct ble_gap_adv_params adv_params; err = set_ad(ad, ad_len, buf, &buf_len); if (err) { @@ -797,8 +799,6 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, } memset(&adv_params, 0, sizeof adv_params); - adv_params.itvl_min = param->interval_min; - adv_params.itvl_max = param->interval_max; if (param->options & BLE_MESH_ADV_OPT_CONNECTABLE) { adv_params.conn_mode = BLE_GAP_CONN_MODE_UND; @@ -811,6 +811,25 @@ int bt_le_adv_start(const struct bt_mesh_adv_param *param, adv_params.disc_mode = BLE_GAP_DISC_MODE_NON; } + interval = param->interval_min; + +#if CONFIG_BLE_MESH_RANDOM_ADV_INTERVAL + /* If non-connectable mesh packets are transmitted with an adv interval + * not smaller than 10ms, then we will use a random adv interval between + * [interval / 2, interval] for them. + */ + if (adv_params.conn_mode == BLE_GAP_CONN_MODE_NON && + adv_params.disc_mode == BLE_GAP_DISC_MODE_NON && interval >= 16) { + interval >>= 1; + interval += (bt_mesh_get_rand() % (interval + 1)); + + BT_INFO("%u->%u", param->interval_min, interval); + } +#endif + + adv_params.itvl_min = interval; + adv_params.itvl_max = interval; + again: err = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER, &adv_params, gap_event_cb, NULL); diff --git a/components/bt/esp_ble_mesh/lib/lib b/components/bt/esp_ble_mesh/lib/lib index 73b3b96db91d..41bf5fc0926f 160000 --- a/components/bt/esp_ble_mesh/lib/lib +++ b/components/bt/esp_ble_mesh/lib/lib @@ -1 +1 @@ -Subproject commit 73b3b96db91d170d96e0f3e901a47f51e749e75b +Subproject commit 41bf5fc0926fd6d3fb39cb5107e97f2fc6aed7e5 diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index f79f1a9cf444..e63d98447a65 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -221,7 +221,10 @@ config BT_GATTS_ROBUST_CACHING_ENABLED depends on BT_GATTS_ENABLE default n help - This option enable gatt robust caching feature on server + This option enables the GATT robust caching feature on the server. + if turned on, the Client Supported Features characteristic, Database Hash characteristic, + and Server Supported Features characteristic will be included in the GAP SERVICE. + config BT_GATTS_DEVICE_NAME_WRITABLE bool "Allow to write device name by GATT clients" diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index cc083a240e9e..ff149501c327 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -577,6 +577,14 @@ void bta_dm_disable (tBTA_DM_MSG *p_data) bta_dm_disable_search_and_disc(); bta_dm_cb.disabling = TRUE; +#if BLE_INCLUDED == TRUE + /* reset scan activity status*/ + btm_cb.ble_ctr_cb.scan_activity = 0; + + /* reset advertising activity status*/ + btm_cb.ble_ctr_cb.inq_var.state = 0; +#endif + #if BLE_INCLUDED == TRUE && BTA_GATT_INCLUDED == TRUE BTM_BleClearBgConnDev(); #endif diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_api.c b/components/bt/host/bluedroid/stack/gatt/gatt_api.c index 31cf6c25449b..8d8056f6d0ff 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_api.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_api.c @@ -122,6 +122,7 @@ BOOLEAN GATTS_NVRegister (const tGATT_APPL_INFO *p_cb_info) return status; } +#if GATTS_ROBUST_CACHING_ENABLED static void gatt_update_for_database_change(void) { UINT8 i; @@ -135,7 +136,7 @@ static void gatt_update_for_database_change(void) } } } - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ /******************************************************************************* ** ** Function GATTS_CreateService @@ -414,7 +415,9 @@ BOOLEAN GATTS_DeleteService (tGATT_IF gatt_if, tBT_UUID *p_svc_uuid, UINT16 svc_ GATT_TRACE_DEBUG ("Delete a new service changed item - the service has not yet started"); osi_free(fixed_queue_try_remove_from_queue(gatt_cb.pending_new_srv_start_q, p_buf)); } else { +#if GATTS_ROBUST_CACHING_ENABLED gatt_update_for_database_change(); +#endif /* GATTS_ROBUST_CACHING_ENABLED */ if (gatt_cb.srv_chg_mode == GATTS_SEND_SERVICE_CHANGE_AUTO) { gatt_proc_srv_chg(); } @@ -527,7 +530,11 @@ tGATT_STATUS GATTS_StartService (tGATT_IF gatt_if, UINT16 service_handle, if ( (p_buf = gatt_sr_is_new_srv_chg(&p_list->asgn_range.app_uuid128, &p_list->asgn_range.svc_uuid, p_list->asgn_range.svc_inst)) != NULL) { + + #if GATTS_ROBUST_CACHING_ENABLED gatt_update_for_database_change(); + #endif /* GATTS_ROBUST_CACHING_ENABLED */ + if (gatt_cb.srv_chg_mode == GATTS_SEND_SERVICE_CHANGE_AUTO) { gatt_proc_srv_chg(); } diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_attr.c b/components/bt/host/bluedroid/stack/gatt/gatt_attr.c index ce3b80289507..3ab573426a96 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_attr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_attr.c @@ -40,7 +40,13 @@ #define BLE_GATT_CL_SUPP_FEAT_BITMASK 0x07 #define GATTP_MAX_NUM_INC_SVR 0 + +#if GATTS_ROBUST_CACHING_ENABLED #define GATTP_MAX_CHAR_NUM 5 +#else +#define GATTP_MAX_CHAR_NUM 2 +#endif /* GATTS_ROBUST_CACHING_ENABLED */ + #define GATTP_MAX_ATTR_NUM (GATTP_MAX_CHAR_NUM * 2 + GATTP_MAX_NUM_INC_SVR + 1) #define GATTP_MAX_CHAR_VALUE_SIZE 50 @@ -196,14 +202,15 @@ tGATT_STATUS gatt_proc_read (UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_READ_RE GATT_TRACE_DEBUG("%s handle %x", __func__, p_data->handle); - UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id); - tGATT_TCB *tcb = gatt_get_tcb_by_idx(tcb_idx); - if (p_data->is_long) { p_rsp->attr_value.offset = p_data->offset; } p_rsp->attr_value.handle = p_data->handle; +#if GATTS_ROBUST_CACHING_ENABLED + + UINT8 tcb_idx = GATT_GET_TCB_IDX(conn_id); + tGATT_TCB *tcb = gatt_get_tcb_by_idx(tcb_idx); /* handle request for reading client supported features */ if (p_data->handle == gatt_cb.handle_of_cl_supported_feat) { @@ -229,7 +236,7 @@ tGATT_STATUS gatt_proc_read (UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_READ_RE memcpy(p_rsp->attr_value.value, &gatt_cb.gatt_sr_supported_feat_mask, 1); return GATT_SUCCESS; } - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ /* handle request for reading service changed des and the others */ status = GATTS_GetAttributeValue(p_data->handle, &len, &value); if(status == GATT_SUCCESS && len > 0 && value) { @@ -241,7 +248,7 @@ tGATT_STATUS gatt_proc_read (UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_READ_RE } return status; } - +#if GATTS_ROBUST_CACHING_ENABLED static tGATT_STATUS gatt_sr_write_cl_supp_feat(UINT16 conn_id, tGATT_WRITE_REQ *p_data) { UINT8 val_new; @@ -286,7 +293,7 @@ static tGATT_STATUS gatt_sr_write_cl_supp_feat(UINT16 conn_id, tGATT_WRITE_REQ * #endif return GATT_SUCCESS; } - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ /****************************************************************************** ** ** Function gatt_proc_write_req @@ -301,7 +308,7 @@ tGATT_STATUS gatt_proc_write_req(UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_WRI if(p_data->len > GATT_MAX_ATTR_LEN) { p_data->len = GATT_MAX_ATTR_LEN; } - +#if GATTS_ROBUST_CACHING_ENABLED if (p_data->handle == gatt_cb.handle_of_h_r) { return GATT_WRITE_NOT_PERMIT; } @@ -317,7 +324,7 @@ tGATT_STATUS gatt_proc_write_req(UINT16 conn_id, tGATTS_REQ_TYPE type, tGATT_WRI if (p_data->handle == gatt_cb.handle_of_sr_supported_feat) { return GATT_WRITE_NOT_PERMIT; } - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ return GATTS_SetAttributeValue(p_data->handle, p_data->len, p_data->value); @@ -470,7 +477,7 @@ void gatt_profile_db_init (void) }; GATTS_AddCharDescriptor (service_handle, GATT_PERM_READ | GATT_PERM_WRITE , &descr_uuid, &attr_val, NULL); - +#if GATTS_ROBUST_CACHING_ENABLED /* add Client Supported Features characteristic */ uuid.uu.uuid16 = GATT_UUID_CLIENT_SUP_FEAT; gatt_cb.handle_of_cl_supported_feat = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ | GATT_PERM_WRITE, @@ -483,7 +490,7 @@ void gatt_profile_db_init (void) /* add Server Supported Features characteristic */ uuid.uu.uuid16 = GATT_UUID_SERVER_SUP_FEAT; gatt_cb.handle_of_sr_supported_feat = GATTS_AddCharacteristic(service_handle, &uuid, GATT_PERM_READ, GATT_CHAR_PROP_BIT_READ, NULL, NULL); - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ /* start service */ status = GATTS_StartService (gatt_cb.gatt_if, service_handle, GATTP_TRANSPORT_SUPPORTED ); @@ -689,6 +696,7 @@ void GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, tBT_TRANSP gatt_cl_start_config_ccc(p_clcb); } +#if GATTS_ROBUST_CACHING_ENABLED /******************************************************************************* ** ** Function gatt_sr_is_cl_robust_caching_supported @@ -700,14 +708,8 @@ void GATT_ConfigServiceChangeCCC (BD_ADDR remote_bda, BOOLEAN enable, tBT_TRANSP *******************************************************************************/ static BOOLEAN gatt_sr_is_cl_robust_caching_supported(tGATT_TCB *p_tcb) { - // Server robust caching not enabled - if (!GATTS_ROBUST_CACHING_ENABLED) { - return FALSE; - } - return (p_tcb->cl_supp_feat & BLE_GATT_CL_SUPP_FEAT_ROBUST_CACHING_BITMASK); } - /******************************************************************************* ** ** Function gatt_sr_is_cl_change_aware @@ -791,4 +793,5 @@ void gatt_sr_update_cl_status(tGATT_TCB *p_tcb, BOOLEAN chg_aware) GATT_TRACE_DEBUG("%s status %d", __func__, chg_aware); } +#endif /* GATTS_ROBUST_CACHING_ENABLED */ #endif /* BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c index 1510f4487145..899a79bd3c9b 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_sr.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_sr.c @@ -1680,9 +1680,10 @@ static BOOLEAN gatts_proc_ind_ack(tGATT_TCB *p_tcb, UINT16 ack_handle) gatts_proc_srv_chg_ind_ack(p_tcb); /* there is no need to inform the application since srv chg is handled internally by GATT */ continue_processing = FALSE; - +#if GATTS_ROBUST_CACHING_ENABLED /* after receiving ack of svc_chg_ind, reset client status */ gatt_sr_update_cl_status(p_tcb, true); +#endif /* GATTS_ROBUST_CACHING_ENABLED */ } gatts_chk_pending_ind(p_tcb); @@ -1729,6 +1730,7 @@ void gatts_process_value_conf(tGATT_TCB *p_tcb, UINT8 op_code) } } +#if GATTS_ROBUST_CACHING_ENABLED static BOOLEAN gatts_handle_db_out_of_sync(tGATT_TCB *p_tcb, UINT8 op_code, UINT16 len, UINT8 *p_data) { @@ -1808,6 +1810,7 @@ static BOOLEAN gatts_handle_db_out_of_sync(tGATT_TCB *p_tcb, UINT8 op_code, return should_ignore; } +#endif /* GATTS_ROBUST_CACHING_ENABLED */ /******************************************************************************* ** ** Function gatt_server_handle_client_req @@ -1839,11 +1842,12 @@ void gatt_server_handle_client_req (tGATT_TCB *p_tcb, UINT8 op_code, } /* otherwise, ignore the pkt */ } else { +#if GATTS_ROBUST_CACHING_ENABLED // handle database out of sync if (gatts_handle_db_out_of_sync(p_tcb, op_code, len, p_data)) { return; } - +#endif /* GATTS_ROBUST_CACHING_ENABLED */ switch (op_code) { case GATT_REQ_READ_BY_GRP_TYPE: /* discover primary services */ case GATT_REQ_FIND_TYPE_VALUE: /* discover service by UUID */ diff --git a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c index 2dbbcd8d8aca..621b2468886d 100644 --- a/components/bt/host/bluedroid/stack/gatt/gatt_utils.c +++ b/components/bt/host/bluedroid/stack/gatt/gatt_utils.c @@ -1090,9 +1090,9 @@ tGATT_TCB *gatt_allocate_tcb_by_bdaddr(BD_ADDR bda, tBT_TRANSPORT transport) p_tcb->transport = transport; } memcpy(p_tcb->peer_bda, bda, BD_ADDR_LEN); -#if (GATTS_INCLUDED == TRUE) +#if GATTS_ROBUST_CACHING_ENABLED gatt_sr_init_cl_status(p_tcb); -#endif ///GATTS_INCLUDED == TRUE +#endif /* GATTS_ROBUST_CACHING_ENABLED */ } return p_tcb; } diff --git a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h index 63bf39ed3130..1161da62b525 100644 --- a/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h +++ b/components/bt/host/bluedroid/stack/gatt/include/gatt_int.h @@ -539,6 +539,7 @@ typedef struct { tGATT_PROFILE_CLCB profile_clcb[GATT_MAX_APPS]; #endif ///GATTS_INCLUDED == TRUE UINT16 handle_of_h_r; /* Handle of the handles reused characteristic value */ +#if GATTS_ROBUST_CACHING_ENABLED UINT16 handle_of_database_hash; UINT16 handle_of_cl_supported_feat; UINT16 handle_of_sr_supported_feat; @@ -546,6 +547,7 @@ typedef struct { UINT8 gatt_sr_supported_feat_mask; UINT8 gatt_cl_supported_feat_mask; +#endif tGATT_APPL_INFO cb_info; diff --git a/components/bt/host/nimble/nimble b/components/bt/host/nimble/nimble index cafd9eed805e..4c366451ae58 160000 --- a/components/bt/host/nimble/nimble +++ b/components/bt/host/nimble/nimble @@ -1 +1 @@ -Subproject commit cafd9eed805e12d134d45c9be91c6d5e46fc3ceb +Subproject commit 4c366451ae586d5b0b3f9a914da511ec293aab42 diff --git a/components/driver/deprecated/adc_dma_legacy.c b/components/driver/deprecated/adc_dma_legacy.c index 170a0b85ad98..93e42cfb1689 100644 --- a/components/driver/deprecated/adc_dma_legacy.c +++ b/components/driver/deprecated/adc_dma_legacy.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2016-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -67,6 +67,7 @@ typedef struct adc_digi_context_t { gdma_channel_handle_t rx_dma_channel; //dma rx channel handle #elif CONFIG_IDF_TARGET_ESP32S2 spi_host_device_t spi_host; //ADC uses this SPI DMA + spi_dma_ctx_t *spi_dma_ctx; //spi_dma context intr_handle_t intr_hdl; //Interrupt handler #elif CONFIG_IDF_TARGET_ESP32 i2s_port_t i2s_host; //ADC uses this I2S DMA @@ -167,7 +168,7 @@ esp_err_t adc_digi_deinitialize(void) gdma_del_channel(s_adc_digi_ctx->rx_dma_channel); #elif CONFIG_IDF_TARGET_ESP32S2 esp_intr_free(s_adc_digi_ctx->intr_hdl); - spicommon_dma_chan_free(s_adc_digi_ctx->spi_host); + spicommon_dma_chan_free(s_adc_digi_ctx->spi_dma_ctx); spicommon_periph_free(s_adc_digi_ctx->spi_host); #elif CONFIG_IDF_TARGET_ESP32 esp_intr_free(s_adc_digi_ctx->intr_hdl); @@ -274,13 +275,14 @@ esp_err_t adc_digi_initialize(const adc_digi_init_config_t *init_config) uint32_t dma_chan = 0; spi_success = spicommon_periph_claim(SPI3_HOST, "adc"); - ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &dma_chan, &dma_chan); + ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &s_adc_digi_ctx->spi_dma_ctx); if (ret == ESP_OK) { s_adc_digi_ctx->spi_host = SPI3_HOST; } if (!spi_success || (s_adc_digi_ctx->spi_host != SPI3_HOST)) { goto cleanup; } + dma_chan = s_adc_digi_ctx->spi_dma_ctx->rx_dma_chan.chan_id; ret = esp_intr_alloc(spicommon_irqdma_source_for_host(s_adc_digi_ctx->spi_host), 0, adc_dma_intr_handler, (void *)s_adc_digi_ctx, &s_adc_digi_ctx->intr_hdl); diff --git a/components/esp_adc/adc_continuous.c b/components/esp_adc/adc_continuous.c index 97208e042969..71d405ccb813 100644 --- a/components/esp_adc/adc_continuous.c +++ b/components/esp_adc/adc_continuous.c @@ -196,13 +196,14 @@ esp_err_t adc_continuous_new_handle(const adc_continuous_handle_cfg_t *hdl_confi uint32_t dma_chan = 0; spi_success = spicommon_periph_claim(SPI3_HOST, "adc"); - ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &dma_chan, &dma_chan); + ret = spicommon_dma_chan_alloc(SPI3_HOST, SPI_DMA_CH_AUTO, &adc_ctx->spi_dma_ctx); if (ret == ESP_OK) { adc_ctx->spi_host = SPI3_HOST; } if (!spi_success || (adc_ctx->spi_host != SPI3_HOST)) { goto cleanup; } + dma_chan = adc_ctx->spi_dma_ctx->rx_dma_chan.chan_id; ret = esp_intr_alloc(spicommon_irqdma_source_for_host(adc_ctx->spi_host), ESP_INTR_FLAG_IRAM, adc_dma_intr_handler, (void *)adc_ctx, &adc_ctx->dma_intr_hdl); @@ -494,7 +495,7 @@ esp_err_t adc_continuous_deinit(adc_continuous_handle_t handle) gdma_del_channel(handle->rx_dma_channel); #elif CONFIG_IDF_TARGET_ESP32S2 esp_intr_free(handle->dma_intr_hdl); - spicommon_dma_chan_free(handle->spi_host); + spicommon_dma_chan_free(handle->spi_dma_ctx); spicommon_periph_free(handle->spi_host); #elif CONFIG_IDF_TARGET_ESP32 esp_intr_free(handle->dma_intr_hdl); diff --git a/components/esp_adc/adc_continuous_internal.h b/components/esp_adc/adc_continuous_internal.h index e78787ba975c..64d6ad2a5fe4 100644 --- a/components/esp_adc/adc_continuous_internal.h +++ b/components/esp_adc/adc_continuous_internal.h @@ -19,6 +19,7 @@ #include "esp_private/gdma.h" #elif CONFIG_IDF_TARGET_ESP32S2 #include "hal/spi_types.h" +#include "esp_private/spi_common_internal.h" #elif CONFIG_IDF_TARGET_ESP32 #include "driver/i2s_types.h" #endif @@ -77,6 +78,7 @@ struct adc_continuous_ctx_t { gdma_channel_handle_t rx_dma_channel; //dma rx channel handle #elif CONFIG_IDF_TARGET_ESP32S2 spi_host_device_t spi_host; //ADC uses this SPI DMA + spi_dma_ctx_t *spi_dma_ctx; //spi_dma context #elif CONFIG_IDF_TARGET_ESP32 i2s_port_t i2s_host; //ADC uses this I2S DMA #endif diff --git a/components/esp_app_format/CMakeLists.txt b/components/esp_app_format/CMakeLists.txt index 05d7c9ce3c80..c25ced06f296 100644 --- a/components/esp_app_format/CMakeLists.txt +++ b/components/esp_app_format/CMakeLists.txt @@ -18,7 +18,7 @@ if(NOT BOOTLOADER_BUILD) target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc") if(CONFIG_APP_PROJECT_VER_FROM_CONFIG) - # Ignore current PROJECT_VER (which was set in __project_get_revision()). + # Ignore current PROJECT_VER (which was set in project.cmake) # Gets the version from the CONFIG_APP_PROJECT_VER. idf_build_set_property(PROJECT_VER "${CONFIG_APP_PROJECT_VER}") endif() diff --git a/components/esp_coex/lib b/components/esp_coex/lib index cc027a43829f..b5da84bed425 160000 --- a/components/esp_coex/lib +++ b/components/esp_coex/lib @@ -1 +1 @@ -Subproject commit cc027a43829f91e0ff5fe0b84713edf61e52cfc6 +Subproject commit b5da84bed42578946162241cfc6b37449bd2c251 diff --git a/components/esp_driver_dac/esp32s2/dac_dma.c b/components/esp_driver_dac/esp32s2/dac_dma.c index 6f40d03f2281..6e715bc4dc35 100644 --- a/components/esp_driver_dac/esp32s2/dac_dma.c +++ b/components/esp_driver_dac/esp32s2/dac_dma.c @@ -38,6 +38,7 @@ typedef struct { void *periph_dev; /* DMA peripheral device address */ uint32_t dma_chan; + spi_dma_ctx_t *spi_dma_ctx; /* spi_dma context */ intr_handle_t intr_handle; /* Interrupt handle */ bool use_apll; /* Whether use APLL as digital controller clock source */ } dac_dma_periph_spi_t; @@ -142,9 +143,10 @@ esp_err_t dac_dma_periph_init(uint32_t freq_hz, bool is_alternate, bool is_apll) /* When transmit alternately, twice frequency is needed to guarantee the convert frequency in one channel */ uint32_t trans_freq_hz = freq_hz * (is_alternate ? 2 : 1); ESP_GOTO_ON_ERROR(s_dac_dma_periph_set_clock(trans_freq_hz, is_apll), err, TAG, "Failed to set clock of DMA peripheral"); - ESP_GOTO_ON_ERROR(spicommon_dma_chan_alloc(DAC_DMA_PERIPH_SPI_HOST, SPI_DMA_CH_AUTO, &s_ddp->dma_chan, &s_ddp->dma_chan), + ESP_GOTO_ON_ERROR(spicommon_dma_chan_alloc(DAC_DMA_PERIPH_SPI_HOST, SPI_DMA_CH_AUTO, &s_ddp->spi_dma_ctx), err, TAG, "Failed to allocate dma peripheral channel"); + s_ddp->dma_chan = s_ddp->spi_dma_ctx->rx_dma_chan.chan_id; spi_ll_enable_intr(s_ddp->periph_dev, SPI_LL_INTR_OUT_EOF | SPI_LL_INTR_OUT_TOTAL_EOF); dac_ll_digi_set_convert_mode(is_alternate); return ret; @@ -157,7 +159,7 @@ esp_err_t dac_dma_periph_deinit(void) { ESP_RETURN_ON_FALSE(s_ddp->intr_handle == NULL, ESP_ERR_INVALID_STATE, TAG, "The interrupt is not deregistered yet"); if (s_ddp->dma_chan) { - ESP_RETURN_ON_ERROR(spicommon_dma_chan_free(DAC_DMA_PERIPH_SPI_HOST), TAG, "Failed to free dma peripheral channel"); + ESP_RETURN_ON_ERROR(spicommon_dma_chan_free(s_ddp->spi_dma_ctx), TAG, "Failed to free dma peripheral channel"); } ESP_RETURN_ON_FALSE(spicommon_periph_free(DAC_DMA_PERIPH_SPI_HOST), ESP_FAIL, TAG, "Failed to release DAC DMA peripheral"); spi_ll_disable_intr(s_ddp->periph_dev, SPI_LL_INTR_OUT_EOF | SPI_LL_INTR_OUT_TOTAL_EOF); diff --git a/components/esp_driver_spi/CMakeLists.txt b/components/esp_driver_spi/CMakeLists.txt index 38aa46cc61d2..a2c123ab761e 100644 --- a/components/esp_driver_spi/CMakeLists.txt +++ b/components/esp_driver_spi/CMakeLists.txt @@ -11,7 +11,8 @@ set(public_include "include") if(CONFIG_SOC_GPSPI_SUPPORTED) list(APPEND srcs "src/gpspi/spi_common.c" "src/gpspi/spi_master.c" - "src/gpspi/spi_slave.c") + "src/gpspi/spi_slave.c" + "src/gpspi/spi_dma.c") endif() if(CONFIG_SOC_SPI_SUPPORT_SLAVE_HD_VER2) diff --git a/components/esp_driver_spi/include/esp_private/spi_common_internal.h b/components/esp_driver_spi/include/esp_private/spi_common_internal.h index 0b4a7ac68ee5..4652347593d3 100644 --- a/components/esp_driver_spi/include/esp_private/spi_common_internal.h +++ b/components/esp_driver_spi/include/esp_private/spi_common_internal.h @@ -13,7 +13,7 @@ #include "freertos/FreeRTOS.h" #include "hal/spi_types.h" #include "hal/dma_types.h" -#include "soc/gdma_channel.h" +#include "esp_private/spi_dma.h" #include "esp_pm.h" #include "esp_private/spi_share_hw_ctrl.h" #if SOC_GDMA_SUPPORTED @@ -37,14 +37,13 @@ extern "C" #define SPI_MASTER_ATTR #endif -#if SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB +//NOTE!! If both A and B are not defined, '#if (A==B)' is true, because GCC use 0 stand for undefined symbol +#if SOC_GPSPI_SUPPORTED && defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) +#define DMA_DESC_MEM_ALIGN_SIZE 8 +typedef dma_descriptor_align8_t spi_dma_desc_t; +#else #define DMA_DESC_MEM_ALIGN_SIZE 4 -#define SPI_GDMA_NEW_CHANNEL gdma_new_ahb_channel typedef dma_descriptor_align4_t spi_dma_desc_t; -#else -#define DMA_DESC_MEM_ALIGN_SIZE 8 -#define SPI_GDMA_NEW_CHANNEL gdma_new_axi_channel -typedef dma_descriptor_align8_t spi_dma_desc_t; #endif /// Attributes of an SPI bus @@ -54,60 +53,64 @@ typedef struct { int max_transfer_sz; ///< Maximum length of bytes available to send bool dma_enabled; ///< To enable DMA or not uint16_t internal_mem_align_size; ///< Buffer align byte requirement for internal memory - int tx_dma_chan; ///< TX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same - int rx_dma_chan; ///< RX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same - int dma_desc_num; ///< DMA descriptor number of dmadesc_tx or dmadesc_rx. - spi_dma_desc_t *dmadesc_tx; ///< DMA descriptor array for TX - spi_dma_desc_t *dmadesc_rx; ///< DMA descriptor array for RX spi_bus_lock_handle_t lock; #ifdef CONFIG_PM_ENABLE esp_pm_lock_handle_t pm_lock; ///< Power management lock #endif } spi_bus_attr_t; +typedef struct { +#if SOC_GDMA_SUPPORTED + gdma_channel_handle_t tx_dma_chan; ///< GDMA tx channel + gdma_channel_handle_t rx_dma_chan; ///< GDMA rx channel +#else + spi_dma_chan_handle_t tx_dma_chan; ///< TX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same + spi_dma_chan_handle_t rx_dma_chan; ///< RX DMA channel, on ESP32 and ESP32S2, tx_dma_chan and rx_dma_chan are same +#endif + int dma_desc_num; ///< DMA descriptor number of dmadesc_tx or dmadesc_rx. + spi_dma_desc_t *dmadesc_tx; ///< DMA descriptor array for TX + spi_dma_desc_t *dmadesc_rx; ///< DMA descriptor array for RX +} spi_dma_ctx_t; + /// Destructor called when a bus is deinitialized. typedef esp_err_t (*spi_destroy_func_t)(void*); /** - * @brief Alloc DMA for SPI + * @brief Alloc DMA channel for SPI * - * @param host_id SPI host ID - * @param dma_chan DMA channel to be used - * @param[out] out_actual_tx_dma_chan Actual TX DMA channel (if you choose to assign a specific DMA channel, this will be the channel you assigned before) - * @param[out] out_actual_rx_dma_chan Actual RX DMA channel (if you choose to assign a specific DMA channel, this will be the channel you assigned before) + * @param host_id SPI host ID + * @param dma_chan DMA channel to be used + * @param out_dma_ctx Actual DMA channel context (if you choose to assign a specific DMA channel, this will be the channel you assigned before) * * @return * - ESP_OK: On success * - ESP_ERR_NO_MEM: No enough memory * - ESP_ERR_NOT_FOUND: There is no available DMA channel */ -esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan); +esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, spi_dma_ctx_t **out_dma_ctx); /** - * @brief Free DMA for SPI + * @brief Alloc DMA descriptors for SPI * - * @param host_id SPI host ID + * @param dma_ctx DMA context returned by `spicommon_dma_chan_alloc` + * @param[in] cfg_max_sz Expected maximum transfer size, in bytes. + * @param[out] actual_max_sz Actual max transfer size one transaction can be, in bytes. * * @return - * - ESP_OK: On success + * - ESP_OK: On success + * - ESP_ERR_NO_MEM: No enough memory */ -esp_err_t spicommon_dma_chan_free(spi_host_device_t host_id); +esp_err_t spicommon_dma_desc_alloc(spi_dma_ctx_t *dma_ctx, int cfg_max_sz, int *actual_max_sz); -#if SOC_GDMA_SUPPORTED /** - * @brief Get SPI GDMA Handle for GMDA Supported Chip + * @brief Free DMA for SPI * - * @param host_id SPI host ID - * @param gdma_handle GDMA Handle to Return - * @param gdma_direction GDMA Channel Direction in Enum - * - GDMA_CHANNEL_DIRECTION_TX - * - GDMA_CHANNEL_DIRECTION_RX + * @param dma_ctx spi_dma_ctx_t struct pointer * * @return * - ESP_OK: On success */ -esp_err_t spicommon_gdma_get_handle(spi_host_device_t host_id, gdma_channel_handle_t *gdma_handle, gdma_channel_direction_t gdma_direction); -#endif +esp_err_t spicommon_dma_chan_free(spi_dma_ctx_t *dma_ctx); /** * @brief Connect a SPI peripheral to GPIO pins @@ -272,6 +275,14 @@ void spi_bus_main_set_lock(spi_bus_lock_handle_t lock); */ const spi_bus_attr_t* spi_bus_get_attr(spi_host_device_t host_id); +/** + * @brief Get the dma context of a specified SPI bus. + * + * @param host_id The specified host to get attribute + * @return (Const) Pointer to the dma context + */ +const spi_dma_ctx_t* spi_bus_get_dma_ctx(spi_host_device_t host_id); + /** * @brief Register a function to a initialized bus to make it called when deinitializing the bus. * diff --git a/components/esp_driver_spi/include/esp_private/spi_dma.h b/components/esp_driver_spi/include/esp_private/spi_dma.h new file mode 100644 index 000000000000..39ff2c3c8fa9 --- /dev/null +++ b/components/esp_driver_spi/include/esp_private/spi_dma.h @@ -0,0 +1,58 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once +#include "stdbool.h" +#include "hal/spi_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if !SOC_GDMA_SUPPORTED +/** + * @brief Enumeration of SPI_DMA channel direction + */ +typedef enum { + DMA_CHANNEL_DIRECTION_TX, /*!< DMA channel direction: TX */ + DMA_CHANNEL_DIRECTION_RX, /*!< DMA channel direction: RX */ +} spi_dma_chan_dir_t; + +typedef struct { + spi_host_device_t host_id; + spi_dma_chan_dir_t dir; + int chan_id; +} spi_dma_chan_handle_t; + +/** + * Enable/Disable data/desc burst for spi_dma channel + * + * @param chan_handle Context of the spi_dma channel. + * @param data_burst enable or disable data burst + * @param desc_burst enable or disable desc burst + */ +void spi_dma_enable_burst(spi_dma_chan_handle_t chan_handle, bool data_burst, bool desc_burst); + +/** + * Reset dma channel for spi_dma + * + * @param chan_handle Context of the spi_dma channel. + */ +void spi_dma_reset(spi_dma_chan_handle_t chan_handle); + +/** + * Start dma channel for spi_dma + * + * @param chan_handle Context of the spi_dma channel. + * @param addr Addr of linked dma descriptor to mount + */ +void spi_dma_start(spi_dma_chan_handle_t chan_handle, void *addr); + +#endif //!SOC_GDMA_SUPPORTED + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_driver_spi/linker.lf b/components/esp_driver_spi/linker.lf index e69de29bb2d1..fe92562a6bb4 100644 --- a/components/esp_driver_spi/linker.lf +++ b/components/esp_driver_spi/linker.lf @@ -0,0 +1,7 @@ +[mapping:gpspi_driver] +archive: libesp_driver_spi.a +entries: + if SOC_GDMA_SUPPORTED = n: + if SPI_MASTER_ISR_IN_IRAM = y || SPI_SLAVE_ISR_IN_IRAM = y: + spi_dma: spi_dma_reset (noflash) + spi_dma: spi_dma_start (noflash) diff --git a/components/esp_driver_spi/src/gpspi/spi_common.c b/components/esp_driver_spi/src/gpspi/spi_common.c index 787c227cbe6d..981cd19ab5b9 100644 --- a/components/esp_driver_spi/src/gpspi/spi_common.c +++ b/components/esp_driver_spi/src/gpspi/spi_common.c @@ -10,6 +10,7 @@ #include "esp_types.h" #include "esp_attr.h" #include "esp_check.h" +#include "esp_cache.h" #include "esp_rom_gpio.h" #include "esp_heap_caps.h" #include "soc/spi_periph.h" @@ -18,6 +19,7 @@ #include "esp_private/periph_ctrl.h" #include "esp_private/spi_common_internal.h" #include "esp_private/spi_share_hw_ctrl.h" +#include "esp_private/esp_cache_private.h" #include "hal/spi_hal.h" #include "hal/gpio_hal.h" #if CONFIG_IDF_TARGET_ESP32 @@ -25,8 +27,6 @@ #endif #if SOC_GDMA_SUPPORTED #include "esp_private/gdma.h" -#include "hal/cache_hal.h" -#include "hal/cache_ll.h" #endif static const char *SPI_TAG = "spi"; @@ -42,10 +42,7 @@ static const char *SPI_TAG = "spi"; #define SPI_MAIN_BUS_DEFAULT() { \ .host_id = 0, \ .bus_attr = { \ - .tx_dma_chan = 0, \ - .rx_dma_chan = 0, \ .max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE, \ - .dma_desc_num= 0, \ }, \ } @@ -56,6 +53,7 @@ typedef struct { spi_destroy_func_t destroy_func; void* destroy_arg; spi_bus_attr_t bus_attr; + spi_dma_ctx_t *dma_ctx; #if SOC_GDMA_SUPPORTED gdma_channel_handle_t tx_channel; gdma_channel_handle_t rx_channel; @@ -75,11 +73,19 @@ static __attribute__((constructor)) void spi_bus_lock_init_main_bus(void) } #endif -#if !SOC_GDMA_SUPPORTED +#if SOC_GDMA_SUPPORTED +//NOTE!! If both A and B are not defined, '#if (A==B)' is true, because GCC use 0 stand for undefined symbol +#if defined(SOC_GDMA_BUS_AXI) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) +#define SPI_GDMA_NEW_CHANNEL gdma_new_axi_channel +#elif defined(SOC_GDMA_BUS_AHB) && (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) +#define SPI_GDMA_NEW_CHANNEL gdma_new_ahb_channel +#endif + +#else //Each bit stands for 1 dma channel, BIT(0) should be used for SPI1 static uint8_t spi_dma_chan_enabled = 0; static portMUX_TYPE spi_dma_spinlock = portMUX_INITIALIZER_UNLOCKED; -#endif //#if !SOC_GDMA_SUPPORTED +#endif //!SOC_GDMA_SUPPORTED static inline bool is_valid_host(spi_host_device_t host) { @@ -157,7 +163,7 @@ static void connect_spi_and_dma(spi_host_device_t host, int dma_chan) #endif } -static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan) +static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_chan, spi_dma_ctx_t *dma_ctx) { assert(is_valid_host(host_id)); #if CONFIG_IDF_TARGET_ESP32 @@ -187,60 +193,66 @@ static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_ch } //On ESP32 and ESP32S2, actual_tx_dma_chan and actual_rx_dma_chan are always same - *out_actual_tx_dma_chan = actual_dma_chan; - *out_actual_rx_dma_chan = actual_dma_chan; + dma_ctx->tx_dma_chan.chan_id = actual_dma_chan; + dma_ctx->rx_dma_chan.chan_id = actual_dma_chan; + dma_ctx->tx_dma_chan.host_id = host_id; + dma_ctx->rx_dma_chan.host_id = host_id; + dma_ctx->tx_dma_chan.dir = DMA_CHANNEL_DIRECTION_TX; + dma_ctx->rx_dma_chan.dir = DMA_CHANNEL_DIRECTION_RX; if (!success) { SPI_CHECK(false, "no available dma channel", ESP_ERR_NOT_FOUND); } + connect_spi_and_dma(host_id, actual_dma_chan); - connect_spi_and_dma(host_id, *out_actual_tx_dma_chan); - + spi_dma_enable_burst(dma_ctx->tx_dma_chan, true, true); + spi_dma_enable_burst(dma_ctx->rx_dma_chan, true, true); return ret; } #else //SOC_GDMA_SUPPORTED -static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan) +static esp_err_t alloc_dma_chan(spi_host_device_t host_id, spi_dma_chan_t dma_chan, spi_dma_ctx_t *dma_ctx) { assert(is_valid_host(host_id)); assert(dma_chan == SPI_DMA_CH_AUTO); - esp_err_t ret = ESP_OK; - spicommon_bus_context_t *ctx = bus_ctx[host_id]; if (dma_chan == SPI_DMA_CH_AUTO) { gdma_channel_alloc_config_t tx_alloc_config = { .flags.reserve_sibling = 1, .direction = GDMA_CHANNEL_DIRECTION_TX, }; - ESP_RETURN_ON_ERROR(SPI_GDMA_NEW_CHANNEL(&tx_alloc_config, &ctx->tx_channel), SPI_TAG, "alloc gdma tx failed"); + ESP_RETURN_ON_ERROR(SPI_GDMA_NEW_CHANNEL(&tx_alloc_config, &dma_ctx->tx_dma_chan), SPI_TAG, "alloc gdma tx failed"); gdma_channel_alloc_config_t rx_alloc_config = { .direction = GDMA_CHANNEL_DIRECTION_RX, - .sibling_chan = ctx->tx_channel, + .sibling_chan = dma_ctx->tx_dma_chan, }; - ESP_RETURN_ON_ERROR(SPI_GDMA_NEW_CHANNEL(&rx_alloc_config, &ctx->rx_channel), SPI_TAG, "alloc gdma rx failed"); + ESP_RETURN_ON_ERROR(SPI_GDMA_NEW_CHANNEL(&rx_alloc_config, &dma_ctx->rx_dma_chan), SPI_TAG, "alloc gdma rx failed"); if (host_id == SPI2_HOST) { - gdma_connect(ctx->rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)); - gdma_connect(ctx->tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)); + gdma_connect(dma_ctx->tx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)); + gdma_connect(dma_ctx->rx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 2)); } #if (SOC_SPI_PERIPH_NUM >= 3) else if (host_id == SPI3_HOST) { - gdma_connect(ctx->rx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3)); - gdma_connect(ctx->tx_channel, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3)); + gdma_connect(dma_ctx->tx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3)); + gdma_connect(dma_ctx->rx_dma_chan, GDMA_MAKE_TRIGGER(GDMA_TRIG_PERIPH_SPI, 3)); } #endif - gdma_get_channel_id(ctx->tx_channel, (int *)out_actual_tx_dma_chan); - gdma_get_channel_id(ctx->rx_channel, (int *)out_actual_rx_dma_chan); + gdma_transfer_ability_t ability = { + .psram_trans_align = 0, // fall back to use the same size of the psram data cache line size + .sram_trans_align = 4, + }; + ESP_RETURN_ON_ERROR(gdma_set_transfer_ability(dma_ctx->tx_dma_chan, &ability), SPI_TAG, "set gdma tx transfer ability failed"); + ESP_RETURN_ON_ERROR(gdma_set_transfer_ability(dma_ctx->rx_dma_chan, &ability), SPI_TAG, "set gdma rx transfer ability failed"); } - return ret; } #endif //#if !SOC_GDMA_SUPPORTED -esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, uint32_t *out_actual_tx_dma_chan, uint32_t *out_actual_rx_dma_chan) +esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma_chan, spi_dma_ctx_t **out_dma_ctx) { assert(is_valid_host(host_id)); #if CONFIG_IDF_TARGET_ESP32 @@ -250,60 +262,56 @@ esp_err_t spicommon_dma_chan_alloc(spi_host_device_t host_id, spi_dma_chan_t dma #endif esp_err_t ret = ESP_OK; - uint32_t actual_tx_dma_chan = 0; - uint32_t actual_rx_dma_chan = 0; - spicommon_bus_context_t *ctx = (spicommon_bus_context_t *)calloc(1, sizeof(spicommon_bus_context_t)); - if (!ctx) { + spi_dma_ctx_t *dma_ctx = (spi_dma_ctx_t *)calloc(1, sizeof(spi_dma_ctx_t)); + if (!dma_ctx) { ret = ESP_ERR_NO_MEM; goto cleanup; } - bus_ctx[host_id] = ctx; - ctx->host_id = host_id; - ret = alloc_dma_chan(host_id, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan); + ret = alloc_dma_chan(host_id, dma_chan, dma_ctx); if (ret != ESP_OK) { goto cleanup; } - ctx->bus_attr.tx_dma_chan = actual_tx_dma_chan; - ctx->bus_attr.rx_dma_chan = actual_rx_dma_chan; - *out_actual_tx_dma_chan = actual_tx_dma_chan; - *out_actual_rx_dma_chan = actual_rx_dma_chan; - + *out_dma_ctx = dma_ctx; return ret; cleanup: - free(ctx); - ctx = NULL; + free(dma_ctx); return ret; } -#if SOC_GDMA_SUPPORTED -esp_err_t spicommon_gdma_get_handle(spi_host_device_t host_id, gdma_channel_handle_t *gdma_handle, gdma_channel_direction_t gdma_direction) +esp_err_t spicommon_dma_desc_alloc(spi_dma_ctx_t *dma_ctx, int cfg_max_sz, int *actual_max_sz) { - assert(is_valid_host(host_id)); - ESP_RETURN_ON_FALSE((gdma_direction == GDMA_CHANNEL_DIRECTION_TX) || \ - (gdma_direction == GDMA_CHANNEL_DIRECTION_RX), \ - ESP_ERR_INVALID_ARG, SPI_TAG, "GDMA Direction not supported!"); - - if (gdma_direction == GDMA_CHANNEL_DIRECTION_TX) { - *gdma_handle = bus_ctx[host_id]->tx_channel; + int dma_desc_ct = (cfg_max_sz + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; + if (dma_desc_ct == 0) { + dma_desc_ct = 1; //default to 4k when max is not given } - if (gdma_direction == GDMA_CHANNEL_DIRECTION_RX) { - *gdma_handle = bus_ctx[host_id]->rx_channel; + + dma_ctx->dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); + dma_ctx->dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); + if (dma_ctx->dmadesc_tx == NULL || dma_ctx->dmadesc_rx == NULL) { + if (dma_ctx->dmadesc_tx) { + free(dma_ctx->dmadesc_tx); + dma_ctx->dmadesc_tx = NULL; + } + if (dma_ctx->dmadesc_rx) { + free(dma_ctx->dmadesc_rx); + dma_ctx->dmadesc_rx = NULL; + } + return ESP_ERR_NO_MEM; } + dma_ctx->dma_desc_num = dma_desc_ct; + *actual_max_sz = dma_desc_ct * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; return ESP_OK; } -#endif // SOC_GDMA_SUPPORTED - //----------------------------------------------------------free dma periph-------------------------------------------------------// -static esp_err_t dma_chan_free(spi_host_device_t host_id) +esp_err_t spicommon_dma_chan_free(spi_dma_ctx_t *dma_ctx) { - assert(is_valid_host(host_id)); + assert(dma_ctx); - spicommon_bus_context_t *ctx = bus_ctx[host_id]; #if !SOC_GDMA_SUPPORTED //On ESP32S2, each SPI controller has its own DMA channel - int dma_chan = ctx->bus_attr.tx_dma_chan; + int dma_chan = dma_ctx->tx_dma_chan.chan_id; assert(spi_dma_chan_enabled & BIT(dma_chan)); portENTER_CRITICAL(&spi_dma_spinlock); @@ -311,41 +319,31 @@ static esp_err_t dma_chan_free(spi_host_device_t host_id) #if SPI_LL_DMA_SHARED PERIPH_RCC_RELEASE_ATOMIC(get_dma_periph(dma_chan), ref_count) { if (ref_count == 0) { - spi_dma_ll_enable_bus_clock(host_id, false); + spi_dma_ll_enable_bus_clock(dma_ctx->tx_dma_chan.host_id, false); } } #else SPI_COMMON_RCC_CLOCK_ATOMIC() { - spi_dma_ll_enable_bus_clock(host_id, false); + spi_dma_ll_enable_bus_clock(dma_ctx->tx_dma_chan.host_id, false); } #endif portEXIT_CRITICAL(&spi_dma_spinlock); #else //SOC_GDMA_SUPPORTED - if (ctx->rx_channel) { - gdma_disconnect(ctx->rx_channel); - gdma_del_channel(ctx->rx_channel); + if (dma_ctx->rx_dma_chan) { + gdma_disconnect(dma_ctx->rx_dma_chan); + gdma_del_channel(dma_ctx->rx_dma_chan); } - if (ctx->tx_channel) { - gdma_disconnect(ctx->tx_channel); - gdma_del_channel(ctx->tx_channel); + if (dma_ctx->tx_dma_chan) { + gdma_disconnect(dma_ctx->tx_dma_chan); + gdma_del_channel(dma_ctx->tx_dma_chan); } #endif + free(dma_ctx); return ESP_OK; } -esp_err_t spicommon_dma_chan_free(spi_host_device_t host_id) -{ - assert(is_valid_host(host_id)); - - esp_err_t ret = dma_chan_free(host_id); - free(bus_ctx[host_id]); - bus_ctx[host_id] = NULL; - - return ret; -} - //----------------------------------------------------------IO general-------------------------------------------------------// #if SOC_SPI_SUPPORT_OCT static bool check_iomux_pins_oct(spi_host_device_t host, const spi_bus_config_t* bus_config) @@ -757,8 +755,6 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t * esp_err_t err = ESP_OK; spicommon_bus_context_t *ctx = NULL; spi_bus_attr_t *bus_attr = NULL; - uint32_t actual_tx_dma_chan = 0; - uint32_t actual_rx_dma_chan = 0; SPI_CHECK(is_valid_host(host_id), "invalid host_id", ESP_ERR_INVALID_ARG); SPI_CHECK(bus_ctx[host_id] == NULL, "SPI bus already initialized.", ESP_ERR_INVALID_STATE); @@ -791,35 +787,22 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t * if (dma_chan != SPI_DMA_DISABLED) { bus_attr->dma_enabled = 1; - err = alloc_dma_chan(host_id, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan); + err = spicommon_dma_chan_alloc(host_id, dma_chan, &ctx->dma_ctx); if (err != ESP_OK) { goto cleanup; } - bus_attr->tx_dma_chan = actual_tx_dma_chan; - bus_attr->rx_dma_chan = actual_rx_dma_chan; - - int dma_desc_ct = (bus_config->max_transfer_sz + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; - if (dma_desc_ct == 0) { - dma_desc_ct = 1; //default to 4k when max is not given - } - - bus_attr->max_transfer_sz = dma_desc_ct * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; - bus_attr->dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - bus_attr->dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - if (bus_attr->dmadesc_tx == NULL || bus_attr->dmadesc_rx == NULL) { - err = ESP_ERR_NO_MEM; + err = spicommon_dma_desc_alloc(ctx->dma_ctx, bus_config->max_transfer_sz, &bus_attr->max_transfer_sz); + if (err != ESP_OK) { goto cleanup; } - bus_attr->dma_desc_num = dma_desc_ct; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE - bus_attr->internal_mem_align_size = cache_hal_get_cache_line_size(CACHE_LL_LEVEL_INT_MEM, CACHE_TYPE_DATA); + esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_DMA, (size_t *)&bus_attr->internal_mem_align_size); #else bus_attr->internal_mem_align_size = 4; #endif } else { bus_attr->dma_enabled = 0; bus_attr->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE; - bus_attr->dma_desc_num = 0; } spi_bus_lock_config_t lock_config = { @@ -854,12 +837,11 @@ esp_err_t spi_bus_initialize(spi_host_device_t host_id, const spi_bus_config_t * if (bus_attr->lock) { spi_bus_deinit_lock(bus_attr->lock); } - free(bus_attr->dmadesc_tx); - free(bus_attr->dmadesc_rx); - bus_attr->dmadesc_tx = NULL; - bus_attr->dmadesc_rx = NULL; - if (bus_attr->dma_enabled) { - dma_chan_free(host_id); + if (ctx->dma_ctx) { + free(ctx->dma_ctx->dmadesc_tx); + free(ctx->dma_ctx->dmadesc_rx); + spicommon_dma_chan_free(ctx->dma_ctx); + ctx->dma_ctx = NULL; } } spicommon_periph_free(host_id); @@ -877,6 +859,15 @@ const spi_bus_attr_t* spi_bus_get_attr(spi_host_device_t host_id) return &bus_ctx[host_id]->bus_attr; } +const spi_dma_ctx_t* spi_bus_get_dma_ctx(spi_host_device_t host_id) +{ + if (bus_ctx[host_id] == NULL) { + return NULL; + } + + return bus_ctx[host_id]->dma_ctx; +} + esp_err_t spi_bus_free(spi_host_device_t host_id) { if (bus_ctx[host_id] == NULL) { @@ -890,19 +881,17 @@ esp_err_t spi_bus_free(spi_host_device_t host_id) if (ctx->destroy_func) { err = ctx->destroy_func(ctx->destroy_arg); } - spicommon_bus_free_io_cfg(&bus_attr->bus_cfg); #ifdef CONFIG_PM_ENABLE esp_pm_lock_delete(bus_attr->pm_lock); #endif spi_bus_deinit_lock(bus_attr->lock); - free(bus_attr->dmadesc_rx); - free(bus_attr->dmadesc_tx); - bus_attr->dmadesc_tx = NULL; - bus_attr->dmadesc_rx = NULL; - if (bus_attr->dma_enabled > 0) { - dma_chan_free(host_id); + if (ctx->dma_ctx) { + free(ctx->dma_ctx->dmadesc_tx); + free(ctx->dma_ctx->dmadesc_rx); + spicommon_dma_chan_free(ctx->dma_ctx); + ctx->dma_ctx = NULL; } spicommon_periph_free(host_id); free(ctx); diff --git a/components/esp_driver_spi/src/gpspi/spi_dma.c b/components/esp_driver_spi/src/gpspi/spi_dma.c new file mode 100644 index 000000000000..4d258602e6f3 --- /dev/null +++ b/components/esp_driver_spi/src/gpspi/spi_dma.c @@ -0,0 +1,47 @@ +/* + * SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#include "esp_private/spi_dma.h" +#include "hal/spi_ll.h" + +#if !SOC_GDMA_SUPPORTED +void spi_dma_enable_burst(spi_dma_chan_handle_t chan_handle, bool data_burst, bool desc_burst) +{ + spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id); + + if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) { + spi_dma_ll_tx_enable_burst_data(spi_dma, chan_handle.chan_id, data_burst); + spi_dma_ll_tx_enable_burst_desc(spi_dma, chan_handle.chan_id, desc_burst); + } else { + spi_dma_ll_rx_enable_burst_data(spi_dma, chan_handle.chan_id, data_burst); + spi_dma_ll_rx_enable_burst_desc(spi_dma, chan_handle.chan_id, desc_burst); + } +} + +/************************************* IRAM CONTEXT **************************************/ + +void spi_dma_reset(spi_dma_chan_handle_t chan_handle) +{ + spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id); + + if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) { + spi_dma_ll_tx_reset(spi_dma, chan_handle.chan_id); + } else { + spi_dma_ll_rx_reset(spi_dma, chan_handle.chan_id); + } +} + +void spi_dma_start(spi_dma_chan_handle_t chan_handle, void *addr) +{ + spi_dma_dev_t *spi_dma = SPI_LL_GET_HW(chan_handle.host_id); + + if (chan_handle.dir == DMA_CHANNEL_DIRECTION_TX) { + spi_dma_ll_tx_start(spi_dma, chan_handle.chan_id, (lldesc_t *)addr); + } else { + spi_dma_ll_rx_start(spi_dma, chan_handle.chan_id, (lldesc_t *)addr); + } +} +#endif diff --git a/components/esp_driver_spi/src/gpspi/spi_master.c b/components/esp_driver_spi/src/gpspi/spi_master.c index b29f55e9c93d..5ae4d1a803de 100644 --- a/components/esp_driver_spi/src/gpspi/spi_master.c +++ b/components/esp_driver_spi/src/gpspi/spi_master.c @@ -149,6 +149,7 @@ typedef struct { spi_trans_priv_t cur_trans_buf; int cur_cs; //current device doing transaction const spi_bus_attr_t* bus_attr; + const spi_dma_ctx_t *dma_ctx; /** * the bus is permanently controlled by a device until `spi_bus_release_bus`` is called. Otherwise @@ -221,6 +222,7 @@ static esp_err_t spi_master_init_driver(spi_host_device_t host_id) esp_err_t err = ESP_OK; const spi_bus_attr_t* bus_attr = spi_bus_get_attr(host_id); + const spi_dma_ctx_t *dma_ctx = spi_bus_get_dma_ctx(host_id); SPI_CHECK(bus_attr != NULL, "host_id not initialized", ESP_ERR_INVALID_STATE); SPI_CHECK(bus_attr->lock != NULL, "SPI Master cannot attach to bus. (Check CONFIG_SPI_FLASH_SHARE_SPI1_BUS)", ESP_ERR_INVALID_ARG); // spihost contains atomic variables, which should not be put in PSRAM @@ -236,6 +238,7 @@ static esp_err_t spi_master_init_driver(spi_host_device_t host_id) .polling = false, .device_acquiring_lock = NULL, .bus_attr = bus_attr, + .dma_ctx = dma_ctx, }; // interrupts are not allowed on SPI1 bus @@ -259,17 +262,24 @@ static esp_err_t spi_master_init_driver(spi_host_device_t host_id) } //assign the SPI, RX DMA and TX DMA peripheral registers beginning address - spi_hal_config_t hal_config = { + spi_hal_config_t hal_config = { .dma_enabled = bus_attr->dma_enabled, }; + if (bus_attr->dma_enabled && dma_ctx) { + hal_config.dmadesc_tx = dma_ctx->dmadesc_tx; + hal_config.dmadesc_rx = dma_ctx->dmadesc_rx; + hal_config.dmadesc_n = dma_ctx->dma_desc_num; +#if SOC_GDMA_SUPPORTED + //temporary used for gdma_ll alias in hal layer + gdma_get_channel_id(dma_ctx->tx_dma_chan, (int *)&hal_config.tx_dma_chan); + gdma_get_channel_id(dma_ctx->rx_dma_chan, (int *)&hal_config.rx_dma_chan); +#else //On ESP32-S2 and earlier chips, DMA registers are part of SPI registers. Pass the registers of SPI peripheral to control it. - .dma_in = SPI_LL_GET_HW(host_id), - .dma_out = SPI_LL_GET_HW(host_id), - .dma_enabled = bus_attr->dma_enabled, - .dmadesc_tx = bus_attr->dmadesc_tx, - .dmadesc_rx = bus_attr->dmadesc_rx, - .tx_dma_chan = bus_attr->tx_dma_chan, - .rx_dma_chan = bus_attr->rx_dma_chan, - .dmadesc_n = bus_attr->dma_desc_num, - }; + hal_config.dma_in = SPI_LL_GET_HW(host_id); + hal_config.dma_out = SPI_LL_GET_HW(host_id); + hal_config.tx_dma_chan = dma_ctx->tx_dma_chan.chan_id; + hal_config.rx_dma_chan = dma_ctx->rx_dma_chan.chan_id; +#endif + } + SPI_MASTER_PERI_CLOCK_ATOMIC() { spi_ll_enable_clock(host_id, true); } @@ -633,8 +643,8 @@ static void SPI_MASTER_ISR_ATTR spi_new_trans(spi_device_t *dev, spi_trans_priv_ spi_hal_trans_config_t hal_trans = {}; hal_trans.tx_bitlen = trans->length; hal_trans.rx_bitlen = trans->rxlength; - hal_trans.rcv_buffer = (uint8_t*)host->cur_trans_buf.buffer_to_rcv; - hal_trans.send_buffer = (uint8_t*)host->cur_trans_buf.buffer_to_send; + hal_trans.rcv_buffer = (uint8_t*)trans_buf->buffer_to_rcv; + hal_trans.send_buffer = (uint8_t*)trans_buf->buffer_to_send; hal_trans.cmd = trans->cmd; hal_trans.addr = trans->addr; hal_trans.cs_keep_active = (trans->flags & SPI_TRANS_CS_KEEP_ACTIVE) ? 1 : 0; @@ -699,6 +709,10 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) BaseType_t do_yield = pdFALSE; spi_host_t *host = (spi_host_t *)arg; const spi_bus_attr_t* bus_attr = host->bus_attr; +#if CONFIG_IDF_TARGET_ESP32 + //only for esp32 dma workaround usage + const spi_dma_ctx_t *dma_ctx = host->dma_ctx; +#endif assert(spi_hal_usr_is_done(&host->hal)); @@ -720,7 +734,7 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) if (bus_attr->dma_enabled) { #if CONFIG_IDF_TARGET_ESP32 //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same - spicommon_dmaworkaround_idle(bus_attr->tx_dma_chan); + spicommon_dmaworkaround_idle(dma_ctx->tx_dma_chan.chan_id); #endif //#if CONFIG_IDF_TARGET_ESP32 #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE //invalidate here to let user access rx data in post_cb if possible @@ -793,7 +807,7 @@ static void SPI_MASTER_ISR_ATTR spi_intr(void *arg) if (bus_attr->dma_enabled && (cur_trans_buf->buffer_to_rcv || cur_trans_buf->buffer_to_send)) { //mark channel as active, so that the DMA will not be reset by the slave //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same - spicommon_dmaworkaround_transfer_active(bus_attr->tx_dma_chan); + spicommon_dmaworkaround_transfer_active(dma_ctx->tx_dma_chan.chan_id); } #endif //#if CONFIG_IDF_TARGET_ESP32 spi_new_trans(device_to_send, cur_trans_buf); @@ -1081,7 +1095,7 @@ esp_err_t SPI_MASTER_ISR_ATTR spi_device_acquire_bus(spi_device_t *device, TickT #if CONFIG_IDF_TARGET_ESP32 if (host->bus_attr->dma_enabled) { //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same - spicommon_dmaworkaround_transfer_active(host->bus_attr->tx_dma_chan); + spicommon_dmaworkaround_transfer_active(host->dma_ctx->tx_dma_chan.chan_id); } #endif //#if CONFIG_IDF_TARGET_ESP32 @@ -1101,7 +1115,7 @@ void SPI_MASTER_ISR_ATTR spi_device_release_bus(spi_device_t *dev) #if CONFIG_IDF_TARGET_ESP32 if (host->bus_attr->dma_enabled) { //This workaround is only for esp32, where tx_dma_chan and rx_dma_chan are always same - spicommon_dmaworkaround_idle(host->bus_attr->tx_dma_chan); + spicommon_dmaworkaround_idle(host->dma_ctx->tx_dma_chan.chan_id); } //Tell common code DMA workaround that our DMA channel is idle. If needed, the code will do a DMA reset. #endif //#if CONFIG_IDF_TARGET_ESP32 diff --git a/components/esp_driver_spi/src/gpspi/spi_slave.c b/components/esp_driver_spi/src/gpspi/spi_slave.c index 14dbe4ecadc0..7c7f00932eb4 100644 --- a/components/esp_driver_spi/src/gpspi/spi_slave.c +++ b/components/esp_driver_spi/src/gpspi/spi_slave.c @@ -59,6 +59,7 @@ typedef struct { typedef struct { int id; spi_bus_config_t bus_config; + spi_dma_ctx_t *dma_ctx; spi_slave_interface_config_t cfg; intr_handle_t intr; spi_slave_hal_context_t hal; @@ -72,8 +73,6 @@ typedef struct { bool cs_iomux; uint8_t cs_in_signal; uint16_t internal_mem_align_size; - uint32_t tx_dma_chan; - uint32_t rx_dma_chan; #ifdef CONFIG_PM_ENABLE esp_pm_lock_handle_t pm_lock; #endif @@ -133,8 +132,6 @@ static void ipc_isr_reg_to_core(void *args) esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *bus_config, const spi_slave_interface_config_t *slave_config, spi_dma_chan_t dma_chan) { bool spi_chan_claimed; - uint32_t actual_tx_dma_chan = 0; - uint32_t actual_rx_dma_chan = 0; esp_err_t ret = ESP_OK; esp_err_t err; SPI_CHECK(is_valid_host(host), "invalid host", ESP_ERR_INVALID_ARG); @@ -172,19 +169,27 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b spihost[host]->dma_enabled = (dma_chan != SPI_DMA_DISABLED); if (spihost[host]->dma_enabled) { - ret = spicommon_dma_chan_alloc(host, dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan); + ret = spicommon_dma_chan_alloc(host, dma_chan, &spihost[host]->dma_ctx); if (ret != ESP_OK) { goto cleanup; } - spihost[host]->tx_dma_chan = actual_tx_dma_chan; - spihost[host]->rx_dma_chan = actual_rx_dma_chan; - - //See how many dma descriptors we need and allocate them - int dma_desc_ct = (bus_config->max_transfer_sz + SPI_MAX_DMA_LEN - 1) / SPI_MAX_DMA_LEN; - if (dma_desc_ct == 0) { - dma_desc_ct = 1; //default to 4k when max is not given + ret = spicommon_dma_desc_alloc(spihost[host]->dma_ctx, bus_config->max_transfer_sz, &spihost[host]->max_transfer_sz); + if (ret != ESP_OK) { + goto cleanup; } - spihost[host]->max_transfer_sz = dma_desc_ct * SPI_MAX_DMA_LEN; + + hal->dmadesc_tx = spihost[host]->dma_ctx->dmadesc_tx; + hal->dmadesc_rx = spihost[host]->dma_ctx->dmadesc_rx; + hal->dmadesc_n = spihost[host]->dma_ctx->dma_desc_num; +#if SOC_GDMA_SUPPORTED + //temporary used for gdma_ll alias in hal layer + gdma_get_channel_id(spihost[host]->dma_ctx->tx_dma_chan, (int *)&hal->tx_dma_chan); + gdma_get_channel_id(spihost[host]->dma_ctx->rx_dma_chan, (int *)&hal->rx_dma_chan); +#else + hal->tx_dma_chan = spihost[host]->dma_ctx->tx_dma_chan.chan_id; + hal->rx_dma_chan = spihost[host]->dma_ctx->rx_dma_chan.chan_id; +#endif + #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE size_t alignment; esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_DMA, &alignment); @@ -192,14 +197,6 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b #else spihost[host]->internal_mem_align_size = 4; #endif - - hal->dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - hal->dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - if (!hal->dmadesc_tx || !hal->dmadesc_rx) { - ret = ESP_ERR_NO_MEM; - goto cleanup; - } - hal->dmadesc_n = dma_desc_ct; } else { //We're limited to non-DMA transfers: the SPI work registers can hold 64 bytes at most. spihost[host]->max_transfer_sz = SOC_SPI_MAXIMUM_BUFFER_SIZE; @@ -278,9 +275,6 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b hal->tx_lsbfirst = (slave_config->flags & SPI_SLAVE_TXBIT_LSBFIRST) ? 1 : 0; hal->mode = slave_config->mode; hal->use_dma = spihost[host]->dma_enabled; - hal->tx_dma_chan = actual_tx_dma_chan; - hal->rx_dma_chan = actual_rx_dma_chan; - spi_slave_hal_setup_device(hal); return ESP_OK; @@ -301,9 +295,9 @@ esp_err_t spi_slave_initialize(spi_host_device_t host, const spi_bus_config_t *b } spi_slave_hal_deinit(&spihost[host]->hal); if (spihost[host]->dma_enabled) { - spicommon_dma_chan_free(host); - free(spihost[host]->hal.dmadesc_tx); - free(spihost[host]->hal.dmadesc_rx); + free(spihost[host]->dma_ctx->dmadesc_tx); + free(spihost[host]->dma_ctx->dmadesc_rx); + spicommon_dma_chan_free(spihost[host]->dma_ctx); } free(spihost[host]); @@ -324,9 +318,9 @@ esp_err_t spi_slave_free(spi_host_device_t host) vQueueDelete(spihost[host]->ret_queue); } if (spihost[host]->dma_enabled) { - spicommon_dma_chan_free(host); - free(spihost[host]->hal.dmadesc_tx); - free(spihost[host]->hal.dmadesc_rx); + free(spihost[host]->dma_ctx->dmadesc_tx); + free(spihost[host]->dma_ctx->dmadesc_rx); + spicommon_dma_chan_free(spihost[host]->dma_ctx); } spicommon_bus_free_io_cfg(&spihost[host]->bus_config); esp_intr_free(spihost[host]->intr); @@ -586,7 +580,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) //This workaround is only for esp32 if (spi_slave_hal_dma_need_reset(hal)) { //On ESP32, actual_tx_dma_chan and actual_rx_dma_chan are always same - spicommon_dmaworkaround_req_reset(host->tx_dma_chan, spi_slave_restart_after_dmareset, host); + spicommon_dmaworkaround_req_reset(host->dma_ctx->tx_dma_chan.chan_id, spi_slave_restart_after_dmareset, host); } #endif //#if CONFIG_IDF_TARGET_ESP32 @@ -614,7 +608,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) //This workaround is only for esp32 if (use_dma) { //On ESP32, actual_tx_dma_chan and actual_rx_dma_chan are always same - spicommon_dmaworkaround_idle(host->tx_dma_chan); + spicommon_dmaworkaround_idle(host->dma_ctx->tx_dma_chan.chan_id); if (spicommon_dmaworkaround_reset_in_progress()) { //We need to wait for the reset to complete. Disable int (will be re-enabled on reset callback) and exit isr. esp_intr_disable(host->intr); @@ -649,7 +643,7 @@ static void SPI_SLAVE_ISR_ATTR spi_intr(void *arg) if (use_dma) { //This workaround is only for esp32 //On ESP32, actual_tx_dma_chan and actual_rx_dma_chan are always same - spicommon_dmaworkaround_transfer_active(host->tx_dma_chan); + spicommon_dmaworkaround_transfer_active(host->dma_ctx->tx_dma_chan.chan_id); } #endif //#if CONFIG_IDF_TARGET_ESP32 diff --git a/components/esp_driver_spi/src/gpspi/spi_slave_hd.c b/components/esp_driver_spi/src/gpspi/spi_slave_hd.c index cdc8f7fd429a..2138db26c0c8 100644 --- a/components/esp_driver_spi/src/gpspi/spi_slave_hd.c +++ b/components/esp_driver_spi/src/gpspi/spi_slave_hd.c @@ -36,15 +36,12 @@ typedef struct { typedef struct { bool dma_enabled; + spi_dma_ctx_t *dma_ctx; uint16_t internal_mem_align_size; int max_transfer_sz; uint32_t flags; portMUX_TYPE int_spinlock; intr_handle_t intr; -#if SOC_GDMA_SUPPORTED - gdma_channel_handle_t gdma_handle_tx; //varible for storge gdma handle - gdma_channel_handle_t gdma_handle_rx; -#endif intr_handle_t intr_dma; spi_slave_hd_callback_config_t callback; spi_slave_hd_hal_context_t hal; @@ -74,13 +71,10 @@ static bool spi_gdma_tx_channel_callback(gdma_channel_handle_t dma_chan, gdma_ev static void spi_slave_hd_intr_append(void *arg); static void spi_slave_hd_intr_segment(void *arg); -esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *bus_config, - const spi_slave_hd_slot_config_t *config) +esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *bus_config, const spi_slave_hd_slot_config_t *config) { bool spi_chan_claimed; bool append_mode = (config->flags & SPI_SLAVE_HD_APPEND_MODE); - uint32_t actual_tx_dma_chan = 0; - uint32_t actual_rx_dma_chan = 0; esp_err_t ret = ESP_OK; SPIHD_CHECK(VALID_HOST(host_id), "invalid host", ESP_ERR_INVALID_ARG); @@ -104,34 +98,28 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b host->append_mode = append_mode; if (host->dma_enabled) { - ret = spicommon_dma_chan_alloc(host_id, config->dma_chan, &actual_tx_dma_chan, &actual_rx_dma_chan); + ret = spicommon_dma_chan_alloc(host_id, config->dma_chan, &host->dma_ctx); if (ret != ESP_OK) { goto cleanup; } - - //Malloc for all the DMA descriptors - int dma_desc_ct = (bus_config->max_transfer_sz + DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED - 1) / DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; - if (dma_desc_ct == 0) { - dma_desc_ct = 1; //default to 4k when max is not given + ret = spicommon_dma_desc_alloc(host->dma_ctx, bus_config->max_transfer_sz, &host->max_transfer_sz); + if (ret != ESP_OK) { + goto cleanup; } - host->hal.dma_desc_num = dma_desc_ct; - spi_dma_desc_t *orig_dmadesc_tx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - spi_dma_desc_t *orig_dmadesc_rx = heap_caps_aligned_alloc(DMA_DESC_MEM_ALIGN_SIZE, sizeof(spi_dma_desc_t) * dma_desc_ct, MALLOC_CAP_DMA); - host->hal.dmadesc_tx = heap_caps_malloc(sizeof(spi_slave_hd_hal_desc_append_t) * dma_desc_ct, MALLOC_CAP_DEFAULT); - host->hal.dmadesc_rx = heap_caps_malloc(sizeof(spi_slave_hd_hal_desc_append_t) * dma_desc_ct, MALLOC_CAP_DEFAULT); - if (!(host->hal.dmadesc_tx && host->hal.dmadesc_rx && orig_dmadesc_tx && orig_dmadesc_rx)) { + host->hal.dma_desc_num = host->dma_ctx->dma_desc_num; + host->hal.dmadesc_tx = heap_caps_malloc(sizeof(spi_slave_hd_hal_desc_append_t) * host->hal.dma_desc_num, MALLOC_CAP_DEFAULT); + host->hal.dmadesc_rx = heap_caps_malloc(sizeof(spi_slave_hd_hal_desc_append_t) * host->hal.dma_desc_num, MALLOC_CAP_DEFAULT); + if (!(host->hal.dmadesc_tx && host->hal.dmadesc_rx)) { ret = ESP_ERR_NO_MEM; goto cleanup; } //Pair each desc to each possible trans - for (int i = 0; i < dma_desc_ct; i ++) { - host->hal.dmadesc_tx[i].desc = &orig_dmadesc_tx[i]; - host->hal.dmadesc_rx[i].desc = &orig_dmadesc_rx[i]; + for (int i = 0; i < host->hal.dma_desc_num; i ++) { + host->hal.dmadesc_tx[i].desc = &host->dma_ctx->dmadesc_tx[i]; + host->hal.dmadesc_rx[i].desc = &host->dma_ctx->dmadesc_rx[i]; } - //Get the actual SPI bus transaction size in bytes. - host->max_transfer_sz = dma_desc_ct * DMA_DESCRIPTOR_BUFFER_MAX_SIZE_4B_ALIGNED; #if SOC_CACHE_INTERNAL_MEM_VIA_L1CACHE size_t alignment; esp_cache_get_alignment(ESP_CACHE_MALLOC_FLAG_DMA, &alignment); @@ -156,14 +144,21 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b .dma_in = SPI_LL_GET_HW(host_id), .dma_out = SPI_LL_GET_HW(host_id), .dma_enabled = host->dma_enabled, - .tx_dma_chan = actual_tx_dma_chan, - .rx_dma_chan = actual_rx_dma_chan, .append_mode = append_mode, .mode = config->mode, .tx_lsbfirst = (config->flags & SPI_SLAVE_HD_RXBIT_LSBFIRST), .rx_lsbfirst = (config->flags & SPI_SLAVE_HD_TXBIT_LSBFIRST), }; +#if SOC_GDMA_SUPPORTED + //temporary used for gdma_ll alias in hal layer + gdma_get_channel_id(host->dma_ctx->tx_dma_chan, (int *)&hal_config.tx_dma_chan); + gdma_get_channel_id(host->dma_ctx->rx_dma_chan, (int *)&hal_config.rx_dma_chan); +#else + hal_config.tx_dma_chan = host->dma_ctx->tx_dma_chan.chan_id; + hal_config.rx_dma_chan = host->dma_ctx->rx_dma_chan.chan_id; +#endif + //Init the hal according to the hal_config set above spi_slave_hd_hal_init(&host->hal, &hal_config); @@ -219,11 +214,10 @@ esp_err_t spi_slave_hd_init(spi_host_device_t host_id, const spi_bus_config_t *b } #if SOC_GDMA_SUPPORTED // config gmda and ISR callback for gdma supported chip - spicommon_gdma_get_handle(host_id, &host->gdma_handle_tx, GDMA_CHANNEL_DIRECTION_TX); gdma_tx_event_callbacks_t tx_cbs = { .on_trans_eof = spi_gdma_tx_channel_callback }; - gdma_register_tx_event_callbacks(host->gdma_handle_tx, &tx_cbs, host); + gdma_register_tx_event_callbacks(host->dma_ctx->tx_dma_chan, &tx_cbs, host); #else ret = esp_intr_alloc(spicommon_irqdma_source_for_host(host_id), 0, spi_slave_hd_intr_append, (void *)host, &host->intr_dma); @@ -293,11 +287,11 @@ esp_err_t spi_slave_hd_deinit(spi_host_device_t host_id) spicommon_periph_free(host_id); if (host->dma_enabled) { - free(host->hal.dmadesc_tx->desc); - free(host->hal.dmadesc_rx->desc); + free(host->dma_ctx->dmadesc_tx); + free(host->dma_ctx->dmadesc_rx); free(host->hal.dmadesc_tx); free(host->hal.dmadesc_rx); - spicommon_dma_chan_free(host_id); + spicommon_dma_chan_free(host->dma_ctx); } free(host); spihost[host_id] = NULL; diff --git a/components/esp_driver_spi/test_apps/spi/slave_hd/main/test_spi_slave_hd.c b/components/esp_driver_spi/test_apps/spi/slave_hd/main/test_spi_slave_hd.c index c790d9b0d107..00622e78b86f 100644 --- a/components/esp_driver_spi/test_apps/spi/slave_hd/main/test_spi_slave_hd.c +++ b/components/esp_driver_spi/test_apps/spi/slave_hd/main/test_spi_slave_hd.c @@ -908,8 +908,8 @@ TEST_CASE_MULTIPLE_DEVICES("SPI quad hd test ", "[spi_ms][test_env=generic_multi #endif // #if !TEMPORARY_DISABLED_FOR_TARGETS(ESP32S2) //***************************************TEST FOR APPEND MODE******************************************// -#define TEST_APPEND_CACHE_SIZE 4 -#define TEST_TRANS_LEN TEST_DMA_MAX_SIZE +#define TEST_APPEND_NUM 4 +#define TEST_TRANS_LEN TEST_DMA_MAX_SIZE void prepare_data(uint8_t *buff, uint32_t len, int8_t diff) { @@ -930,20 +930,20 @@ void slave_run_append(void) TEST_ESP_OK(spi_slave_hd_init(TEST_SPI_HOST, &bus_cfg, &slave_hd_cfg)); unity_wait_for_signal("Master ready"); - spi_slave_hd_data_t *ret_trans, slave_rx_trans[TEST_APPEND_CACHE_SIZE] = {}; + spi_slave_hd_data_t *ret_trans, slave_rx_trans[TEST_APPEND_NUM] = {}; uint8_t *slave_exp = heap_caps_malloc(TEST_TRANS_LEN, MALLOC_CAP_DEFAULT); // append some data first - for (uint32_t cache_instans = 0; cache_instans < TEST_APPEND_CACHE_SIZE; cache_instans++) { - int trans_len = 16 << (cache_instans + 1); + for (uint32_t append_idx = 0; append_idx < TEST_APPEND_NUM; append_idx++) { + int trans_len = 16 << (append_idx + 1); if (trans_len > TEST_TRANS_LEN) { trans_len = TEST_TRANS_LEN; } - slave_rx_trans[cache_instans].data = heap_caps_calloc(1, TEST_TRANS_LEN, MALLOC_CAP_DMA); - TEST_ASSERT_NOT_NULL(slave_rx_trans[cache_instans].data); - slave_rx_trans[cache_instans].len = trans_len; - TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, &slave_rx_trans[cache_instans], portMAX_DELAY)); + slave_rx_trans[append_idx].data = heap_caps_aligned_calloc(4, 1, TEST_TRANS_LEN, MALLOC_CAP_DMA); + TEST_ASSERT_NOT_NULL(slave_rx_trans[append_idx].data); + slave_rx_trans[append_idx].len = trans_len; + TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_RX, &slave_rx_trans[append_idx], portMAX_DELAY)); } for (int trans_num = 1; trans_num <= 8; trans_num ++) { @@ -960,7 +960,7 @@ void slave_run_append(void) ESP_LOG_BUFFER_HEX_LEVEL("slave exp", slave_exp, trans_len, ESP_LOG_DEBUG); spitest_cmp_or_dump(slave_exp, ret_trans->data, trans_len); - if (trans_num <= TEST_APPEND_CACHE_SIZE) { + if (trans_num <= TEST_APPEND_NUM) { // append one more transaction int new_append_len = trans_len << 4; if (new_append_len > TEST_TRANS_LEN) { @@ -976,16 +976,16 @@ void slave_run_append(void) free(slave_exp); //------------------------------------tx direction------------------------------ - spi_slave_hd_data_t slave_tx_trans[TEST_APPEND_CACHE_SIZE] = {}; - for (uint32_t cache_instans = 0; cache_instans < TEST_APPEND_CACHE_SIZE; cache_instans ++) { - int trans_len = 16 << (cache_instans + 1); + spi_slave_hd_data_t slave_tx_trans[TEST_APPEND_NUM] = {}; + for (uint32_t append_idx = 0; append_idx < TEST_APPEND_NUM; append_idx ++) { + int trans_len = 16 << (append_idx + 1); if (trans_len >= TEST_TRANS_LEN) { trans_len = TEST_TRANS_LEN; } - slave_tx_trans[cache_instans].data = slave_rx_trans[cache_instans].data; - slave_tx_trans[cache_instans].len = trans_len; - prepare_data(slave_tx_trans[cache_instans].data, trans_len, -3); - TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &slave_tx_trans[cache_instans], portMAX_DELAY)); + slave_tx_trans[append_idx].data = slave_rx_trans[append_idx].data; + slave_tx_trans[append_idx].len = trans_len; + prepare_data(slave_tx_trans[append_idx].data, trans_len, -3); + TEST_ESP_OK(spi_slave_hd_append_trans(TEST_SPI_HOST, SPI_SLAVE_CHAN_TX, &slave_tx_trans[append_idx], portMAX_DELAY)); } //Get one result and load a new transaction @@ -995,7 +995,7 @@ void slave_run_append(void) ESP_LOGI("slave", "trasacted len: %d", ret_trans->len); ESP_LOG_BUFFER_HEX_LEVEL("slave tx", ret_trans->data, ret_trans->len, ESP_LOG_DEBUG); - if (trans_num <= TEST_APPEND_CACHE_SIZE) { + if (trans_num <= TEST_APPEND_NUM) { // append one more transaction int new_append_len = 16 << (trans_num + 4); if (new_append_len > TEST_TRANS_LEN) { @@ -1008,7 +1008,7 @@ void slave_run_append(void) } } printf("================Master Rx Done==================\n"); - for (int i = 0; i < TEST_APPEND_CACHE_SIZE; i++) { + for (int i = 0; i < TEST_APPEND_NUM; i++) { free(slave_tx_trans[i].data); } diff --git a/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py b/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py index 5af7f940f43a..bf7e71df17a1 100644 --- a/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py +++ b/components/esp_driver_tsens/test_apps/temperature_sensor/pytest_temperature_sensor.py @@ -2,8 +2,8 @@ # SPDX-License-Identifier: CC0-1.0 import pytest -from idf_unity_tester import CaseTester from pytest_embedded import Dut +from pytest_embedded_idf.unity_tester import CaseTester @pytest.mark.esp32s2 diff --git a/components/esp_hw_support/Kconfig b/components/esp_hw_support/Kconfig index e7a36c540a25..aa379e8edc47 100644 --- a/components/esp_hw_support/Kconfig +++ b/components/esp_hw_support/Kconfig @@ -50,6 +50,13 @@ menu "Hardware Settings" If you have an invalid MAC CRC (ESP_ERR_INVALID_CRC) problem and you still want to use this chip, you can enable this option to bypass such an error. This applies to both MAC_FACTORY and CUSTOM_MAC efuses. + + config ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC + bool "Enable using custom mac as base mac" + default n + help + When this configuration is enabled, the user can invoke `esp_read_mac` to obtain the desired type of + MAC using a custom MAC as the base MAC. endmenu menu "Sleep Config" @@ -341,6 +348,16 @@ menu "Hardware Settings" clock support isn't done yet. So with this option, we use xtal on FPGA as the clock source. + # Invisible bringup bypass options for esp_hw_support component + config ESP_BRINGUP_BYPASS_RANDOM_SETTING + bool + default y if !SOC_RNG_SUPPORTED + default n + help + This option is only used for new chip bringup, when + RNG isn't done yet. So with this option, we use 0x5A + to fill the random buffers + config ESP_SPI_BUS_LOCK_ISR_FUNCS_IN_IRAM bool default n diff --git a/components/esp_hw_support/mac_addr.c b/components/esp_hw_support/mac_addr.c index c917b57c1091..a73f40e8e6e3 100644 --- a/components/esp_hw_support/mac_addr.c +++ b/components/esp_hw_support/mac_addr.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -63,7 +63,7 @@ static mac_t s_mac_table[] = { #define ITEMS_IN_MAC_TABLE (sizeof(s_mac_table) / sizeof(mac_t)) static esp_err_t generate_mac(uint8_t *mac, uint8_t *base_mac_addr, esp_mac_type_t type); -static esp_err_t get_efuse_mac_get_default(uint8_t *mac); +static esp_err_t get_efuse_factory_mac(uint8_t *mac); static esp_err_t get_efuse_mac_custom(uint8_t *mac); #if CONFIG_SOC_IEEE802154_SUPPORTED static esp_err_t get_efuse_mac_ext(uint8_t *mac); @@ -89,11 +89,19 @@ static esp_err_t get_mac_addr_from_mac_table(uint8_t *mac, int idx, bool silent) esp_mac_type_t type = s_mac_table[idx].type; if (ESP_MAC_BASE <= type && type <= ESP_MAC_EFUSE_EXT) { esp_err_t err = ESP_OK; - if (type == ESP_MAC_BASE || type == ESP_MAC_EFUSE_FACTORY) { - err = get_efuse_mac_get_default(s_mac_table[idx].mac); - } else if (type == ESP_MAC_EFUSE_CUSTOM) { - err = get_efuse_mac_custom(s_mac_table[idx].mac); - } + if (type == ESP_MAC_EFUSE_FACTORY +#ifndef CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC + || type == ESP_MAC_BASE +#endif + ) { + err = get_efuse_factory_mac(s_mac_table[idx].mac); + } else if (type == ESP_MAC_EFUSE_CUSTOM +#ifdef CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC + || type == ESP_MAC_BASE +#endif + ) { + err = get_efuse_mac_custom(s_mac_table[idx].mac); + } #if CONFIG_SOC_IEEE802154_SUPPORTED else if (type == ESP_MAC_EFUSE_EXT) { err = get_efuse_mac_ext(s_mac_table[idx].mac); @@ -246,7 +254,7 @@ static esp_err_t get_efuse_mac_custom(uint8_t *mac) esp_err_t esp_efuse_mac_get_default(uint8_t *mac) { - esp_err_t err = get_efuse_mac_get_default(mac); + esp_err_t err = get_efuse_factory_mac(mac); if (err != ESP_OK) { return err; } @@ -257,7 +265,7 @@ esp_err_t esp_efuse_mac_get_default(uint8_t *mac) #endif } -static esp_err_t get_efuse_mac_get_default(uint8_t *mac) +static esp_err_t get_efuse_factory_mac(uint8_t *mac) { size_t size_bits = esp_efuse_get_field_size(ESP_EFUSE_MAC_FACTORY); assert((size_bits % 8) == 0); diff --git a/components/esp_netif/lwip/esp_netif_lwip.c b/components/esp_netif/lwip/esp_netif_lwip.c index 311462b96be4..7f51aed896e2 100644 --- a/components/esp_netif/lwip/esp_netif_lwip.c +++ b/components/esp_netif/lwip/esp_netif_lwip.c @@ -2315,10 +2315,7 @@ esp_err_t esp_netif_dhcps_option_api(esp_netif_api_msg_t *msg) if ((end_ip - start_ip + 1 > DHCPS_MAX_LEASE) || (start_ip >= end_ip)) { return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } - } else { - return ESP_ERR_ESP_NETIF_INVALID_PARAMS; } - memcpy(opt_info, opt->val, opt->len); break; } diff --git a/components/esp_psram/Kconfig.spiram.common b/components/esp_psram/Kconfig.spiram.common index 9cce77667c8f..dd584a55b41a 100644 --- a/components/esp_psram/Kconfig.spiram.common +++ b/components/esp_psram/Kconfig.spiram.common @@ -13,11 +13,19 @@ config SPIRAM_BOOT_INIT config SPIRAM_IGNORE_NOTFOUND bool "Ignore PSRAM when not found" default "n" - depends on SPIRAM_BOOT_INIT && !SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY + depends on SPIRAM_BOOT_INIT && !SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY && !SPIRAM_ALLOW_NOINIT_SEG_EXTERNAL_MEMORY help Normally, if psram initialization is enabled during compile time but not found at runtime, it is seen as an error making the CPU panic. If this is enabled, booting will complete - but no PSRAM will be available. + but no PSRAM will be available. If PSRAM failed to initialize, the following configs may be affected + and may need to be corrected manually. SPIRAM_TRY_ALLOCATE_WIFI_LWIP will affect some LWIP and WiFi buffer + default values and range values. Enable SPIRAM_TRY_ALLOCATE_WIFI_LWIP, ESP_WIFI_AMSDU_TX_ENABLED, + ESP_WIFI_CACHE_TX_BUFFER_NUM and use static WiFi Tx buffer may cause potential memory exhaustion issues. + Suggest disable SPIRAM_TRY_ALLOCATE_WIFI_LWIP. + Suggest disable ESP_WIFI_AMSDU_TX_ENABLED. + Suggest disable ESP_WIFI_CACHE_TX_BUFFER_NUM, need clear CONFIG_FEATURE_CACHE_TX_BUF_BIT of config->feature_caps. + Suggest change ESP_WIFI_TX_BUFFER from static to dynamic. Also suggest to adjust some buffer numbers to the + values used without PSRAM case. Such as, ESP_WIFI_STATIC_TX_BUFFER_NUM, ESP_WIFI_DYNAMIC_TX_BUFFER_NUM. choice SPIRAM_USE prompt "SPI RAM access method" diff --git a/components/esp_rom/CMakeLists.txt b/components/esp_rom/CMakeLists.txt index 7775cde4a6b3..de6d90dcae44 100644 --- a/components/esp_rom/CMakeLists.txt +++ b/components/esp_rom/CMakeLists.txt @@ -22,7 +22,7 @@ else() # Override regi2c implementation in ROM if(CONFIG_ESP_ROM_HAS_REGI2C_BUG OR CONFIG_ESP_ROM_WITHOUT_REGI2C) - if(target STREQUAL "esp32c6") + if(target STREQUAL "esp32c6" OR target STREQUAL "esp32c5") list(APPEND sources "patches/esp_rom_hp_regi2c_${target}.c") else() list(APPEND sources "patches/esp_rom_regi2c_${target}.c") @@ -123,6 +123,9 @@ if(BOOTLOADER_BUILD) endif() rom_linker_script("version") + elseif(target STREQUAL "esp32c5") + rom_linker_script("newlib") + elseif(target STREQUAL "esp32h2") rom_linker_script("newlib") if(CONFIG_HAL_WDT_USE_ROM_IMPL) @@ -243,6 +246,7 @@ else() # Regular app build rom_linker_script("version") # esp32c6.rom.api.ld has been split to several lds by components. + # esp32c6.rom.api.ld is still reserved to map the APIs rom_linker_script("phy") rom_linker_script("coexist") rom_linker_script("net80211") @@ -261,6 +265,21 @@ else() # Regular app build rom_linker_script("newlib-normal") endif() + elseif(target STREQUAL "esp32c5") + rom_linker_script("newlib") + rom_linker_script("version") + + # esp32c5.rom.api.ld has been split to several lds by components. + # esp32c5.rom.api.ld is still reserved to map the APIs + if(CONFIG_SPI_FLASH_ROM_IMPL) + rom_linker_script("spiflash") + endif() + + if(NOT CONFIG_NEWLIB_NANO_FORMAT) + # Normal(Non-nano) formatting functions in ROM are also built for 64-bit time_t. + rom_linker_script("newlib-normal") + endif() + elseif(target STREQUAL "esp32h2") rom_linker_script("newlib") rom_linker_script("version") diff --git a/components/esp_rom/esp32c5/.gitkeep b/components/esp_rom/esp32c5/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/components/esp_rom/esp32c5/Kconfig.soc_caps.in b/components/esp_rom/esp32c5/Kconfig.soc_caps.in new file mode 100644 index 000000000000..62c92152b0fa --- /dev/null +++ b/components/esp_rom/esp32c5/Kconfig.soc_caps.in @@ -0,0 +1,80 @@ +##################################################### +# This file is auto-generated from SoC caps +# using gen_soc_caps_kconfig.py, do not edit manually +##################################################### + +config ESP_ROM_HAS_CRC_LE + bool + default y + +config ESP_ROM_HAS_CRC_BE + bool + default y + +config ESP_ROM_HAS_JPEG_DECODE + bool + default y + +config ESP_ROM_UART_CLK_IS_XTAL + bool + default y + +config ESP_ROM_USB_SERIAL_DEVICE_NUM + int + default 3 + +config ESP_ROM_HAS_RETARGETABLE_LOCKING + bool + default y + +config ESP_ROM_GET_CLK_FREQ + bool + default y + +config ESP_ROM_HAS_RVFPLIB + bool + default y + +config ESP_ROM_HAS_HAL_WDT + bool + default y + +config ESP_ROM_HAS_HAL_SYSTIMER + bool + default y + +config ESP_ROM_HAS_HEAP_TLSF + bool + default y + +config ESP_ROM_TLSF_CHECK_PATCH + bool + default y + +config ESP_ROM_HAS_LAYOUT_TABLE + bool + default y + +config ESP_ROM_HAS_SPI_FLASH + bool + default y + +config ESP_ROM_WITHOUT_REGI2C + bool + default y + +config ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT + bool + default y + +config ESP_ROM_REV0_HAS_NO_ECDSA_INTERFACE + bool + default y + +config ESP_ROM_WDT_INIT_PATCH + bool + default y + +config ESP_ROM_RAM_APP_NEEDS_MMU_INIT + bool + default y diff --git a/components/esp_rom/esp32c5/esp_rom_caps.h b/components/esp_rom/esp32c5/esp_rom_caps.h new file mode 100644 index 000000000000..f6fd8b12f19d --- /dev/null +++ b/components/esp_rom/esp32c5/esp_rom_caps.h @@ -0,0 +1,27 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#define ESP_ROM_HAS_CRC_LE (1) // ROM CRC library supports Little Endian +#define ESP_ROM_HAS_CRC_BE (1) // ROM CRC library supports Big Endian +#define ESP_ROM_HAS_JPEG_DECODE (1) // ROM has JPEG decode library +#define ESP_ROM_UART_CLK_IS_XTAL (1) // UART clock source is selected to XTAL in ROM +#define ESP_ROM_USB_SERIAL_DEVICE_NUM (3) // UART uses USB_SERIAL_JTAG port in ROM. +#define ESP_ROM_HAS_RETARGETABLE_LOCKING (1) // ROM was built with retargetable locking +#define ESP_ROM_GET_CLK_FREQ (1) // Get clk frequency with rom function `ets_get_cpu_frequency` +#define ESP_ROM_HAS_RVFPLIB (1) // ROM has the rvfplib +#define ESP_ROM_HAS_HAL_WDT (1) // ROM has the implementation of Watchdog HAL driver +#define ESP_ROM_HAS_HAL_SYSTIMER (1) // ROM has the implementation of Systimer HAL driver +#define ESP_ROM_HAS_HEAP_TLSF (1) // ROM has the implementation of the tlsf and multi-heap library +#define ESP_ROM_TLSF_CHECK_PATCH (1) // ROM does not contain the patch of tlsf_check_pool() +#define ESP_ROM_HAS_LAYOUT_TABLE (1) // ROM has the layout table +#define ESP_ROM_HAS_SPI_FLASH (1) // ROM has the implementation of SPI Flash driver +#define ESP_ROM_WITHOUT_REGI2C (1) // ROM has no regi2c APIs +#define ESP_ROM_HAS_NEWLIB_NORMAL_FORMAT (1) // ROM has the newlib normal/full version of formatting functions (as opposed to the nano versions) +#define ESP_ROM_REV0_HAS_NO_ECDSA_INTERFACE (1) // ECO 0 does not have ets_ecdsa_verify symbol, future revision will have it +#define ESP_ROM_WDT_INIT_PATCH (1) // ROM version does not configure the clock +#define ESP_ROM_RAM_APP_NEEDS_MMU_INIT (1) // ROM doesn't init cache MMU when it's a RAM APP, needs MMU hal to init diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.api.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.api.ld new file mode 100644 index 000000000000..cf8c34778ee3 --- /dev/null +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.api.ld @@ -0,0 +1,57 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +/** ROM APIs + */ + +PROVIDE ( esp_rom_crc32_le = crc32_le ); +PROVIDE ( esp_rom_crc16_le = crc16_le ); +PROVIDE ( esp_rom_crc8_le = crc8_le ); +PROVIDE ( esp_rom_crc32_be = crc32_be ); +PROVIDE ( esp_rom_crc16_be = crc16_be ); +PROVIDE ( esp_rom_crc8_be = crc8_be ); + +PROVIDE ( esp_rom_gpio_pad_select_gpio = gpio_pad_select_gpio ); +PROVIDE ( esp_rom_gpio_pad_pullup_only = gpio_pad_pullup ); +PROVIDE ( esp_rom_gpio_pad_set_drv = gpio_pad_set_drv ); +PROVIDE ( esp_rom_gpio_pad_unhold = gpio_pad_unhold ); +PROVIDE ( esp_rom_gpio_connect_in_signal = gpio_matrix_in ); +PROVIDE ( esp_rom_gpio_connect_out_signal = gpio_matrix_out ); + +PROVIDE ( esp_rom_efuse_mac_address_crc8 = esp_crc8 ); +PROVIDE ( esp_rom_efuse_is_secure_boot_enabled = ets_efuse_secure_boot_enabled ); + +PROVIDE ( esp_rom_uart_flush_tx = uart_tx_flush ); +PROVIDE ( esp_rom_uart_tx_one_char = uart_tx_one_char2 ); +PROVIDE ( esp_rom_uart_tx_wait_idle = uart_tx_wait_idle ); +PROVIDE ( esp_rom_uart_rx_one_char = uart_rx_one_char ); +PROVIDE ( esp_rom_uart_rx_string = UartRxString ); +PROVIDE ( esp_rom_uart_set_as_console = uart_tx_switch ); +PROVIDE ( esp_rom_uart_putc = ets_write_char_uart ); + +PROVIDE ( esp_rom_md5_init = MD5Init ); +PROVIDE ( esp_rom_md5_update = MD5Update ); +PROVIDE ( esp_rom_md5_final = MD5Final ); + +PROVIDE ( esp_rom_software_reset_system = software_reset ); +PROVIDE ( esp_rom_software_reset_cpu = software_reset_cpu ); + +PROVIDE ( esp_rom_printf = ets_printf ); +PROVIDE ( esp_rom_install_uart_printf = ets_install_uart_printf ); +PROVIDE ( esp_rom_delay_us = ets_delay_us ); +PROVIDE ( esp_rom_get_reset_reason = rtc_get_reset_reason ); +PROVIDE ( esp_rom_route_intr_matrix = intr_matrix_set ); +PROVIDE ( esp_rom_get_cpu_ticks_per_us = ets_get_cpu_frequency ); +PROVIDE ( esp_rom_set_cpu_ticks_per_us = ets_update_cpu_frequency ); + +PROVIDE ( esp_rom_spiflash_attach = spi_flash_attach ); +PROVIDE ( esp_rom_spiflash_clear_bp = esp_rom_spiflash_unlock ); +PROVIDE ( esp_rom_spiflash_write_enable = SPI_write_enable ); +PROVIDE ( esp_rom_spiflash_erase_area = SPIEraseArea ); + +PROVIDE ( esp_rom_spiflash_fix_dummylen = spi_dummy_len_fix ); +PROVIDE ( esp_rom_spiflash_set_drvs = SetSpiDrvs); +PROVIDE ( esp_rom_spiflash_select_padsfunc = SelectSpiFunction ); +PROVIDE ( esp_rom_spiflash_common_cmd = SPI_Common_Command ); diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.heap.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.heap.ld new file mode 100644 index 000000000000..62200c5af54e --- /dev/null +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.heap.ld @@ -0,0 +1,76 @@ +/* ROM function interface esp32c5.rom.heap.ld for esp32c5 + * + * + * Generated from ./target/esp32c5/interface-esp32c5.yml md5sum 2476337377df636dda217b0b3c1a63db + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group heap + ***************************************/ + +/* Functions */ +tlsf_create = 0x400003f8; +tlsf_create_with_pool = 0x400003fc; +tlsf_get_pool = 0x40000400; +tlsf_add_pool = 0x40000404; +tlsf_remove_pool = 0x40000408; +tlsf_malloc = 0x4000040c; +tlsf_memalign = 0x40000410; +tlsf_memalign_offs = 0x40000414; +tlsf_realloc = 0x40000418; +tlsf_free = 0x4000041c; +tlsf_block_size = 0x40000420; +tlsf_size = 0x40000424; +tlsf_align_size = 0x40000428; +tlsf_block_size_min = 0x4000042c; +tlsf_block_size_max = 0x40000430; +tlsf_pool_overhead = 0x40000434; +tlsf_alloc_overhead = 0x40000438; +tlsf_walk_pool = 0x4000043c; +tlsf_check = 0x40000440; +tlsf_check_pool = 0x40000444; +tlsf_poison_fill_pfunc_set = 0x40000448; +tlsf_poison_check_pfunc_set = 0x4000044c; +multi_heap_get_block_address_impl = 0x40000450; +multi_heap_get_allocated_size_impl = 0x40000454; +multi_heap_register_impl = 0x40000458; +multi_heap_set_lock = 0x4000045c; +multi_heap_os_funcs_init = 0x40000460; +multi_heap_internal_lock = 0x40000464; +multi_heap_internal_unlock = 0x40000468; +multi_heap_get_first_block = 0x4000046c; +multi_heap_get_next_block = 0x40000470; +multi_heap_is_free = 0x40000474; +multi_heap_malloc_impl = 0x40000478; +multi_heap_free_impl = 0x4000047c; +multi_heap_realloc_impl = 0x40000480; +multi_heap_aligned_alloc_impl_offs = 0x40000484; +multi_heap_aligned_alloc_impl = 0x40000488; +multi_heap_check = 0x4000048c; +multi_heap_dump = 0x40000490; +multi_heap_free_size_impl = 0x40000494; +multi_heap_minimum_free_size_impl = 0x40000498; +multi_heap_get_info_impl = 0x4000049c; +/* Data (.data, .bss, .rodata) */ +heap_tlsf_table_ptr = 0x4087ffd8; + +PROVIDE (multi_heap_malloc = multi_heap_malloc_impl); +PROVIDE (multi_heap_free = multi_heap_free_impl); +PROVIDE (multi_heap_realloc = multi_heap_realloc_impl); +PROVIDE (multi_heap_get_allocated_size = multi_heap_get_allocated_size_impl); +PROVIDE (multi_heap_register = multi_heap_register_impl); +PROVIDE (multi_heap_get_info = multi_heap_get_info_impl); +PROVIDE (multi_heap_free_size = multi_heap_free_size_impl); +PROVIDE (multi_heap_minimum_free_size = multi_heap_minimum_free_size_impl); +PROVIDE (multi_heap_get_block_address = multi_heap_get_block_address_impl); +PROVIDE (multi_heap_aligned_alloc = multi_heap_aligned_alloc_impl); +PROVIDE (multi_heap_aligned_free = multi_heap_aligned_free_impl); +PROVIDE (multi_heap_check = multi_heap_check); +PROVIDE (multi_heap_set_lock = multi_heap_set_lock); +PROVIDE (multi_heap_os_funcs_init = multi_heap_mutex_init); +PROVIDE (multi_heap_internal_lock = multi_heap_internal_lock); +PROVIDE (multi_heap_internal_unlock = multi_heap_internal_unlock); diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.ld new file mode 100644 index 000000000000..ce63a26314b8 --- /dev/null +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.ld @@ -0,0 +1,578 @@ +/* ROM function interface esp32c5.rom.ld for esp32c5 + * + * + * Generated from ./target/esp32c5/interface-esp32c5.yml md5sum 2476337377df636dda217b0b3c1a63db + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group common + ***************************************/ + +/* Functions */ +rtc_get_reset_reason = 0x40000018; +rtc_get_wakeup_cause = 0x4000001c; +pmu_enable_unhold_pads = 0x40000020; +ets_printf = 0x40000024; +ets_install_putc1 = 0x40000028; +ets_install_putc2 = 0x4000002c; +ets_install_uart_printf = 0x40000030; +ets_install_usb_printf = 0x40000034; +ets_get_printf_channel = 0x40000038; +ets_delay_us = 0x4000003c; +ets_get_cpu_frequency = 0x40000040; +ets_update_cpu_frequency = 0x40000044; +ets_install_lock = 0x40000048; +UartRxString = 0x4000004c; +UartGetCmdLn = 0x40000050; +uart_tx_one_char = 0x40000054; +uart_tx_one_char2 = 0x40000058; +uart_tx_one_char3 = 0x4000005c; +uart_rx_one_char = 0x40000060; +uart_rx_one_char_block = 0x40000064; +uart_rx_intr_handler = 0x40000068; +uart_rx_readbuff = 0x4000006c; +uartAttach = 0x40000070; +uart_tx_flush = 0x40000074; +uart_tx_wait_idle = 0x40000078; +uart_div_modify = 0x4000007c; +ets_write_char_uart = 0x40000080; +uart_tx_switch = 0x40000084; +uart_buff_switch = 0x40000088; +roundup2 = 0x4000008c; +multofup = 0x40000090; +software_reset = 0x40000094; +software_reset_cpu = 0x40000098; +ets_clk_assist_debug_clock_enable = 0x4000009c; +clear_super_wdt_reset_flag = 0x400000a0; +disable_default_watchdog = 0x400000a4; +esp_rom_set_rtc_wake_addr = 0x400000a8; +esp_rom_get_rtc_wake_addr = 0x400000ac; +send_packet = 0x400000b0; +recv_packet = 0x400000b4; +GetUartDevice = 0x400000b8; +UartDwnLdProc = 0x400000bc; +GetSecurityInfoProc = 0x400000c0; +Uart_Init = 0x400000c4; +ets_set_user_start = 0x400000c8; +/* Data (.data, .bss, .rodata) */ +ets_rom_layout_p = 0x4004fffc; +ets_ops_table_ptr = 0x4087fff8; +g_saved_pc = 0x4087fffc; + + +/*************************************** + Group miniz + ***************************************/ + +/* Functions */ +mz_adler32 = 0x400000cc; +mz_free = 0x400000d0; +tdefl_compress = 0x400000d4; +tdefl_compress_buffer = 0x400000d8; +tdefl_compress_mem_to_heap = 0x400000dc; +tdefl_compress_mem_to_mem = 0x400000e0; +tdefl_compress_mem_to_output = 0x400000e4; +tdefl_get_adler32 = 0x400000e8; +tdefl_get_prev_return_status = 0x400000ec; +tdefl_init = 0x400000f0; +tdefl_write_image_to_png_file_in_memory = 0x400000f4; +tdefl_write_image_to_png_file_in_memory_ex = 0x400000f8; +tinfl_decompress = 0x400000fc; +tinfl_decompress_mem_to_callback = 0x40000100; +tinfl_decompress_mem_to_heap = 0x40000104; +tinfl_decompress_mem_to_mem = 0x40000108; + + +/*************************************** + Group spiflash_legacy + ***************************************/ + +/* Functions */ +esp_rom_spiflash_wait_idle = 0x4000010c; +esp_rom_spiflash_write_encrypted = 0x40000110; +esp_rom_spiflash_write_encrypted_dest = 0x40000114; +esp_rom_spiflash_write_encrypted_enable = 0x40000118; +esp_rom_spiflash_write_encrypted_disable = 0x4000011c; +esp_rom_spiflash_erase_chip = 0x40000120; +_esp_rom_spiflash_erase_sector = 0x40000124; +_esp_rom_spiflash_erase_block = 0x40000128; +_esp_rom_spiflash_write = 0x4000012c; +_esp_rom_spiflash_read = 0x40000130; +_esp_rom_spiflash_unlock = 0x40000134; +_SPIEraseArea = 0x40000138; +_SPI_write_enable = 0x4000013c; +esp_rom_spiflash_erase_sector = 0x40000140; +esp_rom_spiflash_erase_block = 0x40000144; +esp_rom_spiflash_write = 0x40000148; +esp_rom_spiflash_read = 0x4000014c; +esp_rom_spiflash_unlock = 0x40000150; +SPIEraseArea = 0x40000154; +SPI_write_enable = 0x40000158; +esp_rom_spiflash_config_param = 0x4000015c; +esp_rom_spiflash_read_user_cmd = 0x40000160; +esp_rom_spiflash_select_qio_pins = 0x40000164; +esp_rom_spi_flash_auto_sus_res = 0x40000168; +esp_rom_spi_flash_send_resume = 0x4000016c; +esp_rom_spi_flash_update_id = 0x40000170; +esp_rom_spiflash_config_clk = 0x40000174; +esp_rom_spiflash_config_readmode = 0x40000178; +esp_rom_spiflash_read_status = 0x4000017c; +esp_rom_spiflash_read_statushigh = 0x40000180; +esp_rom_spiflash_write_status = 0x40000184; +esp_rom_spiflash_write_disable = 0x40000188; +spi_cache_mode_switch = 0x4000018c; +spi_common_set_dummy_output = 0x40000190; +spi_common_set_flash_cs_timing = 0x40000194; +esp_rom_spi_set_address_bit_len = 0x40000198; +SPILock = 0x4000019c; +SPIMasterReadModeCnfig = 0x400001a0; +SPI_Common_Command = 0x400001a4; +SPI_WakeUp = 0x400001a8; +SPI_block_erase = 0x400001ac; +SPI_chip_erase = 0x400001b0; +SPI_init = 0x400001b4; +SPI_page_program = 0x400001b8; +SPI_read_data = 0x400001bc; +SPI_sector_erase = 0x400001c0; +SelectSpiFunction = 0x400001c4; +SetSpiDrvs = 0x400001c8; +Wait_SPI_Idle = 0x400001cc; +spi_dummy_len_fix = 0x400001d0; +Disable_QMode = 0x400001d4; +Enable_QMode = 0x400001d8; +spi_flash_attach = 0x400001dc; +spi_flash_get_chip_size = 0x400001e0; +spi_flash_guard_set = 0x400001e4; +spi_flash_guard_get = 0x400001e8; +spi_flash_read_encrypted = 0x400001ec; +/* Data (.data, .bss, .rodata) */ +rom_spiflash_legacy_funcs = 0x4087fff0; +rom_spiflash_legacy_data = 0x4087ffec; +g_flash_guard_ops = 0x4087fff4; + + +/*************************************** + Group hal_wdt + ***************************************/ + +/* Functions */ +wdt_hal_init = 0x40000390; +wdt_hal_deinit = 0x40000394; +wdt_hal_config_stage = 0x40000398; +wdt_hal_write_protect_disable = 0x4000039c; +wdt_hal_write_protect_enable = 0x400003a0; +wdt_hal_enable = 0x400003a4; +wdt_hal_disable = 0x400003a8; +wdt_hal_handle_intr = 0x400003ac; +wdt_hal_feed = 0x400003b0; +wdt_hal_set_flashboot_en = 0x400003b4; +wdt_hal_is_enabled = 0x400003b8; + + +/*************************************** + Group hal_systimer + ***************************************/ + +/* Functions */ +systimer_hal_init = 0x400003bc; +systimer_hal_deinit = 0x400003c0; +systimer_hal_set_tick_rate_ops = 0x400003c4; +systimer_hal_get_counter_value = 0x400003c8; +systimer_hal_get_time = 0x400003cc; +systimer_hal_set_alarm_target = 0x400003d0; +systimer_hal_set_alarm_period = 0x400003d4; +systimer_hal_get_alarm_value = 0x400003d8; +systimer_hal_enable_alarm_int = 0x400003dc; +systimer_hal_on_apb_freq_update = 0x400003e0; +systimer_hal_counter_value_advance = 0x400003e4; +systimer_hal_enable_counter = 0x400003e8; +systimer_hal_select_alarm_mode = 0x400003ec; +systimer_hal_connect_alarm_counter = 0x400003f0; +systimer_hal_counter_can_stall_by_cpu = 0x400003f4; + + +/*************************************** + Group cache + ***************************************/ + +/* Functions */ +Cache_Get_ICache_Line_Size = 0x40000624; +Cache_Get_Mode = 0x40000628; +Cache_Address_Through_Cache = 0x4000062c; +ROM_Boot_Cache_Init = 0x40000630; +MMU_Set_Page_Mode = 0x40000634; +MMU_Get_Page_Mode = 0x40000638; +Cache_Invalidate_ICache_Items = 0x4000063c; +Cache_Op_Addr = 0x40000640; +Cache_Invalidate_Addr = 0x40000644; +Cache_Invalidate_ICache_All = 0x40000648; +Cache_Mask_All = 0x4000064c; +Cache_UnMask_Dram0 = 0x40000650; +Cache_Suspend_ICache_Autoload = 0x40000654; +Cache_Resume_ICache_Autoload = 0x40000658; +Cache_Start_ICache_Preload = 0x4000065c; +Cache_ICache_Preload_Done = 0x40000660; +Cache_End_ICache_Preload = 0x40000664; +Cache_Config_ICache_Autoload = 0x40000668; +Cache_Enable_ICache_Autoload = 0x4000066c; +Cache_Disable_ICache_Autoload = 0x40000670; +Cache_Enable_ICache_PreLock = 0x40000674; +Cache_Disable_ICache_PreLock = 0x40000678; +Cache_Lock_ICache_Items = 0x4000067c; +Cache_Unlock_ICache_Items = 0x40000680; +Cache_Lock_Addr = 0x40000684; +Cache_Unlock_Addr = 0x40000688; +Cache_Disable_ICache = 0x4000068c; +Cache_Enable_ICache = 0x40000690; +Cache_Suspend_ICache = 0x40000694; +Cache_Resume_ICache = 0x40000698; +Cache_Freeze_ICache_Enable = 0x4000069c; +Cache_Freeze_ICache_Disable = 0x400006a0; +Cache_Set_IDROM_MMU_Size = 0x400006a4; +Cache_Get_IROM_MMU_End = 0x400006a8; +Cache_Get_DROM_MMU_End = 0x400006ac; +Cache_MMU_Init = 0x400006b0; +Cache_MSPI_MMU_Set = 0x400006b4; +Cache_MSPI_MMU_Set_Secure = 0x400006b8; +Cache_Travel_Tag_Memory = 0x400006bc; +Cache_Get_Virtual_Addr = 0x400006c0; +/* Data (.data, .bss, .rodata) */ +rom_cache_op_cb = 0x4087ffcc; +rom_cache_internal_table_ptr = 0x4087ffc8; + + +/*************************************** + Group clock + ***************************************/ + +/* Functions */ +ets_clk_get_xtal_freq = 0x400006c4; +ets_clk_get_cpu_freq = 0x400006c8; + + +/*************************************** + Group gpio + ***************************************/ + +/* Functions */ +gpio_set_output_level = 0x400006cc; +gpio_get_input_level = 0x400006d0; +gpio_matrix_in = 0x400006d4; +gpio_matrix_out = 0x400006d8; +gpio_bypass_matrix_in = 0x400006dc; +gpio_output_disable = 0x400006e0; +gpio_output_enable = 0x400006e4; +gpio_pad_input_disable = 0x400006e8; +gpio_pad_input_enable = 0x400006ec; +gpio_pad_pulldown = 0x400006f0; +gpio_pad_pullup = 0x400006f4; +gpio_pad_select_gpio = 0x400006f8; +gpio_pad_set_drv = 0x400006fc; +gpio_pad_unhold = 0x40000700; +gpio_pad_hold = 0x40000704; + + +/*************************************** + Group interrupts + ***************************************/ + +/* Functions */ +esprv_intc_int_set_priority = 0x40000708; +esprv_intc_int_set_threshold = 0x4000070c; +esprv_intc_int_enable = 0x40000710; +esprv_intc_int_disable = 0x40000714; +esprv_intc_int_set_type = 0x40000718; +PROVIDE( intr_handler_set = 0x4000071c ); +intr_matrix_set = 0x40000720; +ets_intr_lock = 0x40000724; +ets_intr_unlock = 0x40000728; +ets_isr_attach = 0x4000072c; +ets_isr_mask = 0x40000730; +ets_isr_unmask = 0x40000734; + + +/*************************************** + Group crypto + ***************************************/ + +/* Functions */ +md5_vector = 0x40000738; +MD5Init = 0x4000073c; +MD5Update = 0x40000740; +MD5Final = 0x40000744; +crc32_le = 0x40000748; +crc16_le = 0x4000074c; +crc8_le = 0x40000750; +crc32_be = 0x40000754; +crc16_be = 0x40000758; +crc8_be = 0x4000075c; +esp_crc8 = 0x40000760; +ets_sha_enable = 0x40000764; +ets_sha_disable = 0x40000768; +ets_sha_get_state = 0x4000076c; +ets_sha_init = 0x40000770; +ets_sha_process = 0x40000774; +ets_sha_starts = 0x40000778; +ets_sha_update = 0x4000077c; +ets_sha_finish = 0x40000780; +ets_sha_clone = 0x40000784; +ets_hmac_enable = 0x40000788; +ets_hmac_disable = 0x4000078c; +ets_hmac_calculate_message = 0x40000790; +ets_hmac_calculate_downstream = 0x40000794; +ets_hmac_invalidate_downstream = 0x40000798; +ets_jtag_enable_temporarily = 0x4000079c; +ets_aes_enable = 0x400007a0; +ets_aes_disable = 0x400007a4; +ets_aes_setkey = 0x400007a8; +ets_aes_block = 0x400007ac; +ets_aes_setkey_dec = 0x400007b0; +ets_aes_setkey_enc = 0x400007b4; +ets_bigint_enable = 0x400007b8; +ets_bigint_disable = 0x400007bc; +ets_bigint_multiply = 0x400007c0; +ets_bigint_modmult = 0x400007c4; +ets_bigint_modexp = 0x400007c8; +ets_bigint_wait_finish = 0x400007cc; +ets_bigint_getz = 0x400007d0; +ets_ds_enable = 0x400007d4; +ets_ds_disable = 0x400007d8; +ets_ds_start_sign = 0x400007dc; +ets_ds_is_busy = 0x400007e0; +ets_ds_finish_sign = 0x400007e4; +ets_ds_encrypt_params = 0x400007e8; +ets_mgf1_sha256 = 0x400007ec; +/* Data (.data, .bss, .rodata) */ +crc32_le_table_ptr = 0x4004fff8; +crc16_le_table_ptr = 0x4004fff4; +crc8_le_table_ptr = 0x4004fff0; +crc32_be_table_ptr = 0x4004ffec; +crc16_be_table_ptr = 0x4004ffe8; +crc8_be_table_ptr = 0x4004ffe4; + + +/*************************************** + Group efuse + ***************************************/ + +/* Functions */ +ets_efuse_read = 0x400007f0; +ets_efuse_program = 0x400007f4; +ets_efuse_clear_program_registers = 0x400007f8; +ets_efuse_write_key = 0x400007fc; +ets_efuse_get_read_register_address = 0x40000800; +ets_efuse_get_key_purpose = 0x40000804; +ets_efuse_key_block_unused = 0x40000808; +ets_efuse_find_unused_key_block = 0x4000080c; +ets_efuse_rs_calculate = 0x40000810; +ets_efuse_count_unused_key_blocks = 0x40000814; +ets_efuse_secure_boot_enabled = 0x40000818; +ets_efuse_secure_boot_aggressive_revoke_enabled = 0x4000081c; +ets_efuse_cache_encryption_enabled = 0x40000820; +ets_efuse_download_modes_disabled = 0x40000824; +ets_efuse_find_purpose = 0x40000828; +ets_efuse_force_send_resume = 0x4000082c; +ets_efuse_get_flash_delay_us = 0x40000830; +ets_efuse_get_uart_print_control = 0x40000834; +ets_efuse_direct_boot_mode_disabled = 0x40000838; +ets_efuse_security_download_modes_enabled = 0x4000083c; +ets_efuse_jtag_disabled = 0x40000840; +ets_efuse_usb_print_is_disabled = 0x40000844; +ets_efuse_usb_download_mode_disabled = 0x40000848; +ets_efuse_usb_device_disabled = 0x4000084c; +ets_efuse_secure_boot_fast_wake_enabled = 0x40000850; + + +/*************************************** + Group secureboot + ***************************************/ + +/* Functions */ +ets_emsa_pss_verify = 0x40000854; +ets_rsa_pss_verify = 0x40000858; +ets_ecdsa_verify = 0x4000085c; +ets_secure_boot_verify_bootloader_with_keys = 0x40000860; +ets_secure_boot_verify_signature = 0x40000864; +ets_secure_boot_read_key_digests = 0x40000868; +ets_secure_boot_revoke_public_key_digest = 0x4000086c; + + +/*************************************** + Group usb_device_uart + ***************************************/ + +/* Functions */ +usb_serial_device_rx_one_char = 0x40000a6c; +usb_serial_device_rx_one_char_block = 0x40000a70; +usb_serial_device_tx_flush = 0x40000a74; +usb_serial_device_tx_one_char = 0x40000a78; + + +/*************************************** + Group usb_dwcotg_uart + ***************************************/ + +/* Functions */ +Uart_Init_USB = 0x40000a7c; +usb_serial_otg_rx_one_char = 0x40000a80; +usb_serial_otg_rx_one_char_block = 0x40000a84; +usb_serial_otg_tx_flush = 0x40000a88; +usb_serial_otg_tx_one_char = 0x40000a8c; +/* Data (.data, .bss, .rodata) */ +uart_acm_dev = 0x4087ffc4; + + +/*************************************** + Group usb_dwcotg_module + ***************************************/ + +/* Functions */ +cdc_acm_class_handle_req = 0x40000a90; +cdc_acm_init = 0x40000a94; +cdc_acm_fifo_fill = 0x40000a98; +cdc_acm_rx_fifo_cnt = 0x40000a9c; +cdc_acm_fifo_read = 0x40000aa0; +cdc_acm_irq_tx_enable = 0x40000aa4; +cdc_acm_irq_tx_disable = 0x40000aa8; +cdc_acm_irq_state_enable = 0x40000aac; +cdc_acm_irq_state_disable = 0x40000ab0; +cdc_acm_irq_tx_ready = 0x40000ab4; +cdc_acm_irq_rx_enable = 0x40000ab8; +cdc_acm_irq_rx_disable = 0x40000abc; +cdc_acm_irq_rx_ready = 0x40000ac0; +cdc_acm_irq_is_pending = 0x40000ac4; +cdc_acm_irq_callback_set = 0x40000ac8; +cdc_acm_line_ctrl_set = 0x40000acc; +cdc_acm_line_ctrl_get = 0x40000ad0; +cdc_acm_poll_out = 0x40000ad4; +chip_usb_dw_did_persist = 0x40000ad8; +chip_usb_dw_init = 0x40000adc; +chip_usb_detach = 0x40000ae0; +chip_usb_dw_prepare_persist = 0x40000ae4; +chip_usb_get_persist_flags = 0x40000ae8; +chip_usb_set_persist_flags = 0x40000aec; +cpio_start = 0x40000af0; +cpio_feed = 0x40000af4; +cpio_done = 0x40000af8; +cpio_destroy = 0x40000afc; +dfu_flash_init = 0x40000b00; +dfu_flash_erase = 0x40000b04; +dfu_flash_program = 0x40000b08; +dfu_flash_read = 0x40000b0c; +dfu_flash_attach = 0x40000b10; +dfu_cpio_callback = 0x40000b14; +dfu_updater_get_err = 0x40000b18; +dfu_updater_clear_err = 0x40000b1c; +dfu_updater_enable = 0x40000b20; +dfu_updater_begin = 0x40000b24; +dfu_updater_feed = 0x40000b28; +dfu_updater_end = 0x40000b2c; +dfu_updater_set_raw_addr = 0x40000b30; +dfu_updater_flash_read = 0x40000b34; +usb_dc_prepare_persist = 0x40000b38; +usb_dw_isr_handler = 0x40000b3c; +usb_dc_attach = 0x40000b40; +usb_dc_detach = 0x40000b44; +usb_dc_reset = 0x40000b48; +usb_dc_set_address = 0x40000b4c; +usb_dc_ep_check_cap = 0x40000b50; +usb_dc_ep_configure = 0x40000b54; +usb_dc_ep_set_stall = 0x40000b58; +usb_dc_ep_clear_stall = 0x40000b5c; +usb_dc_ep_halt = 0x40000b60; +usb_dc_ep_is_stalled = 0x40000b64; +usb_dc_ep_enable = 0x40000b68; +usb_dc_ep_disable = 0x40000b6c; +usb_dc_ep_flush = 0x40000b70; +usb_dc_ep_write_would_block = 0x40000b74; +usb_dc_ep_write = 0x40000b78; +usb_dc_ep_read_wait = 0x40000b7c; +usb_dc_ep_read_continue = 0x40000b80; +usb_dc_ep_read = 0x40000b84; +usb_dc_ep_set_callback = 0x40000b88; +usb_dc_set_status_callback = 0x40000b8c; +usb_dc_ep_mps = 0x40000b90; +usb_dc_check_poll_for_interrupts = 0x40000b94; +mac_addr_to_serial_str_desc = 0x40000b98; +usb_set_current_descriptor = 0x40000b9c; +usb_get_descriptor = 0x40000ba0; +usb_dev_resume = 0x40000ba4; +usb_dev_get_configuration = 0x40000ba8; +usb_set_config = 0x40000bac; +usb_deconfig = 0x40000bb0; +usb_enable = 0x40000bb4; +usb_disable = 0x40000bb8; +usb_write_would_block = 0x40000bbc; +usb_write = 0x40000bc0; +usb_read = 0x40000bc4; +usb_ep_set_stall = 0x40000bc8; +usb_ep_clear_stall = 0x40000bcc; +usb_ep_read_wait = 0x40000bd0; +usb_ep_read_continue = 0x40000bd4; +usb_transfer_ep_callback = 0x40000bd8; +usb_transfer = 0x40000bdc; +usb_cancel_transfer = 0x40000be0; +usb_transfer_sync = 0x40000be4; +usb_dfu_set_detach_cb = 0x40000be8; +dfu_class_handle_req = 0x40000bec; +dfu_status_cb = 0x40000bf0; +dfu_custom_handle_req = 0x40000bf4; +usb_dfu_init = 0x40000bf8; +usb_dfu_force_detach = 0x40000bfc; +usb_dev_deinit = 0x40000c00; +usb_dw_ctrl_deinit = 0x40000c04; +/* Data (.data, .bss, .rodata) */ +s_usb_osglue = 0x4087ffb8; + + +/*************************************** + Group lldesc + ***************************************/ + +/* Functions */ +lldesc_build_chain = 0x40000c08; + + +/*************************************** + Group sip + ***************************************/ + +/* Functions */ +sip_after_tx_complete = 0x40000c0c; +sip_alloc_to_host_evt = 0x40000c10; +sip_download_begin = 0x40000c14; +sip_get_ptr = 0x40000c18; +sip_get_state = 0x40000c1c; +sip_init_attach = 0x40000c20; +sip_install_rx_ctrl_cb = 0x40000c24; +sip_install_rx_data_cb = 0x40000c28; +sip_is_active = 0x40000c2c; +sip_post_init = 0x40000c30; +sip_reclaim_from_host_cmd = 0x40000c34; +sip_reclaim_tx_data_pkt = 0x40000c38; +sip_send = 0x40000c3c; +sip_to_host_chain_append = 0x40000c40; +sip_to_host_evt_send_done = 0x40000c44; + + +/*************************************** + Group slc + ***************************************/ + +/* Functions */ +slc_add_credits = 0x40000c48; +slc_enable = 0x40000c4c; +slc_from_host_chain_fetch = 0x40000c50; +slc_from_host_chain_recycle = 0x40000c54; +slc_has_pkt_to_host = 0x40000c58; +slc_init_attach = 0x40000c5c; +slc_init_credit = 0x40000c60; +slc_reattach = 0x40000c64; +slc_send_to_host_chain = 0x40000c68; +slc_set_host_io_max_window = 0x40000c6c; +slc_to_host_chain_recycle = 0x40000c70; + diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.libgcc.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.libgcc.ld new file mode 100644 index 000000000000..2634ce20ba89 --- /dev/null +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.libgcc.ld @@ -0,0 +1,115 @@ +/* ROM function interface esp32c5.rom.libgcc.ld for esp32c5 + * + * + * Generated from ./target/esp32c5/interface-esp32c5.yml md5sum 2476337377df636dda217b0b3c1a63db + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group libgccsf + ***************************************/ + +/* Functions */ +__addsf3 = 0x40000870; +__divsf3 = 0x40000874; +__eqsf2 = 0x40000878; +__fixsfsi = 0x4000087c; +__floatsisf = 0x40000880; +__floatunsisf = 0x40000884; +__gesf2 = 0x40000888; +__gtsf2 = 0x4000088c; +__lesf2 = 0x40000890; +__ltsf2 = 0x40000894; +__mulsf3 = 0x40000898; +__negsf2 = 0x4000089c; +__nesf2 = 0x400008a0; +__powisf2 = 0x400008a4; +__subsf3 = 0x400008a8; +__truncdfsf2 = 0x400008ac; +__unordsf2 = 0x400008b0; + + +/*************************************** + Group libgccdf + ***************************************/ + +/* Functions */ +__absvdi2 = 0x400008b4; +__absvsi2 = 0x400008b8; +__adddf3 = 0x400008bc; +__addvdi3 = 0x400008c0; +__addvsi3 = 0x400008c4; +__ashldi3 = 0x400008c8; +__ashrdi3 = 0x400008cc; +__bswapdi2 = 0x400008d0; +__bswapsi2 = 0x400008d4; +__clear_cache = 0x400008d8; +__clrsbdi2 = 0x400008dc; +__clrsbsi2 = 0x400008e0; +__clzdi2 = 0x400008e4; +__clzsi2 = 0x400008e8; +__cmpdi2 = 0x400008ec; +__ctzdi2 = 0x400008f0; +__ctzsi2 = 0x400008f4; +__divdc3 = 0x400008f8; +__divdf3 = 0x400008fc; +__divdi3 = 0x40000900; +__divsc3 = 0x40000904; +__divsi3 = 0x40000908; +__eqdf2 = 0x4000090c; +__extendsfdf2 = 0x40000910; +__ffsdi2 = 0x40000914; +__ffssi2 = 0x40000918; +__fixdfdi = 0x4000091c; +__fixdfsi = 0x40000920; +__fixsfdi = 0x40000924; +__fixunsdfsi = 0x40000928; +__fixunssfdi = 0x4000092c; +__fixunssfsi = 0x40000930; +__floatdidf = 0x40000934; +__floatdisf = 0x40000938; +__floatsidf = 0x4000093c; +__floatundidf = 0x40000940; +__floatundisf = 0x40000944; +__floatunsidf = 0x40000948; +__gcc_bcmp = 0x4000094c; +__gedf2 = 0x40000950; +__gtdf2 = 0x40000954; +__ledf2 = 0x40000958; +__lshrdi3 = 0x4000095c; +__ltdf2 = 0x40000960; +__moddi3 = 0x40000964; +__modsi3 = 0x40000968; +__muldc3 = 0x4000096c; +__muldf3 = 0x40000970; +__muldi3 = 0x40000974; +__mulsc3 = 0x40000978; +__mulsi3 = 0x4000097c; +__mulvdi3 = 0x40000980; +__mulvsi3 = 0x40000984; +__nedf2 = 0x40000988; +__negdf2 = 0x4000098c; +__negdi2 = 0x40000990; +__negvdi2 = 0x40000994; +__negvsi2 = 0x40000998; +__paritysi2 = 0x4000099c; +__popcountdi2 = 0x400009a0; +__popcountsi2 = 0x400009a4; +__powidf2 = 0x400009a8; +__subdf3 = 0x400009ac; +__subvdi3 = 0x400009b0; +__subvsi3 = 0x400009b4; +__ucmpdi2 = 0x400009b8; +__udivdi3 = 0x400009bc; +__udivmoddi4 = 0x400009c0; +__udivsi3 = 0x400009c4; +__udiv_w_sdiv = 0x400009c8; +__umoddi3 = 0x400009cc; +__umodsi3 = 0x400009d0; +__unorddf2 = 0x400009d4; +__extenddftf2 = 0x400009d8; +__trunctfdf2 = 0x400009dc; + diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.newlib-normal.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.newlib-normal.ld new file mode 100644 index 000000000000..aa93ad135592 --- /dev/null +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.newlib-normal.ld @@ -0,0 +1,37 @@ +/* ROM function interface esp32c5.rom.newlib-normal.ld for esp32c5 + * + * + * Generated from ./target/esp32c5/interface-esp32c5.yml md5sum 2476337377df636dda217b0b3c1a63db + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group newlib_normal_format + ***************************************/ + +/* Functions */ +__sprint_r = 0x400005d0; +_fiprintf_r = 0x400005d4; +_fprintf_r = 0x400005d8; +_vfiprintf_r = 0x400005dc; +_vfprintf_r = 0x400005e0; +fiprintf = 0x400005e4; +fprintf = 0x400005e8; +printf = 0x400005ec; +vfiprintf = 0x400005f0; +vfprintf = 0x400005f4; +asprintf = 0x400005f8; +sprintf = 0x400005fc; +snprintf = 0x40000600; +siprintf = 0x40000604; +sniprintf = 0x40000608; +vprintf = 0x4000060c; +viprintf = 0x40000610; +vsnprintf = 0x40000614; +vsniprintf = 0x40000618; +sscanf = 0x4000061c; +siscanf = 0x40000620; + diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.newlib.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.newlib.ld new file mode 100644 index 000000000000..d36e57b7ec93 --- /dev/null +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.newlib.ld @@ -0,0 +1,95 @@ +/* ROM function interface esp32c5.rom.newlib.ld for esp32c5 + * + * + * Generated from ./target/esp32c5/interface-esp32c5.yml md5sum 2476337377df636dda217b0b3c1a63db + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group newlib + ***************************************/ + +/* Functions */ +esp_rom_newlib_init_common_mutexes = 0x400004a0; +memset = 0x400004a4; +memcpy = 0x400004a8; +memmove = 0x400004ac; +memcmp = 0x400004b0; +strcpy = 0x400004b4; +strncpy = 0x400004b8; +strcmp = 0x400004bc; +strncmp = 0x400004c0; +strlen = 0x400004c4; +strstr = 0x400004c8; +bzero = 0x400004cc; +_isatty_r = 0x400004d0; +sbrk = 0x400004d4; +isalnum = 0x400004d8; +isalpha = 0x400004dc; +isascii = 0x400004e0; +isblank = 0x400004e4; +iscntrl = 0x400004e8; +isdigit = 0x400004ec; +islower = 0x400004f0; +isgraph = 0x400004f4; +isprint = 0x400004f8; +ispunct = 0x400004fc; +isspace = 0x40000500; +isupper = 0x40000504; +toupper = 0x40000508; +tolower = 0x4000050c; +toascii = 0x40000510; +memccpy = 0x40000514; +memchr = 0x40000518; +memrchr = 0x4000051c; +strcasecmp = 0x40000520; +strcasestr = 0x40000524; +strcat = 0x40000528; +strdup = 0x4000052c; +strchr = 0x40000530; +strcspn = 0x40000534; +strcoll = 0x40000538; +strlcat = 0x4000053c; +strlcpy = 0x40000540; +strlwr = 0x40000544; +strncasecmp = 0x40000548; +strncat = 0x4000054c; +strndup = 0x40000550; +strnlen = 0x40000554; +strrchr = 0x40000558; +strsep = 0x4000055c; +strspn = 0x40000560; +strtok_r = 0x40000564; +strupr = 0x40000568; +longjmp = 0x4000056c; +setjmp = 0x40000570; +abs = 0x40000574; +div = 0x40000578; +labs = 0x4000057c; +ldiv = 0x40000580; +qsort = 0x40000584; +rand_r = 0x40000588; +rand = 0x4000058c; +srand = 0x40000590; +utoa = 0x40000594; +itoa = 0x40000598; +atoi = 0x4000059c; +atol = 0x400005a0; +strtol = 0x400005a4; +strtoul = 0x400005a8; +fflush = 0x400005ac; +_fflush_r = 0x400005b0; +_fwalk = 0x400005b4; +_fwalk_reent = 0x400005b8; +__smakebuf_r = 0x400005bc; +__swhatbuf_r = 0x400005c0; +__swbuf_r = 0x400005c4; +__swbuf = 0x400005c8; +__swsetup_r = 0x400005cc; +/* Data (.data, .bss, .rodata) */ +syscall_table_ptr = 0x4087ffd4; +_global_impure_ptr = 0x4087ffd0; + diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.rvfp.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.rvfp.ld new file mode 100644 index 000000000000..8fbe9c26516a --- /dev/null +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.rvfp.ld @@ -0,0 +1,120 @@ +/* ROM function interface esp32c5.rom.rvfp.ld for esp32c5 + * + * + * Generated from ./target/esp32c5/interface-esp32c5.yml md5sum 2476337377df636dda217b0b3c1a63db + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group rvfplibsf + ***************************************/ + +/* Functions */ +__addsf3 = 0x400009e0; +__eqsf2 = 0x400009e4; +__extendsfdf2 = 0x400009e8; +__fixsfsi = 0x400009ec; +__fixunssfsi = 0x400009f0; +__floatdisf = 0x400009f4; +__floatsisf = 0x400009f8; +__floatundisf = 0x400009fc; +__floatunsisf = 0x40000a00; +__gesf2 = 0x40000a04; +__gtsf2 = 0x40000a08; +__lesf2 = 0x40000a0c; +__ltsf2 = 0x40000a10; +__mulsf3 = 0x40000a14; +__nesf2 = 0x40000a18; +__subsf3 = 0x40000a1c; +__truncdfsf2 = 0x40000a20; + + +/*************************************** + Group rvfplibdf + ***************************************/ + +/* Functions */ +__adddf3 = 0x40000a24; +__eqdf2 = 0x40000a28; +__fixdfdi = 0x40000a2c; +__fixdfsi = 0x40000a30; +__fixsfdi = 0x40000a34; +__fixunsdfsi = 0x40000a38; +__fixunssfdi = 0x40000a3c; +__floatdidf = 0x40000a40; +__floatsidf = 0x40000a44; +__floatundidf = 0x40000a48; +__floatunsidf = 0x40000a4c; +__gedf2 = 0x40000a50; +__gtdf2 = 0x40000a54; +__ledf2 = 0x40000a58; +__ltdf2 = 0x40000a5c; +__muldf3 = 0x40000a60; +__nedf2 = 0x40000a64; +__subdf3 = 0x40000a68; + +/*************************************** + Group libgcc +***************************************/ + +/* Functions */ +__divsf3 = 0x40000874; +__negsf2 = 0x4000089c; +__powisf2 = 0x400008a4; +__unordsf2 = 0x400008b0; +__absvdi2 = 0x400008b4; +__absvsi2 = 0x400008b8; +__addvdi3 = 0x400008c0; +__addvsi3 = 0x400008c4; +__ashldi3 = 0x400008c8; +__ashrdi3 = 0x400008cc; +__bswapdi2 = 0x400008d0; +__bswapsi2 = 0x400008d4; +__clear_cache = 0x400008d8; +__clrsbdi2 = 0x400008dc; +__clrsbsi2 = 0x400008e0; +__clzdi2 = 0x400008e4; +__clzsi2 = 0x400008e8; +__cmpdi2 = 0x400008ec; +__ctzdi2 = 0x400008f0; +__ctzsi2 = 0x400008f4; +__divdc3 = 0x400008f8; +__divdf3 = 0x400008fc; +__divdi3 = 0x40000900; +__divsc3 = 0x40000904; +__divsi3 = 0x40000908; +__ffsdi2 = 0x40000914; +__ffssi2 = 0x40000918; +__gcc_bcmp = 0x4000094c; +__lshrdi3 = 0x4000095c; +__moddi3 = 0x40000964; +__modsi3 = 0x40000968; +__muldc3 = 0x4000096c; +__muldi3 = 0x40000974; +__mulsc3 = 0x40000978; +__mulsi3 = 0x4000097c; +__mulvdi3 = 0x40000980; +__mulvsi3 = 0x40000984; +__negdf2 = 0x4000098c; +__negdi2 = 0x40000990; +__negvdi2 = 0x40000994; +__negvsi2 = 0x40000998; +__paritysi2 = 0x4000099c; +__popcountdi2 = 0x400009a0; +__popcountsi2 = 0x400009a4; +__powidf2 = 0x400009a8; +__subvdi3 = 0x400009b0; +__subvsi3 = 0x400009b4; +__ucmpdi2 = 0x400009b8; +__udivdi3 = 0x400009bc; +__udivmoddi4 = 0x400009c0; +__udivsi3 = 0x400009c4; +__udiv_w_sdiv = 0x400009c8; +__umoddi3 = 0x400009cc; +__umodsi3 = 0x400009d0; +__unorddf2 = 0x400009d4; +__extenddftf2 = 0x400009d8; +__trunctfdf2 = 0x400009dc; diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.spiflash.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.spiflash.ld new file mode 100644 index 000000000000..7528ca7c7436 --- /dev/null +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.spiflash.ld @@ -0,0 +1,161 @@ +/* ROM function interface esp32c5.rom.spiflash.ld for esp32c5 + * + * + * Generated from ./target/esp32c5/interface-esp32c5.yml md5sum 2476337377df636dda217b0b3c1a63db + * + * Compatible with ROM where ECO version equal or greater to 0. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ + +/*************************************** + Group spi_flash_cache + ***************************************/ + +/* Functions */ +spi_flash_disable_cache = 0x400001f0; +spi_flash_restore_cache = 0x400001f4; +spi_flash_cache_enabled = 0x400001f8; +spi_flash_enable_cache = 0x400001fc; +esp_enable_cache_flash_wrap = 0x40000200; + + +/*************************************** + Group spi_flash_mmap + ***************************************/ + +/* Functions */ +spi_flash_mmap_os_func_set = 0x40000204; +spi_flash_mmap_page_num_init = 0x40000208; +spi_flash_mmap = 0x4000020c; +spi_flash_mmap_pages = 0x40000210; +spi_flash_munmap = 0x40000214; +spi_flash_mmap_dump = 0x40000218; +spi_flash_check_and_flush_cache = 0x4000021c; +spi_flash_mmap_get_free_pages = 0x40000220; +spi_flash_cache2phys = 0x40000224; +spi_flash_phys2cache = 0x40000228; + + +/*************************************** + Group esp_flash + ***************************************/ + +/* Functions */ +esp_flash_chip_driver_initialized = 0x4000022c; +esp_flash_read_id = 0x40000230; +esp_flash_get_size = 0x40000234; +esp_flash_erase_chip = 0x40000238; +esp_flash_erase_region = 0x4000023c; +esp_flash_get_chip_write_protect = 0x40000240; +esp_flash_set_chip_write_protect = 0x40000244; +esp_flash_get_protectable_regions = 0x40000248; +esp_flash_get_protected_region = 0x4000024c; +esp_flash_set_protected_region = 0x40000250; +esp_flash_read = 0x40000254; +esp_flash_write = 0x40000258; +esp_flash_write_encrypted = 0x4000025c; +esp_flash_read_encrypted = 0x40000260; +esp_flash_get_io_mode = 0x40000264; +esp_flash_set_io_mode = 0x40000268; +spi_flash_boot_attach = 0x4000026c; +esp_flash_read_chip_id = 0x40000270; +detect_spi_flash_chip = 0x40000274; +esp_flash_suspend_cmd_init = 0x40000278; +/* Data (.data, .bss, .rodata) */ +esp_flash_default_chip = 0x4087ffe8; +esp_flash_api_funcs = 0x4087ffe4; + + +/*************************************** + Group spi_flash_chips + ***************************************/ + +/* Functions */ +spi_flash_chip_generic_probe = 0x4000027c; +spi_flash_chip_generic_detect_size = 0x40000280; +spi_flash_chip_generic_write = 0x40000284; +spi_flash_chip_generic_write_encrypted = 0x40000288; +spi_flash_chip_generic_set_write_protect = 0x4000028c; +spi_flash_common_write_status_16b_wrsr = 0x40000290; +spi_flash_chip_generic_reset = 0x40000294; +spi_flash_chip_generic_erase_chip = 0x40000298; +spi_flash_chip_generic_erase_sector = 0x4000029c; +spi_flash_chip_generic_erase_block = 0x400002a0; +spi_flash_chip_generic_page_program = 0x400002a4; +spi_flash_chip_generic_get_write_protect = 0x400002a8; +spi_flash_common_read_status_16b_rdsr_rdsr2 = 0x400002ac; +spi_flash_chip_generic_read_reg = 0x400002b0; +spi_flash_chip_generic_yield = 0x400002b4; +spi_flash_generic_wait_host_idle = 0x400002b8; +spi_flash_chip_generic_wait_idle = 0x400002bc; +spi_flash_chip_generic_config_host_io_mode = 0x400002c0; +spi_flash_chip_generic_read = 0x400002c4; +spi_flash_common_read_status_8b_rdsr2 = 0x400002c8; +spi_flash_chip_generic_get_io_mode = 0x400002cc; +spi_flash_common_read_status_8b_rdsr = 0x400002d0; +spi_flash_common_write_status_8b_wrsr = 0x400002d4; +spi_flash_common_write_status_8b_wrsr2 = 0x400002d8; +spi_flash_common_set_io_mode = 0x400002dc; +spi_flash_chip_generic_set_io_mode = 0x400002e0; +spi_flash_chip_generic_read_unique_id = 0x400002e4; +spi_flash_chip_generic_get_caps = 0x400002e8; +spi_flash_chip_generic_suspend_cmd_conf = 0x400002ec; +spi_flash_chip_gd_get_io_mode = 0x400002f0; +spi_flash_chip_gd_probe = 0x400002f4; +spi_flash_chip_gd_set_io_mode = 0x400002f8; +/* Data (.data, .bss, .rodata) */ +spi_flash_chip_generic_config_data = 0x4087ffe0; +spi_flash_encryption = 0x4087ffdc; + + +/*************************************** + Group memspi_host + ***************************************/ + +/* Functions */ +memspi_host_read_id_hs = 0x400002fc; +memspi_host_read_status_hs = 0x40000300; +memspi_host_flush_cache = 0x40000304; +memspi_host_erase_chip = 0x40000308; +memspi_host_erase_sector = 0x4000030c; +memspi_host_erase_block = 0x40000310; +memspi_host_program_page = 0x40000314; +memspi_host_read = 0x40000318; +memspi_host_set_write_protect = 0x4000031c; +memspi_host_set_max_read_len = 0x40000320; +memspi_host_read_data_slicer = 0x40000324; +memspi_host_write_data_slicer = 0x40000328; + + +/*************************************** + Group hal_spiflash + ***************************************/ + +/* Functions */ +spi_flash_hal_poll_cmd_done = 0x4000032c; +spi_flash_hal_device_config = 0x40000330; +spi_flash_hal_configure_host_io_mode = 0x40000334; +spi_flash_hal_common_command = 0x40000338; +spi_flash_hal_read = 0x4000033c; +spi_flash_hal_erase_chip = 0x40000340; +spi_flash_hal_erase_sector = 0x40000344; +spi_flash_hal_erase_block = 0x40000348; +spi_flash_hal_program_page = 0x4000034c; +spi_flash_hal_set_write_protect = 0x40000350; +spi_flash_hal_host_idle = 0x40000354; +spi_flash_hal_check_status = 0x40000358; +spi_flash_hal_setup_read_suspend = 0x4000035c; +spi_flash_hal_setup_auto_suspend_mode = 0x40000360; +spi_flash_hal_setup_auto_resume_mode = 0x40000364; +spi_flash_hal_disable_auto_suspend_mode = 0x40000368; +spi_flash_hal_disable_auto_resume_mode = 0x4000036c; +spi_flash_hal_resume = 0x40000370; +spi_flash_hal_suspend = 0x40000374; +spi_flash_encryption_hal_enable = 0x40000378; +spi_flash_encryption_hal_disable = 0x4000037c; +spi_flash_encryption_hal_prepare = 0x40000380; +spi_flash_encryption_hal_done = 0x40000384; +spi_flash_encryption_hal_destroy = 0x40000388; +spi_flash_encryption_hal_check = 0x4000038c; + diff --git a/components/esp_rom/esp32c5/ld/esp32c5.rom.version.ld b/components/esp_rom/esp32c5/ld/esp32c5.rom.version.ld new file mode 100644 index 000000000000..e139c043c9d8 --- /dev/null +++ b/components/esp_rom/esp32c5/ld/esp32c5.rom.version.ld @@ -0,0 +1,8 @@ +/* ROM version variables for esp32c5 + * + * These addresses should be compatible with any ROM version for this chip. + * + * THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT. + */ +_rom_chip_id = 0x40000010; +_rom_eco_version = 0x40000014; diff --git a/components/esp_rom/include/esp32c5/rom/.gitkeep b/components/esp_rom/include/esp32c5/rom/.gitkeep deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/components/esp_rom/include/esp32c5/rom/aes.h b/components/esp_rom/include/esp32c5/rom/aes.h new file mode 100644 index 000000000000..0af206663742 --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/aes.h @@ -0,0 +1,46 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_AES_H_ +#define _ROM_AES_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define AES_BLOCK_SIZE 16 + +enum AES_TYPE { + AES_ENC, + AES_DEC, +}; + +enum AES_BITS { + AES128, + AES192, + AES256 +}; + +void ets_aes_enable(void); + +void ets_aes_disable(void); + +int ets_aes_setkey(enum AES_TYPE type, const void *key, enum AES_BITS bits); + +int ets_aes_setkey_enc(const void *key, enum AES_BITS bits); + +int ets_aes_setkey_dec(const void *key, enum AES_BITS bits); + +void ets_aes_block(const void *input, void *output); + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_AES_H_ */ diff --git a/components/esp_rom/include/esp32c5/rom/bigint.h b/components/esp_rom/include/esp32c5/rom/bigint.h new file mode 100644 index 000000000000..ef82674b330a --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/bigint.h @@ -0,0 +1,35 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_BIGINT_H_ +#define _ROM_BIGINT_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void ets_bigint_enable(void); + +void ets_bigint_disable(void); + +int ets_bigint_multiply(const uint32_t *x, const uint32_t *y, uint32_t len_words); + +int ets_bigint_modmult(const uint32_t *x, const uint32_t *y, const uint32_t *m, uint32_t m_dash, const uint32_t *rb, uint32_t len_words); + +int ets_bigint_modexp(const uint32_t *x, const uint32_t *y, const uint32_t *m, uint32_t m_dash, const uint32_t *rb, bool constant_time, uint32_t len_words); + +void ets_bigint_wait_finish(void); + +int ets_bigint_getz(uint32_t *z, uint32_t len_words); + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_BIGINT_H_ */ diff --git a/components/esp_rom/include/esp32c5/rom/cache.h b/components/esp_rom/include/esp32c5/rom/cache.h new file mode 100644 index 000000000000..dfa657e865ba --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/cache.h @@ -0,0 +1,609 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include "esp_bit_defs.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup cache_apis, cache operation related apis + * @brief cache apis + */ + +/** @addtogroup cache_apis + * @{ + */ +#define MIN_ICACHE_SIZE 16384 +#define MAX_ICACHE_SIZE 16384 +#define MIN_ICACHE_WAYS 8 +#define MAX_ICACHE_WAYS 8 +#define MAX_CACHE_WAYS 8 +#define MIN_CACHE_LINE_SIZE 32 +#define TAG_SIZE 4 +#define MIN_ICACHE_BANK_NUM 1 +#define MAX_ICACHE_BANK_NUM 1 +#define CACHE_MEMORY_BANK_NUM 1 +#define CACHE_MEMORY_IBANK_SIZE 0x4000 + +#define MAX_ITAG_BANK_ITEMS (MAX_ICACHE_SIZE / MAX_ICACHE_BANK_NUM / MIN_CACHE_LINE_SIZE) +#define MAX_ITAG_BLOCK_ITEMS (MAX_ICACHE_SIZE / MAX_ICACHE_BANK_NUM / MAX_ICACHE_WAYS / MIN_CACHE_LINE_SIZE) +#define MAX_ITAG_BANK_SIZE (MAX_ITAG_BANK_ITEMS * TAG_SIZE) +#define MAX_ITAG_BLOCK_SIZE (MAX_ITAG_BLOCK_ITEMS * TAG_SIZE) + +typedef enum { + CACHE_SIZE_HALF = 0, /*!< 8KB for icache and dcache */ + CACHE_SIZE_FULL = 1, /*!< 16KB for icache and dcache */ +} cache_size_t; + +typedef enum { + CACHE_4WAYS_ASSOC = 0, /*!< 4 way associated cache */ + CACHE_8WAYS_ASSOC = 1, /*!< 8 way associated cache */ +} cache_ways_t; + +typedef enum { + CACHE_LINE_SIZE_16B = 0, /*!< 16 Byte cache line size */ + CACHE_LINE_SIZE_32B = 1, /*!< 32 Byte cache line size */ + CACHE_LINE_SIZE_64B = 2, /*!< 64 Byte cache line size */ +} cache_line_size_t; + +typedef enum { + CACHE_AUTOLOAD_POSITIVE = 0, /*!< cache autoload step is positive */ + CACHE_AUTOLOAD_NEGATIVE = 1, /*!< cache autoload step is negative */ +} cache_autoload_order_t; + +#define CACHE_AUTOLOAD_STEP(i) ((i) - 1) + +typedef enum { + CACHE_AUTOLOAD_MISS_TRIGGER = 0, /*!< autoload only triggered by cache miss */ + CACHE_AUTOLOAD_HIT_TRIGGER = 1, /*!< autoload only triggered by cache hit */ + CACHE_AUTOLOAD_BOTH_TRIGGER = 2, /*!< autoload triggered both by cache miss and hit */ +} cache_autoload_trigger_t; + +typedef enum { + CACHE_FREEZE_ACK_BUSY = 0, /*!< in this mode, cache ack busy to CPU if a cache miss happens*/ + CACHE_FREEZE_ACK_ERROR = 1, /*!< in this mode, cache ack wrong data to CPU and trigger an error if a cache miss happens */ +} cache_freeze_mode_t; + +typedef enum { + MMU_PAGE_MODE_64KB = 0, + MMU_PAGE_MODE_32KB = 1, + MMU_PAGE_MODE_16KB = 2, + MMU_PAGE_MODE_8KB = 3, + MMU_PAGE_MODE_INVALID, +} mmu_page_mode_t; + +struct cache_mode { + uint32_t cache_size; /*!< cache size in byte */ + uint16_t cache_line_size; /*!< cache line size in byte */ + uint8_t cache_ways; /*!< cache ways, always 4 */ + uint8_t ibus; /*!< the cache index, 0 for dcache, 1 for icache */ +}; + +struct icache_tag_item { + uint32_t valid:1; /*!< the tag item is valid or not */ + uint32_t lock:1; /*!< the cache line is locked or not */ + uint32_t fifo_cnt:3; /*!< fifo cnt, 0 ~ 3 for 4 ways cache */ + uint32_t tag:13; /*!< the tag is the high part of the cache address, however is only 16MB (8MB Ibus + 8MB Dbus) range, and without low part */ + uint32_t reserved:14; +}; + +struct autoload_config { + uint8_t order; /*!< autoload step is positive or negative */ + uint8_t trigger; /*!< autoload trigger */ + uint8_t ena0; /*!< autoload region0 enable */ + uint8_t ena1; /*!< autoload region1 enable */ + uint32_t addr0; /*!< autoload region0 start address */ + uint32_t size0; /*!< autoload region0 size */ + uint32_t addr1; /*!< autoload region1 start address */ + uint32_t size1; /*!< autoload region1 size */ +}; + +struct tag_group_info { + struct cache_mode mode; /*!< cache and cache mode */ + uint32_t filter_addr; /*!< the address that used to generate the struct */ + uint32_t vaddr_offset; /*!< virtual address offset of the cache ways */ + uint32_t tag_addr[MAX_CACHE_WAYS]; /*!< tag memory address, only [0~mode.ways-1] is valid to use */ + uint32_t cache_memory_offset[MAX_CACHE_WAYS]; /*!< cache memory address, only [0~mode.ways-1] is valid to use */ +}; + +struct lock_config { + uint32_t addr; /*!< manual lock address*/ + uint16_t size; /*!< manual lock size*/ + uint16_t group; /*!< manual lock group, 0 or 1*/ +}; + +struct cache_internal_stub_table { + uint32_t (* icache_line_size)(void); + uint32_t (* icache_addr)(uint32_t addr); + uint32_t (* dcache_addr)(uint32_t addr); + void (* invalidate_icache_items)(uint32_t addr, uint32_t items); + void (* lock_icache_items)(uint32_t addr, uint32_t items); + void (* unlock_icache_items)(uint32_t addr, uint32_t items); + uint32_t (* suspend_icache_autoload)(void); + void (* resume_icache_autoload)(uint32_t autoload); + void (* freeze_icache_enable)(cache_freeze_mode_t mode); + void (* freeze_icache_disable)(void); + int (* op_addr)(uint32_t start_addr, uint32_t size, uint32_t cache_line_size, uint32_t max_sync_num, void(* cache_Iop)(uint32_t, uint32_t)); +}; + +/* Defined in the interface file, default value is rom_default_cache_internal_table */ +extern const struct cache_internal_stub_table* rom_cache_internal_table_ptr; + +typedef void (* cache_op_start)(void); +typedef void (* cache_op_end)(void); + +typedef struct { + cache_op_start start; + cache_op_end end; +} cache_op_cb_t; + +/* Defined in the interface file, default value is NULL */ +extern const cache_op_cb_t* rom_cache_op_cb; + +#define ESP_ROM_ERR_INVALID_ARG 1 +#define MMU_SET_ADDR_ALIGNED_ERROR 2 +#define MMU_SET_PASE_SIZE_ERROR 3 +#define MMU_SET_VADDR_OUT_RANGE 4 + +#define CACHE_OP_ICACHE_Y 1 +#define CACHE_OP_ICACHE_N 0 + +/** + * @brief Initialise cache mmu, mark all entries as invalid. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return None + */ +void Cache_MMU_Init(void); + +/** + * @brief Init Cache for ROM boot, including resetting the Icache, initializing MMU, Enabling ICache, unmasking bus. + * + * @param None + * + * @return None + */ +void ROM_Boot_Cache_Init(void); + +/** + * @brief Set ICache mmu mapping. + * Please do not call this function in your SDK application. + * + * @param uint32_t senitive : Config this page should apply flash encryption or not + * + * @param uint32_t ext_ram : DPORT_MMU_ACCESS_FLASH for flash, DPORT_MMU_INVALID for invalid. In + * esp32c6, external memory is always flash + * + * @param uint32_t vaddr : virtual address in CPU address space. + * Can be Iram0,Iram1,Irom0,Drom0 and AHB buses address. + * Should be aligned by psize. + * + * @param uint32_t paddr : physical address in external memory. + * Should be aligned by psize. + * + * @param uint32_t psize : page size of ICache, in kilobytes. Should be 64 here. + * + * @param uint32_t num : pages to be set. + * + * @param uint32_t fixed : 0 for physical pages grow with virtual pages, other for virtual pages map to same physical page. + * + * @return uint32_t: error status + * 0 : mmu set success + * 2 : vaddr or paddr is not aligned + * 3 : psize error + * 4 : vaddr is out of range + */ +int Cache_MSPI_MMU_Set(uint32_t sensitive, uint32_t ext_ram, uint32_t vaddr, uint32_t paddr, uint32_t psize, uint32_t num, uint32_t fixed); + +/** + * @brief Set DCache mmu mapping. + * Please do not call this function in your SDK application. + * + * @param uint32_t ext_ram : DPORT_MMU_ACCESS_FLASH for flash, DPORT_MMU_INVALID for invalid. In + * esp32c6, external memory is always flash + * + * @param uint32_t vaddr : virtual address in CPU address space. + * Can be DRam0, DRam1, DRom0, DPort and AHB buses address. + * Should be aligned by psize. + * + * @param uint32_t paddr : physical address in external memory. + * Should be aligned by psize. + * + * @param uint32_t psize : page size of DCache, in kilobytes. Should be 64 here. + * + * @param uint32_t num : pages to be set. + + * @param uint32_t fixed : 0 for physical pages grow with virtual pages, other for virtual pages map to same physical page. + * + * @return uint32_t: error status + * 0 : mmu set success + * 2 : vaddr or paddr is not aligned + * 3 : psize error + * 4 : vaddr is out of range + */ +int Cache_Dbus_MMU_Set(uint32_t ext_ram, uint32_t vaddr, uint32_t paddr, uint32_t psize, uint32_t num, uint32_t fixed); + + +/** + * @brief Get cache mode of ICache or DCache. + * Please do not call this function in your SDK application. + * + * @param struct cache_mode * mode : the pointer of cache mode struct, caller should set the icache field + * + * return none + */ +void Cache_Get_Mode(struct cache_mode * mode); + +/** + * @brief Set cache page mode. + * + * @param mmu_page_mode_t + * + * @return None + */ +void MMU_Set_Page_Mode(mmu_page_mode_t pg_mode); + +/** + * @brief Get cache page mode. + * + * @param None + * + * @return page mode + */ +mmu_page_mode_t MMU_Get_Page_Mode(void); + +/** + * @brief Invalidate the cache items for ICache. + * Operation will be done CACHE_LINE_SIZE aligned. + * If the region is not in ICache addr room, nothing will be done. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr: start address to invalidate + * + * @param uint32_t items: cache lines to invalidate, items * cache_line_size should not exceed the bus address size(16MB/32MB/64MB) + * + * @return None + */ +void Cache_Invalidate_ICache_Items(uint32_t addr, uint32_t items); + +/** + * @brief Invalidate the Cache items in the region from ICache or DCache. + * If the region is not in Cache addr room, nothing will be done. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr : invalidated region start address. + * + * @param uint32_t size : invalidated region size. + * + * @return 0 for success + * 1 for invalid argument + */ +int Cache_Invalidate_Addr(uint32_t addr, uint32_t size); + +/** + * @brief Invalidate all cache items in ICache. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return None + */ +void Cache_Invalidate_ICache_All(void); + +/** + * @brief Mask all buses through ICache and DCache. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return None + */ +void Cache_Mask_All(void); + +/** + * @brief Suspend ICache auto preload operation, then you can resume it after some ICache operations. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return uint32_t : 0 for ICache not auto preload before suspend. + */ +uint32_t Cache_Suspend_ICache_Autoload(void); + +/** + * @brief Resume ICache auto preload operation after some ICache operations. + * Please do not call this function in your SDK application. + * + * @param uint32_t autoload : 0 for ICache not auto preload before suspend. + * + * @return None. + */ +void Cache_Resume_ICache_Autoload(uint32_t autoload); + +/** + * @brief Start an ICache manual preload, will suspend auto preload of ICache. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr : start address of the preload region. + * + * @param uint32_t size : size of the preload region, should not exceed the size of ICache. + * + * @param uint32_t order : the preload order, 0 for positive, other for negative + * + * @return uint32_t : 0 for ICache not auto preload before manual preload. + */ +uint32_t Cache_Start_ICache_Preload(uint32_t addr, uint32_t size, uint32_t order); + +/** + * @brief Return if the ICache manual preload done. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return uint32_t : 0 for ICache manual preload not done. + */ +uint32_t Cache_ICache_Preload_Done(void); + +/** + * @brief End the ICache manual preload to resume auto preload of ICache. + * Please do not call this function in your SDK application. + * + * @param uint32_t autoload : 0 for ICache not auto preload before manual preload. + * + * @return None + */ +void Cache_End_ICache_Preload(uint32_t autoload); + +/** + * @brief Config autoload parameters of ICache. + * Please do not call this function in your SDK application. + * + * @param struct autoload_config * config : autoload parameters. + * + * @return None + */ +void Cache_Config_ICache_Autoload(const struct autoload_config * config); + +/** + * @brief Enable auto preload for ICache. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return None + */ +void Cache_Enable_ICache_Autoload(void); + +/** + * @brief Disable auto preload for ICache. + * Please do not call this function in your SDK application. + * + * @param None + * + * @return None + */ +void Cache_Disable_ICache_Autoload(void); + +/** + * @brief Config a group of prelock parameters of ICache. + * Please do not call this function in your SDK application. + * + * @param struct lock_config * config : a group of lock parameters. + * + * @return None + */ + +void Cache_Enable_ICache_PreLock(const struct lock_config *config); + +/** + * @brief Disable a group of prelock parameters for ICache. + * However, the locked data will not be released. + * Please do not call this function in your SDK application. + * + * @param uint16_t group : 0 for group0, 1 for group1. + * + * @return None + */ +void Cache_Disable_ICache_PreLock(uint16_t group); + +/** + * @brief Lock the cache items for ICache. + * Operation will be done CACHE_LINE_SIZE aligned. + * If the region is not in ICache addr room, nothing will be done. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr: start address to lock + * + * @param uint32_t items: cache lines to lock, items * cache_line_size should not exceed the bus address size(16MB/32MB/64MB) + * + * @return None + */ +void Cache_Lock_ICache_Items(uint32_t addr, uint32_t items); + +/** + * @brief Unlock the cache items for ICache. + * Operation will be done CACHE_LINE_SIZE aligned. + * If the region is not in ICache addr room, nothing will be done. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr: start address to unlock + * + * @param uint32_t items: cache lines to unlock, items * cache_line_size should not exceed the bus address size(16MB/32MB/64MB) + * + * @return None + */ +void Cache_Unlock_ICache_Items(uint32_t addr, uint32_t items); + +/** + * @brief Lock the cache items in tag memory for ICache or DCache. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr : start address of lock region. + * + * @param uint32_t size : size of lock region. + * + * @return 0 for success + * 1 for invalid argument + */ +int Cache_Lock_Addr(uint32_t addr, uint32_t size); + +/** + * @brief Unlock the cache items in tag memory for ICache or DCache. + * Please do not call this function in your SDK application. + * + * @param uint32_t addr : start address of unlock region. + * + * @param uint32_t size : size of unlock region. + * + * @return 0 for success + * 1 for invalid argument + */ +int Cache_Unlock_Addr(uint32_t addr, uint32_t size); + +/** + * @brief Disable ICache access for the cpu. + * This operation will make all ICache tag memory invalid, CPU can't access ICache, ICache will keep idle. + * Please do not call this function in your SDK application. + * + * @return uint32_t : auto preload enabled before + */ +uint32_t Cache_Disable_ICache(void); + +/** + * @brief Enable ICache access for the cpu. + * Please do not call this function in your SDK application. + * + * @param uint32_t autoload : ICache will preload then. + * + * @return None + */ +void Cache_Enable_ICache(uint32_t autoload); + +/** + * @brief Suspend ICache access for the cpu. + * The ICache tag memory is still there, CPU can't access ICache, ICache will keep idle. + * Please do not change MMU, cache mode or tag memory(tag memory can be changed in some special case). + * Please do not call this function in your SDK application. + * + * @param None + * + * @return uint32_t : auto preload enabled before + */ +uint32_t Cache_Suspend_ICache(void); + +/** + * @brief Resume ICache access for the cpu. + * Please do not call this function in your SDK application. + * + * @param uint32_t autoload : ICache will preload then. + * + * @return None + */ +void Cache_Resume_ICache(uint32_t autoload); + +/** + * @brief Get ICache cache line size + * + * @param None + * + * @return uint32_t: 16, 32, 64 Byte + */ +uint32_t Cache_Get_ICache_Line_Size(void); + +/** + * @brief Enable freeze for ICache. + * Any miss request will be rejected, including cpu miss and preload/autoload miss. + * Please do not call this function in your SDK application. + * + * @param cache_freeze_mode_t mode : 0 for assert busy 1 for assert hit + * + * @return None + */ +void Cache_Freeze_ICache_Enable(cache_freeze_mode_t mode); + +/** + * @brief Disable freeze for ICache. + * Please do not call this function in your SDK application. + * + * @return None + */ +void Cache_Freeze_ICache_Disable(void); + +/** + * @brief Travel tag memory to run a call back function. + * ICache and DCache are suspend when doing this. + * The callback will get the parameter tag_group_info, which will include a group of tag memory addresses and cache memory addresses. + * Please do not call this function in your SDK application. + * + * @param struct cache_mode * mode : the cache to check and the cache mode. + * + * @param uint32_t filter_addr : only the cache lines which may include the filter_address will be returned to the call back function. + * 0 for do not filter, all cache lines will be returned. + * + * @param void (* process)(struct tag_group_info *) : call back function, which may be called many times, a group(the addresses in the group are in the same position in the cache ways) a time. + * + * @return None + */ +void Cache_Travel_Tag_Memory(struct cache_mode * mode, uint32_t filter_addr, void (* process)(struct tag_group_info *)); + +/** + * @brief Get the virtual address from cache mode, cache tag and the virtual address offset of cache ways. + * Please do not call this function in your SDK application. + * + * @param struct cache_mode * mode : the cache to calculate the virtual address and the cache mode. + * + * @param uint32_t tag : the tag part fo a tag item, 12-14 bits. + * + * @param uint32_t addr_offset : the virtual address offset of the cache ways. + * + * @return uint32_t : the virtual address. + */ +uint32_t Cache_Get_Virtual_Addr(struct cache_mode *mode, uint32_t tag, uint32_t vaddr_offset); + +/** + * @} + */ + +/** + * @brief Get the cache MMU IROM end address. + * Please do not call this function in your SDK application. + * + * @param void + * + * @return uint32_t : the word value of the address. + */ +uint32_t Cache_Get_IROM_MMU_End(void); + +/** + * @brief Get the cache MMU DROM end address. + * Please do not call this function in your SDK application. + * + * @param void + * + * @return uint32_t : the word value of the address. + */ +uint32_t Cache_Get_DROM_MMU_End(void); + +/** + * @brief Configure cache MMU page size according to instruction and rodata size + * + * @param irom_size The instruction cache MMU page size + * @param drom_size The rodata data cache MMU page size + */ +void Cache_Set_IDROM_MMU_Size(uint32_t irom_size, uint32_t drom_size); + +#define Cache_Dbus_MMU_Set(ext_ram, vaddr, paddr, psize, num, fixed) \ + Cache_MSPI_MMU_Set(ets_efuse_cache_encryption_enabled() ? SOC_MMU_SENSITIVE : 0, ext_ram, vaddr, paddr, psize, num, fixed) + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c5/rom/crc.h b/components/esp_rom/include/esp32c5/rom/crc.h new file mode 100644 index 000000000000..de7002f7a52d --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/crc.h @@ -0,0 +1,119 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ROM_CRC_H +#define ROM_CRC_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup crc_apis, uart configuration and communication related apis + * @brief crc apis + */ + +/** @addtogroup crc_apis + * @{ + */ + + +/* Standard CRC8/16/32 algorithms. */ +// CRC-8 x8+x2+x1+1 0x07 +// CRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS +// CRC32: +//G(x) = x32 +x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x1 + 1 +//If your buf is not continuous, you can use the first result to be the second parameter. + +/** + * @brief Crc32 value that is in little endian. + * + * @param uint32_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint32_t crc32_le(uint32_t crc, uint8_t const *buf, uint32_t len); + +/** + * @brief Crc32 value that is in big endian. + * + * @param uint32_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint32_t crc32_be(uint32_t crc, uint8_t const *buf, uint32_t len); + +/** + * @brief Crc16 value that is in little endian. + * + * @param uint16_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint16_t crc16_le(uint16_t crc, uint8_t const *buf, uint32_t len); + +/** + * @brief Crc16 value that is in big endian. + * + * @param uint16_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint16_t crc16_be(uint16_t crc, uint8_t const *buf, uint32_t len); + +/** + * @brief Crc8 value that is in little endian. + * + * @param uint8_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint8_t crc8_le(uint8_t crc, uint8_t const *buf, uint32_t len); + +/** + * @brief Crc8 value that is in big endian. + * + * @param uint32_t crc : init crc value, use 0 at the first use. + * + * @param uint8_t const *buf : buffer to start calculate crc. + * + * @param uint32_t len : buffer length in byte. + * + * @return None + */ +uint8_t crc8_be(uint8_t crc, uint8_t const *buf, uint32_t len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + + +#endif diff --git a/components/esp_rom/include/esp32c5/rom/digital_signature.h b/components/esp_rom/include/esp32c5/rom/digital_signature.h new file mode 100644 index 000000000000..e2f62bb15ef5 --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/digital_signature.h @@ -0,0 +1,142 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#define ETS_DS_MAX_BITS 3072 + +#define ETS_DS_IV_LEN 16 + +/* Length of parameter 'C' stored in flash (not including IV) + + Comprises encrypted Y, M, rinv, md (32), mprime (4), length (4), padding (8) + + Note that if ETS_DS_MAX_BITS<4096, 'C' needs to be split up when writing to hardware +*/ +#define ETS_DS_C_LEN ((ETS_DS_MAX_BITS * 3 / 8) + 32 + 8 + 8) + +/* Encrypted ETS data. Recommended to store in flash in this format. + */ +typedef struct { + /* RSA LENGTH register parameters + * (number of words in RSA key & operands, minus one). + * + * + * This value must match the length field encrypted and stored in 'c', + * or invalid results will be returned. (The DS peripheral will + * always use the value in 'c', not this value, so an attacker can't + * alter the DS peripheral results this way, it will just truncate or + * extend the message and the resulting signature in software.) + */ + unsigned rsa_length; + + /* IV value used to encrypt 'c' */ + uint8_t iv[ETS_DS_IV_LEN]; + + /* Encrypted Digital Signature parameters. Result of AES-CBC encryption + of plaintext values. Includes an encrypted message digest. + */ + uint8_t c[ETS_DS_C_LEN]; +} ets_ds_data_t; + +typedef enum { + ETS_DS_OK, + ETS_DS_INVALID_PARAM, /* Supplied parameters are invalid */ + ETS_DS_INVALID_KEY, /* HMAC peripheral failed to supply key */ + ETS_DS_INVALID_PADDING, /* 'c' decrypted with invalid padding */ + ETS_DS_INVALID_DIGEST, /* 'c' decrypted with invalid digest */ +} ets_ds_result_t; + +void ets_ds_enable(void); + +void ets_ds_disable(void); + + +/* + * @brief Start signing a message (or padded message digest) using the Digital Signature peripheral + * + * - @param message Pointer to message (or padded digest) containing the message to sign. Should be + * (data->rsa_length + 1)*4 bytes long. @param data Pointer to DS data. Can be a pointer to data + * in flash. + * + * Caller must have already called ets_ds_enable() and ets_hmac_calculate_downstream() before calling + * this function, and is responsible for calling ets_ds_finish_sign() and then + * ets_hmac_invalidate_downstream() afterwards. + * + * @return ETS_DS_OK if signature is in progress, ETS_DS_INVALID_PARAM if param is invalid, + * EST_DS_INVALID_KEY if key or HMAC peripheral is configured incorrectly. + */ +ets_ds_result_t ets_ds_start_sign(const void *message, const ets_ds_data_t *data); + + +/* + * @brief Returns true if the DS peripheral is busy following a call to ets_ds_start_sign() + * + * A result of false indicates that a call to ets_ds_finish_sign() will not block. + * + * Only valid if ets_ds_enable() has been called. + */ +bool ets_ds_is_busy(void); + + +/* @brief Finish signing a message using the Digital Signature peripheral + * + * Must be called after ets_ds_start_sign(). Can use ets_ds_busy() to wait until + * peripheral is no longer busy. + * + * - @param signature Pointer to buffer to contain the signature. Should be + * (data->rsa_length + 1)*4 bytes long. + * - @param data Should match the 'data' parameter passed to ets_ds_start_sign() + * + * @param ETS_DS_OK if signing succeeded, ETS_DS_INVALID_PARAM if param is invalid, + * ETS_DS_INVALID_DIGEST or ETS_DS_INVALID_PADDING if there is a problem with the + * encrypted data digest or padding bytes (in case of ETS_DS_INVALID_PADDING, a + * digest is produced anyhow.) + */ +ets_ds_result_t ets_ds_finish_sign(void *signature, const ets_ds_data_t *data); + + +/* Plaintext parameters used by Digital Signature. + + Not used for signing with DS peripheral, but can be encrypted + in-device by calling ets_ds_encrypt_params() +*/ +typedef struct { + uint32_t Y[ETS_DS_MAX_BITS / 32]; + uint32_t M[ETS_DS_MAX_BITS / 32]; + uint32_t Rb[ETS_DS_MAX_BITS / 32]; + uint32_t M_prime; + uint32_t length; +} ets_ds_p_data_t; + +typedef enum { + ETS_DS_KEY_HMAC, /* The HMAC key (as stored in efuse) */ + ETS_DS_KEY_AES, /* The AES key (as derived from HMAC key by HMAC peripheral in downstream mode) */ +} ets_ds_key_t; + +/* @brief Encrypt DS parameters suitable for storing and later use with DS peripheral + * + * @param data Output buffer to store encrypted data, suitable for later use generating signatures. + * @param iv Pointer to 16 byte IV buffer, will be copied into 'data'. Should be randomly generated bytes each time. + * @param p_data Pointer to input plaintext key data. The expectation is this data will be deleted after this process is done and 'data' is stored. + * @param key Pointer to 32 bytes of key data. Type determined by key_type parameter. The expectation is the corresponding HMAC key will be stored to efuse and then permanently erased. + * @param key_type Type of key stored in 'key' (either the AES-256 DS key, or an HMAC DS key from which the AES DS key is derived using HMAC peripheral) + * + * @return ETS_DS_INVALID_PARAM if any parameter is invalid, or ETS_DS_OK if 'data' is successfully generated from the input parameters. + */ +ets_ds_result_t ets_ds_encrypt_params(ets_ds_data_t *data, const void *iv, const ets_ds_p_data_t *p_data, const void *key, ets_ds_key_t key_type); + + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c5/rom/ecdsa.h b/components/esp_rom/include/esp32c5/rom/ecdsa.h new file mode 100644 index 000000000000..7be1fada95b3 --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/ecdsa.h @@ -0,0 +1,26 @@ +/* + * SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ETS_DIGEST_LEN 32 /* SHA-256, bytes */ + +typedef enum { + ECDSA_CURVE_P192 = 1, + ECDSA_CURVE_P256 = 2 +} ECDSA_CURVE; + +int ets_ecdsa_verify(const uint8_t *key, const uint8_t *sig, ECDSA_CURVE curve_id, const uint8_t *digest, uint8_t *verified_digest); + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c5/rom/efuse.h b/components/esp_rom/include/esp32c5/rom/efuse.h new file mode 100644 index 000000000000..6cd9f4b377ec --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/efuse.h @@ -0,0 +1,283 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_EFUSE_H_ +#define _ROM_EFUSE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +/** \defgroup efuse_APIs efuse APIs + * @brief ESP32 efuse read/write APIs + * @attention + * + */ + +/** @addtogroup efuse_APIs + * @{ + */ + +typedef enum { + ETS_EFUSE_KEY_PURPOSE_USER = 0, + ETS_EFUSE_KEY_PURPOSE_RESERVED = 1, + ETS_EFUSE_KEY_PURPOSE_XTS_AES_128_KEY = 4, + ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL = 5, + ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG = 6, + ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE = 7, + ETS_EFUSE_KEY_PURPOSE_HMAC_UP = 8, + ETS_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST0 = 9, + ETS_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST1 = 10, + ETS_EFUSE_KEY_PURPOSE_SECURE_BOOT_DIGEST2 = 11, + ETS_EFUSE_KEY_PURPOSE_MAX, +} ets_efuse_purpose_t; + +typedef enum { + ETS_EFUSE_BLOCK0 = 0, + ETS_EFUSE_MAC_SPI_SYS_0 = 1, + ETS_EFUSE_BLOCK_SYS_DATA = 2, + ETS_EFUSE_BLOCK_USR_DATA = 3, + ETS_EFUSE_BLOCK_KEY0 = 4, + ETS_EFUSE_BLOCK_KEY1 = 5, + ETS_EFUSE_BLOCK_KEY2 = 6, + ETS_EFUSE_BLOCK_KEY3 = 7, + ETS_EFUSE_BLOCK_KEY4 = 8, + ETS_EFUSE_BLOCK_KEY5 = 9, + ETS_EFUSE_BLOCK_KEY6 = 10, + ETS_EFUSE_BLOCK_MAX, +} ets_efuse_block_t; + +/** + * @brief Efuse read operation: copies data from physical efuses to efuse read registers. + * + * @param null + * + * @return : 0 if success, others if apb clock is not accepted + */ +int ets_efuse_read(void); + +/** + * @brief Efuse write operation: Copies data from efuse write registers to efuse. Operates on a single block of efuses at a time. + * + * @note This function does not update read efuses, call ets_efuse_read() once all programming is complete. + * + * @return : 0 if success, others if apb clock is not accepted + */ +int ets_efuse_program(ets_efuse_block_t block); + +/** + * @brief Set all Efuse program registers to zero. + * + * Call this before writing new data to the program registers. + */ +void ets_efuse_clear_program_registers(void); + +/** + * @brief Program a block of key data to an efuse block + * + * @param key_block Block to read purpose for. Must be in range ETS_EFUSE_BLOCK_KEY0 to ETS_EFUSE_BLOCK_KEY6. Key block must be unused (@ref ets_efuse_key_block_unused). + * @param purpose Purpose to set for this key. Purpose must be already unset. + * @param data Pointer to data to write. + * @param data_len Length of data to write. + * + * @note This function also calls ets_efuse_program() for the specified block, and for block 0 (setting the purpose) + */ +int ets_efuse_write_key(ets_efuse_block_t key_block, ets_efuse_purpose_t purpose, const void *data, size_t data_len); + + +/* @brief Return the address of a particular efuse block's first read register + * + * @param block Index of efuse block to look up + * + * @return 0 if block is invalid, otherwise a numeric read register address + * of the first word in the block. + */ +uint32_t ets_efuse_get_read_register_address(ets_efuse_block_t block); + +/** + * @brief Return the current purpose set for an efuse key block + * + * @param key_block Block to read purpose for. Must be in range ETS_EFUSE_BLOCK_KEY0 to ETS_EFUSE_BLOCK_KEY6. + */ +ets_efuse_purpose_t ets_efuse_get_key_purpose(ets_efuse_block_t key_block); + +/** + * @brief Find a key block with the particular purpose set + * + * @param purpose Purpose to search for. + * @param[out] key_block Pointer which will be set to the key block if found. Can be NULL, if only need to test the key block exists. + * @return true if found, false if not found. If false, value at key_block pointer is unchanged. + */ +bool ets_efuse_find_purpose(ets_efuse_purpose_t purpose, ets_efuse_block_t *key_block); + +/** + * Return true if the key block is unused, false otherwise. + * + * An unused key block is all zero content, not read or write protected, + * and has purpose 0 (ETS_EFUSE_KEY_PURPOSE_USER) + * + * @param key_block key block to check. + * + * @return true if key block is unused, false if key block or used + * or the specified block index is not a key block. + */ +bool ets_efuse_key_block_unused(ets_efuse_block_t key_block); + + +/** + * @brief Search for an unused key block and return the first one found. + * + * See @ref ets_efuse_key_block_unused for a description of an unused key block. + * + * @return First unused key block, or ETS_EFUSE_BLOCK_MAX if no unused key block is found. + */ +ets_efuse_block_t ets_efuse_find_unused_key_block(void); + +/** + * @brief Return the number of unused efuse key blocks (0-6) + */ +unsigned ets_efuse_count_unused_key_blocks(void); + +/** + * @brief Calculate Reed-Solomon Encoding values for a block of efuse data. + * + * @param data Pointer to data buffer (length 32 bytes) + * @param rs_values Pointer to write encoded data to (length 12 bytes) + */ +void ets_efuse_rs_calculate(const void *data, void *rs_values); + +/** + * @brief Read if download mode disabled from Efuse + * + * @return + * - true for efuse disable download mode. + * - false for efuse doesn't disable download mode. + */ +bool ets_efuse_download_modes_disabled(void); + +/** + * @brief Read if uart print control value from Efuse + * + * @return + * - 0 for uart force print. + * - 1 for uart print when GPIO8 is low when digital reset. + * 2 for uart print when GPIO8 is high when digital reset. + * 3 for uart force slient + */ +uint32_t ets_efuse_get_uart_print_control(void); + +/** + * @brief Read if usb download mode disabled from Efuse + * + * (Also returns true if security download mode is enabled, as this mode + * disables USB download.) + * + * @return + * - true for efuse disable usb download mode. + * - false for efuse doesn't disable usb download mode. + */ +bool ets_efuse_usb_download_mode_disabled(void); + +/** + * @brief Read if security download modes enabled from Efuse + * + * @return + * - true for efuse enable security download mode. + * - false for efuse doesn't enable security download mode. + */ +bool ets_efuse_security_download_modes_enabled(void); + +/** + * @brief Return true if secure boot is enabled in EFuse + */ +bool ets_efuse_secure_boot_enabled(void); + +/** + * @brief Return true if secure boot aggressive revoke is enabled in EFuse + */ +bool ets_efuse_secure_boot_aggressive_revoke_enabled(void); + +/** + * @brief Return true if cache encryption (flash, etc) is enabled from boot via EFuse + */ +bool ets_efuse_cache_encryption_enabled(void); + +/** + * @brief Return true if EFuse indicates to send a flash resume command. + */ +bool ets_efuse_force_send_resume(void); + +/** + * @brief return the time in us ROM boot need wait flash to power on from Efuse + * + * @return + * - uint32_t the time in us. + */ +uint32_t ets_efuse_get_flash_delay_us(void); + +#define EFUSE_SPICONFIG_SPI_DEFAULTS 0 +#define EFUSE_SPICONFIG_HSPI_DEFAULTS 1 + +#define EFUSE_SPICONFIG_RET_SPICLK_MASK 0x3f +#define EFUSE_SPICONFIG_RET_SPICLK_SHIFT 0 +#define EFUSE_SPICONFIG_RET_SPICLK(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPICLK_SHIFT) & EFUSE_SPICONFIG_RET_SPICLK_MASK) + +#define EFUSE_SPICONFIG_RET_SPIQ_MASK 0x3f +#define EFUSE_SPICONFIG_RET_SPIQ_SHIFT 6 +#define EFUSE_SPICONFIG_RET_SPIQ(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPIQ_SHIFT) & EFUSE_SPICONFIG_RET_SPIQ_MASK) + +#define EFUSE_SPICONFIG_RET_SPID_MASK 0x3f +#define EFUSE_SPICONFIG_RET_SPID_SHIFT 12 +#define EFUSE_SPICONFIG_RET_SPID(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPID_SHIFT) & EFUSE_SPICONFIG_RET_SPID_MASK) + +#define EFUSE_SPICONFIG_RET_SPICS0_MASK 0x3f +#define EFUSE_SPICONFIG_RET_SPICS0_SHIFT 18 +#define EFUSE_SPICONFIG_RET_SPICS0(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPICS0_SHIFT) & EFUSE_SPICONFIG_RET_SPICS0_MASK) + + +#define EFUSE_SPICONFIG_RET_SPIHD_MASK 0x3f +#define EFUSE_SPICONFIG_RET_SPIHD_SHIFT 24 +#define EFUSE_SPICONFIG_RET_SPIHD(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPIHD_SHIFT) & EFUSE_SPICONFIG_RET_SPIHD_MASK) + +/** + * @brief Enable JTAG temporarily by writing a JTAG HMAC "key" into + * the JTAG_CTRL registers. + * + * Works if JTAG has been "soft" disabled by burning the EFUSE_SOFT_DIS_JTAG efuse. + * + * Will enable the HMAC module to generate a "downstream" HMAC value from a key already saved in efuse, and then write the JTAG HMAC "key" which will enable JTAG if the two keys match. + * + * @param jtag_hmac_key Pointer to a 32 byte array containing a valid key. Supplied by user. + * @param key_block Index of a key block containing the source for this key. + * + * @return ETS_FAILED if HMAC operation fails or invalid parameter, ETS_OK otherwise. ETS_OK doesn't necessarily mean that JTAG was enabled. + */ +int ets_jtag_enable_temporarily(const uint8_t *jtag_hmac_key, ets_efuse_block_t key_block); + +/** + * @brief A crc8 algorithm used for MAC addresses in efuse + * + * @param unsigned char const *p : Pointer to original data. + * + * @param unsigned int len : Data length in byte. + * + * @return unsigned char: Crc value. + */ +unsigned char esp_crc8(unsigned char const *p, unsigned int len); + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_EFUSE_H_ */ diff --git a/components/esp_rom/include/esp32c5/rom/ets_sys.h b/components/esp_rom/include/esp32c5/rom/ets_sys.h new file mode 100644 index 000000000000..7c04af3a54ce --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/ets_sys.h @@ -0,0 +1,432 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_ETS_SYS_H_ +#define _ROM_ETS_SYS_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup ets_sys_apis, ets system related apis + * @brief ets system apis + */ + +/** @addtogroup ets_sys_apis + * @{ + */ + +/************************************************************************ + * NOTE + * Many functions in this header files can't be run in FreeRTOS. + * Please see the comment of the Functions. + * There are also some functions that doesn't work on FreeRTOS + * without listed in the header, such as: + * xtos functions start with "_xtos_" in ld file. + * + *********************************************************************** + */ + +/** \defgroup ets_apis, Espressif Task Scheduler related apis + * @brief ets apis + */ + +/** @addtogroup ets_apis + * @{ + */ + +typedef enum { + ETS_OK = 0, /**< return successful in ets*/ + ETS_FAILED = 1, /**< return failed in ets*/ + ETS_PENDING = 2, + ETS_BUSY = 3, + ETS_CANCEL = 4, +} ETS_STATUS; + +typedef ETS_STATUS ets_status_t; + +typedef uint32_t ETSSignal; +typedef uint32_t ETSParam; + +typedef struct ETSEventTag ETSEvent; /**< Event transmit/receive in ets*/ + +struct ETSEventTag { + ETSSignal sig; /**< Event signal, in same task, different Event with different signal*/ + ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/ +}; + +typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processer*/ +typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callback*/ + + + + + +/** + * @} + */ + +/** \defgroup ets_boot_apis, Boot routing related apis + * @brief ets boot apis + */ + +/** @addtogroup ets_apis + * @{ + */ + +extern const char *const exc_cause_table[40]; ///**< excption cause that defined by the core.*/ + +/** + * @brief Set Pro cpu Entry code, code can be called in PRO CPU when booting is not completed. + * When Pro CPU booting is completed, Pro CPU will call the Entry code if not NULL. + * + * @param uint32_t start : the PRO Entry code address value in uint32_t + * + * @return None + */ +void ets_set_user_start(uint32_t start); + +/** + * @} + */ + +/** \defgroup ets_printf_apis, ets_printf related apis used in ets + * @brief ets printf apis + */ + +/** @addtogroup ets_printf_apis + * @{ + */ + +/** + * @brief Printf the strings to uart or other devices, similar with printf, simple than printf. + * Can not print float point data format, or longlong data format. + * So we maybe only use this in ROM. + * + * @param const char *fmt : See printf. + * + * @param ... : See printf. + * + * @return int : the length printed to the output device. + */ +int ets_printf(const char *fmt, ...); + +/** + * @brief Get the uart channel of ets_printf(uart_tx_one_char). + * + * @return uint8_t uart channel used by ets_printf(uart_tx_one_char). + */ +uint8_t ets_get_printf_channel(void); + +/** + * @brief Output a char to uart, which uart to output(which is in uart module in ROM) is not in scope of the function. + * Can not print float point data format, or longlong data format + * + * @param char c : char to output. + * + * @return None + */ +void ets_write_char_uart(char c); + +/** + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * To install putc1, which is defaulted installed as ets_write_char_uart in none silent boot mode, as NULL in silent mode. + * + * @param void (*)(char) p: Output function to install. + * + * @return None + */ +void ets_install_putc1(void (*p)(char c)); + +/** + * @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput. + * To install putc2, which is defaulted installed as NULL. + * + * @param void (*)(char) p: Output function to install. + * + * @return None + */ +void ets_install_putc2(void (*p)(char c)); + +/** + * @brief Install putc1 as ets_write_char_uart. + * In silent boot mode(to void interfere the UART attached MCU), we can call this function, after booting ok. + * + * @param None + * + * @return None + */ +void ets_install_uart_printf(void); + +#define ETS_PRINTF(...) ets_printf(...) + +#define ETS_ASSERT(v) do { \ + if (!(v)) { \ + ets_printf("%s %u \n", __FILE__, __LINE__); \ + while (1) {}; \ + } \ +} while (0); + +/** + * @} + */ + +/** \defgroup ets_timer_apis, ets_timer related apis used in ets + * @brief ets timer apis + */ + +/** @addtogroup ets_timer_apis + * @{ + */ +typedef void ETSTimerFunc(void *timer_arg);/**< timer handler*/ + +typedef struct _ETSTIMER_ { + struct _ETSTIMER_ *timer_next; /**< timer linker*/ + uint32_t timer_expire; /**< abstruct time when timer expire*/ + uint32_t timer_period; /**< timer period, 0 means timer is not periodic repeated*/ + ETSTimerFunc *timer_func; /**< timer handler*/ + void *timer_arg; /**< timer handler argument*/ +} ETSTimer; + +/** + * @brief Init ets timer, this timer range is 640 us to 429496 ms + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param None + * + * @return None + */ +void ets_timer_init(void); + +/** + * @brief In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param None + * + * @return None + */ +void ets_timer_deinit(void); + +/** + * @brief Arm an ets timer, this timer range is 640 us to 429496 ms. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param ETSTimer *timer : Timer struct pointer. + * + * @param uint32_t tmout : Timer value in ms, range is 1 to 429496. + * + * @param bool repeat : Timer is periodic repeated. + * + * @return None + */ +void ets_timer_arm(ETSTimer *timer, uint32_t tmout, bool repeat); + +/** + * @brief Arm an ets timer, this timer range is 640 us to 429496 ms. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param ETSTimer *timer : Timer struct pointer. + * + * @param uint32_t tmout : Timer value in us, range is 1 to 429496729. + * + * @param bool repeat : Timer is periodic repeated. + * + * @return None + */ +void ets_timer_arm_us(ETSTimer *ptimer, uint32_t us, bool repeat); + +/** + * @brief Disarm an ets timer. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param ETSTimer *timer : Timer struct pointer. + * + * @return None + */ +void ets_timer_disarm(ETSTimer *timer); + +/** + * @brief Set timer callback and argument. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param ETSTimer *timer : Timer struct pointer. + * + * @param ETSTimerFunc *pfunction : Timer callback. + * + * @param void *parg : Timer callback argument. + * + * @return None + */ +void ets_timer_setfn(ETSTimer *ptimer, ETSTimerFunc *pfunction, void *parg); + +/** + * @brief Unset timer callback and argument to NULL. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param ETSTimer *timer : Timer struct pointer. + * + * @return None + */ +void ets_timer_done(ETSTimer *ptimer); + +/** + * @brief CPU do while loop for some time. + * In FreeRTOS task, please call FreeRTOS apis. + * + * @param uint32_t us : Delay time in us. + * + * @return None + */ +void ets_delay_us(uint32_t us); + +/** + * @brief Set the real CPU ticks per us to the ets, so that ets_delay_us will be accurate. + * Call this function when CPU frequency is changed. + * + * @param uint32_t ticks_per_us : CPU ticks per us. + * + * @return None + */ +void ets_update_cpu_frequency(uint32_t ticks_per_us); + + + +/** + * @brief Get the real CPU ticks per us to the ets. + * This function do not return real CPU ticks per us, just the record in ets. It can be used to check with the real CPU frequency. + * + * @param None + * + * @return uint32_t : CPU ticks per us record in ets. + */ +uint32_t ets_get_cpu_frequency(void); + +/** + * @} + */ + +/** \defgroup ets_intr_apis, ets interrupt configure related apis + * @brief ets intr apis + */ + +/** @addtogroup ets_intr_apis + * @{ + */ + +typedef void (* ets_isr_t)(void *);/**< interrupt handler type*/ + +/** + * @brief Attach a interrupt handler to a CPU interrupt number. + * This function equals to _xtos_set_interrupt_handler_arg(i, func, arg). + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param int i : CPU interrupt number. + * + * @param ets_isr_t func : Interrupt handler. + * + * @param void *arg : argument of the handler. + * + * @return None + */ +void ets_isr_attach(int i, ets_isr_t func, void *arg); + +/** + * @brief Mask the interrupts which show in mask bits. + * This function equals to _xtos_ints_off(mask). + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param uint32_t mask : BIT(i) means mask CPU interrupt number i. + * + * @return None + */ +void ets_isr_mask(uint32_t mask); + +/** + * @brief Unmask the interrupts which show in mask bits. + * This function equals to _xtos_ints_on(mask). + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param uint32_t mask : BIT(i) means mask CPU interrupt number i. + * + * @return None + */ +void ets_isr_unmask(uint32_t unmask); + +/** + * @brief Lock the interrupt to level 2. + * This function direct set the CPU registers. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param None + * + * @return None + */ +void ets_intr_lock(void); + +/** + * @brief Unlock the interrupt to level 0. + * This function direct set the CPU registers. + * In FreeRTOS, please call FreeRTOS apis, never call this api. + * + * @param None + * + * @return None + */ +void ets_intr_unlock(void); + + +/** + * @brief Attach an CPU interrupt to a hardware source. + * We have 4 steps to use an interrupt: + * 1.Attach hardware interrupt source to CPU. intr_matrix_set(0, ETS_WIFI_MAC_INTR_SOURCE, ETS_WMAC_INUM); + * 2.Set interrupt handler. xt_set_interrupt_handler(ETS_WMAC_INUM, func, NULL); + * 3.Enable interrupt for CPU. xt_ints_on(1 << ETS_WMAC_INUM); + * 4.Enable interrupt in the module. + * + * @param int cpu_no : The CPU which the interrupt number belongs. + * + * @param uint32_t model_num : The interrupt hardware source number, please see the interrupt hardware source table. + * + * @param uint32_t intr_num : The interrupt number CPU, please see the interrupt cpu using table. + * + * @return None + */ +void intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num); + +/** + * @} + */ + +#ifndef MAC2STR +#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] +#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x" +#endif + +#define ETS_MEM_BAR() asm volatile ( "" : : : "memory" ) + +#ifdef ESP_PLATFORM +// Remove in IDF v6.0 (IDF-7044) +typedef enum { + OK = 0, + FAIL, + PENDING, + BUSY, + CANCEL, +} STATUS __attribute__((deprecated("Use ETS_STATUS instead"))); +#endif + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_ETS_SYS_H_ */ diff --git a/components/esp_rom/include/esp32c5/rom/hmac.h b/components/esp_rom/include/esp32c5/rom/hmac.h new file mode 100644 index 000000000000..126b8a46a102 --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/hmac.h @@ -0,0 +1,55 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_HMAC_H_ +#define _ROM_HMAC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "efuse.h" + +void ets_hmac_enable(void); + +void ets_hmac_disable(void); + +/* Use the "upstream" HMAC key (ETS_EFUSE_KEY_PURPOSE_HMAC_UP) + to digest a message. +*/ +int ets_hmac_calculate_message(ets_efuse_block_t key_block, const void *message, size_t message_len, uint8_t *hmac); + +/* Calculate a downstream HMAC message to temporarily enable JTAG, or + to generate a Digital Signature data decryption key. + + - purpose must be ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_DIGITAL_SIGNATURE + or ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_JTAG + + - key_block must be in range ETS_EFUSE_BLOCK_KEY0 toETS_EFUSE_BLOCK_KEY6. + This efuse block must have the corresponding purpose set in "purpose", or + ETS_EFUSE_KEY_PURPOSE_HMAC_DOWN_ALL. + + The result of this HMAC calculation is only made available "downstream" to the + corresponding hardware module, and cannot be accessed by software. +*/ +int ets_hmac_calculate_downstream(ets_efuse_block_t key_block, ets_efuse_purpose_t purpose); + +/* Invalidate a downstream HMAC value previously calculated by ets_hmac_calculate_downstream(). + * + * - purpose must match a previous call to ets_hmac_calculate_downstream(). + * + * After this function is called, the corresponding internal operation (JTAG or DS) will no longer + * have access to the generated key. + */ +int ets_hmac_invalidate_downstream(ets_efuse_purpose_t purpose); + +#ifdef __cplusplus +} +#endif + +#endif // _ROM_HMAC_H_ diff --git a/components/esp_rom/include/esp32c5/rom/libc_stubs.h b/components/esp_rom/include/esp32c5/rom/libc_stubs.h new file mode 100644 index 000000000000..cf1ffbbbf382 --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/libc_stubs.h @@ -0,0 +1,83 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _ROM_LIBC_STUBS_H_ +#define _ROM_LIBC_STUBS_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* +ESP32-C6 ROM code contains implementations of some of C library functions. +Whenever a function in ROM needs to use a syscall, it calls a pointer to the corresponding syscall +implementation defined in the following struct. + +The table itself, by default, is not allocated in RAM. A global pointer syscall_table_ptr is used to +set the address + +So, before using any of the C library functions (except for pure functions and memcpy/memset functions), +application must allocate syscall table structure for each CPU being used, and populate it with pointers +to actual implementations of corresponding syscalls. +*/ + +struct syscall_stub_table { + struct _reent *(*__getreent)(void); + void *(*_malloc_r)(struct _reent *r, size_t); + void (*_free_r)(struct _reent *r, void *); + void *(*_realloc_r)(struct _reent *r, void *, size_t); + void *(*_calloc_r)(struct _reent *r, size_t, size_t); + void (*_abort)(void); + int (*_system_r)(struct _reent *r, const char *); + int (*_rename_r)(struct _reent *r, const char *, const char *); + clock_t (*_times_r)(struct _reent *r, struct tms *); + int (*_gettimeofday_r) (struct _reent *r, struct timeval *, void *); + void (*_raise_r)(struct _reent *r); + int (*_unlink_r)(struct _reent *r, const char *); + int (*_link_r)(struct _reent *r, const char *, const char *); + int (*_stat_r)(struct _reent *r, const char *, struct stat *); + int (*_fstat_r)(struct _reent *r, int, struct stat *); + void *(*_sbrk_r)(struct _reent *r, ptrdiff_t); + int (*_getpid_r)(struct _reent *r); + int (*_kill_r)(struct _reent *r, int, int); + void (*_exit_r)(struct _reent *r, int); + int (*_close_r)(struct _reent *r, int); + int (*_open_r)(struct _reent *r, const char *, int, int); + int (*_write_r)(struct _reent *r, int, const void *, int); + int (*_lseek_r)(struct _reent *r, int, int, int); + int (*_read_r)(struct _reent *r, int, void *, int); + void (*_retarget_lock_init)(_LOCK_T *lock); + void (*_retarget_lock_init_recursive)(_LOCK_T *lock); + void (*_retarget_lock_close)(_LOCK_T lock); + void (*_retarget_lock_close_recursive)(_LOCK_T lock); + void (*_retarget_lock_acquire)(_LOCK_T lock); + void (*_retarget_lock_acquire_recursive)(_LOCK_T lock); + int (*_retarget_lock_try_acquire)(_LOCK_T lock); + int (*_retarget_lock_try_acquire_recursive)(_LOCK_T lock); + void (*_retarget_lock_release)(_LOCK_T lock); + void (*_retarget_lock_release_recursive)(_LOCK_T lock); + int (*_printf_float)(struct _reent *data, void *pdata, FILE *fp, int (*pfunc) (struct _reent *, FILE *, const char *, size_t len), va_list *ap); + int (*_scanf_float) (struct _reent *rptr, void *pdata, FILE *fp, va_list *ap); + void (*__assert_func) (const char *file, int line, const char *func, const char *failedexpr) __attribute__((__noreturn__)); + void (*__sinit) (struct _reent *r); + void (*_cleanup_r) (struct _reent *r); +}; + +extern struct syscall_stub_table *syscall_table_ptr; + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif /* _ROM_LIBC_STUBS_H_ */ diff --git a/components/esp_rom/include/esp32c5/rom/lldesc.h b/components/esp_rom/include/esp32c5/rom/lldesc.h new file mode 100644 index 000000000000..d5cb674df165 --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/lldesc.h @@ -0,0 +1,139 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_LLDESC_H_ +#define _ROM_LLDESC_H_ + +#include + +#include "sys/queue.h" +#include "esp_rom_lldesc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define LLDESC_TX_MBLK_SIZE 268 /* */ +#define LLDESC_RX_SMBLK_SIZE 64 /* small block size, for small mgmt frame */ +#define LLDESC_RX_MBLK_SIZE 524 /* rx is large sinec we want to contain mgmt frame in one block*/ +#define LLDESC_RX_AMPDU_ENTRY_MBLK_SIZE 64 /* it is a small buffer which is a cycle link*/ +#define LLDESC_RX_AMPDU_LEN_MBLK_SIZE 256 /*for ampdu entry*/ +#ifdef ESP_MAC_5 +#define LLDESC_TX_MBLK_NUM 116 /* 64K / 256 */ +#define LLDESC_RX_MBLK_NUM 82 /* 64K / 512 MAX 172*/ +#define LLDESC_RX_AMPDU_ENTRY_MBLK_NUM 4 +#define LLDESC_RX_AMPDU_LEN_MLBK_NUM 12 +#else +#ifdef SBUF_RXTX +#define LLDESC_TX_MBLK_NUM_MAX (2 * 48) /* 23K / 260 - 8 */ +#define LLDESC_RX_MBLK_NUM_MAX (2 * 48) /* 23K / 524 */ +#define LLDESC_TX_MBLK_NUM_MIN (2 * 16) /* 23K / 260 - 8 */ +#define LLDESC_RX_MBLK_NUM_MIN (2 * 16) /* 23K / 524 */ +#endif +#define LLDESC_TX_MBLK_NUM 10 //(2 * 32) /* 23K / 260 - 8 */ + +#ifdef IEEE80211_RX_AMPDU +#define LLDESC_RX_MBLK_NUM 30 +#else +#define LLDESC_RX_MBLK_NUM 10 +#endif /*IEEE80211_RX_AMPDU*/ + +#define LLDESC_RX_AMPDU_ENTRY_MBLK_NUM 4 +#define LLDESC_RX_AMPDU_LEN_MLBK_NUM 8 +#endif /* !ESP_MAC_5 */ + +typedef struct tx_ampdu_entry_s { + uint32_t sub_len : 12, + dili_num : 7, + : 1, + null_byte: 2, + data : 1, + enc : 1, + seq : 8; +} tx_ampdu_entry_t; + +typedef struct lldesc_chain_s { + lldesc_t *head; + lldesc_t *tail; +} lldesc_chain_t; + +#ifdef SBUF_RXTX +enum sbuf_mask_s { + SBUF_MOVE_NO = 0, + SBUF_MOVE_TX2RX, + SBUF_MOVE_RX2TX, +} ; + +#define SBUF_MOVE_STEP 8 +#endif +#define LLDESC_SIZE sizeof(struct lldesc_s) + +/* SLC Descriptor */ +#define LLDESC_OWNER_MASK 0x80000000 +#define LLDESC_OWNER_SHIFT 31 +#define LLDESC_SW_OWNED 0 +#define LLDESC_HW_OWNED 1 + +#define LLDESC_EOF_MASK 0x40000000 +#define LLDESC_EOF_SHIFT 30 + +#define LLDESC_SOSF_MASK 0x20000000 +#define LLDESC_SOSF_SHIFT 29 + +#define LLDESC_LENGTH_MASK 0x00fff000 +#define LLDESC_LENGTH_SHIFT 12 + +#define LLDESC_SIZE_MASK 0x00000fff +#define LLDESC_SIZE_SHIFT 0 + +#define LLDESC_ADDR_MASK 0x000fffff + +void lldesc_build_chain(uint8_t *descptr, uint32_t desclen, uint8_t *mblkptr, uint32_t buflen, uint32_t blksz, uint8_t owner, + lldesc_t **head, +#ifdef TO_HOST_RESTART + lldesc_t **one_before_tail, +#endif + lldesc_t **tail); + +static inline uint32_t lldesc_get_chain_length(lldesc_t *head) +{ + lldesc_t *ds = head; + uint32_t len = 0; + + while (ds) { + len += ds->length; + ds = STAILQ_NEXT(ds, qe); + } + + return len; +} + +static inline void lldesc_config(lldesc_t *ds, uint8_t owner, uint8_t eof, uint8_t sosf, uint16_t len) +{ + ds->owner = owner; + ds->eof = eof; + ds->sosf = sosf; + ds->length = len; +} + +#define LLDESC_CONFIG(_desc, _owner, _eof, _sosf, _len) do { \ + (_desc)->owner = (_owner); \ + (_desc)->eof = (_eof); \ + (_desc)->sosf = (_sosf); \ + (_desc)->length = (_len); \ +} while(0) + +#define LLDESC_FROM_HOST_CLEANUP(ds) LLDESC_CONFIG((ds), LLDESC_HW_OWNED, 0, 0, 0) + +#define LLDESC_MAC_RX_CLEANUP(ds) LLDESC_CONFIG((ds), LLDESC_HW_OWNED, 0, 0, (ds)->size) + +#define LLDESC_TO_HOST_CLEANUP(ds) LLDESC_CONFIG((ds), LLDESC_HW_OWNED, 0, 0, 0) + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_LLDESC_H_ */ diff --git a/components/esp_rom/include/esp32c5/rom/md5_hash.h b/components/esp_rom/include/esp32c5/rom/md5_hash.h new file mode 100644 index 000000000000..3c5e10d1bf66 --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/md5_hash.h @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2003-2005, Jouni Malinen + * + * SPDX-License-Identifier: BSD-3-Clause + */ +/* + * MD5 internal definitions + * Copyright (c) 2003-2005, Jouni Malinen + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Alternatively, this software may be distributed under the terms of BSD + * license. + * + * See README and COPYING for more details. + */ + +#ifndef _ROM_MD5_HASH_H_ +#define _ROM_MD5_HASH_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct MD5Context { + uint32_t buf[4]; + uint32_t bits[2]; + uint8_t in[64]; +}; + +void MD5Init(struct MD5Context *context); +void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len); +void MD5Final(unsigned char digest[16], struct MD5Context *context); + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_MD5_HASH_H_ */ diff --git a/components/esp_rom/include/esp32c5/rom/miniz.h b/components/esp_rom/include/esp32c5/rom/miniz.h new file mode 100644 index 000000000000..f0baecabdcec --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/miniz.h @@ -0,0 +1,8 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#warning "{target}/rom/miniz.h is deprecated, please use (#include "miniz.h") instead" +#include "../../miniz.h" diff --git a/components/esp_rom/include/esp32c5/rom/rom_layout.h b/components/esp_rom/include/esp32c5/rom/rom_layout.h new file mode 100644 index 000000000000..18b6d79ba7cd --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/rom_layout.h @@ -0,0 +1,102 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define SUPPORT_BTDM 0 +#define SUPPORT_BTBB 0 +#define SUPPORT_WIFI 1 +#define SUPPORT_USB_DWCOTG 0 +#define SUPPORT_COEXIST 1 +#define SUPPORT_MBEDTLS 0 + +/* Structure and functions for returning ROM global layout + * + * This is for address symbols defined in the linker script, which may change during ECOs. + */ +typedef struct { + void *dram0_stack_shared_mem_start; + void *dram0_rtos_reserved_start; + void *stack_sentry; + void *stack; + +#if SUPPORT_BTDM + void *data_start_btdm; + void *data_end_btdm; + void *bss_start_btdm; + void *bss_end_btdm; + void *data_start_btdm_rom; + void *data_start_interface_btdm; + void *data_end_interface_btdm; + void *bss_start_interface_btdm; + void *bss_end_interface_btdm; +#endif + +#if SUPPORT_BTBB + void *dram_start_btbbrom; + void *dram_end_btbbrom; +#endif + +#if SUPPORT_BTDM || SUPPORT_WIFI + void *dram_start_phyrom; + void *dram_end_phyrom; +#endif + +#if SUPPORT_WIFI + void *dram_start_net80211; + void *dram_end_net80211; + void *data_start_interface_net80211; + void *data_end_interface_net80211; + void *bss_start_interface_net80211; + void *bss_end_interface_net80211; + void *dram_start_pp; + void *dram_end_pp; + void *data_start_interface_pp; + void *data_end_interface_pp; + void *bss_start_interface_pp; + void *bss_end_interface_pp; +#endif + +#if SUPPORT_COEXIST + void *dram_start_coexist; + void *dram_end_coexist; + void *data_start_interface_coexist; + void *data_end_interface_coexist; + void *bss_start_interface_coexist; + void *bss_end_interface_coexist; +#endif + +#if SUPPORT_MBEDTLS + void *dram_start_mbedtls_rom; + void *dram_end_mbedtls_rom; +#endif + +#if SUPPORT_USB_DWCOTG + void *dram_start_usb_dwcotg_rom; + void *dram_end_usb_dwcotg_rom; +#else + //Two reserved members are defined here, so the structure will not be broken, + //please keep in mind that there is no memory can be released between + //dram_start_usb_reserved_rom ~ dram_end_usb_reserved_rom. + void *dram_start_usb_reserved_rom; + void *dram_end_usb_reserved_rom; +#endif + + void *dram_start_uart_rom; + void *dram_end_uart_rom; +} ets_rom_layout_t; + +extern const ets_rom_layout_t *const ets_rom_layout_p; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c5/rom/rsa_pss.h b/components/esp_rom/include/esp32c5/rom/rsa_pss.h new file mode 100644 index 000000000000..d6140879c83e --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/rsa_pss.h @@ -0,0 +1,38 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_RSA_PSS_H_ +#define _ROM_RSA_PSS_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define ETS_SIG_LEN 384 /* Bytes */ +#define ETS_DIGEST_LEN 32 /* SHA-256, bytes */ + +typedef struct { + uint8_t n[384]; /* Public key modulus */ + uint32_t e; /* Public key exponent */ + uint8_t rinv[384]; + uint32_t mdash; +} ets_rsa_pubkey_t; + +bool ets_rsa_pss_verify(const ets_rsa_pubkey_t *key, const uint8_t *sig, const uint8_t *digest, uint8_t *verified_digest); + +void ets_mgf1_sha256(const uint8_t *mgfSeed, size_t seedLen, size_t maskLen, uint8_t *mask); + +bool ets_emsa_pss_verify(const uint8_t *encoded_message, const uint8_t *mhash); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/components/esp_rom/include/esp32c5/rom/rtc.h b/components/esp_rom/include/esp32c5/rom/rtc.h new file mode 100644 index 000000000000..6a046fa25a49 --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/rtc.h @@ -0,0 +1,254 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_assert.h" + +#include "soc/soc.h" +#include "soc/lp_aon_reg.h" +#include "soc/reset_reasons.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup rtc_apis, rtc registers and memory related apis + * @brief rtc apis + */ + +/** @addtogroup rtc_apis + * @{ + */ + +/************************************************************************************** + * Note: * + * Some Rtc memory and registers are used, in ROM or in internal library. * + * Please do not use reserved or used rtc memory or registers. * + * * + ************************************************************************************* + * LP Memory & Store Register usage + ************************************************************************************* + * rtc memory addr type size usage + * 0x3f421000(0x50000000) Slow SIZE_CP Co-Processor code/Reset Entry + * 0x3f421000+SIZE_CP Slow 8192-SIZE_CP + * + * 0x3ff80000(0x40070000) Fast 8192 deep sleep entry code + * + ************************************************************************************* + * RTC store registers usage + * LP_AON_STORE0_REG Reserved + * LP_AON_STORE1_REG RTC_SLOW_CLK calibration value + * LP_AON_STORE2_REG Boot time, low word + * LP_AON_STORE3_REG Boot time, high word + * LP_AON_STORE4_REG External XTAL frequency + * LP_AON_STORE5_REG FAST_RTC_MEMORY_LENGTH + * LP_AON_STORE6_REG FAST_RTC_MEMORY_ENTRY + * LP_AON_STORE7_REG FAST_RTC_MEMORY_CRC + * LP_AON_STORE8_REG Store light sleep wake stub addr + * LP_AON_STORE9_REG Store the sleep mode at bit[0] (0:light sleep 1:deep sleep) + ************************************************************************************* + */ + +#define RTC_SLOW_CLK_CAL_REG LP_AON_STORE1_REG +#define RTC_BOOT_TIME_LOW_REG LP_AON_STORE2_REG +#define RTC_BOOT_TIME_HIGH_REG LP_AON_STORE3_REG +#define RTC_XTAL_FREQ_REG LP_AON_STORE4_REG +#define RTC_ENTRY_LENGTH_REG LP_AON_STORE5_REG +#define RTC_ENTRY_ADDR_REG LP_AON_STORE6_REG +#define RTC_RESET_CAUSE_REG LP_AON_STORE6_REG +#define RTC_MEMORY_CRC_REG LP_AON_STORE7_REG +#define LIGHT_SLEEP_WAKE_STUB_ADDR_REG LP_AON_STORE8_REG +#define SLEEP_MODE_REG LP_AON_STORE9_REG + +#define RTC_DISABLE_ROM_LOG ((1 << 0) | (1 << 16)) //!< Disable logging from the ROM code. + +typedef enum { + AWAKE = 0, // +#include +#include "ets_sys.h" +#include "ecdsa.h" +#include "rsa_pss.h" +#include "esp_assert.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#if CONFIG_SECURE_BOOT_V2_ENABLED || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT + +typedef struct ets_secure_boot_sig_block ets_secure_boot_sig_block_t; +typedef struct ets_secure_boot_signature ets_secure_boot_signature_t; +typedef struct ets_secure_boot_key_digests ets_secure_boot_key_digests_t; + +/* Anti-FI measure: use full words for success/fail, instead of + 0/non-zero +*/ +typedef enum { + SB_SUCCESS = 0x3A5A5AA5, + SB_FAILED = 0x7533885E, +} ets_secure_boot_status_t; + +/* Verify bootloader image (reconfigures cache to map), + with key digests provided as parameters.) + + Can be used to verify secure boot status before enabling + secure boot permanently. + + If stage_load parameter is true, bootloader is copied into staging + buffer in RAM at the same time. + + If result is SB_SUCCESS, the "simple hash" of the bootloader is + copied into verified_hash. +*/ +ets_secure_boot_status_t ets_secure_boot_verify_bootloader_with_keys(uint8_t *verified_hash, const ets_secure_boot_key_digests_t *trusted_keys, bool stage_load); + +/* Read key digests from efuse. Any revoked/missing digests will be + marked as NULL +*/ +ETS_STATUS ets_secure_boot_read_key_digests(ets_secure_boot_key_digests_t *trusted_keys); + +/* Verify supplied signature against supplied digest, using + supplied trusted key digests. + + Doesn't reconfigure cache or any other hardware access except for RSA peripheral. + + If result is SB_SUCCESS, the image_digest value is copied into verified_digest. +*/ +ets_secure_boot_status_t ets_secure_boot_verify_signature(const ets_secure_boot_signature_t *sig, const uint8_t *image_digest, const ets_secure_boot_key_digests_t *trusted_keys, uint8_t *verified_digest); + +/* Revoke a public key digest in efuse. + @param index Digest to revoke. Must be 0, 1 or 2. + */ +void ets_secure_boot_revoke_public_key_digest(int index); + +#define CRC_SIGN_BLOCK_LEN 1196 +#define SIG_BLOCK_PADDING 4096 +#define ETS_SECURE_BOOT_V2_SIGNATURE_MAGIC 0xE7 + +/* Secure Boot V2 signature block + + (Up to 3 in a signature sector are appended to the image) + */ +#if CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME + +struct ets_secure_boot_sig_block { + uint8_t magic_byte; + uint8_t version; + uint8_t _reserved1; + uint8_t _reserved2; + uint8_t image_digest[32]; + ets_rsa_pubkey_t key; + uint8_t signature[384]; + uint32_t block_crc; + uint8_t _padding[16]; +}; + +#elif CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME + +struct __attribute((packed)) ets_secure_boot_sig_block { + uint8_t magic_byte; + uint8_t version; + uint8_t _reserved1; + uint8_t _reserved2; + uint8_t image_digest[32]; + struct { + struct { + uint8_t curve_id; /* ETS_ECDSA_CURVE_P192 / ETS_ECDSA_CURVE_P256 */ + uint8_t point[64]; /* X followed by Y (both little-endian), plus zero bytes if P192 */ + } key; + uint8_t signature[64]; /* r followed by s (both little-endian) */ + uint8_t padding[1031]; + } ecdsa; + uint32_t block_crc; /* note: crc covers all bytes in the structure before it, regardless of version field */ + uint8_t _padding[16]; +}; +#endif + +ESP_STATIC_ASSERT(sizeof(ets_secure_boot_sig_block_t) == 1216, "invalid sig block size"); + +#define SECURE_BOOT_NUM_BLOCKS 3 + +/* V2 Secure boot signature sector (up to 3 blocks) */ +struct ets_secure_boot_signature { + ets_secure_boot_sig_block_t block[SECURE_BOOT_NUM_BLOCKS]; + uint8_t _padding[4096 - (sizeof(ets_secure_boot_sig_block_t) * SECURE_BOOT_NUM_BLOCKS)]; +}; + +ESP_STATIC_ASSERT(sizeof(ets_secure_boot_signature_t) == 4096, "invalid sig sector size"); + +#define MAX_KEY_DIGESTS 3 + +struct ets_secure_boot_key_digests { + const void *key_digests[MAX_KEY_DIGESTS]; + bool allow_key_revoke; +}; + +#endif /* CONFIG_SECURE_BOOT_V2_ENABLED || CONFIG_SECURE_SIGNED_APPS_NO_SECURE_BOOT */ + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c5/rom/sha.h b/components/esp_rom/include/esp32c5/rom/sha.h new file mode 100644 index 000000000000..c9eda2fd99f9 --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/sha.h @@ -0,0 +1,53 @@ +/* + * SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#ifndef _ROM_SHA_H_ +#define _ROM_SHA_H_ + +#include +#include +#include "ets_sys.h" + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + SHA1 = 0, + SHA2_224, + SHA2_256, + SHA_TYPE_MAX +} SHA_TYPE; + +typedef struct SHAContext { + bool start; + bool in_hardware; // Is this context currently in peripheral? Needs to be manually cleared if multiple SHAs are interleaved + SHA_TYPE type; + uint32_t state[16]; // For SHA1/SHA224/SHA256, used 8, other used 16 + unsigned char buffer[128]; // For SHA1/SHA224/SHA256, used 64, other used 128 + uint32_t total_bits[4]; +} SHA_CTX; + +void ets_sha_enable(void); + +void ets_sha_disable(void); + +ets_status_t ets_sha_init(SHA_CTX *ctx, SHA_TYPE type); + +ets_status_t ets_sha_starts(SHA_CTX *ctx, uint16_t sha512_t); + +void ets_sha_get_state(SHA_CTX *ctx); + +void ets_sha_process(SHA_CTX *ctx, const unsigned char *input); + +void ets_sha_update(SHA_CTX *ctx, const unsigned char *input, uint32_t input_bytes, bool update_ctx); + +ets_status_t ets_sha_finish(SHA_CTX *ctx, unsigned char *output); + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_SHA_H_ */ diff --git a/components/esp_rom/include/esp32c5/rom/spi_flash.h b/components/esp_rom/include/esp32c5/rom/spi_flash.h new file mode 100644 index 000000000000..2d782dee4f36 --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/spi_flash.h @@ -0,0 +1,458 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#pragma once + +#include +#include +#include "esp_attr.h" +#include "esp_rom_spiflash.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define PERIPHS_SPI_FLASH_CMD SPI_MEM_CMD_REG(1) +#define PERIPHS_SPI_FLASH_ADDR SPI_MEM_ADDR_REG(1) +#define PERIPHS_SPI_FLASH_CTRL SPI_MEM_CTRL_REG(1) +#define PERIPHS_SPI_FLASH_CTRL1 SPI_MEM_CTRL1_REG(1) +#define PERIPHS_SPI_FLASH_STATUS SPI_MEM_RD_STATUS_REG(1) +#define PERIPHS_SPI_FLASH_USRREG SPI_MEM_USER_REG(1) +#define PERIPHS_SPI_FLASH_USRREG1 SPI_MEM_USER1_REG(1) +#define PERIPHS_SPI_FLASH_USRREG2 SPI_MEM_USER2_REG(1) +#define PERIPHS_SPI_FLASH_C0 SPI_MEM_W0_REG(1) +#define PERIPHS_SPI_FLASH_C1 SPI_MEM_W1_REG(1) +#define PERIPHS_SPI_FLASH_C2 SPI_MEM_W2_REG(1) +#define PERIPHS_SPI_FLASH_C3 SPI_MEM_W3_REG(1) +#define PERIPHS_SPI_FLASH_C4 SPI_MEM_W4_REG(1) +#define PERIPHS_SPI_FLASH_C5 SPI_MEM_W5_REG(1) +#define PERIPHS_SPI_FLASH_C6 SPI_MEM_W6_REG(1) +#define PERIPHS_SPI_FLASH_C7 SPI_MEM_W7_REG(1) +#define PERIPHS_SPI_FLASH_TX_CRC SPI_MEM_TX_CRC_REG(1) + +#define SPI0_R_QIO_DUMMY_CYCLELEN 5 +#define SPI0_R_QIO_ADDR_BITSLEN 23 +#define SPI0_R_FAST_DUMMY_CYCLELEN 7 +#define SPI0_R_DIO_DUMMY_CYCLELEN 3 +#define SPI0_R_FAST_ADDR_BITSLEN 23 +#define SPI0_R_SIO_ADDR_BITSLEN 23 + +#define SPI1_R_QIO_DUMMY_CYCLELEN 5 +#define SPI1_R_QIO_ADDR_BITSLEN 23 +#define SPI1_R_FAST_DUMMY_CYCLELEN 7 +#define SPI1_R_DIO_DUMMY_CYCLELEN 3 +#define SPI1_R_DIO_ADDR_BITSLEN 23 +#define SPI1_R_FAST_ADDR_BITSLEN 23 +#define SPI1_R_SIO_ADDR_BITSLEN 23 + +#define ESP_ROM_SPIFLASH_W_SIO_ADDR_BITSLEN 23 + +#define ESP_ROM_SPIFLASH_TWO_BYTE_STATUS_EN SPI_MEM_WRSR_2B + +//SPI address register +#define ESP_ROM_SPIFLASH_BYTES_LEN 24 +#define ESP_ROM_SPIFLASH_BUFF_BYTE_WRITE_NUM 32 +#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_NUM 16 +#define ESP_ROM_SPIFLASH_BUFF_BYTE_READ_BITS 0xf + +typedef void (* spi_flash_func_t)(void); +typedef esp_rom_spiflash_result_t (* spi_flash_op_t)(void); +typedef esp_rom_spiflash_result_t (* spi_flash_erase_t)(uint32_t); +typedef esp_rom_spiflash_result_t (* spi_flash_rd_t)(uint32_t, uint32_t*, int); +typedef esp_rom_spiflash_result_t (* spi_flash_wr_t)(uint32_t, const uint32_t*, int); +typedef esp_rom_spiflash_result_t (* spi_flash_ewr_t)(uint32_t, const void*, uint32_t); +typedef esp_rom_spiflash_result_t (* spi_flash_wren_t)(void*); +typedef esp_rom_spiflash_result_t (* spi_flash_erase_area_t)(uint32_t, uint32_t); + +typedef struct { + uint8_t pp_addr_bit_len; + uint8_t se_addr_bit_len; + uint8_t be_addr_bit_len; + uint8_t rd_addr_bit_len; + uint32_t read_sub_len; + uint32_t write_sub_len; + spi_flash_op_t unlock; + spi_flash_erase_t erase_sector; + spi_flash_erase_t erase_block; + spi_flash_rd_t read; + spi_flash_wr_t write; + spi_flash_ewr_t encrypt_write; + spi_flash_func_t check_sus; + spi_flash_wren_t wren; + spi_flash_op_t wait_idle; + spi_flash_erase_area_t erase_area; +} spiflash_legacy_funcs_t; + +typedef struct { + uint8_t data_length; + uint8_t read_cmd0; + uint8_t read_cmd1; + uint8_t write_cmd; + uint16_t data_mask; + uint16_t data; +} esp_rom_spiflash_common_cmd_t; + +/** + * @brief SPI Read Flash status register. We use CMD 0x05 (RDSR). + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file. + * + * @param uint32_t *status : The pointer to which to return the Flash status value. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_read_status(esp_rom_spiflash_chip_t *spi, uint32_t *status); + +/** + * @brief SPI Read Flash status register bits 8-15. We use CMD 0x35 (RDSR2). + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file. + * + * @param uint32_t *status : The pointer to which to return the Flash status value. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_read_statushigh(esp_rom_spiflash_chip_t *spi, uint32_t *status); + +/** + * @brief Write status to Flash status register. + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file. + * + * @param uint32_t status_value : Value to . + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : write OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : write error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : write timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_write_status(esp_rom_spiflash_chip_t *spi, uint32_t status_value); + +/** + * @brief Use a command to Read Flash status register. + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file. + * + * @param uint32_t*status : The pointer to which to return the Flash status value. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : read timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_read_user_cmd(uint32_t *status, uint8_t cmd); + +/** + * @brief Config SPI Flash read mode when init. + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_read_mode_t mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD. + * + * This function does not try to set the QIO Enable bit in the status register, caller is responsible for this. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : config OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : config error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_config_readmode(esp_rom_spiflash_read_mode_t mode); + +/** + * @brief Config SPI Flash clock divisor. + * Please do not call this function in SDK. + * + * @param uint8_t freqdiv: clock divisor. + * + * @param uint8_t spi: 0 for SPI0, 1 for SPI1. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : config OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : config error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : config timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_config_clk(uint8_t freqdiv, uint8_t spi); + +/** + * @brief Clear all SR bits except QE bit. + * Please do not call this function in SDK. + * + * @param None. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Unlock OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Unlock error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Unlock timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_clear_bp(void); + +/** + * @brief Clear all SR bits except QE bit. + * Please do not call this function in SDK. + * + * @param None. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Unlock OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Unlock error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Unlock timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_unlock(void); + +/** + * @brief Update SPI Flash parameter. + * Please do not call this function in SDK. + * + * @param uint32_t deviceId : Device ID read from SPI, the low 32 bit. + * + * @param uint32_t chip_size : The Flash size. + * + * @param uint32_t block_size : The Flash block size. + * + * @param uint32_t sector_size : The Flash sector size. + * + * @param uint32_t page_size : The Flash page size. + * + * @param uint32_t status_mask : The Mask used when read status from Flash(use single CMD). + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Update OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Update error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Update timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_config_param(uint32_t deviceId, uint32_t chip_size, uint32_t block_size, + uint32_t sector_size, uint32_t page_size, uint32_t status_mask); + +/** + * @brief Erase whole flash chip. + * Please do not call this function in SDK. + * + * @param None + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_erase_chip(void); + +/** + * @brief Erase a 64KB block of flash + * Uses SPI flash command D8H. + * Please do not call this function in SDK. + * + * @param uint32_t block_num : Which block to erase. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_erase_block(uint32_t block_num); + +/** + * @brief Erase a sector of flash. + * Uses SPI flash command 20H. + * Please do not call this function in SDK. + * + * @param uint32_t sector_num : Which sector to erase. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_erase_sector(uint32_t sector_num); + +/** + * @brief Erase some sectors. + * Please do not call this function in SDK. + * + * @param uint32_t start_addr : Start addr to erase, should be sector aligned. + * + * @param uint32_t area_len : Length to erase, should be sector aligned. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Erase OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Erase error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Erase timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_erase_area(uint32_t start_addr, uint32_t area_len); + +/** + * @brief Write Data to Flash, you should Erase it yourself if need. + * Please do not call this function in SDK. + * + * @param uint32_t dest_addr : Address to write, should be 4 bytes aligned. + * + * @param const uint32_t *src : The pointer to data which is to write. + * + * @param uint32_t len : Length to write, should be 4 bytes aligned. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Write OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Write error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Write timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_write(uint32_t dest_addr, const uint32_t *src, int32_t len); + +/** + * @brief Read Data from Flash, you should Erase it yourself if need. + * Please do not call this function in SDK. + * + * @param uint32_t src_addr : Address to read, should be 4 bytes aligned. + * + * @param uint32_t *dest : The buf to read the data. + * + * @param uint32_t len : Length to read, should be 4 bytes aligned. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Read OK. + * ESP_ROM_SPIFLASH_RESULT_ERR : Read error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Read timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_read(uint32_t src_addr, uint32_t *dest, int32_t len); + +/** + * @brief SPI1 go into encrypto mode. + * Please do not call this function in SDK. + * + * @param None + * + * @return None + */ +void esp_rom_spiflash_write_encrypted_enable(void); + +/** + * @brief SPI1 go out of encrypto mode. + * Please do not call this function in SDK. + * + * @param None + * + * @return None + */ +void esp_rom_spiflash_write_encrypted_disable(void); + +/** + * @brief Write data to flash with transparent encryption. + * @note Sectors to be written should already be erased. + * + * @note Please do not call this function in SDK. + * + * @param uint32_t flash_addr : Address to write, should be 32 byte aligned. + * + * @param uint32_t *data : The pointer to data to write. Note, this pointer must + * be 32 bit aligned and the content of the data will be + * modified by the encryption function. + * + * @param uint32_t len : Length to write, should be 32 bytes aligned. + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Data written successfully. + * ESP_ROM_SPIFLASH_RESULT_ERR : Encryption write error. + * ESP_ROM_SPIFLASH_RESULT_TIMEOUT : Encrypto write timeout. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_write_encrypted(uint32_t flash_addr, uint32_t *data, uint32_t len); + + +/** @brief Wait until SPI flash write operation is complete + * + * @note Please do not call this function in SDK. + * + * Reads the Write In Progress bit of the SPI flash status register, + * repeats until this bit is zero (indicating write complete). + * + * @return ESP_ROM_SPIFLASH_RESULT_OK : Write is complete + * ESP_ROM_SPIFLASH_RESULT_ERR : Error while reading status. + */ +esp_rom_spiflash_result_t esp_rom_spiflash_wait_idle(esp_rom_spiflash_chip_t *spi); + + +/** @brief Enable Quad I/O pin functions + * + * @note Please do not call this function in SDK. + * + * Sets the HD & WP pin functions for Quad I/O modes, based on the + * efuse SPI pin configuration. + * + * @param wp_gpio_num - Number of the WP pin to reconfigure for quad I/O. + * + * @param spiconfig - Pin configuration, as returned from ets_efuse_get_spiconfig(). + * - If this parameter is 0, default SPI pins are used and wp_gpio_num parameter is ignored. + * - If this parameter is 1, default HSPI pins are used and wp_gpio_num parameter is ignored. + * - For other values, this parameter encodes the HD pin number and also the CLK pin number. CLK pin selection is used + * to determine if HSPI or SPI peripheral will be used (use HSPI if CLK pin is the HSPI clock pin, otherwise use SPI). + * Both HD & WP pins are configured via GPIO matrix to map to the selected peripheral. + */ +void esp_rom_spiflash_select_qio_pins(uint8_t wp_gpio_num, uint32_t spiconfig); + +/** + * @brief Clear WEL bit unconditionally. + * + * @return always ESP_ROM_SPIFLASH_RESULT_OK + */ +esp_rom_spiflash_result_t esp_rom_spiflash_write_disable(void); + +/** + * @brief Set WREN bit. + * + * @param esp_rom_spiflash_chip_t *spi : The information for Flash, which is exported from ld file. + * + * @return always ESP_ROM_SPIFLASH_RESULT_OK + */ +esp_rom_spiflash_result_t esp_rom_spiflash_write_enable(esp_rom_spiflash_chip_t *spi); + +/** + * @brief Fix the bug in SPI hardware communication with Flash/Ext-SRAM in High Speed. + * Please do not call this function in SDK. + * + * @param uint8_t spi: 0 for SPI0(Cache Access), 1 for SPI1(Flash read/write). + * + * @param uint8_t freqdiv: Pll is 80M, 4 for 20M, 3 for 26.7M, 2 for 40M, 1 for 80M. + * + * @return None + */ +void esp_rom_spiflash_fix_dummylen(uint8_t spi, uint8_t freqdiv); + +/** + * @brief Set SPI Flash pad drivers. + * Please do not call this function in SDK. + * + * @param uint8_t wp_gpio_num: WP gpio number. + * + * @param uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping + * else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, bit[23:18] spics0, bit[29:24] spihd + * + * @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid + * drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp. + * Values usually read from falsh by rom code, function usually callde by rom code. + * if value with bit(3) set, the value is valid, bit[2:0] is the real value. + * + * @return None + */ +void esp_rom_spiflash_set_drvs(uint8_t wp_gpio_num, uint32_t ishspi, uint8_t *drvs); + +/** + * @brief Select SPI Flash function for pads. + * Please do not call this function in SDK. + * + * @param uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping + * else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, bit[23:18] spics0, bit[29:24] spihd + * + * @return None + */ +void esp_rom_spiflash_select_padsfunc(uint32_t ishspi); + +/** + * @brief Send CommonCmd to Flash so that is can go into QIO mode, some Flash use different CMD. + * Please do not call this function in SDK. + * + * @param esp_rom_spiflash_common_cmd_t *cmd : A struct to show the action of a command. + * + * @return uint16_t 0 : do not send command any more. + * 1 : go to the next command. + * n > 1 : skip (n - 1) commands. + */ +uint16_t esp_rom_spiflash_common_cmd(esp_rom_spiflash_common_cmd_t *cmd); + +extern const spiflash_legacy_funcs_t *rom_spiflash_legacy_funcs; + +#ifdef __cplusplus +} +#endif diff --git a/components/esp_rom/include/esp32c5/rom/uart.h b/components/esp_rom/include/esp32c5/rom/uart.h new file mode 100644 index 000000000000..9045c42f6f6e --- /dev/null +++ b/components/esp_rom/include/esp32c5/rom/uart.h @@ -0,0 +1,353 @@ +/* + * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _ROM_UART_H_ +#define _ROM_UART_H_ + +#include "esp_types.h" +#include "esp_attr.h" +#include "ets_sys.h" +#include "soc/soc.h" +#include "soc/uart_reg.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** \defgroup uart_apis, uart configuration and communication related apis + * @brief uart apis + */ + +/** @addtogroup uart_apis + * @{ + */ + +#define RX_BUFF_SIZE 0x400 +#define TX_BUFF_SIZE 100 + +//uart int enalbe register ctrl bits +#define UART_RCV_INTEN BIT0 +#define UART_TRX_INTEN BIT1 +#define UART_LINE_STATUS_INTEN BIT2 + +//uart int identification ctrl bits +#define UART_INT_FLAG_MASK 0x0E + +//uart fifo ctrl bits +#define UART_CLR_RCV_FIFO BIT1 +#define UART_CLR_TRX_FIFO BIT2 +#define UART_RCVFIFO_TRG_LVL_BITS BIT6 + +//uart line control bits +#define UART_DIV_LATCH_ACCESS_BIT BIT7 + +//uart line status bits +#define UART_RCV_DATA_RDY_FLAG BIT0 +#define UART_RCV_OVER_FLOW_FLAG BIT1 +#define UART_RCV_PARITY_ERR_FLAG BIT2 +#define UART_RCV_FRAME_ERR_FLAG BIT3 +#define UART_BRK_INT_FLAG BIT4 +#define UART_TRX_FIFO_EMPTY_FLAG BIT5 +#define UART_TRX_ALL_EMPTY_FLAG BIT6 // include fifo and shift reg +#define UART_RCV_ERR_FLAG BIT7 + +//send and receive message frame head +#define FRAME_FLAG 0x7E + +typedef enum { + UART_LINE_STATUS_INT_FLAG = 0x06, + UART_RCV_FIFO_INT_FLAG = 0x04, + UART_RCV_TMOUT_INT_FLAG = 0x0C, + UART_TXBUFF_EMPTY_INT_FLAG = 0x02 +} UartIntType; //consider bit0 for int_flag + +typedef enum { + RCV_ONE_BYTE = 0x0, + RCV_FOUR_BYTE = 0x1, + RCV_EIGHT_BYTE = 0x2, + RCV_FOURTEEN_BYTE = 0x3 +} UartRcvFifoTrgLvl; + +typedef enum { + FIVE_BITS = 0x0, + SIX_BITS = 0x1, + SEVEN_BITS = 0x2, + EIGHT_BITS = 0x3 +} UartBitsNum4Char; + +typedef enum { + ONE_STOP_BIT = 1, + ONE_HALF_STOP_BIT = 2, + TWO_STOP_BIT = 3 +} UartStopBitsNum; + +typedef enum { + NONE_BITS = 0, + ODD_BITS = 2, + EVEN_BITS = 3 + +} UartParityMode; + +typedef enum { + STICK_PARITY_DIS = 0, + STICK_PARITY_EN = 2 +} UartExistParity; + +typedef enum { + BIT_RATE_9600 = 9600, + BIT_RATE_19200 = 19200, + BIT_RATE_38400 = 38400, + BIT_RATE_57600 = 57600, + BIT_RATE_115200 = 115200, + BIT_RATE_230400 = 230400, + BIT_RATE_460800 = 460800, + BIT_RATE_921600 = 921600 +} UartBautRate; + +typedef enum { + NONE_CTRL, + HARDWARE_CTRL, + XON_XOFF_CTRL +} UartFlowCtrl; + +typedef enum { + EMPTY, + UNDER_WRITE, + WRITE_OVER +} RcvMsgBuffState; + +typedef struct { + uint8_t *pRcvMsgBuff; + uint8_t *pWritePos; + uint8_t *pReadPos; + uint8_t TrigLvl; + RcvMsgBuffState BuffState; +} RcvMsgBuff; + +typedef struct { + uint32_t TrxBuffSize; + uint8_t *pTrxBuff; +} TrxMsgBuff; + +typedef enum { + BAUD_RATE_DET, + WAIT_SYNC_FRM, + SRCH_MSG_HEAD, + RCV_MSG_BODY, + RCV_ESC_CHAR, +} RcvMsgState; + +typedef struct { + UartBautRate baut_rate; + UartBitsNum4Char data_bits; + UartExistParity exist_parity; + UartParityMode parity; // chip size in byte + UartStopBitsNum stop_bits; + UartFlowCtrl flow_ctrl; + uint8_t buff_uart_no; //indicate which uart use tx/rx buffer + RcvMsgBuff rcv_buff; +// TrxMsgBuff trx_buff; + RcvMsgState rcv_state; + int received; +} UartDevice; + +/** + * @brief Init uart device struct value and reset uart0/uart1 rx. + * Please do not call this function in SDK. + * + * @param rxBuffer, must be a pointer to RX_BUFF_SIZE bytes or NULL + * + * @return None + */ +void uartAttach(void *rxBuffer); + +/** + * @brief Init uart0 or uart1 for UART download booting mode. + * Please do not call this function in SDK. + * + * @param uint8_t uart_no : 0 for UART0, else for UART1. + * + * @param uint32_t clock : clock used by uart module, to adjust baudrate. + * + * @return None + */ +void Uart_Init(uint8_t uart_no, uint32_t clock); + +/** + * @brief Modify uart baudrate. + * This function will reset RX/TX fifo for uart. + * + * @param uint8_t uart_no : 0 for UART0, 1 for UART1. + * + * @param uint32_t DivLatchValue : (clock << 4)/baudrate. + * + * @return None + */ +void uart_div_modify(uint8_t uart_no, uint32_t DivLatchValue); + +/** + * @brief Switch printf channel of uart_tx_one_char. + * Please do not call this function when printf. + * + * @param uint8_t uart_no : 0 for UART0, 1 for UART1. + * + * @return None + */ +void uart_tx_switch(uint8_t uart_no); + +/** + * @brief Output a char to printf channel, wait until fifo not full. + * + * @param None + * + * @return OK. + */ +ETS_STATUS uart_tx_one_char(uint8_t TxChar); + +/** + * @brief Output a char to message exchange channel, wait until fifo not full. + * Please do not call this function in SDK. + * + * @param None + * + * @return OK. + */ +ETS_STATUS uart_tx_one_char2(uint8_t TxChar); + +/** + * @brief Wait until uart tx full empty. + * + * @param uint8_t uart_no : 0 for UART0, 1 for UART1. + * + * @return None. + */ +void uart_tx_flush(uint8_t uart_no); + +/** + * @brief Wait until uart tx full empty and the last char send ok. + * + * @param uart_no : 0 for UART0, 1 for UART1 + * + * The function defined in ROM code has a bug, so we define the correct version + * here for compatibility. + */ +void uart_tx_wait_idle(uint8_t uart_no); + +/** + * @brief Get an input char from message channel. + * Please do not call this function in SDK. + * + * @param uint8_t *pRxChar : the pointer to store the char. + * + * @return OK for successful. + * FAIL for failed. + */ +ETS_STATUS uart_rx_one_char(uint8_t *pRxChar); + +/** + * @brief Get an input char from message channel, wait until successful. + * Please do not call this function in SDK. + * + * @param None + * + * @return char : input char value. + */ +char uart_rx_one_char_block(void); + +/** + * @brief Get an input string line from message channel. + * Please do not call this function in SDK. + * + * @param uint8_t *pString : the pointer to store the string. + * + * @param uint8_t MaxStrlen : the max string length, incude '\0'. + * + * @return OK. + */ +ETS_STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen); + +/** + * @brief Process uart recevied information in the interrupt handler. + * Please do not call this function in SDK. + * + * @param void *para : the message receive buffer. + * + * @return None + */ +void uart_rx_intr_handler(void *para); + +/** + * @brief Get an char from receive buffer. + * Please do not call this function in SDK. + * + * @param RcvMsgBuff *pRxBuff : the pointer to the struct that include receive buffer. + * + * @param uint8_t *pRxByte : the pointer to store the char. + * + * @return OK for successful. + * FAIL for failed. + */ +ETS_STATUS uart_rx_readbuff( RcvMsgBuff *pRxBuff, uint8_t *pRxByte); + +/** + * @brief Get all chars from receive buffer. + * Please do not call this function in SDK. + * + * @param uint8_t *pCmdLn : the pointer to store the string. + * + * @return OK for successful. + * FAIL for failed. + */ +ETS_STATUS UartGetCmdLn(uint8_t *pCmdLn); + +/** + * @brief Get uart configuration struct. + * Please do not call this function in SDK. + * + * @param None + * + * @return UartDevice * : uart configuration struct pointer. + */ +UartDevice *GetUartDevice(void); + +/** + * @brief Send an packet to download tool, with SLIP escaping. + * Please do not call this function in SDK. + * + * @param uint8_t *p : the pointer to output string. + * + * @param int len : the string length. + * + * @return None. + */ +void send_packet(uint8_t *p, int len); + +/** + * @brief Receive an packet from download tool, with SLIP escaping. + * Please do not call this function in SDK. + * + * @param uint8_t *p : the pointer to input string. + * + * @param int len : If string length > len, the string will be truncated. + * + * @param uint8_t is_sync : 0, only one UART module; + * 1, two UART modules. + * + * @return int : the length of the string. + */ +int recv_packet(uint8_t *p, int len, uint8_t is_sync); + +extern UartDevice UartDev; + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif /* _ROM_UART_H_ */ diff --git a/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c b/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c new file mode 100644 index 000000000000..f89538d21040 --- /dev/null +++ b/components/esp_rom/patches/esp_rom_hp_regi2c_esp32c5.c @@ -0,0 +1,188 @@ +/* + * SPDX-FileCopyrightText: 2019-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "esp_rom_sys.h" +#include "esp_attr.h" +#include "soc/i2c_ana_mst_reg.h" +#include "modem/modem_lpcon_reg.h" +/** + * BB - 0x67 - BIT0 + * TXRF - 0x6B - BIT1 + * SDM - 0x63 - BIT2 + * PLL - 0x62 - BIT3 + * BIAS - 0x6A - BIT4 + * BBPLL - 0x66 - BIT5 + * ULP - 0x61 - BIT6 + * SAR - 0x69 - BIT7 + * PMU - 0x6d - BIT8 +*/ + +#define REGI2C_BIAS_MST_SEL (BIT(8)) +#define REGI2C_BBPLL_MST_SEL (BIT(9)) +#define REGI2C_ULP_CAL_MST_SEL (BIT(10)) +#define REGI2C_SAR_I2C_MST_SEL (BIT(11)) +#define REGI2C_DIG_REG_MST_SEL (BIT(12)) + +#define REGI2C_BIAS_RD_MASK (~BIT(6) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_BBPLL_RD_MASK (~BIT(7) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_ULP_CAL_RD_MASK (~BIT(8) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_SAR_I2C_RD_MASK (~BIT(9) & I2C_ANA_MST_ANA_CONF1_M) +#define REGI2C_DIG_REG_RD_MASK (~BIT(10) & I2C_ANA_MST_ANA_CONF1_M) + +#define I2C_ANA_MST_I2C_CTRL_REG(n) (I2C_ANA_MST_I2C0_CTRL_REG + n*4) // 0: I2C_ANA_MST_I2C0_CTRL_REG; 1: I2C_ANA_MST_I2C1_CTRL_REG + +#define REGI2C_RTC_BUSY (BIT(25)) +#define REGI2C_RTC_BUSY_M (BIT(25)) +#define REGI2C_RTC_BUSY_V 0x1 +#define REGI2C_RTC_BUSY_S 25 + +#define REGI2C_RTC_WR_CNTL (BIT(24)) +#define REGI2C_RTC_WR_CNTL_M (BIT(24)) +#define REGI2C_RTC_WR_CNTL_V 0x1 +#define REGI2C_RTC_WR_CNTL_S 24 + +#define REGI2C_RTC_DATA 0x000000FF +#define REGI2C_RTC_DATA_M ((I2C_RTC_DATA_V)<<(I2C_RTC_DATA_S)) +#define REGI2C_RTC_DATA_V 0xFF +#define REGI2C_RTC_DATA_S 16 + +#define REGI2C_RTC_ADDR 0x000000FF +#define REGI2C_RTC_ADDR_M ((I2C_RTC_ADDR_V)<<(I2C_RTC_ADDR_S)) +#define REGI2C_RTC_ADDR_V 0xFF +#define REGI2C_RTC_ADDR_S 8 + +#define REGI2C_RTC_SLAVE_ID 0x000000FF +#define REGI2C_RTC_SLAVE_ID_M ((I2C_RTC_SLAVE_ID_V)<<(I2C_RTC_SLAVE_ID_S)) +#define REGI2C_RTC_SLAVE_ID_V 0xFF +#define REGI2C_RTC_SLAVE_ID_S 0 + +/* SLAVE */ + +#define REGI2C_BBPLL (0x66) +#define REGI2C_BBPLL_HOSTID 0 + +#define REGI2C_BIAS (0x6a) +#define REGI2C_BIAS_HOSTID 0 + +#define REGI2C_DIG_REG (0x6d) +#define REGI2C_DIG_REG_HOSTID 0 + +#define REGI2C_ULP_CAL (0x61) +#define REGI2C_ULP_CAL_HOSTID 0 + +#define REGI2C_SAR_I2C (0x69) +#define REGI2C_SAR_I2C_HOSTID 0 + +/* SLAVE END */ + +uint8_t esp_rom_regi2c_read(uint8_t block, uint8_t host_id, uint8_t reg_add) __attribute__((alias("regi2c_read_impl"))); +uint8_t esp_rom_regi2c_read_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) __attribute__((alias("regi2c_read_mask_impl"))); +void esp_rom_regi2c_write(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) __attribute__((alias("regi2c_write_impl"))); +void esp_rom_regi2c_write_mask(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) __attribute__((alias("regi2c_write_mask_impl"))); + +static IRAM_ATTR uint8_t regi2c_enable_block(uint8_t block) +{ + uint32_t i2c_sel = 0; + + REG_SET_BIT(MODEM_LPCON_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_EN); + REG_SET_BIT(MODEM_LPCON_I2C_MST_CLK_CONF_REG, MODEM_LPCON_CLK_I2C_MST_SEL_160M); + + /* Before config I2C register, enable corresponding slave. */ + switch (block) { + case REGI2C_BBPLL : + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_BBPLL_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_BBPLL_RD_MASK); + break; + case REGI2C_BIAS : + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_BIAS_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_BIAS_RD_MASK); + break; + case REGI2C_DIG_REG: + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_DIG_REG_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_DIG_REG_RD_MASK); + break; + case REGI2C_ULP_CAL: + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_ULP_CAL_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_ULP_CAL_RD_MASK); + break; + case REGI2C_SAR_I2C: + i2c_sel = REG_GET_BIT(I2C_ANA_MST_ANA_CONF2_REG, REGI2C_SAR_I2C_MST_SEL); + REG_WRITE(I2C_ANA_MST_ANA_CONF1_REG, REGI2C_SAR_I2C_RD_MASK); + break; + } + + return (uint8_t)(i2c_sel ? 0: 1); +} + +uint8_t IRAM_ATTR regi2c_read_impl(uint8_t block, uint8_t host_id, uint8_t reg_add) +{ + (void)host_id; + uint8_t i2c_sel = regi2c_enable_block(block); + + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + uint8_t ret = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); + + return ret; +} + +uint8_t IRAM_ATTR regi2c_read_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb) +{ + assert(msb - lsb < 8); + uint8_t i2c_sel = regi2c_enable_block(block); + + (void)host_id; + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + uint32_t data = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); + uint8_t ret = (uint8_t)((data >> lsb) & (~(0xFFFFFFFF << (msb - lsb + 1)))); + + return ret; +} + +void IRAM_ATTR regi2c_write_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t data) +{ + (void)host_id; + uint8_t i2c_sel = regi2c_enable_block(block); + + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); // wait i2c idle + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S) + | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) // 0: READ I2C register; 1: Write I2C register; + | (((uint32_t)data & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + +} + +void IRAM_ATTR regi2c_write_mask_impl(uint8_t block, uint8_t host_id, uint8_t reg_add, uint8_t msb, uint8_t lsb, uint8_t data) +{ + (void)host_id; + assert(msb - lsb < 8); + uint8_t i2c_sel = regi2c_enable_block(block); + + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + /*Read the i2c bus register*/ + uint32_t temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | (reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S; + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); + temp = REG_GET_FIELD(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_DATA); + /*Write the i2c bus register*/ + temp &= ((~(0xFFFFFFFF << lsb)) | (0xFFFFFFFF << (msb + 1))); + temp = (((uint32_t)data & (~(0xFFFFFFFF << (msb - lsb + 1)))) << lsb) | temp; + temp = ((block & REGI2C_RTC_SLAVE_ID_V) << REGI2C_RTC_SLAVE_ID_S) + | ((reg_add & REGI2C_RTC_ADDR_V) << REGI2C_RTC_ADDR_S) + | ((0x1 & REGI2C_RTC_WR_CNTL_V) << REGI2C_RTC_WR_CNTL_S) + | ((temp & REGI2C_RTC_DATA_V) << REGI2C_RTC_DATA_S); + REG_WRITE(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), temp); + while (REG_GET_BIT(I2C_ANA_MST_I2C_CTRL_REG(i2c_sel), REGI2C_RTC_BUSY)); +} diff --git a/components/esp_rom/patches/esp_rom_systimer.c b/components/esp_rom/patches/esp_rom_systimer.c index 686fc24689e8..673220bcc679 100644 --- a/components/esp_rom/patches/esp_rom_systimer.c +++ b/components/esp_rom/patches/esp_rom_systimer.c @@ -64,7 +64,7 @@ void systimer_hal_counter_value_advance(systimer_hal_context_t *hal, uint32_t co } #endif // CONFIG_IDF_TARGET_ESP32C2 -#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 +#if CONFIG_IDF_TARGET_ESP32C6 || CONFIG_IDF_TARGET_ESP32H2 || CONFIG_IDF_TARGET_ESP32P4 || CONFIG_IDF_TARGET_ESP32C5 void systimer_hal_init(systimer_hal_context_t *hal) { hal->dev = &SYSTIMER; diff --git a/components/esp_system/CMakeLists.txt b/components/esp_system/CMakeLists.txt index 04ad996b4e72..53bab1f35a31 100644 --- a/components/esp_system/CMakeLists.txt +++ b/components/esp_system/CMakeLists.txt @@ -13,7 +13,11 @@ endif() set(srcs "esp_err.c") if(CONFIG_IDF_ENV_FPGA OR CONFIG_ESP_BRINGUP_BYPASS_CPU_CLK_SETTING) - list(APPEND srcs "fpga_overrides.c") + list(APPEND srcs "fpga_overrides_clk.c") +endif() + +if(CONFIG_IDF_ENV_FPGA OR CONFIG_ESP_BRINGUP_BYPASS_RANDOM_SETTING) + list(APPEND srcs "fpga_overrides_rng.c") endif() if(BOOTLOADER_BUILD) @@ -91,7 +95,12 @@ endif() if(CONFIG_IDF_ENV_FPGA OR CONFIG_ESP_BRINGUP_BYPASS_CPU_CLK_SETTING) # Forces the linker to include fpga stubs from this component - target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_common_include_fpga_overrides") + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_common_include_fpga_overrides_clk") +endif() + +if(CONFIG_IDF_ENV_FPGA OR CONFIG_ESP_BRINGUP_BYPASS_RANDOM_SETTING) + # Forces the linker to include fpga stubs from this component + target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_common_include_fpga_overrides_rng") endif() # Force linking UBSAN hooks. If UBSAN is not enabled, the hooks will ultimately be removed diff --git a/components/esp_system/fpga_overrides.c b/components/esp_system/fpga_overrides_clk.c similarity index 78% rename from components/esp_system/fpga_overrides.c rename to components/esp_system/fpga_overrides_clk.c index 210517bb5730..72c7aa5ff233 100644 --- a/components/esp_system/fpga_overrides.c +++ b/components/esp_system/fpga_overrides_clk.c @@ -31,13 +31,12 @@ #include "esp_log.h" #include "esp_rom_sys.h" #include "esp_rom_uart.h" -#include "esp_attr.h" -static const char *TAG = "fpga"; +static const char *TAG = "fpga_clk"; static void s_warn(void) { - ESP_EARLY_LOGW(TAG, "Project configuration is for internal FPGA use, not all functions will work"); + ESP_EARLY_LOGE(TAG, "Project configuration is for internal FPGA use, clock functions will not work"); } void bootloader_clock_configure(void) @@ -58,15 +57,6 @@ void bootloader_clock_configure(void) REG_WRITE(RTC_XTAL_FREQ_REG, (xtal_freq_mhz) | ((xtal_freq_mhz) << 16)); } -/* Placed in IRAM since test_apps expects it to be */ -void IRAM_ATTR bootloader_fill_random(void *buffer, size_t length) -{ - uint8_t *buffer_bytes = (uint8_t *)buffer; - for (int i = 0; i < length; i++) { - buffer_bytes[i] = 0x5A; - } -} - void esp_clk_init(void) { s_warn(); @@ -83,6 +73,6 @@ void esp_perip_clk_init(void) * @brief No-op function, used to force linking this file * */ -void esp_common_include_fpga_overrides(void) +void esp_common_include_fpga_overrides_clk(void) { } diff --git a/components/esp_system/fpga_overrides_rng.c b/components/esp_system/fpga_overrides_rng.c new file mode 100644 index 000000000000..10014e5cecf2 --- /dev/null +++ b/components/esp_system/fpga_overrides_rng.c @@ -0,0 +1,29 @@ +/* + * SPDX-FileCopyrightText: 2010-2023 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include "esp_log.h" +#include "esp_attr.h" + +static const char *TAG = "fpga_rng"; + +/* Placed in IRAM since test_apps expects it to be */ +void IRAM_ATTR bootloader_fill_random(void *buffer, size_t length) +{ + ESP_EARLY_LOGE(TAG, "Project configuration is for internal FPGA use, RNG will not work"); + + uint8_t *buffer_bytes = (uint8_t *)buffer; + for (int i = 0; i < length; i++) { + buffer_bytes[i] = 0x5A; + } +} + +/** + * @brief No-op function, used to force linking this file + * + */ +void esp_common_include_fpga_overrides_rng(void) +{ +} diff --git a/components/esp_system/include/esp_task_wdt.h b/components/esp_system/include/esp_task_wdt.h index cf7e8dacfba3..58b6482a4080 100644 --- a/components/esp_system/include/esp_task_wdt.h +++ b/components/esp_system/include/esp_task_wdt.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -179,6 +179,31 @@ esp_err_t esp_task_wdt_status(TaskHandle_t task_handle); */ void __attribute__((weak)) esp_task_wdt_isr_user_handler(void); +typedef void (*task_wdt_msg_handler)(void *opaque, const char *msg); + +/** + * @brief Prints or retrieves information about tasks/users that triggered the Task Watchdog Timeout. + * + * This function provides various operations to handle tasks/users that did not reset the Task Watchdog in time. + * It can print detailed information about these tasks/users, such as their names, associated CPUs, and whether they have been reset. + * Additionally, it can retrieve the total length of the printed information or the CPU affinity of the failing tasks. + * + * @param[in] msg_handler Optional message handler function that will be called for each printed line. + * @param[in] opaque Optional pointer to opaque data that will be passed to the message handler function. + * @param[out] cpus_fail Optional pointer to an integer where the CPU affinity of the failing tasks will be stored. + * + * @return + * - ESP_OK: The function executed successfully. + * - ESP_FAIL: No triggered tasks were found, and thus no information was printed or retrieved. + * + * @note + * - If `msg_handler` is not provided, the information will be printed to console using ESP_EARLY_LOGE. + * - If `msg_handler` is provided, the function will send the printed information to the provided message handler function. + * - If `cpus_fail` is provided, the function will store the CPU affinity of the failing tasks in the provided integer. + * - During the execution of this function, logging is allowed in critical sections, as TWDT timeouts are considered fatal errors. + */ +esp_err_t esp_task_wdt_print_triggered_tasks(task_wdt_msg_handler msg_handler, void *opaque, int *cpus_fail); + #ifdef __cplusplus } #endif diff --git a/components/esp_system/port/cpu_start.c b/components/esp_system/port/cpu_start.c index 99d6e8b42d89..09fde98aedcc 100644 --- a/components/esp_system/port/cpu_start.c +++ b/components/esp_system/port/cpu_start.c @@ -66,6 +66,7 @@ #include "soc/hp_sys_clkrst_reg.h" #include "soc/interrupt_core0_reg.h" #include "soc/interrupt_core1_reg.h" +#include "soc/keymng_reg.h" #endif #include "esp_private/esp_mmu_map_private.h" @@ -299,6 +300,11 @@ static void start_other_core(void) if(REG_GET_BIT(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_CORE1_GLOBAL)){ REG_CLR_BIT(HP_SYS_CLKRST_HP_RST_EN0_REG, HP_SYS_CLKRST_REG_RST_EN_CORE1_GLOBAL); } + // The following operation makes the Key Manager to use eFuse key for ECDSA and XTS-AES operation by default + // This is to keep the default behavior same as the other chips + // If the Key Manager configuration is already locked then following operation does not have any effect + // TODO-IDF 7925 (Move this under SOC_KEY_MANAGER_SUPPORTED) + REG_SET_FIELD(KEYMNG_STATIC_REG, KEYMNG_USE_EFUSE_KEY, 3); #endif ets_set_appcpu_boot_addr((uint32_t)call_start_cpu1); diff --git a/components/esp_system/task_wdt/task_wdt.c b/components/esp_system/task_wdt/task_wdt.c index df50385ddea9..e1a4017b864f 100644 --- a/components/esp_system/task_wdt/task_wdt.c +++ b/components/esp_system/task_wdt/task_wdt.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -337,6 +338,32 @@ static void subscribe_idle(uint32_t core_mask) * */ +static UBaseType_t get_task_affinity(const TaskHandle_t xTask) +{ + if (xTask == NULL) { + /* User entry, we cannot predict on which core it is scheduled to run, + * so let's mark all cores as failing */ +#if configNUM_CORES > 1 + return BIT(1) | BIT(0); +#else + return BIT(0); +#endif + } + +#if CONFIG_FREERTOS_SMP + #if configNUM_CORES > 1 + return vTaskCoreAffinityGet(xTask); + #else + return BIT(0); + #endif +#else + BaseType_t task_affinity = xTaskGetCoreID(xTask); + if (task_affinity == 0 || task_affinity == 1) { + return BIT(task_affinity); + } + return BIT(1) | BIT(0); +#endif +} /** * Function simulating an abort coming from the interrupted task of the current @@ -456,65 +483,17 @@ static void task_wdt_isr(void *arg) portENTER_CRITICAL_ISR(&spinlock); esp_task_wdt_impl_timeout_triggered(p_twdt_obj->impl_ctx); - // If there are no entries, there's nothing to do. - if (SLIST_EMPTY(&p_twdt_obj->entries_slist)) { - portEXIT_CRITICAL_ISR(&spinlock); - return; - } - // Find what entries triggered the TWDT timeout (i.e., which entries have not been reset) - /* - Note: We are currently in a critical section, thus under normal circumstances, logging should not be allowed. - However, TWDT timeouts count as fatal errors, thus reporting the fatal error is considered more important than - minimizing interrupt latency. Thus we allow logging in critical sections in this narrow case. - */ - ESP_EARLY_LOGE(TAG, "Task watchdog got triggered. The following tasks/users did not reset the watchdog in time:"); - twdt_entry_t *entry; /* Keep a bitmap of CPU cores having tasks that have not reset TWDT. * Bit 0 represents core 0, bit 1 represents core 1, and so on. */ int cpus_fail = 0; bool panic = p_twdt_obj->panic; - SLIST_FOREACH(entry, &p_twdt_obj->entries_slist, slist_entry) { - if (!entry->has_reset) { - if (entry->task_handle) { -#if CONFIG_FREERTOS_SMP -#if configNUM_CORES > 1 - // Log the task's name and its affinity - const UBaseType_t affinity = vTaskCoreAffinityGet(entry->task_handle); - ESP_EARLY_LOGE(TAG, " - %s (0x%x)", pcTaskGetName(entry->task_handle), affinity); - cpus_fail |= affinity; -#else // configNUM_CORES > 1 - // Log the task's name - ESP_EARLY_LOGE(TAG, " - %s", pcTaskGetName(entry->task_handle)); - cpus_fail |= BIT(0); -#endif // configNUM_CORES > 1 -#else // CONFIG_FREERTOS_SMP - BaseType_t task_affinity = xTaskGetCoreID(entry->task_handle); - const char *cpu; - if (task_affinity == 0) { - cpu = DRAM_STR("CPU 0"); - cpus_fail |= BIT(0); - } else if (task_affinity == 1) { - cpu = DRAM_STR("CPU 1"); - cpus_fail |= BIT(1); - } else { - cpu = DRAM_STR("CPU 0/1"); - cpus_fail |= BIT(1) | BIT(0); - } - ESP_EARLY_LOGE(TAG, " - %s (%s)", pcTaskGetName(entry->task_handle), cpu); -#endif // CONFIG_FREERTOS_SMP - } else { - /* User entry, we cannot predict on which core it is scheduled to run, - * so let's mark all cores as failing */ -#if configNUM_CORES > 1 - cpus_fail = BIT(1) | BIT(0); -#else // configNUM_CORES > 1 - cpus_fail = BIT(0); -#endif // configNUM_CORES > 1 - ESP_EARLY_LOGE(TAG, " - %s", entry->user_name); - } - } - } + if (esp_task_wdt_print_triggered_tasks(NULL, NULL, &cpus_fail) != ESP_OK) { + // If there are no entries, there's nothing to do. + portEXIT_CRITICAL_ISR(&spinlock); + return; + } + ESP_EARLY_LOGE(TAG, "%s", DRAM_STR("Tasks currently running:")); for (int x = 0; x < portNUM_PROCESSORS; x++) { ESP_EARLY_LOGE(TAG, "CPU %d: %s", x, pcTaskGetName(xTaskGetCurrentTaskHandleForCore(x))); @@ -806,3 +785,47 @@ esp_err_t esp_task_wdt_status(TaskHandle_t task_handle) return ret; } + +esp_err_t esp_task_wdt_print_triggered_tasks(task_wdt_msg_handler msg_handler, void *opaque, int *cpus_fail) +{ + if (SLIST_EMPTY(&p_twdt_obj->entries_slist)) { + return ESP_FAIL; + } + + twdt_entry_t *entry; + const char *caption = "Task watchdog got triggered. " + "The following tasks/users did not reset the watchdog in time:"; + + if (msg_handler == NULL) { + ESP_EARLY_LOGE(TAG, "%s", caption); + } else { + msg_handler(opaque, caption); + } + + // Find what entries triggered the TWDT timeout (i.e., which entries have not been reset) + SLIST_FOREACH(entry, &p_twdt_obj->entries_slist, slist_entry) { + if (!entry->has_reset) { + const char *cpu; + const char *name = entry->task_handle ? pcTaskGetName(entry->task_handle) : entry->user_name; + const UBaseType_t affinity = get_task_affinity(entry->task_handle); + if (cpus_fail) { + *cpus_fail |= affinity; + } + if (affinity == BIT(0)) { + cpu = " (CPU 0)"; + } else if (affinity == BIT(1)) { + cpu = " (CPU 1)"; + } else { + cpu = " (CPU 0/1)"; + } + if (msg_handler == NULL) { + ESP_EARLY_LOGE(TAG, " - %s%s", name, cpu); + } else { + msg_handler(opaque, "\n - "); + msg_handler(opaque, name); + msg_handler(opaque, cpu); + } + } + } + return ESP_OK; +} diff --git a/components/esp_wifi/CMakeLists.txt b/components/esp_wifi/CMakeLists.txt index 14d5d423a810..8605bed5dfa4 100644 --- a/components/esp_wifi/CMakeLists.txt +++ b/components/esp_wifi/CMakeLists.txt @@ -71,4 +71,8 @@ if(CONFIG_ESP_WIFI_ENABLED) endforeach() endif() + if(CONFIG_SPIRAM) + idf_component_optional_requires(PRIVATE esp_psram) + endif() + endif() diff --git a/components/esp_wifi/include/esp_wifi.h b/components/esp_wifi/include/esp_wifi.h index 55cefbc205fe..e4ea220cf7ee 100644 --- a/components/esp_wifi/include/esp_wifi.h +++ b/components/esp_wifi/include/esp_wifi.h @@ -181,7 +181,6 @@ typedef struct { #endif extern const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs; -extern uint64_t g_wifi_feature_caps; #define WIFI_INIT_CONFIG_MAGIC 0x1F2F3F4F @@ -215,11 +214,41 @@ extern uint64_t g_wifi_feature_caps; #define WIFI_STA_DISCONNECTED_PM_ENABLED false #endif -#define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0) +#if CONFIG_ESP_WIFI_ENABLE_WPA3_SAE +#define WIFI_ENABLE_WPA3_SAE (1<<0) +#else +#define WIFI_ENABLE_WPA3_SAE 0 +#endif + +#if CONFIG_SPIRAM +#define WIFI_ENABLE_SPIRAM (1<<1) +#else +#define WIFI_ENABLE_SPIRAM 0 +#endif + +#if CONFIG_ESP_WIFI_FTM_INITIATOR_SUPPORT +#define WIFI_FTM_INITIATOR (1<<2) +#else +#define WIFI_FTM_INITIATOR 0 +#endif + +#if CONFIG_ESP_WIFI_FTM_RESPONDER_SUPPORT +#define WIFI_FTM_RESPONDER (1<<3) +#else +#define WIFI_FTM_RESPONDER 0 +#endif + +#define CONFIG_FEATURE_WPA3_SAE_BIT (1<<0) #define CONFIG_FEATURE_CACHE_TX_BUF_BIT (1<<1) #define CONFIG_FEATURE_FTM_INITIATOR_BIT (1<<2) #define CONFIG_FEATURE_FTM_RESPONDER_BIT (1<<3) +/* Set additional WiFi features and capabilities */ +#define WIFI_FEATURE_CAPS (WIFI_ENABLE_WPA3_SAE | \ + WIFI_ENABLE_SPIRAM | \ + WIFI_FTM_INITIATOR | \ + WIFI_FTM_RESPONDER) + #define WIFI_INIT_CONFIG_DEFAULT() { \ .osi_funcs = &g_wifi_osi_funcs, \ .wpa_crypto_funcs = g_wifi_default_wpa_crypto_funcs, \ @@ -241,7 +270,7 @@ extern uint64_t g_wifi_feature_caps; .wifi_task_core_id = WIFI_TASK_CORE_ID,\ .beacon_max_len = WIFI_SOFTAP_BEACON_MAX_LEN, \ .mgmt_sbuf_num = WIFI_MGMT_SBUF_NUM, \ - .feature_caps = g_wifi_feature_caps, \ + .feature_caps = WIFI_FEATURE_CAPS, \ .sta_disconnected_pm = WIFI_STA_DISCONNECTED_PM_ENABLED, \ .espnow_max_encrypt_num = CONFIG_ESP_WIFI_ESPNOW_MAX_ENCRYPT_NUM, \ .magic = WIFI_INIT_CONFIG_MAGIC\ diff --git a/components/esp_wifi/lib b/components/esp_wifi/lib index 07bb480841d3..b8965b78b189 160000 --- a/components/esp_wifi/lib +++ b/components/esp_wifi/lib @@ -1 +1 @@ -Subproject commit 07bb480841d33fc1f7c1cd1e96f774604a8e4b56 +Subproject commit b8965b78b189369de1ac22b86aab1356fad01d1a diff --git a/components/esp_wifi/src/wifi_init.c b/components/esp_wifi/src/wifi_init.c index 43e856d9489a..73b11acf9abf 100644 --- a/components/esp_wifi/src/wifi_init.c +++ b/components/esp_wifi/src/wifi_init.c @@ -19,6 +19,9 @@ #include "private/esp_coexist_internal.h" #include "esp_phy_init.h" #include "esp_private/phy.h" +#if __has_include("esp_psram.h") +#include "esp_psram.h" +#endif #ifdef CONFIG_ESP_WIFI_NAN_ENABLE #include "apps_private/wifi_apps_private.h" #endif @@ -45,22 +48,6 @@ static esp_pm_lock_handle_t s_wifi_modem_sleep_lock; wifi_mac_time_update_cb_t s_wifi_mac_time_update_cb = NULL; #endif -/* Set additional WiFi features and capabilities */ -uint64_t g_wifi_feature_caps = -#if CONFIG_ESP_WIFI_ENABLE_WPA3_SAE - CONFIG_FEATURE_WPA3_SAE_BIT | -#endif -#if CONFIG_SPIRAM - CONFIG_FEATURE_CACHE_TX_BUF_BIT | -#endif -#if CONFIG_ESP_WIFI_FTM_INITIATOR_SUPPORT - CONFIG_FEATURE_FTM_INITIATOR_BIT | -#endif -#if CONFIG_ESP_WIFI_FTM_RESPONDER_SUPPORT - CONFIG_FEATURE_FTM_RESPONDER_BIT | -#endif -0; - #if SOC_PM_SUPPORT_PMU_MODEM_STATE # define WIFI_BEACON_MONITOR_CONFIG_DEFAULT(ena) { \ .enable = (ena), \ @@ -235,17 +222,46 @@ static void esp_wifi_config_info(void) #endif } +#if CONFIG_SPIRAM +static esp_err_t esp_wifi_psram_check(const wifi_init_config_t *config) +{ +#if CONFIG_SPIRAM_IGNORE_NOTFOUND + if (!esp_psram_is_initialized()) { + if (config->feature_caps & CONFIG_FEATURE_CACHE_TX_BUF_BIT) { + ESP_LOGW(TAG, "WiFi cache TX buffers should be disabled when initialize SPIRAM failed"); + } + if (config->tx_buf_type == 0) { + ESP_LOGW(TAG, "TX buffers type should be changed from static to dynamic when initialize SPIRAM failed"); + } +#ifdef CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP + ESP_LOGW(TAG, "WiFi/LWIP prefer SPIRAM should be disabled when initialize SPIRAM failed"); +#endif + if (config->amsdu_tx_enable) { + ESP_LOGW(TAG, "WiFi AMSDU TX should be disabled when initialize SPIRAM failed"); + } + } +#endif + if ((config->feature_caps & CONFIG_FEATURE_CACHE_TX_BUF_BIT) && (WIFI_CACHE_TX_BUFFER_NUM == 0)) { + ESP_LOGE(TAG, "Number of WiFi cache TX buffers should not equal 0 when enable SPIRAM"); + return ESP_ERR_NOT_SUPPORTED; + } + return ESP_OK; +} +#endif + esp_err_t esp_wifi_init(const wifi_init_config_t *config) { if (s_wifi_inited) { return ESP_OK; } - if ((config->feature_caps & CONFIG_FEATURE_CACHE_TX_BUF_BIT) && (WIFI_CACHE_TX_BUFFER_NUM == 0)) - { - ESP_LOGE(TAG, "Number of WiFi cache TX buffers should not equal 0 when enable SPIRAM"); - return ESP_ERR_NOT_SUPPORTED; + esp_err_t result = ESP_OK; +#ifdef CONFIG_SPIRAM + result = esp_wifi_psram_check(config); + if (result != ESP_OK) { + return result; } +#endif #if CONFIG_ESP_WIFI_SLP_IRAM_OPT int min_freq_mhz = esp_pm_impl_get_cpu_freq(PM_MODE_LIGHT_SLEEP); @@ -302,7 +318,7 @@ esp_err_t esp_wifi_init(const wifi_init_config_t *config) #endif esp_wifi_set_log_level(); esp_wifi_power_domain_on(); - esp_err_t result = esp_wifi_init_internal(config); + result = esp_wifi_init_internal(config); if (result == ESP_OK) { #if CONFIG_MAC_BB_PD esp_mac_bb_pd_mem_init(); diff --git a/components/esp_wifi/test_apps/wifi_connect/main/test_wifi_conn.c b/components/esp_wifi/test_apps/wifi_connect/main/test_wifi_conn.c index d65d4bc75f8e..9608f122cbe6 100644 --- a/components/esp_wifi/test_apps/wifi_connect/main/test_wifi_conn.c +++ b/components/esp_wifi/test_apps/wifi_connect/main/test_wifi_conn.c @@ -72,6 +72,8 @@ static void wifi_event_handler(void* arg, esp_event_base_t event_base, break; case WIFI_EVENT_STA_DISCONNECTED: ESP_LOGI(TAG, "WIFI_EVENT_STA_DISCONNECTED"); + wifi_event_sta_disconnected_t *event = (wifi_event_sta_disconnected_t *)event_data; + ESP_LOGI(TAG, "disconnect reason: %u", event->reason); if (! (EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT & wifi_event_handler_flag) ) { TEST_ESP_OK(esp_wifi_connect()); } @@ -279,6 +281,7 @@ static void esp_wifi_connect_first_time(void) memset(&w_config, 0, sizeof(w_config)); memcpy(w_config.sta.ssid, TEST_DEFAULT_SSID, strlen(TEST_DEFAULT_SSID)); memcpy(w_config.sta.password, TEST_DEFAULT_PWD, strlen(TEST_DEFAULT_PWD)); + w_config.sta.channel = 1; wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT; @@ -307,7 +310,7 @@ static void test_wifi_connect_before_connected_phase(void) esp_wifi_connect_first_time(); // connect before connected - vTaskDelay(800/portTICK_PERIOD_MS); + vTaskDelay(730/portTICK_PERIOD_MS); ESP_LOGI(TAG, "connect when first connect after scan before connected"); TEST_ESP_ERR(ESP_ERR_WIFI_CONN, esp_wifi_connect()); wifi_event_handler_flag |= EVENT_HANDLER_FLAG_DO_NOT_AUTO_RECONNECT; diff --git a/components/esp_wifi/test_apps/wifi_connect/pytest_wifi_connect.py b/components/esp_wifi/test_apps/wifi_connect/pytest_wifi_connect.py index b53cf631f7b3..1604e7901736 100644 --- a/components/esp_wifi/test_apps/wifi_connect/pytest_wifi_connect.py +++ b/components/esp_wifi/test_apps/wifi_connect/pytest_wifi_connect.py @@ -2,7 +2,7 @@ # SPDX-License-Identifier: Unlicense OR CC0-1.0 import pytest -from idf_unity_tester import CaseTester +from pytest_embedded_idf.unity_tester import CaseTester @pytest.mark.esp32 diff --git a/components/espcoredump/src/core_dump_elf.c b/components/espcoredump/src/core_dump_elf.c index cd93d26b2100..9fdcf9a6aeae 100644 --- a/components/espcoredump/src/core_dump_elf.c +++ b/components/espcoredump/src/core_dump_elf.c @@ -14,6 +14,7 @@ #include "esp_core_dump_port_impl.h" #include "esp_core_dump_common.h" #include "hal/efuse_hal.h" +#include "esp_task_wdt.h" #ifdef CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF #include // for the MIN macro @@ -35,6 +36,8 @@ #define ELF_NOTE_NAME_MAX_SIZE 32 #define ELF_APP_SHA256_SIZE 66 +#define ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME "ESP_PANIC_DETAILS" + #define ELF_CHECK_ERR(a, ret_val, str, ...) \ if (!(a)) { \ ESP_COREDUMP_LOGE("%s(%u): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \ @@ -82,18 +85,23 @@ typedef struct _core_dump_elf_t uint32_t elf_next_data_offset; uint16_t segs_count; core_dump_write_config_t * write_cfg; + uint32_t note_data_size; /* can be used where static storage needed */ } core_dump_elf_t; -// Represents lightweight implementation to save core dump data into ELF formatted binary +typedef struct { + core_dump_elf_t *self; + uint32_t total_size; + bool size_only; +} core_dump_elf_opaque_t; -#define ALIGN(b, var) var = align(b, var) +// Represents lightweight implementation to save core dump data into ELF formatted binary #if CONFIG_ESP_COREDUMP_DATA_FORMAT_ELF -static inline uint32_t align(uint32_t width, uint32_t in) -{ - return (in + (width - 1)) & -width; -} +#ifdef ALIGN_UP +#undef ALIGN_UP +#endif +#define ALIGN_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) // Builds elf header and check all data offsets static int elf_write_file_header(core_dump_elf_t *self, uint32_t seg_count) @@ -158,13 +166,11 @@ static int elf_add_segment(core_dump_elf_t *self, { esp_err_t err = ESP_FAIL; elf_phdr seg_hdr = { 0 }; - int data_len = data_sz; + int data_len = ALIGN_UP(data_sz, 4); ELF_CHECK_ERR((data != NULL), ELF_PROC_ERR_OTHER, "Invalid data for segment."); - ALIGN(4, data_len); - if (self->elf_stage == ELF_STAGE_CALC_SPACE) { self->segs_count++; return data_len + sizeof(elf_phdr); @@ -193,6 +199,29 @@ static int elf_add_segment(core_dump_elf_t *self, return data_len; } +static int elf_write_note_header(core_dump_elf_t *self, + const char* name, uint32_t name_len, uint32_t data_sz, uint32_t type) +{ + // temporary aligned buffer for note name + static char name_buffer[ELF_NOTE_NAME_MAX_SIZE] = { 0 }; + elf_note note_hdr = { 0 }; + + memcpy((void*)name_buffer, (void*)name, name_len); + note_hdr.n_namesz = name_len; + note_hdr.n_descsz = data_sz; + note_hdr.n_type = type; + // write note header + esp_err_t err = self->write_cfg->write(self->write_cfg->priv, ¬e_hdr, sizeof(note_hdr)); + ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, + "Write ELF note header failure (%d)", err); + // write note name + err = self->write_cfg->write(self->write_cfg->priv, name_buffer, name_len); + ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, + "Write ELF note name failure (%d)", err); + + return err; +} + static int elf_write_note(core_dump_elf_t *self, const char* name, uint32_t type, @@ -200,38 +229,34 @@ static int elf_write_note(core_dump_elf_t *self, uint32_t data_sz) { esp_err_t err = ESP_FAIL; - // temporary buffer for note name - static char name_buffer[ELF_NOTE_NAME_MAX_SIZE] = { 0 }; - elf_note note_hdr = { 0 }; - uint32_t name_len = strlen(name) + 1; // get name length including terminator - uint32_t data_len = data_sz; + uint32_t name_len = ALIGN_UP(strlen(name) + 1, 4); // get name length including terminator + uint32_t data_len = ALIGN_UP(data_sz, 4); - ELF_CHECK_ERR(data, ELF_PROC_ERR_OTHER, - "Invalid data pointer %x.", (uint32_t)data); ELF_CHECK_ERR((name_len <= ELF_NOTE_NAME_MAX_SIZE), 0, "Segment note name is too long %d.", name_len); - ALIGN(4, data_len); - ALIGN(4, name_len); - uint32_t note_size = name_len + data_len + sizeof(elf_note); - ALIGN(4, note_size); + uint32_t note_size = ALIGN_UP(name_len + data_len + sizeof(elf_note), 4); // write segment data during second pass if (self->elf_stage == ELF_STAGE_PLACE_DATA) { - memcpy((void*)name_buffer, (void*)name, name_len); - note_hdr.n_namesz = name_len; - note_hdr.n_descsz = data_sz; - note_hdr.n_type = type; - // write note header - err = self->write_cfg->write(self->write_cfg->priv, (void*)¬e_hdr, sizeof(note_hdr)); - ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, - "Write ELF note header failure (%d)", err); - // write note name - err = self->write_cfg->write(self->write_cfg->priv, (void*)name_buffer, name_len); - ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, - "Write ELF note name failure (%d)", err); - // write note data - err = self->write_cfg->write(self->write_cfg->priv, (void*)data, data_len); + ELF_CHECK_ERR(data, ELF_PROC_ERR_OTHER, "Invalid data pointer %x.", (uint32_t)data); + err = elf_write_note_header(self, name, name_len, data_sz, type); + if (err != ESP_OK) { + return err; + } + + // note data must be aligned in memory. we write aligned byte structures and panic details in strings, + // which might not be aligned by default. Therefore, we need to verify alignment and add padding if necessary. + err = self->write_cfg->write(self->write_cfg->priv, data, data_sz); + if (err == ESP_OK) { + int pad_size = data_len - data_sz; + if (pad_size != 0) { + uint8_t pad_bytes[3] = {0}; + ESP_COREDUMP_LOG_PROCESS("Core dump note data needs %d bytes padding", pad_size); + err = self->write_cfg->write(self->write_cfg->priv, pad_bytes, pad_size); + } + } + ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note data failure (%d)", err); ESP_COREDUMP_LOG_PROCESS("Add note size=%d, start_off=0x%x", @@ -495,6 +520,65 @@ static int elf_write_core_dump_user_data(core_dump_elf_t *self) return total_sz; } +#if CONFIG_ESP_TASK_WDT_EN +static void elf_write_core_dump_note_cb(void *opaque, const char *data) +{ + core_dump_elf_opaque_t *param = opaque; + core_dump_elf_t *self = param->self; + const size_t data_len = strlen(data); + + ESP_COREDUMP_LOG_PROCESS("Core dump note cb data_len:(%d)", data_len); + + param->total_size += data_len; + + if (!param->size_only) { + esp_err_t err = self->write_cfg->write(self->write_cfg->priv, (void *)data, data_len); + if (err != ESP_OK) { + param->total_size = 0; + } + } +} + +static int elf_add_wdt_panic_details(core_dump_elf_t *self) +{ + uint32_t name_len = ALIGN_UP(sizeof(ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME), 4); + core_dump_elf_opaque_t param = { + .self = self, + .total_size = 0, + .size_only = false, + }; + + if (self->elf_stage == ELF_STAGE_CALC_SPACE) { + param.size_only = true; + esp_task_wdt_print_triggered_tasks(elf_write_core_dump_note_cb, ¶m, NULL); + ELF_CHECK_ERR((param.total_size > 0), ELF_PROC_ERR_OTHER, "wdt panic message len is zero!"); + self->note_data_size = param.total_size; + } else if (self->elf_stage == ELF_STAGE_PLACE_DATA) { + esp_err_t err = elf_write_note_header(self, + ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME, + name_len, + self->note_data_size, + ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE); + if (err != ESP_OK) { + return err; + } + + esp_task_wdt_print_triggered_tasks(elf_write_core_dump_note_cb, ¶m, NULL); + ELF_CHECK_ERR((param.total_size > 0), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note data failure (%d)", err); + const uint32_t mod = self->note_data_size & 3; + if (mod != 0) { + uint8_t pad_bytes[3] = {0}; + uint32_t pad_size = 4 - mod; + ESP_COREDUMP_LOG_PROCESS("Core dump note needs %d bytes padding", pad_size); + err = self->write_cfg->write(self->write_cfg->priv, pad_bytes, pad_size); + ELF_CHECK_ERR((err == ESP_OK), ELF_PROC_ERR_WRITE_FAIL, "Write ELF note padding failure (%d)", err); + } + } + + return ALIGN_UP(name_len + ALIGN_UP(self->note_data_size, 4) + sizeof(elf_note), 4); +} +#endif //CONFIG_ESP_TASK_WDT_EN + static int elf_write_core_dump_info(core_dump_elf_t *self) { void *extra_info = NULL; @@ -530,13 +614,22 @@ static int elf_write_core_dump_info(core_dump_elf_t *self) ELF_CHECK_ERR((ret > 0), ret, "Extra info note write failed. Returned (%d).", ret); data_len += ret; +#if CONFIG_ESP_TASK_WDT_EN + extern bool g_twdt_isr; + if (g_twdt_isr) { + ret = elf_add_wdt_panic_details(self); + if (ret <= 0) { return ret; } + data_len += ret; + } +#endif + if (g_panic_abort_details && strlen(g_panic_abort_details) > 0) { ret = elf_add_note(self, - "ESP_PANIC_DETAILS", - ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE, - g_panic_abort_details, - strlen(g_panic_abort_details)); - ELF_CHECK_ERR((ret > 0), ret, "Panic details note write failed. Returned (%d).", ret); + ELF_ESP_CORE_DUMP_PANIC_DETAILS_NOTE_NAME, + ELF_ESP_CORE_DUMP_PANIC_DETAILS_TYPE, + g_panic_abort_details, + strlen(g_panic_abort_details)); + ELF_CHECK_ERR((ret > 0), ret, "Panic details note write failed. Returned (%d).", ret); data_len += ret; } @@ -769,8 +862,7 @@ static void esp_core_dump_parse_note_section(uint8_t *coredump_data, elf_note_co break; } } - consumed_note_sz += note->n_namesz + note->n_descsz + sizeof(elf_note); - ALIGN(4, consumed_note_sz); + consumed_note_sz += ALIGN_UP(note->n_namesz + note->n_descsz + sizeof(elf_note), 4); } } } diff --git a/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h b/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h index de642b56d692..fbdb89909883 100644 --- a/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h +++ b/components/hal/esp32p4/include/hal/spi_flash_encrypted_ll.h @@ -24,8 +24,6 @@ extern "C" { #endif -//TODO: IDF-7545 - /// Choose type of chip you want to encrypt manully typedef enum { @@ -38,10 +36,9 @@ typedef enum */ static inline void spi_flash_encrypt_ll_enable(void) { - // REG_SET_BIT(HP_SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG, - // HP_SYSTEM_ENABLE_DOWNLOAD_MANUAL_ENCRYPT | - // HP_SYSTEM_ENABLE_SPI_MANUAL_ENCRYPT); - abort(); + REG_SET_BIT(HP_SYSTEM_CRYPTO_CTRL_REG, + HP_SYSTEM_REG_ENABLE_DOWNLOAD_MANUAL_ENCRYPT | + HP_SYSTEM_REG_ENABLE_SPI_MANUAL_ENCRYPT); } /* @@ -49,9 +46,8 @@ static inline void spi_flash_encrypt_ll_enable(void) */ static inline void spi_flash_encrypt_ll_disable(void) { - // REG_CLR_BIT(HP_SYSTEM_EXTERNAL_DEVICE_ENCRYPT_DECRYPT_CONTROL_REG, - // HP_SYSTEM_ENABLE_SPI_MANUAL_ENCRYPT); - abort(); + REG_CLR_BIT(HP_SYSTEM_CRYPTO_CTRL_REG, + HP_SYSTEM_REG_ENABLE_SPI_MANUAL_ENCRYPT); } /** diff --git a/components/hal/spi_hal.c b/components/hal/spi_hal.c index 25b77b8ef6b3..ee58edae0315 100644 --- a/components/hal/spi_hal.c +++ b/components/hal/spi_hal.c @@ -12,29 +12,6 @@ #include "soc/soc_caps.h" #include "soc/clk_tree_defs.h" -//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros. -#if SOC_GDMA_SUPPORTED -#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) && (SOC_AHB_GDMA_VERSION == 1) -#include "soc/gdma_struct.h" -#include "hal/gdma_ll.h" -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) gdma_ll_rx_enable_data_burst(&GDMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) gdma_ll_tx_enable_data_burst(&GDMA, chan, enable); -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, chan, enable); -#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, chan, enable); -#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) gdma_ll_tx_set_eof_mode(&GDMA, chan, enable); - -#elif (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) //TODO: IDF-6152, refactor spi hal layer -#include "hal/axi_dma_ll.h" -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) axi_dma_ll_rx_enable_data_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) axi_dma_ll_tx_enable_data_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) axi_dma_ll_rx_enable_descriptor_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) axi_dma_ll_tx_enable_descriptor_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) axi_dma_ll_tx_enable_auto_write_back(&AXI_DMA, chan, enable); -#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) axi_dma_ll_tx_set_eof_mode(&AXI_DMA, chan, enable); -#endif -#endif //SOC_GDMA_SUPPORTED - /* The tag may be unused if log level is set to NONE */ static const __attribute__((unused)) char SPI_HAL_TAG[] = "spi_hal"; @@ -44,14 +21,6 @@ static const __attribute__((unused)) char SPI_HAL_TAG[] = "spi_hal"; return (ret_val); \ } -static void s_spi_hal_dma_init_config(const spi_hal_context_t *hal) -{ - spi_dma_ll_rx_enable_burst_data(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_data(hal->dma_out, hal->tx_dma_chan, 1); - spi_dma_ll_rx_enable_burst_desc(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_desc(hal->dma_out, hal->tx_dma_chan, 1); -} - void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id, const spi_hal_config_t *config) { memset(hal, 0, sizeof(spi_hal_context_t)); @@ -71,9 +40,6 @@ void spi_hal_init(spi_hal_context_t *hal, uint32_t host_id, const spi_hal_config spi_ll_set_mosi_free_level(hw, 0); #endif spi_ll_master_init(hw); - if (config->dma_enabled) { - s_spi_hal_dma_init_config(hal); - } //Force a transaction done interrupt. This interrupt won't fire yet because //we initialized the SPI interrupt as disabled. This way, we can just diff --git a/components/hal/spi_slave_hal.c b/components/hal/spi_slave_hal.c index c53bd600cadf..5d0f570b5449 100644 --- a/components/hal/spi_slave_hal.c +++ b/components/hal/spi_slave_hal.c @@ -2,37 +2,6 @@ #include "hal/spi_ll.h" #include "soc/soc_caps.h" -//This GDMA related part will be introduced by GDMA dedicated APIs in the future. Here we temporarily use macros. -#if SOC_GDMA_SUPPORTED -#if (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AHB) && (SOC_AHB_GDMA_VERSION == 1) -#include "soc/gdma_struct.h" -#include "hal/gdma_ll.h" -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) gdma_ll_rx_enable_data_burst(&GDMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) gdma_ll_tx_enable_data_burst(&GDMA, chan, enable); -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, chan, enable); -#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, chan, enable); -#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) gdma_ll_tx_set_eof_mode(&GDMA, chan, enable); - -#elif (SOC_GDMA_TRIG_PERIPH_SPI2_BUS == SOC_GDMA_BUS_AXI) //TODO: IDF-6152, refactor spi hal layer -#include "hal/axi_dma_ll.h" -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) axi_dma_ll_rx_enable_data_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) axi_dma_ll_tx_enable_data_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) axi_dma_ll_rx_enable_descriptor_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) axi_dma_ll_tx_enable_descriptor_burst(&AXI_DMA, chan, enable); -#define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) axi_dma_ll_tx_enable_auto_write_back(&AXI_DMA, chan, enable); -#define spi_dma_ll_set_out_eof_generation(dev, chan, enable) axi_dma_ll_tx_set_eof_mode(&AXI_DMA, chan, enable); -#endif -#endif //SOC_GDMA_SUPPORTED - -static void s_spi_slave_hal_dma_init_config(const spi_slave_hal_context_t *hal) -{ - spi_dma_ll_rx_enable_burst_data(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_data(hal->dma_out, hal->tx_dma_chan, 1); - spi_dma_ll_rx_enable_burst_desc(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_desc(hal->dma_out, hal->tx_dma_chan, 1); -} - void spi_slave_hal_init(spi_slave_hal_context_t *hal, const spi_slave_hal_config_t *hal_config) { spi_dev_t *hw = SPI_LL_GET_HW(hal_config->host_id); @@ -40,9 +9,6 @@ void spi_slave_hal_init(spi_slave_hal_context_t *hal, const spi_slave_hal_config hal->dma_in = hal_config->dma_in; hal->dma_out = hal_config->dma_out; - if (hal->use_dma) { - s_spi_slave_hal_dma_init_config(hal); - } spi_ll_slave_init(hal->hw); //Force a transaction done interrupt. This interrupt won't fire yet because we initialized the SPI interrupt as diff --git a/components/hal/spi_slave_hd_hal.c b/components/hal/spi_slave_hd_hal.c index ff7d48abb2d6..a62a51726982 100644 --- a/components/hal/spi_slave_hd_hal.c +++ b/components/hal/spi_slave_hd_hal.c @@ -27,10 +27,6 @@ #define spi_dma_ll_rx_restart(dev, chan) gdma_ll_rx_restart(&GDMA, chan) #define spi_dma_ll_rx_reset(dev, chan) gdma_ll_rx_reset_channel(&GDMA, chan) #define spi_dma_ll_tx_reset(dev, chan) gdma_ll_tx_reset_channel(&GDMA, chan) -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) gdma_ll_rx_enable_data_burst(&GDMA, chan, enable) -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) gdma_ll_tx_enable_data_burst(&GDMA, chan, enable) -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) gdma_ll_rx_enable_descriptor_burst(&GDMA, chan, enable) -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) gdma_ll_tx_enable_descriptor_burst(&GDMA, chan, enable) #define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) gdma_ll_tx_enable_auto_write_back(&GDMA, chan, enable) #define spi_dma_ll_set_out_eof_generation(dev, chan, enable) gdma_ll_tx_set_eof_mode(&GDMA, chan, enable) #define spi_dma_ll_get_out_eof_desc_addr(dev, chan) gdma_ll_tx_get_eof_desc_addr(&GDMA, chan) @@ -50,10 +46,6 @@ #define spi_dma_ll_rx_restart(dev, chan) axi_dma_ll_rx_restart(&AXI_DMA, chan) #define spi_dma_ll_rx_reset(dev, chan) axi_dma_ll_rx_reset_channel(&AXI_DMA, chan) #define spi_dma_ll_tx_reset(dev, chan) axi_dma_ll_tx_reset_channel(&AXI_DMA, chan) -#define spi_dma_ll_rx_enable_burst_data(dev, chan, enable) axi_dma_ll_rx_enable_data_burst(&AXI_DMA, chan, enable) -#define spi_dma_ll_tx_enable_burst_data(dev, chan, enable) axi_dma_ll_tx_enable_data_burst(&AXI_DMA, chan, enable) -#define spi_dma_ll_rx_enable_burst_desc(dev, chan, enable) axi_dma_ll_rx_enable_descriptor_burst(&AXI_DMA, chan, enable) -#define spi_dma_ll_tx_enable_burst_desc(dev, chan, enable) axi_dma_ll_tx_enable_descriptor_burst(&AXI_DMA, chan, enable) #define spi_dma_ll_enable_out_auto_wrback(dev, chan, enable) axi_dma_ll_tx_enable_auto_write_back(&AXI_DMA, chan, enable) #define spi_dma_ll_set_out_eof_generation(dev, chan, enable) axi_dma_ll_tx_set_eof_mode(&AXI_DMA, chan, enable) #define spi_dma_ll_get_out_eof_desc_addr(dev, chan) axi_dma_ll_tx_get_eof_desc_addr(&AXI_DMA, chan) @@ -71,10 +63,6 @@ static void s_spi_slave_hd_hal_dma_init_config(const spi_slave_hd_hal_context_t *hal) { - spi_dma_ll_rx_enable_burst_data(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_data(hal->dma_out, hal->tx_dma_chan, 1); - spi_dma_ll_rx_enable_burst_desc(hal->dma_in, hal->rx_dma_chan, 1); - spi_dma_ll_tx_enable_burst_desc(hal->dma_out, hal->tx_dma_chan, 1); spi_dma_ll_enable_out_auto_wrback(hal->dma_out, hal->tx_dma_chan, 1); spi_dma_ll_set_out_eof_generation(hal->dma_out, hal->tx_dma_chan, 1); } diff --git a/components/nvs_flash/test_apps/main/test_nvs.c b/components/nvs_flash/test_apps/main/test_nvs.c index 45abee6831ef..4b34e5bddf44 100644 --- a/components/nvs_flash/test_apps/main/test_nvs.c +++ b/components/nvs_flash/test_apps/main/test_nvs.c @@ -97,12 +97,6 @@ TEST_CASE("nvs_flash_init_partition_ptr() works correctly", "[nvs]") } #ifdef CONFIG_SOC_HMAC_SUPPORTED -/* TODO: This test does not run in CI as the runner assigned has - * flash encryption enabled by default. Enabling flash encryption - * 'selects' NVS encryption; a new runner needs to be setup - * for testing the HMAC NVS encryption scheme without flash encryption - * enabled for this test. - */ TEST_CASE("test nvs encryption with HMAC-based scheme without toggling any config options", "[nvs_encr_hmac]") { nvs_handle_t handle; diff --git a/components/nvs_flash/test_apps/pytest_nvs_flash.py b/components/nvs_flash/test_apps/pytest_nvs_flash.py index 1da98e2da0af..174664912ed3 100644 --- a/components/nvs_flash/test_apps/pytest_nvs_flash.py +++ b/components/nvs_flash/test_apps/pytest_nvs_flash.py @@ -26,6 +26,13 @@ def test_nvs_flash_encr_hmac(dut: IdfDut) -> None: dut.run_all_single_board_cases() +@pytest.mark.esp32c3 +@pytest.mark.nvs_encr_hmac +@pytest.mark.parametrize('config', ['nvs_encr_hmac_no_cfg_esp32c3'], indirect=True) +def test_nvs_flash_encr_hmac_no_cfg(dut: IdfDut) -> None: + dut.run_all_single_board_cases(group='nvs_encr_hmac', timeout=120) + + @pytest.mark.flash_encryption @pytest.mark.parametrize('config', CONFIGS_NVS_ENCR_FLASH_ENC, indirect=True) def test_nvs_flash_encr_flash_enc(dut: IdfDut) -> None: diff --git a/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_hmac_no_cfg_esp32c3 b/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_hmac_no_cfg_esp32c3 new file mode 100644 index 000000000000..6d5be69e2601 --- /dev/null +++ b/components/nvs_flash/test_apps/sdkconfig.ci.nvs_encr_hmac_no_cfg_esp32c3 @@ -0,0 +1,22 @@ +# Restricting to ESP32C3 +CONFIG_IDF_TARGET="esp32c3" + +# NOTE: The runner for this test-app has flash-encryption enabled +# Partition Table +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions_nvs_encr_flash_enc.csv" +CONFIG_PARTITION_TABLE_FILENAME="partitions_nvs_encr_flash_enc.csv" +CONFIG_PARTITION_TABLE_OFFSET=0x9000 + +# Enabling Flash Encryption +CONFIG_SECURE_FLASH_ENC_ENABLED=y +CONFIG_SECURE_FLASH_ENCRYPTION_MODE_DEVELOPMENT=y +CONFIG_SECURE_BOOT_ALLOW_ROM_BASIC=y +CONFIG_SECURE_BOOT_ALLOW_JTAG=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_ENC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_DEC=y +CONFIG_SECURE_FLASH_UART_BOOTLOADER_ALLOW_CACHE=y +CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y + +# Disabling NVS encryption +CONFIG_NVS_ENCRYPTION=n diff --git a/components/soc/esp32/include/soc/Kconfig.soc_caps.in b/components/soc/esp32/include/soc/Kconfig.soc_caps.in index 9e411c9a83da..530d6589f572 100644 --- a/components/soc/esp32/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32/include/soc/Kconfig.soc_caps.in @@ -167,6 +167,10 @@ config SOC_SPI_FLASH_SUPPORTED bool default y +config SOC_RNG_SUPPORTED + bool + default y + config SOC_DPORT_WORKAROUND_DIS_INTERRUPT_LVL int default 5 @@ -275,6 +279,10 @@ config SOC_CPU_HAS_FPU bool default y +config SOC_HP_CPU_HAS_MULTIPLE_CORES + bool + default y + config SOC_CPU_BREAKPOINTS_NUM int default 2 diff --git a/components/soc/esp32/include/soc/soc_caps.h b/components/soc/esp32/include/soc/soc_caps.h index 40d3a50cef44..917a8e343152 100644 --- a/components/soc/esp32/include/soc/soc_caps.h +++ b/components/soc/esp32/include/soc/soc_caps.h @@ -99,6 +99,7 @@ #define SOC_MPU_SUPPORTED 1 #define SOC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 +#define SOC_RNG_SUPPORTED 1 #if SOC_CAPS_ECO_VER < 200 #define SOC_DPORT_WORKAROUND 1 @@ -152,6 +153,7 @@ #define SOC_CPU_CORES_NUM 2 #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FPU 1 +#define SOC_HP_CPU_HAS_MULTIPLE_CORES 1 // Convenience boolean macro used to determine if a target has multiple cores. #define SOC_CPU_BREAKPOINTS_NUM 2 #define SOC_CPU_WATCHPOINTS_NUM 2 diff --git a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in index 98769110cfc4..83c9a56721bb 100644 --- a/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c2/include/soc/Kconfig.soc_caps.in @@ -111,6 +111,10 @@ config SOC_SPI_FLASH_SUPPORTED bool default y +config SOC_RNG_SUPPORTED + bool + default y + config SOC_XTAL_SUPPORT_26M bool default y diff --git a/components/soc/esp32c2/include/soc/soc_caps.h b/components/soc/esp32c2/include/soc/soc_caps.h index 1670a5aa1010..15b026dd3b13 100644 --- a/components/soc/esp32c2/include/soc/soc_caps.h +++ b/components/soc/esp32c2/include/soc/soc_caps.h @@ -48,7 +48,8 @@ #define SOC_CLK_TREE_SUPPORTED 1 #define SOC_ASSIST_DEBUG_SUPPORTED 1 #define SOC_WDT_SUPPORTED 1 -#define SOC_SPI_FLASH_SUPPORTED 1 +#define SOC_SPI_FLASH_SUPPORTED 1 +#define SOC_RNG_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_26M 1 diff --git a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in index 1819e07a9f6d..3e6ef402338a 100644 --- a/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c3/include/soc/Kconfig.soc_caps.in @@ -163,6 +163,10 @@ config SOC_SPI_FLASH_SUPPORTED bool default y +config SOC_RNG_SUPPORTED + bool + default y + config SOC_XTAL_SUPPORT_40M bool default y diff --git a/components/soc/esp32c3/include/soc/soc_caps.h b/components/soc/esp32c3/include/soc/soc_caps.h index 200977586944..bf11ccdf0a10 100644 --- a/components/soc/esp32c3/include/soc/soc_caps.h +++ b/components/soc/esp32c3/include/soc/soc_caps.h @@ -65,6 +65,7 @@ #define SOC_ASSIST_DEBUG_SUPPORTED 1 #define SOC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 +#define SOC_RNG_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 diff --git a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in index 203213c783b8..010768937b56 100644 --- a/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32c6/include/soc/Kconfig.soc_caps.in @@ -219,6 +219,10 @@ config SOC_SPI_FLASH_SUPPORTED bool default y +config SOC_RNG_SUPPORTED + bool + default y + config SOC_XTAL_SUPPORT_40M bool default y diff --git a/components/soc/esp32c6/include/soc/soc_caps.h b/components/soc/esp32c6/include/soc/soc_caps.h index 035994b20526..9c26a847d907 100644 --- a/components/soc/esp32c6/include/soc/soc_caps.h +++ b/components/soc/esp32c6/include/soc/soc_caps.h @@ -76,6 +76,7 @@ #define SOC_ASSIST_DEBUG_SUPPORTED 1 #define SOC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 +#define SOC_RNG_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 diff --git a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in index 17592b662641..801bf6df77e1 100644 --- a/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32h2/include/soc/Kconfig.soc_caps.in @@ -203,6 +203,10 @@ config SOC_SPI_FLASH_SUPPORTED bool default y +config SOC_RNG_SUPPORTED + bool + default y + config SOC_XTAL_SUPPORT_32M bool default y diff --git a/components/soc/esp32h2/include/soc/soc_caps.h b/components/soc/esp32h2/include/soc/soc_caps.h index 8bfc07a9cb5c..3291a9afbbf3 100644 --- a/components/soc/esp32h2/include/soc/soc_caps.h +++ b/components/soc/esp32h2/include/soc/soc_caps.h @@ -73,6 +73,7 @@ #define SOC_ASSIST_DEBUG_SUPPORTED 1 #define SOC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 +#define SOC_RNG_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_32M 1 diff --git a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in index 5f0fc573d1db..535398eab694 100644 --- a/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32p4/include/soc/Kconfig.soc_caps.in @@ -319,6 +319,10 @@ config SOC_CPU_COPROC_NUM int default 2 +config SOC_HP_CPU_HAS_MULTIPLE_CORES + bool + default y + config SOC_CPU_BREAKPOINTS_NUM int default 3 @@ -1115,10 +1119,6 @@ config SOC_TWAI_SUPPORTS_RX_STATUS bool default y -config SOC_EFUSE_DIS_DOWNLOAD_ICACHE - bool - default y - config SOC_EFUSE_DIS_PAD_JTAG bool default y @@ -1135,6 +1135,10 @@ config SOC_EFUSE_SOFT_DIS_JTAG bool default y +config SOC_EFUSE_DIS_DOWNLOAD_MSPI + bool + default y + config SOC_SECURE_BOOT_V2_RSA bool default y @@ -1163,10 +1167,18 @@ config SOC_FLASH_ENCRYPTION_XTS_AES bool default y +config SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS + bool + default y + config SOC_FLASH_ENCRYPTION_XTS_AES_128 bool default y +config SOC_FLASH_ENCRYPTION_XTS_AES_256 + bool + default y + config SOC_UART_NUM int default 6 diff --git a/components/soc/esp32p4/include/soc/soc_caps.h b/components/soc/esp32p4/include/soc/soc_caps.h index 78949e97bb33..d642af7c70c6 100644 --- a/components/soc/esp32p4/include/soc/soc_caps.h +++ b/components/soc/esp32p4/include/soc/soc_caps.h @@ -82,6 +82,7 @@ #define SOC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 // #define SOC_TOUCH_SENSOR_SUPPORTED 1 //TODO: IDF-7477 +// #define SOC_RNG_SUPPORTED 1 //TODO: IDF-6522 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 @@ -151,6 +152,7 @@ #define SOC_CPU_HAS_FPU 1 #define SOC_CPU_HAS_FPU_EXT_ILL_BUG 1 // EXT_ILL CSR doesn't support FLW/FSW #define SOC_CPU_COPROC_NUM 2 +#define SOC_HP_CPU_HAS_MULTIPLE_CORES 1 // Convenience boolean macro used to determine if a target has multiple cores. #define SOC_CPU_BREAKPOINTS_NUM 3 #define SOC_CPU_WATCHPOINTS_NUM 3 @@ -491,11 +493,12 @@ #define SOC_TWAI_SUPPORTS_RX_STATUS 1 /*-------------------------- eFuse CAPS----------------------------*/ -#define SOC_EFUSE_DIS_DOWNLOAD_ICACHE 1 #define SOC_EFUSE_DIS_PAD_JTAG 1 #define SOC_EFUSE_DIS_USB_JTAG 1 #define SOC_EFUSE_DIS_DIRECT_BOOT 1 #define SOC_EFUSE_SOFT_DIS_JTAG 1 +/* Capability to disable the MSPI access in download mode */ +#define SOC_EFUSE_DIS_DOWNLOAD_MSPI 1 /*-------------------------- Secure Boot CAPS----------------------------*/ #define SOC_SECURE_BOOT_V2_RSA 1 @@ -507,7 +510,9 @@ /*-------------------------- Flash Encryption CAPS----------------------------*/ #define SOC_FLASH_ENCRYPTED_XTS_AES_BLOCK_MAX (64) #define SOC_FLASH_ENCRYPTION_XTS_AES 1 +#define SOC_FLASH_ENCRYPTION_XTS_AES_OPTIONS 1 #define SOC_FLASH_ENCRYPTION_XTS_AES_128 1 +#define SOC_FLASH_ENCRYPTION_XTS_AES_256 1 /*-------------------------- MEMPROT CAPS ------------------------------------*/ diff --git a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in index 3de14bb8272e..e611214dd18b 100644 --- a/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s2/include/soc/Kconfig.soc_caps.in @@ -191,6 +191,10 @@ config SOC_SPI_FLASH_SUPPORTED bool default y +config SOC_RNG_SUPPORTED + bool + default y + config SOC_XTAL_SUPPORT_40M bool default y diff --git a/components/soc/esp32s2/include/soc/soc_caps.h b/components/soc/esp32s2/include/soc/soc_caps.h index cb1c2481ab90..d27ce9eebfff 100644 --- a/components/soc/esp32s2/include/soc/soc_caps.h +++ b/components/soc/esp32s2/include/soc/soc_caps.h @@ -84,6 +84,7 @@ #define SOC_MPU_SUPPORTED 1 #define SOC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 +#define SOC_RNG_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 diff --git a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in index eb4a906a93ca..2cad7fd64746 100644 --- a/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in +++ b/components/soc/esp32s3/include/soc/Kconfig.soc_caps.in @@ -231,6 +231,10 @@ config SOC_SPI_FLASH_SUPPORTED bool default y +config SOC_RNG_SUPPORTED + bool + default y + config SOC_XTAL_SUPPORT_40M bool default y @@ -363,6 +367,10 @@ config SOC_CPU_HAS_FPU bool default y +config SOC_HP_CPU_HAS_MULTIPLE_CORES + bool + default y + config SOC_CPU_BREAKPOINTS_NUM int default 2 diff --git a/components/soc/esp32s3/include/soc/soc_caps.h b/components/soc/esp32s3/include/soc/soc_caps.h index 966d25e39e05..0e1952d88c02 100644 --- a/components/soc/esp32s3/include/soc/soc_caps.h +++ b/components/soc/esp32s3/include/soc/soc_caps.h @@ -74,6 +74,7 @@ #define SOC_MPU_SUPPORTED 1 #define SOC_WDT_SUPPORTED 1 #define SOC_SPI_FLASH_SUPPORTED 1 +#define SOC_RNG_SUPPORTED 1 /*-------------------------- XTAL CAPS ---------------------------------------*/ #define SOC_XTAL_SUPPORT_40M 1 @@ -133,6 +134,7 @@ #define SOC_CPU_CORES_NUM 2 #define SOC_CPU_INTR_NUM 32 #define SOC_CPU_HAS_FPU 1 +#define SOC_HP_CPU_HAS_MULTIPLE_CORES 1 // Convenience boolean macro used to determine if a target has multiple cores. #define SOC_CPU_BREAKPOINTS_NUM 2 #define SOC_CPU_WATCHPOINTS_NUM 2 diff --git a/components/spi_flash/test_apps/.build-test-rules.yml b/components/spi_flash/test_apps/.build-test-rules.yml index eb48921719e5..873efbdf7084 100644 --- a/components/spi_flash/test_apps/.build-test-rules.yml +++ b/components/spi_flash/test_apps/.build-test-rules.yml @@ -17,13 +17,10 @@ components/spi_flash/test_apps/esp_flash: components/spi_flash/test_apps/flash_encryption: disable_test: - - if: IDF_TARGET in ["esp32c2", "esp32s2", "esp32c6", "esp32h2"] + - if: IDF_TARGET in ["esp32c2", "esp32s2", "esp32c6", "esp32h2", "esp32p4"] temporary: true reason: No runners # IDF-5634 - disable: - - if: IDF_TARGET == "esp32p4" - temporary: true - reason: target esp32p4 is not supported yet # TODO: IDF-7545 + depends_components: - esp_mm - spi_flash diff --git a/components/spi_flash/test_apps/flash_encryption/README.md b/components/spi_flash/test_apps/flash_encryption/README.md index 304c4d955a1c..5e87c92c2a88 100644 --- a/components/spi_flash/test_apps/flash_encryption/README.md +++ b/components/spi_flash/test_apps/flash_encryption/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-S2 | ESP32-S3 | -| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | +| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C6 | ESP32-H2 | ESP32-P4 | ESP32-S2 | ESP32-S3 | +| ----------------- | ----- | -------- | -------- | -------- | -------- | -------- | -------- | -------- | ## Prepare runner diff --git a/components/wpa_supplicant/test_apps/pytest_wpa_supplicant_ut.py b/components/wpa_supplicant/test_apps/pytest_wpa_supplicant_ut.py index f2d647ed70eb..2db192bb1195 100644 --- a/components/wpa_supplicant/test_apps/pytest_wpa_supplicant_ut.py +++ b/components/wpa_supplicant/test_apps/pytest_wpa_supplicant_ut.py @@ -2,8 +2,8 @@ # SPDX-License-Identifier: CC0-1.0 import pytest -from idf_unity_tester import CaseTester from pytest_embedded import Dut +from pytest_embedded_idf.unity_tester import CaseTester @pytest.mark.generic @@ -19,6 +19,13 @@ def test_wpa_supplicant_ut(dut: Dut) -> None: @pytest.mark.esp32 @pytest.mark.wifi_two_dut +@pytest.mark.parametrize( + 'count', + [ + 2, + ], + indirect=True +) def test_wpa_supplicant_ut_offchan(case_tester: CaseTester) -> None: for case in case_tester.test_menu: if case.attributes.get('test_env') == 'wifi_two_dut': diff --git a/conftest.py b/conftest.py index cf127e7fe98c..0fdc3ad45add 100644 --- a/conftest.py +++ b/conftest.py @@ -28,20 +28,19 @@ from _pytest.fixtures import FixtureRequest from pytest_embedded.plugin import multi_dut_argument, multi_dut_fixture from pytest_embedded_idf.dut import IdfDut +from pytest_embedded_idf.unity_tester import CaseTester try: from idf_ci_utils import IDF_PATH from idf_pytest.constants import DEFAULT_SDKCONFIG, ENV_MARKERS, SPECIAL_MARKERS, TARGET_MARKERS from idf_pytest.plugin import IDF_PYTEST_EMBEDDED_KEY, IdfPytestEmbedded from idf_pytest.utils import format_case_id, get_target_marker_from_expr - from idf_unity_tester import CaseTester except ImportError: sys.path.append(os.path.join(os.path.dirname(__file__), 'tools', 'ci')) from idf_ci_utils import IDF_PATH from idf_pytest.constants import DEFAULT_SDKCONFIG, ENV_MARKERS, SPECIAL_MARKERS, TARGET_MARKERS from idf_pytest.plugin import IDF_PYTEST_EMBEDDED_KEY, IdfPytestEmbedded from idf_pytest.utils import format_case_id, get_target_marker_from_expr - from idf_unity_tester import CaseTester try: import common_test_methods # noqa: F401 @@ -70,8 +69,8 @@ def session_tempdir() -> str: @pytest.fixture -def case_tester(dut: IdfDut, **kwargs): # type: ignore - yield CaseTester(dut, **kwargs) +def case_tester(unity_tester: CaseTester) -> CaseTester: + return unity_tester @pytest.fixture diff --git a/docs/en/api-guides/app_trace.rst b/docs/en/api-guides/app_trace.rst index 3a9a198f9851..1507f0d8d73d 100644 --- a/docs/en/api-guides/app_trace.rst +++ b/docs/en/api-guides/app_trace.rst @@ -420,7 +420,7 @@ Data Visualization After trace data are collected, users can use a special tool to visualize the results and inspect behavior of the program. -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES Unfortunately, SystemView does not support tracing from multiple cores. So when tracing from {IDF_TARGET_NAME} with JTAG interfaces in the dual-core mode, two files are generated: one for PRO CPU and another for APP CPU. Users can load each file into separate instances of the tool. For tracing over UART, users can select ``Component config`` > ``Application Level Tracing`` > ``FreeRTOS SystemView Tracing`` in menuconfig Pro or App to choose which CPU has to be traced. @@ -432,7 +432,7 @@ Good instructions on how to install, configure, and visualize data in Impulse fr ESP-IDF uses its own mapping for SystemView FreeRTOS events IDs, so users need to replace the original file mapping ``$SYSVIEW_INSTALL_DIR/Description/SYSVIEW_FreeRTOS.txt`` with ``$IDF_PATH/tools/esp_app_trace/SYSVIEW_FreeRTOS.txt``. Also, contents of that ESP-IDF-specific file should be used when configuring SystemView serializer using the above link. -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES Configure Impulse for Dual Core Traces ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/en/api-guides/build-system.rst b/docs/en/api-guides/build-system.rst index 3ca033ea2ea6..de708a7834ae 100644 --- a/docs/en/api-guides/build-system.rst +++ b/docs/en/api-guides/build-system.rst @@ -361,6 +361,7 @@ The following are some project/build variables that are available as build prope * If :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` option is set, the value of :ref:`CONFIG_APP_PROJECT_VER` will be used. * Else, if ``PROJECT_VER`` variable is set in project CMakeLists.txt file, its value will be used. * Else, if the ``PROJECT_DIR/version.txt`` exists, its contents will be used as ``PROJECT_VER``. + * Else, if ``VERSION`` argument is passed to the ``project()`` call in the CMakeLists.txt file as ``project(... VERSION x.y.z.w )`` then it will be used as ``PROJECT_VER``. The ``VERSION`` argument must be compilant with the `cmake standard `_. * Else, if the project is located inside a Git repository, the output of git description will be used. * Otherwise, ``PROJECT_VER`` will be "1". - ``EXTRA_PARTITION_SUBTYPES``: CMake list of extra partition subtypes. Each subtype description is a comma-separated string with ``type_name, subtype_name, numeric_value`` format. Components may add new subtypes by appending them to this list. diff --git a/docs/en/api-guides/deep-sleep-stub.rst b/docs/en/api-guides/deep-sleep-stub.rst index eb172dc43df6..d5f4f50fdad8 100644 --- a/docs/en/api-guides/deep-sleep-stub.rst +++ b/docs/en/api-guides/deep-sleep-stub.rst @@ -78,7 +78,7 @@ The first way is to use the ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` to specify .. only:: SOC_RTC_SLOW_MEM_SUPPORTED - The RTC memory area where this data will be placed can be configured via menuconfig option named ``CONFIG_{IDF_TARGET_CFG_PREFIX}_RTCDATA_IN_FAST_MEM``. This option allows to keep slow memory area for ULP programs and once it is enabled the data marked with ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` are placed in the RTC fast memory segment otherwise it goes to RTC slow memory (default option). This option depends on the ``CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE`` because RTC fast memory can be accessed only by PRO_CPU. + The RTC memory area where this data will be placed can be configured via menuconfig option named ``CONFIG_{IDF_TARGET_CFG_PREFIX}_RTCDATA_IN_FAST_MEM``. This option allows to keep slow memory area for ULP programs and once it is enabled the data marked with ``RTC_DATA_ATTR`` and ``RTC_RODATA_ATTR`` are placed in the RTC fast memory segment otherwise it goes to RTC slow memory (default option). This option depends on the :ref:`CONFIG_FREERTOS_UNICORE` option because RTC fast memory can be accessed only by PRO_CPU. The attributes ``RTC_FAST_ATTR`` and ``RTC_SLOW_ATTR`` can be used to specify data that will be force placed into RTC_FAST and RTC_SLOW memory respectively. Any access to data marked with ``RTC_FAST_ATTR`` is allowed by PRO_CPU only and it is responsibility of user to make sure about it. diff --git a/docs/en/api-guides/index.rst b/docs/en/api-guides/index.rst index 0f2afc32c27e..c3ceeeb05838 100644 --- a/docs/en/api-guides/index.rst +++ b/docs/en/api-guides/index.rst @@ -43,3 +43,4 @@ API Guides :SOC_USB_SERIAL_JTAG_SUPPORTED: usb-serial-jtag-console :SOC_WIFI_SUPPORTED: wifi :SOC_WIFI_SUPPORTED: wifi-security + low-power-mode diff --git a/docs/en/api-guides/low-power-mode.rst b/docs/en/api-guides/low-power-mode.rst new file mode 100644 index 000000000000..cefab6cc2398 --- /dev/null +++ b/docs/en/api-guides/low-power-mode.rst @@ -0,0 +1,7 @@ +Low Power Mode User Guide +========================== + + +:link_to_translation:`zh_CN:[中文]` + +The document has not been translated into English yet. In the meantime, please refer to the Chinese version. \ No newline at end of file diff --git a/docs/en/api-guides/performance/speed.rst b/docs/en/api-guides/performance/speed.rst index c54292ff87b7..03c067c24819 100644 --- a/docs/en/api-guides/performance/speed.rst +++ b/docs/en/api-guides/performance/speed.rst @@ -54,7 +54,7 @@ Executing the target multiple times can help average out factors, e.g., RTOS con - It is also possible to use the standard Unix ``gettimeofday()`` and ``utime()`` functions, although the overhead is slightly higher. - Otherwise, including ``hal/cpu_hal.h`` and calling the HAL function ``cpu_hal_get_cycle_count()`` returns the number of CPU cycles executed. This function has lower overhead than the others, which is good for measuring very short execution times with high precision. - .. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE + .. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES The CPU cycles are counted per-core, so only use this method from an interrupt handler, or a task that is pinned to a single core. @@ -159,7 +159,7 @@ Common priorities are: .. Note: the following two lists should be kept the same, but the second list also shows CPU affinities -.. only:: CONFIG_FREERTOS_UNICORE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES .. list:: @@ -176,7 +176,7 @@ Common priorities are: - If using the :doc:`/api-reference/protocols/mqtt` component, it creates a task with default priority 5 (:ref:`configurable`), depending on :ref:`CONFIG_MQTT_USE_CUSTOM_CONFIG`, and also configurable at runtime by ``task_prio`` field in the :cpp:class:`esp_mqtt_client_config_t`) - To see what is the task priority for ``mDNS`` service, please check `Performance Optimization `__. -.. only :: not CONFIG_FREERTOS_UNICORE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES .. list:: @@ -204,11 +204,11 @@ Common priorities are: Choosing Task Priorities of the Application ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. only:: CONFIG_FREERTOS_UNICORE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES In general, it is not recommended to set task priorities higher than the built-in {IDF_TARGET_RF_TYPE} operations as starving them of CPU may make the system unstable. For very short timing-critical operations that do not use the network, use an ISR or a very restricted task (with very short bursts of runtime only) at the highest priority (24). Choosing priority 19 allows lower-layer {IDF_TARGET_RF_TYPE} functionality to run without delays, but still preempts the lwIP TCP/IP stack and other less time-critical internal functionality - this is the best option for time-critical tasks that do not perform network operations. Any task that does TCP/IP network operations should run at a lower priority than the lwIP TCP/IP task (18) to avoid priority-inversion issues. -.. only:: not CONFIG_FREERTOS_UNICORE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES With a few exceptions, most importantly the lwIP TCP/IP task, in the default configuration most built-in tasks are pinned to Core 0. This makes it quite easy for the application to place high priority tasks on Core 1. Using priority 19 or higher guarantees that an application task can run on Core 1 without being preempted by any built-in task. To further isolate the tasks running on each CPU, configure the :ref:`lwIP task ` to only run on Core 0 instead of either core, which may reduce total TCP/IP throughput depending on what other tasks are running. @@ -234,7 +234,7 @@ To obtain the best performance for a particular interrupt handler: .. list:: - Assign more important interrupts a higher priority using a flag such as ``ESP_INTR_FLAG_LEVEL2`` or ``ESP_INTR_FLAG_LEVEL3`` when calling :cpp:func:`esp_intr_alloc`. - :not CONFIG_FREERTOS_UNICORE: - Assign the interrupt on a CPU where built-in {IDF_TARGET_RF_TYPE} tasks are not configured to run, which means assigning the interrupt on Core 1 by default, see :ref:`built-in-task-priorities`. Interrupts are assigned on the same CPU where the :cpp:func:`esp_intr_alloc` function call is made. + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - Assign the interrupt on a CPU where built-in {IDF_TARGET_RF_TYPE} tasks are not configured to run, which means assigning the interrupt on Core 1 by default, see :ref:`built-in-task-priorities`. Interrupts are assigned on the same CPU where the :cpp:func:`esp_intr_alloc` function call is made. - If you are sure the entire interrupt handler can run from IRAM (see :ref:`iram-safe-interrupt-handlers`) then set the ``ESP_INTR_FLAG_IRAM`` flag when calling :cpp:func:`esp_intr_alloc` to assign the interrupt. This prevents it being temporarily disabled if the application firmware writes to the internal SPI flash. - Even if the interrupt handler is not IRAM-safe, if it is going to be executed frequently then consider moving the handler function to IRAM anyhow. This minimizes the chance of a flash cache miss when the interrupt code is executed (see :ref:`speed-targeted-optimizations`). It is possible to do this without adding the ``ESP_INTR_FLAG_IRAM`` flag to mark the interrupt as IRAM-safe, if only part of the handler is guaranteed to be in IRAM. diff --git a/docs/en/api-guides/startup.rst b/docs/en/api-guides/startup.rst index 18871ae5d556..db0903e19def 100644 --- a/docs/en/api-guides/startup.rst +++ b/docs/en/api-guides/startup.rst @@ -22,11 +22,11 @@ This process is explained in detail in the following sections. First Stage Bootloader ^^^^^^^^^^^^^^^^^^^^^^ -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES After SoC reset, PRO CPU will start running immediately, executing reset vector code, while APP CPU will be held in reset. During startup process, PRO CPU does all the initialization. APP CPU reset is de-asserted in the ``call_start_cpu0`` function of application startup code. Reset vector code is located in the mask ROM of the {IDF_TARGET_NAME} chip and cannot be modified. -.. only:: CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES After SoC reset, the CPU will start running immediately to perform initialization. The reset vector code is located in the mask ROM of the {IDF_TARGET_NAME} chip and cannot be modified. @@ -76,7 +76,7 @@ For the selected partition, second stage bootloader reads the binary image from - For segments with load addresses in internal :ref:`iram` or :ref:`dram`, the contents are copied from flash to the load address. - For segments which have load addresses in :ref:`drom` or :ref:`irom` regions, the flash MMU is configured to provide the correct mapping from the flash to the load address. -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES Note that the second stage bootloader configures flash MMU for both PRO and APP CPUs, but it only enables flash MMU for PRO CPU. Reason for this is that second stage bootloader code is loaded into the memory region used by APP CPU cache. The duty of enabling cache for APP CPU is passed on to the application. @@ -114,13 +114,13 @@ This port-layer initialization function initializes the basic C Runtime Environm - Set the CPU clocks to the frequencies configured for the project. :CONFIG_ESP_SYSTEM_MEMPROT_FEATURE: - Initialize memory protection if configured. :esp32: - Reconfigure the main SPI flash based on the app header settings (necessary for compatibility with bootloader versions before ESP-IDF V4.0, see :ref:`bootloader-compatibility`). - :not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE: - If the app is configured to run on multiple cores, start the other core and wait for it to initialize as well (inside the similar "port layer" initialization function ``call_start_cpu1``). + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - If the app is configured to run on multiple cores, start the other core and wait for it to initialize as well (inside the similar "port layer" initialization function ``call_start_cpu1``). -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES Once ``call_start_cpu0`` completes running, it calls the "system layer" initialization function ``start_cpu0`` found in :idf_file:`components/esp_system/startup.c`. Other cores will also complete port-layer initialization and call ``start_other_cores`` found in the same file. -.. only:: CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES Once ``call_start_cpu0`` completes running, it calls the "system layer" initialization function ``start_cpu0`` found in :idf_file:`components/esp_system/startup.c`. @@ -156,13 +156,13 @@ After doing some more initialization tasks (that require the scheduler to have s The main task that runs ``app_main`` has a fixed RTOS priority (one higher than the minimum) and a :ref:`configurable stack size `. -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES The main task core affinity is also configurable: :ref:`CONFIG_ESP_MAIN_TASK_AFFINITY`. Unlike normal FreeRTOS tasks (or embedded C ``main`` functions), the ``app_main`` task is allowed to return. If this happens, The task is cleaned up and the system will continue running with other RTOS tasks scheduled normally. Therefore, it is possible to implement ``app_main`` as either a function that creates other application tasks and then returns, or as a main application task itself. -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES Second Core Startup ------------------- diff --git a/docs/en/api-guides/tools/idf-docker-image.rst b/docs/en/api-guides/tools/idf-docker-image.rst index 12a9bc752022..03f4f544c02c 100644 --- a/docs/en/api-guides/tools/idf-docker-image.rst +++ b/docs/en/api-guides/tools/idf-docker-image.rst @@ -143,7 +143,8 @@ The Docker file in ESP-IDF repository provides several build arguments which can - ``IDF_CLONE_URL``: URL of the repository to clone ESP-IDF from. Can be set to a custom URL when working with a fork of ESP-IDF. The default is ``https://github.com/espressif/esp-idf.git``. - ``IDF_CLONE_BRANCH_OR_TAG``: Name of a git branch or tag used when cloning ESP-IDF. This value is passed to the ``git clone`` command using the ``--branch`` argument. The default is ``master``. - ``IDF_CHECKOUT_REF``: If this argument is set to a non-empty value, ``git checkout $IDF_CHECKOUT_REF`` command performs after cloning. This argument can be set to the SHA of the specific commit to check out, for example, if some specific commit on a release branch is desired. -- ``IDF_CLONE_SHALLOW``: If this argument is set to a non-empty value, ``--depth=1 --shallow-submodules`` arguments are be used when performing ``git clone``. This significantly reduces the amount of data downloaded and the size of the resulting Docker image. However, if switching to a different branch in such a "shallow" repository is necessary, an additional ``git fetch origin `` command must be executed first. +- ``IDF_CLONE_SHALLOW``: If this argument is set to a non-empty value, ``--depth=1 --shallow-submodules`` arguments are used when performing ``git clone``. Depth can be customized using ``IDF_CLONE_SHALLOW_DEPTH``. Doing a shallow clone significantly reduces the amount of data downloaded and the size of the resulting Docker image. However, if switching to a different branch in such a "shallow" repository is necessary, an additional ``git fetch origin `` command must be executed first. +- ``IDF_CLONE_SHALLOW_DEPTH``: This argument specifies the depth value to use when doing a shallow clone. If not set, ``--depth=1`` will be used. This argument has effect only if ``IDF_CLONE_SHALLOW`` is used. Use this argument if you are building a Docker image for a branch, and the image has to contain the latest tag on that branch. To determine the required depth, run ``git describe`` for the given branch and note the offset number. Increment it by 1, then use it as the value of this argument. The resulting image will contain the latest tag on the branch, and consequently ``git describe`` command inside the Docker image will work as expected. - ``IDF_INSTALL_TARGETS``: Comma-separated list of ESP-IDF targets to install toolchains for, or ``all`` to install toolchains for all targets. Selecting specific targets reduces the amount of data downloaded and the size of the resulting Docker image. The default is ``all``. To use these arguments, pass them via the ``--build-arg`` command line option. For example, the following command builds a Docker image with a shallow clone of ESP-IDF v4.4.1 and tools for ESP32-C3 only: diff --git a/docs/en/api-guides/tools/qemu.rst b/docs/en/api-guides/tools/qemu.rst index ee0d48f1185a..48eba546c177 100644 --- a/docs/en/api-guides/tools/qemu.rst +++ b/docs/en/api-guides/tools/qemu.rst @@ -8,11 +8,11 @@ Espressif maintains a `fork `_ of the QEMU em Prerequisites ------------- -To use QEMU with ``idf.py`` you first need to install the above-mentioned fork of QEMU. ESP-IDF provides pre-built binaries for x86_64 Linux. If you are using this platform, you can install the pre-built binaries with the following command: +To use QEMU with ``idf.py`` you first need to install the above-mentioned fork of QEMU. ESP-IDF provides pre-built binaries for x86_64 and arm64 Linux and macOS, as well as x86_64 Windows. If you are using this platform, you can install the pre-built binaries with the following command: .. code-block:: console - python $IDF_PATH/tools/idf_tools.py install qemu-xtensa qemu-riscv + python $IDF_PATH/tools/idf_tools.py install qemu-xtensa qemu-riscv32 After installing QEMU, make sure it is added to PATH by running ``. ./export.sh`` in the IDF directory. diff --git a/docs/en/api-guides/wifi.rst b/docs/en/api-guides/wifi.rst index 9ecca1607353..a1e9e27c132b 100644 --- a/docs/en/api-guides/wifi.rst +++ b/docs/en/api-guides/wifi.rst @@ -1752,6 +1752,8 @@ A config option :ref:`CONFIG_ESP_WIFI_11R_SUPPORT` and configuration parameter : {IDF_TARGET_NAME} Wi-Fi Power-saving Mode ----------------------------------------- +This subsection will briefly introduce the concepts and usage related to Wi-Fi Power Saving Mode, for a more detailed introduction please refer to the :doc:`Low Power Mode User Guide <../api-guides/low-power-mode>` + Station Sleep ++++++++++++++++++++++ diff --git a/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst b/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst index 2d6a22451fa5..897f4f552c48 100644 --- a/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst +++ b/docs/en/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst @@ -42,11 +42,11 @@ Under this condition, all CPUs should always execute code and access data from i When :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` and :ref:`CONFIG_SPIRAM_RODATA` are both enabled, these APIs will not disable the caches. -.. only:: not CONFIG_FREERTOS_UNICORE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES The way that these APIs disable the caches suspends all the other tasks. Besides, all non-IRAM-safe interrupts will be disabled. The other core will be polling in a busy loop. These will be restored until the Flash operation completes. -.. only:: CONFIG_FREERTOS_UNICORE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES The way that these APIs disable the caches also disables non-IRAM-safe interrupts. These will be restored until the Flash operation completes. diff --git a/docs/en/api-reference/storage/nvs_encryption.rst b/docs/en/api-reference/storage/nvs_encryption.rst index e9fbaeaa0552..ef061b2c3398 100644 --- a/docs/en/api-reference/storage/nvs_encryption.rst +++ b/docs/en/api-reference/storage/nvs_encryption.rst @@ -20,7 +20,13 @@ NVS Encryption: Flash Encryption-Based Scheme In this scheme, the keys required for NVS encryption are stored in yet another partition, which is protected using :doc:`Flash Encryption <../../security/flash-encryption>`. Therefore, enabling :doc:`Flash Encryption <../../security/flash-encryption>` becomes a prerequisite for NVS encryption here. -NVS encryption is enabled by default when :doc:`../../security/flash-encryption` is enabled. This is done because Wi-Fi driver stores credentials (like SSID and passphrase) in the default NVS partition. It is important to encrypt them as default choice if platform level encryption is already enabled. +.. only:: SOC_HMAC_SUPPORTED + + NVS encryption should be enabled when :doc:`../../security/flash-encryption` is enabled because the Wi-Fi driver stores credentials (like SSID and passphrase) in the default NVS partition. It is important to encrypt them if platform-level encryption is already enabled. + +.. only:: not SOC_HMAC_SUPPORTED + + NVS encryption is enabled by default when :doc:`../../security/flash-encryption` is enabled. This is done because Wi-Fi driver stores credentials (like SSID and passphrase) in the default NVS partition. It is important to encrypt them as default choice if platform-level encryption is already enabled. For using NVS encryption using this scheme, the partition table must contain the :ref:`nvs_encr_key_partition`. Two partition tables containing the :ref:`nvs_encr_key_partition` are provided for NVS encryption under the partition table option (``menuconfig`` > ``Partition Table``). They can be selected with the project configuration menu (``idf.py menuconfig``). Please refer to the example :example:`security/flash_encryption` for how to configure and use the NVS encryption feature. diff --git a/docs/en/api-reference/system/freertos.rst b/docs/en/api-reference/system/freertos.rst index ca1b1fcdc559..db18a5813161 100644 --- a/docs/en/api-reference/system/freertos.rst +++ b/docs/en/api-reference/system/freertos.rst @@ -51,7 +51,7 @@ For the full list of user configurable kernel options, see :doc:`/api-reference/ - :ref:`CONFIG_FREERTOS_UNICORE` runs FreeRTOS only on CPU0. Note that this is **not equivalent to running Vanilla FreeRTOS**. Furthermore, this option may affect behavior of components other than :component:`freertos`. For more details regarding the effects of running FreeRTOS on a single core, refer to :ref:`freertos-smp-single-core` (if using ESP-IDF FreeRTOS) or the official Amazon SMP FreeRTOS documentation. Alternatively, users can also search for occurrences of ``CONFIG_FREERTOS_UNICORE`` in the ESP-IDF components. -.. only:: CONFIG_FREERTOS_UNICORE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES .. note:: As {IDF_TARGET_NAME} is a single core SoC, the :ref:`CONFIG_FREERTOS_UNICORE` configuration is always set. diff --git a/docs/en/api-reference/system/index.rst b/docs/en/api-reference/system/index.rst index 3f284fcf092f..9b288356d093 100644 --- a/docs/en/api-reference/system/index.rst +++ b/docs/en/api-reference/system/index.rst @@ -25,7 +25,7 @@ System API heap_debug esp_timer internal-unstable - :not CONFIG_FREERTOS_UNICORE: ipc + :SOC_HP_CPU_HAS_MULTIPLE_CORES: ipc intr_alloc log misc_system_api diff --git a/docs/en/api-reference/system/intr_alloc.rst b/docs/en/api-reference/system/intr_alloc.rst index 6085b74bd3d0..62329d945dbd 100644 --- a/docs/en/api-reference/system/intr_alloc.rst +++ b/docs/en/api-reference/system/intr_alloc.rst @@ -143,7 +143,7 @@ If you have confirmed that the application is indeed running out of interrupts, .. list:: - :not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE: - On multi-core SoCs, try initializing some of the peripheral drivers from a task pinned to the second core. Interrupts are typically allocated on the same core where the peripheral driver initialization function runs. Therefore by running the initialization function on the second core, more interrupt inputs can be used. + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - On multi-core SoCs, try initializing some of the peripheral drivers from a task pinned to the second core. Interrupts are typically allocated on the same core where the peripheral driver initialization function runs. Therefore by running the initialization function on the second core, more interrupt inputs can be used. - Determine the interrupts which can tolerate higher latency, and allocate them using ``ESP_INTR_FLAG_SHARED`` flag (optionally ORed with ``ESP_INTR_FLAG_LOWMED``). Using this flag for two or more peripherals will let them use a single interrupt input, and therefore save interrupt inputs for other peripherals. See :ref:`intr-alloc-shared-interrupts` above. :not SOC_CPU_HAS_FLEXIBLE_INTC: - Some peripheral driver may default to allocating interrupts with ``ESP_INTR_FLAG_LEVEL1`` flag, so priority 2 and 3 interrupts do not get used by default. If :cpp:func:`esp_intr_dump` shows that some priority 2 or 3 interrupts are available, try changing the interrupt allocation flags when initializing the driver to ``ESP_INTR_FLAG_LEVEL2`` or ``ESP_INTR_FLAG_LEVEL3``. - Check if some of the peripheral drivers do not need to be used all the time, and initialize or deinitialize them on demand. This can reduce the number of simultaneously allocated interrupts. diff --git a/docs/en/api-reference/system/pthread.rst b/docs/en/api-reference/system/pthread.rst index 783a66548a16..ec79ca8d62bf 100644 --- a/docs/en/api-reference/system/pthread.rst +++ b/docs/en/api-reference/system/pthread.rst @@ -189,7 +189,7 @@ The API :cpp:func:`esp_pthread_set_cfg` defined in the ``esp_pthreads.h`` header .. list:: - Default stack size of new threads, if not specified when calling ``pthread_create()`` (overrides :ref:`CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT`). - RTOS priority of new threads (overrides :ref:`CONFIG_PTHREAD_TASK_PRIO_DEFAULT`). - :not CONFIG_FREERTOS_UNICORE: - Core affinity / core pinning of new threads (overrides :ref:`CONFIG_PTHREAD_TASK_CORE_DEFAULT`). + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - Core affinity / core pinning of new threads (overrides :ref:`CONFIG_PTHREAD_TASK_CORE_DEFAULT`). - FreeRTOS task name for new threads (overrides :ref:`CONFIG_PTHREAD_TASK_NAME_DEFAULT`) This configuration is scoped to the calling thread (or FreeRTOS task), meaning that :cpp:func:`esp_pthread_set_cfg` can be called independently in different threads or tasks. If the ``inherit_cfg`` flag is set in the current configuration then any new thread created will inherit the creator's configuration (if that thread calls ``pthread_create()`` recursively), otherwise the new thread will have the default configuration. diff --git a/docs/en/api-reference/system/wdts.rst b/docs/en/api-reference/system/wdts.rst index 7f73aaf085cc..f1525362b332 100644 --- a/docs/en/api-reference/system/wdts.rst +++ b/docs/en/api-reference/system/wdts.rst @@ -113,7 +113,7 @@ The following config options control TWDT configuration. They are all enabled by - :ref:`CONFIG_ESP_TASK_WDT_EN` - enables TWDT feature. If this option is disabled, TWDT cannot be used, even if initialized at runtime. - :ref:`CONFIG_ESP_TASK_WDT_INIT` - the TWDT is initialized automatically during startup. If this option is disabled, it is still possible to initialize the Task WDT at runtime by calling :cpp:func:`esp_task_wdt_init`. - :ref:`CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0` - {IDF_TARGET_IDLE_TASK} is subscribed to the TWDT during startup. If this option is disabled, it is still possible to subscribe the idle task by calling :cpp:func:`esp_task_wdt_init` again. - :not CONFIG_FREERTOS_UNICORE: - :ref:`CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1` - CPU1 Idle task is subscribed to the TWDT during startup. + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - :ref:`CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1` - CPU1 Idle task is subscribed to the TWDT during startup. .. note:: diff --git a/docs/en/migration-guides/release-5.x/5.2/index.rst b/docs/en/migration-guides/release-5.x/5.2/index.rst index c497099d32bb..79168d866555 100644 --- a/docs/en/migration-guides/release-5.x/5.2/index.rst +++ b/docs/en/migration-guides/release-5.x/5.2/index.rst @@ -9,5 +9,6 @@ Migration from 5.1 to 5.2 gcc peripherals protocols + storage system wifi diff --git a/docs/en/migration-guides/release-5.x/5.2/storage.rst b/docs/en/migration-guides/release-5.x/5.2/storage.rst new file mode 100644 index 000000000000..31bda417007f --- /dev/null +++ b/docs/en/migration-guides/release-5.x/5.2/storage.rst @@ -0,0 +1,11 @@ +Storage +======= + +:link_to_translation:`zh_CN:[中文]` + +NVS Encryption +-------------- + +- For SoCs with the HMAC peripheral (``SOC_HMAC_SUPPORTED``), turning on :doc:`../../../security/flash-encryption` will no longer automatically turn on :doc:`../../../api-reference/storage/nvs_encryption`. +- You will need to explicitly turn on NVS encryption and select the required scheme (flash encryption-based or HMAC peripheral-based). You can select the HMAC peripheral-based scheme (:ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME`), even if flash encryption is not enabled. +- SoCs without the HMAC peripheral will still automatically turn on NVS encryption when flash encryption is enabled. diff --git a/docs/en/migration-guides/release-5.x/5.2/system.rst b/docs/en/migration-guides/release-5.x/5.2/system.rst index 1cf76ae4beb0..916ad605f39a 100644 --- a/docs/en/migration-guides/release-5.x/5.2/system.rst +++ b/docs/en/migration-guides/release-5.x/5.2/system.rst @@ -11,4 +11,13 @@ Task Snapshot The Task Snapshot API has been made private due to a lack of a practical way for the API to be used from user code (the scheduler must be halted before the API can be called). -As a result, the ``#include "freertos/task_snapshot.h"`` include path has been deprecated. \ No newline at end of file +.. only:: CONFIG_IDF_TARGET_ARCH_XTENSA + + Xtensa + ------ + + A number of legacy include paths for Xtensa headers have been deprecated: + + - ``#include "freertos/xtensa_api.h"`` is deprecated, please use ``#include "xtensa_api.h"`` instead. + - ``#include "freertos/xtensa_context.h"`` is deprecated, please use ``#include "xtensa_context.h"`` instead. + - ``#include "freertos/xtensa_timer.h"`` is deprecated, please use ``#include "xtensa_timer.h"`` instead. diff --git a/docs/en/security/flash-encryption.rst b/docs/en/security/flash-encryption.rst index f8f93249f1cd..22db63990e28 100644 --- a/docs/en/security/flash-encryption.rst +++ b/docs/en/security/flash-encryption.rst @@ -929,6 +929,7 @@ On the first boot, the flash encryption process burns by default the following e :SOC_EFUSE_DIS_PAD_JTAG and SOC_EFUSE_DIS_USB_JTAG: - ``DIS_PAD_JTAG`` and ``DIS_USB_JTAG`` which disables JTAG. :SOC_EFUSE_HARD_DIS_JTAG and SOC_EFUSE_DIS_USB_JTAG: - ``HARD_DIS_JTAG`` and ``DIS_USB_JTAG`` which disables JTAG. - ``DIS_DIRECT_BOOT`` (old name ``DIS_LEGACY_SPI_BOOT``) which disables direct boot mode + :SOC_EFUSE_DIS_DOWNLOAD_MSPI: - ``DIS_DOWNLOAD_MSPI`` which disables the MSPI access in download mode. However, before the first boot you can choose to keep any of these features enabled by burning only selected eFuses and write-protect the rest of eFuses with unset value 0. For example: diff --git a/docs/en/security/host-based-security-workflows.rst b/docs/en/security/host-based-security-workflows.rst index 5753572f92a9..96855700d37d 100644 --- a/docs/en/security/host-based-security-workflows.rst +++ b/docs/en/security/host-based-security-workflows.rst @@ -290,6 +290,7 @@ In this case, all the eFuses related to flash encryption are written with help o :SOC_EFUSE_DIS_USB_JTAG: - ``DIS_USB_JTAG``: Disable USB switch to JTAG :SOC_EFUSE_DIS_PAD_JTAG: - ``DIS_PAD_JTAG``: Disable JTAG permanently :not esp32: - ``DIS_DOWNLOAD_MANUAL_ENCRYPT``: Disable UART bootloader encryption access + :SOC_EFUSE_DIS_DOWNLOAD_MSPI: - ``DIS_DOWNLOAD_MSPI``: Disable the MSPI access in download mode The respective eFuses can be burned by running: diff --git a/docs/zh_CN/api-guides/app_trace.rst b/docs/zh_CN/api-guides/app_trace.rst index 8f9d123ecc6d..1e00241e9219 100644 --- a/docs/zh_CN/api-guides/app_trace.rst +++ b/docs/zh_CN/api-guides/app_trace.rst @@ -420,7 +420,7 @@ Start 子命令语法: 收集到跟踪数据后,用户可以使用特殊的工具对结果进行可视化并分析程序行为。 -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES 遗憾的是,SystemView 不支持从多个核心进行跟踪。所以当使用 JTAG 追踪双核模式下的 {IDF_TARGET_NAME} 时会生成两个文件:一个用于 PRO CPU,另一个用于 APP CPU。用户可以将每个文件加载到工具中单独分析。使用 UART 进行追踪时,用户可以在 menuconfig Pro 或 App 中点击 ``Component config`` > ``Application Level Tracing`` > ``FreeRTOS SystemView Tracing`` 并选择要追踪的 CPU。 @@ -432,7 +432,7 @@ Start 子命令语法: ESP-IDF 使用自己的 SystemView FreeRTOS 事件 ID 映射,因此用户需要将 ``$SYSVIEW_INSTALL_DIR/Description/SYSVIEW_FreeRTOS.txt`` 替换成 ``$IDF_PATH/tools/esp_app_trace/SYSVIEW_FreeRTOS.txt``。在使用上述链接配置 SystemView 序列化程序时,也应该使用该特定文件的内容。 -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES 配置 Impulse 实现双核跟踪 ~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/docs/zh_CN/api-guides/build-system.rst b/docs/zh_CN/api-guides/build-system.rst index 344c8782fbfc..dfe2c1fa6db0 100644 --- a/docs/zh_CN/api-guides/build-system.rst +++ b/docs/zh_CN/api-guides/build-system.rst @@ -361,6 +361,7 @@ ESP-IDF 在搜索所有待构建的组件时,会按照 ``COMPONENT_DIRS`` 指 * 如果设置 :ref:`CONFIG_APP_PROJECT_VER_FROM_CONFIG` 选项,将会使用 :ref:`CONFIG_APP_PROJECT_VER` 的值。 * 或者,如果在项目 CMakeLists.txt 文件中设置了 ``PROJECT_VER`` 变量,则该变量值可以使用。 * 或者,如果 ``PROJECT_DIR/version.txt`` 文件存在,其内容会用作 ``PROJECT_VER`` 的值。 + * 或者,如果在 CMakeLists.txt 文件中将 ``VERSION`` 参数传递给 ``project()`` 调用,形式为 ``project(... VERSION x.y.z.w )``,那么 ``VERSION`` 参数将用作为 ``PROJECT_VER`` 的值。``VERSION`` 参数必须符合 `cmake 标准 `_。 * 或者,如果项目位于某个 Git 仓库中,则使用 ``git describe`` 命令的输出作为 ``PROJECT_VER`` 的值。 * 否则,``PROJECT_VER`` 的值为 1。 - ``EXTRA_PARTITION_SUBTYPES``:CMake 列表,用于创建额外的分区子类型。子类型的描述由字符串组成,以逗号为分隔,格式为 ``type_name, subtype_name, numeric_value``。组件可通过此列表,添加新的子类型。 diff --git a/docs/zh_CN/api-guides/index.rst b/docs/zh_CN/api-guides/index.rst index f4ce0b5a1e3c..5896478b9be6 100644 --- a/docs/zh_CN/api-guides/index.rst +++ b/docs/zh_CN/api-guides/index.rst @@ -43,3 +43,4 @@ API 指南 :SOC_USB_SERIAL_JTAG_SUPPORTED: usb-serial-jtag-console :SOC_WIFI_SUPPORTED: wifi :SOC_WIFI_SUPPORTED: wifi-security + low-power-mode diff --git a/docs/zh_CN/api-guides/low-power-mode.rst b/docs/zh_CN/api-guides/low-power-mode.rst new file mode 100644 index 000000000000..75df5d1883df --- /dev/null +++ b/docs/zh_CN/api-guides/low-power-mode.rst @@ -0,0 +1,735 @@ +低功耗模式使用指南 +================== + +:link_to_translation:`en:[English]` + +对于物联网应用场景,终端的待机性能表现十分重要,本文档旨在介绍 {IDF_TARGET_NAME} 低功耗的基本原理,同时介绍 {IDF_TARGET_NAME} 支持的低功耗模式,需注意本文档主要针对 station mode。文档还会具体给出每种模式的配置步骤、推荐配置和功耗表现,以帮助用户根据实际需求快速配置适合的低功耗模式。 + +系统低功耗模式介绍 +---------------------------------- + +低功耗模式不仅涉及到系统相关问题,还涉及到芯片具体的工作场景,如处在 Wi-Fi 工作场景就会与处在蓝牙工作场景时产生不同。为此本节将首先介绍纯系统角度,即不涉及具体场景的低功耗模式,主要有 DFS、Light-sleep、Deep-sleep。纯系统下的低功耗模式主要思想就是在休眠时关闭或门控一些功能模块来降低功耗。 + +DFS +++++++++++++++++++++++++++++++++++ + +DFS (Dynamic frequency scaling) 即动态频率切换,是 ESP-IDF 中集成的电源管理机制的基础功能。DFS 可以根据应用程序持有电源锁的情况,调整外围总线 (APB) 频率和 CPU 频率。持有高性能锁就使用高频,空闲状态不持有电源锁时则使用低频来降低功耗,以此来尽可能减少运行应用程序的功耗。 + +DFS 的调频机制即根据持有电源锁的最大频率需求来调整频率,同时,freertos tick rates 的数值也会对 DFS 调频产生影响。系统任务调度的灵敏度越大,则意味着系统能更及时的根据需求调整频率。有关调频机制的详细信息,请参见 :doc:`电源管理 <../api-reference/system/power_management>`。 + +下图为 DFS 调频机制运行的理想电流情况。 + +.. figure:: ../../_static/Low-power-DFS-current.png + :align: center + + 理想 DFS 机制调频电流图 + +DFS 适用于 CPU 必须处于工作状态但是对低功耗有需求的场景,因此 DFS 经常与其他低功耗模式共同开启,下文会详细介绍。 + +Light-sleep +++++++++++++++++++++++++++++++++++ + +Light-sleep 模式是 {IDF_TARGET_NAME} 预设的一种低功耗模式,其核心思想就是在休眠时关闭或门控一些功能模块来降低功耗。从纯系统方面来说,Light-sleep 模式有两种进入方式,一种是通过 API 调用进入休眠,一种是自动进入的 auto 模式。两种模式都需要配置唤醒源进行唤醒,同时在进入休眠后会门控或关闭一些模块。这里主要介绍 Auto Light-sleep 模式。 + +Auto Light-sleep 模式是 ESP-IDF 电源管理机制和 Light-sleep 模式的结合。开启电源管理机制是其前置条件,auto 体现在系统进入空闲状态 (IDLE) 超过设定时间后,自动进入 Light-sleep。空闲状态下,应用程序释放所有电源锁,此时,DFS 将降频以减小功耗。 + +Auto Light-sleep 依赖于电源管理机制,系统经过提前判断,发现空闲时间超过设定时间时,则直接进入休眠。该过程为自动进行。休眠时会自动关闭 RF、8 MHz 振荡器、40 MHz 高速晶振、PLL、门控数字内核时钟,暂停 CPU 工作。 + +Auto Light-sleep 模式需配置唤醒源。该模式拥有多种唤醒源,支持相互组合,此时任何一个唤醒源都可以触发唤醒。唤醒后,会从进入休眠的位置继续执行程序。若不配置唤醒源,进入 Light-sleep 休眠后,芯片将一直处在睡眠状态,直到外部复位。具体唤醒源有 RTC 定时器、触摸传感器、外部唤醒 (ext0)、外部唤醒 (ext1)、ULP 协处理器、SDIO、GPIO、UART、Wi-Fi、BT 唤醒等。 + +Auto Light-sleep 模式工作流程相对复杂,但是进入休眠状态是自动进行,同时需注意在进入前配置好唤醒源,防止芯片一直处在休眠状态。 + +.. figure:: ../../_static/Low-power-auto-light-sleep-process.png + :align: center + + Auto Light-sleep 模式工作流程图 + +根据 Auto Light-sleep 的工作流程可得其理想电流图,关键节点均在图上标出。 + +.. figure:: ../../_static/Low-power-auto-light-sleep-current.png + :align: center + + Auto Light-sleep 模式模式理想电流图 + +.. note:: + 为更加清晰地展现出 Auto Light-sleep 的主要变化,图中省略了 DFS 降频过程。 + +Auto Light-sleep 模式适用于不需要实时响应外界需求的场景。 + +Deep-sleep +++++++++++++++++++++++++++++++++++ + +Deep-sleep 模式是为了追求更好的功耗表现所设计,休眠时仅保留 RTC 控制器、RTC 外设(可配置)、ULP 协处理器、RTC 高速内存、RTC 低速内存,其余模块全部关闭。与 Light-sleep 类似,Deep-sleep 同样通过 API 进入,且需要配置唤醒源进行唤醒。 + +Deep-sleep 通过调用 API 进入,休眠时会关闭除 RTC 控制器、RTC 外设、ULP 协处理器、RTC 高速内存、RTC 低速内存外的所有模块。 + +Deep-sleep 模式需配置唤醒源,其拥有多种唤醒源,这些唤醒源也可以组合在一起,此时任何一个唤醒源都可以触发唤醒。若不配置唤醒源进入 Deep-sleep 模式,芯片将一直处在睡眠状态,直到外部复位。具体唤醒源有 RTC 定时器、触摸传感器、外部唤醒 (ext0)、外部唤醒 (ext1)、ULP 协处理器、GPIO 唤醒等。 + +Deep-sleep 模式工作流程如下图所示: + +.. figure:: ../../_static/Low-power-deep-sleep-process.png + :align: center + + Deep-sleep 模式工作流程图 + +Deep-sleep 模式主要应用场景决定了系统很长时间才会苏醒一次,完成工作后又会继续进入 Deep-sleep,所以其理想电流图如下。 + +.. figure:: ../../_static/Low-power-deep-sleep-current.png + :align: center + + Deep-sleep 模式理想电流图 + +Deep-sleep 可以用于低功耗的传感器应用,或是大部分时间都不需要进行数据传输的情况,也就是通常所说的待机模式。设备可以每隔一段时间从 Deep-sleep 状态醒来测量数据并上传,之后重新进入 Deep-sleep;也可以将多个数据存储于 RTC memory,然后一次性发送出去。 + +如何配置纯系统下低功耗模式 ++++++++++++++++++++++++++++++++++++++ + +介绍完纯系统下的低功耗模式后,本节将介绍公共配置选项、每种模式独有的配置选项,以及相应低功耗模式 API 的使用说明,同时给出相应模式推荐的配置。 + +公共配置选项 ++++++++++++++ + +.. only:: esp32 or esp32s3 + + - 单双核工作模式 + 对于多核心芯片,可以选择单核工作模式。 + + + - RTOS Tick rate (Hz) + 该参数表示系统周期任务调度的频率。例如,当 RTOS Tick rate 配置为 1000 时,系统每毫秒都会进行一次任务调度;空闲时,系统也能够更敏锐的感知到空闲状态。 + + +DFS 配置 ++++++++++++++++++++++++ + +DFS 有如下可配置选项: + +- max_freq_mhz + 该参数表示最大 CPU 频率 (MHz),即 CPU 最高性能工作时候的频率,一般设置为芯片参数的最大值。 + +- min_freq_mhz + 该参数表示最小 CPU 频率 (MHz),即系统处在空闲状态时 CPU 的工作频率。该字段可设置为晶振 (XTAL) 频率值,或者 XTAL 频率值除以整数。 + +- light_sleep_enable + 使能该选项,系统将在空闲状态下自动进入 Light-sleep 状态,即 Auto Light-sleep 使能,上文已经具体介绍。 + +具体配置方法如下: + +- 1. 使能 CONFIG_PM_ENABLE +- 2. 配置 max_freq_mhz 和 min_freq_mhz,方式如下: + + :: + + esp_pm_config_t pm_config = { + .max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ, + .min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ, + .light_sleep_enable = flase + }; + ESP_ERROR_CHECK( esp_pm_configure(&pm_config) ); + +推荐配置: + +.. list-table:: + :header-rows: 1 + :widths: 20 20 + + * - 配置名称 + - 设置情况 + + * - CONFIG_PM_ENABLE + - ON + + * - RTOS Tick rate (Hz) + - 1000 + + * - max_freq_mhz + - 160 + + * - min_freq_mhz + - 40 + + * - light_sleep_enable + - false + +.. note:: + 上表中不涉及的配置均是默认。 + + +Light-sleep 配置 ++++++++++++++++++++ + +本节介绍 Auto Light-sleep 的推荐配置和配置步骤。 + +Auto Light-sleep 有如下可配置选项: + +- Minimum step to enter sleep mode + 该参数表示系统自动进入休眠的阈值。该参数单位为 RTOS Tick,故其表示的时间与 RTOS Tick rate 相关,例该参数值为 3,RTOS Tick rate 配置为 1000 Hz 时,即当系统空闲时间大于等于 3 ms 时进入 休眠。 + +- Put light sleep related codes in internal RAM + 如果使能该选项,一些 light-sleep 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加 1.8kB。 + +- Put RTOS IDLE related codes in internal RAM + 如果使能该选项,一些 RTOS IDLE 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加 260B。 + +- RTC slow clock source + 该参数表表示 RTC 慢速时钟源。系统休眠时计时器模块的时钟被门控,此时使用 RTC Timer 进行计时,唤醒后使用 RTC Timer 的计数值对系统时间进行补偿。 + +.. list-table:: + :header-rows: 1 + :widths: 20 20 20 + + * - 时钟源 + - 精度 + - 频偏 + + * - Internal 150kHz OSC + - 约6.7us/cycle + - 大 + + * - External 32kHz XTAL + - 约30.5us/cycle + - 小 + +- Disable all GPIO when chip at sleep + 如果使能该选项,系统将在休眠过程中禁用所有 GPIO 管脚,消除 GPIO 漏电,降低功耗,但是休眠过程中 GPIO 无法进行信号输入和输出。 + +.. only:: esp32c3 or esp32s3 + + - Power down MAC and baseband + 如果使能该选项,系统将在休眠时关闭 Wi-Fi 和蓝牙的 MAC 和 baseband 来降低功耗,休眠电流约降低 100 uA, 但是为保存上下文信息,将额外消耗 5.3 K DRAM。 + + - Power down CPU + 如果使能该选项,系统将在休眠时将关闭 CPU 来降低功耗,对于 esp32c3,休眠电流减小 100 uA 左右,对于 esp32s3,休眠电流减小 650 uA 左右。但是为保存上下文信息,对于 esp32c3,将消耗 1.6 KB 的 DRAM 空间,对于 esp32s3,将消耗 8.58 KB 的 DRAM 空间。 + + - Power down I/D-cache tag memory + 如果使能该选项,系统将在休眠时关闭 I/D cache tag memory 来降低功耗, 但是为保存 tag memory 信息,将额外消耗最大约 9 KB DRAM,同时因为 tag memory 信息特殊性,如需打开该选项,建议多进行测试。 + + - Power down flash in Light-sleep + 如果使能该选项,系统将在 Light-sleep 休眠时关闭 flash,降低系统功耗,该选项的前提是系统没有使用 PSRAM。 + +唤醒源: + +- RTC Timer Wakeup +- GPIO Wakeup +- UART Wakeup +- Touchpad Wakeup +- External Wakeup (ext0) +- External Wakeup (ext1) +- ULP Coprocessor Wakeup + +.. note:: + 以上仅列出可配置唤醒源,详细介绍请参考 :doc:`睡眠模式 <../api-reference/system/sleep_modes>`。 + +配置方法: + +- 1. 配置唤醒源 +- 2. 使能 CONFIG_PM_ENABLE +- 3. 使能 CONFIG_FREERTOS_USE_TICKLESS_IDLE +- 4. 配置 DFS 参数 +- 5. light_sleep_enable = true,具体如下: + + :: + + esp_pm_config_t pm_config = { + .max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ, + .min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ, + #if CONFIG_FREERTOS_USE_TICKLESS_IDLE + .light_sleep_enable = true + #endif + }; + ESP_ERROR_CHECK( esp_pm_configure(&pm_config) ); + +- 6. 配置介绍的其余相关参数 + +推荐配置: + +.. only:: esp32c3 or esp32s3 + + .. list-table:: + :header-rows: 1 + :widths: 30 15 + + * - 配置名称 + - 设置情况 + + * - CONFIG_PM_ENABLE + - ON + + * - CONFIG_FREERTOS_USE_TICKLESS_IDLE + - ON + + * - max_freq_mhz + - 160 + + * - min_freq_mhz + - 40 + + * - RTOS Tick rate (Hz) + - 1000 + + * - light_sleep_enable + - true + + * - Minimum step to enter sleep mode + - 3 + + * - Put light sleep codes in IRAM + - OFF + + * - Put RTOS IDLE codes in IRAM + - OFF + + * - RTC slow clock source + - Internal 150kHz OSC + + * - Disable all GPIO when chip at sleep + - ON + + * - Power down MAC and baseband + - ON + + * - Power down I/D-cache tag memory + - ON + + * - Power down CPU + - ON + + * - Power down flash in light sleep + - OFF + + .. note:: + 上表中不涉及的配置均是默认 + +.. only:: esp32 or esp32s2 + + .. list-table:: + :header-rows: 1 + :widths: 30 15 + + * - 配置名称 + - 设置情况 + + * - CONFIG_PM_ENABLE + - ON + + * - CONFIG_FREERTOS_USE_TICKLESS_IDLE + - ON + + * - max_freq_mhz + - 160 + + * - min_freq_mhz + - 40 + + * - RTOS Tick rate (Hz) + - 1000 + + * - light_sleep_enable + - true + + * - Minimum step to enter sleep mode + - 3 + + * - Put light sleep codes in IRAM + - OFF + + * - Put RTOS IDLE codes in IRAM + - OFF + + * - RTC slow clock source + - Internal 150kHz OSC + + * - Disable all GPIO when chip at sleep + - ON + + .. note:: + 上表中不涉及的配置均是默认 + +.. only:: esp32c2 + + .. list-table:: + :header-rows: 1 + :widths: 30 15 + + * - 配置名称 + - 设置情况 + + * - CONFIG_PM_ENABLE + - ON + + * - CONFIG_FREERTOS_USE_TICKLESS_IDLE + - ON + + * - max_freq_mhz + - 120 + + * - min_freq_mhz + - 40 + + * - RTOS Tick rate (Hz) + - 1000 + + * - light_sleep_enable + - true + + * - Minimum step to enter sleep mode + - 3 + + * - Put light sleep codes in IRAM + - OFF + + * - Put RTOS IDLE codes in IRAM + - OFF + + * - RTC slow clock source + - Internal 150kHz OSC + + * - Disable all GPIO when chip at sleep + - ON + + * - Power down MAC and baseband + - ON + + * - Power down I/D-cache tag memory + - ON + + * - Power down CPU + - ON + + * - Power down flash in light sleep + - OFF + + .. note:: + 上表中不涉及的配置均是默认 + +Deep-sleep 配置 +++++++++++++++++++ + +对 Deep-sleep 模式来说,除了唤醒源相关配置,其余配置意义已经不大。 + +Deep-sleep 有如下可配置选项: + +- RTC Timer wakeup +- EXT0/1 wakeup +- Touchpad wakeup +- ULP wakeup + +.. note:: + 以上仅列出可配置唤醒源,详细介绍请参考 :doc:`睡眠模式 <../api-reference/system/sleep_modes>`。 + +配置步骤: + +- 配置唤醒源 +- 调用 API,具体如下:: + + /* Enter deep sleep */ + esp_deep_sleep_start(); + +用户可以通过下列配置选项,让一些特定模块在休眠时保持开启状态: + +- Power up External 40 MHz XTAL + 在一些特殊应用中,部分模块对休眠时的时钟精度及稳定度有很高要求(例如 BT)。这种情况下,可以考虑在休眠过程中打开 External 40 MHz XTAL。 + 打开和关闭代码如下:: + + ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON)); + ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF)); + +- Power up Internal 8 MHz OSC + 在一些特殊应用中,部分模块(例如 LEDC)将 Internal 8 MHz OSC 作为时钟源,并且希望在 Light-sleep 休眠过程中也可以正常使用。这种情况下,可以考虑在休眠过程中打开 Internal 8 MHz OSC。 + 打开和关闭代码如下:: + + ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC8M, ESP_PD_OPTION_ON)); + ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC8M, ESP_PD_OPTION_OFF)); + +.. only:: SOC_WIFI_SUPPORTED + + Wi-Fi 场景下低功耗模式介绍 + ---------------------------------- + + 上文介绍了纯系统方向下的低功耗模式,但在实际应用中还需结合具体应用场景。本节将结合纯系统下的功耗模式来介绍在 Wi-Fi 场景下的低功耗模式。因为 Wi-Fi 场景的复杂性,本节会会首先介绍 Wi-Fi 省电的基本原理,然后再介绍具体的低功耗模式,同时本节主要针对 station 模式。 + + Wi-Fi 场景如何选择低功耗模式 + ++++++++++++++++++++++++++++++++++ + + 为方便用户选择合适的低功耗模式,在介绍具体内容前先给出 Wi-Fi 场景下低功耗模式总结表,以方便用户根据需求快速选择想要了解的内容。 + + .. include:: sleep-current/{IDF_TARGET_PATH_NAME}_summary.inc + + .. note:: + + 上表中所有电流均为平均电流,表中术语在下文均有介绍,用户可根据需求进行查看 + + + Wi-Fi 省电的基本原理 + +++++++++++++++++++++ + + 首先,在 station 的工作过程中,为在接收发送过程中避免冲突,需要长时间监听信道,能耗较大的 RF 模块会一直处于工作中,浪费电量。为此,Wi-Fi 协议引入省电模式。 + + 省电模式的基本原理是通过减少不必要的监听时间来降低耗能。AP 会缓存进入省电模式的 station 的包,同时周期发送包含 TIM 信息的 Beacon 帧,TIM 会指示 AP 缓存的单播包。TIM 中,DTIM 较为特殊,其会缓存广播包,并以 n 个(由 AP 决定)TIM 为周期发送。对 station 来说,TIM 非必听,而 DTIM 为必听。因此,station 可以选择只在每一个 DTIM 帧前醒来打开 Wi-Fi 相关模块(RF 模块),而不必时刻处于监听状态,这样就能有效降低功耗。 + + .. figure:: ../../_static/Low-power-DTIM4.png + :align: center + + DTIM4 省电模式示意图 + + 其次,station 从打开到再次关闭 Wi-Fi 相关模块的时间也会影响功耗。除必要的数据传输处理时间外,主要有四项配置会影响时间长短: + + - 时钟准确性导致的 time offset,主要原因是时钟或多或少都会与理想的时间存在偏移,同时偏移的正负不定。 + - 处理 Beacon 漏听后的时间,如漏听后持续监听时间、允许最多丢失 Beacon 数目等,这段时间存不存在以及存在多久都不定,但是可以配置范围。 + - 为了确保能够接受突发数据包而添加的 active 时间,可由配置决定。 + - ILDE 时间是具体某些功耗模式进入条件要求。因此在满足通信需求的情况下,降低工作时间可以改善功耗表现。 + + .. figure:: ../../_static/Low-power-time.png + :align: center + + 芯片工作时间组成图 + + 此外,在 station 没有处于 Wi-Fi 接收或发送状态时,影响功耗的因素变成了芯片的其他模块。不同的功耗模式会配置不同的时钟源,或者动态调整一些模块的工作频率如 CPU,同时还会关闭不同数量的功能模块,这将有效降低芯片的功耗。其实也就是纯系统相关的模式,用户可根据需求自己选择合适的配置。 + + 如果以时间为横轴,电流大小为纵轴建立坐标轴,那么处在低功耗模式下芯片的理想工作电流图可以简化成下图: + + .. figure:: ../../_static/Low-power-WiFi-base-current.png + :align: center + + 理想情况下 Wi-Fi 场景低功耗模式电流图 + + 其中 station 要进行 Wi-Fi 通信时,Wi-Fi 相关模块 (PHY) 开启,电流会显著上升,在工作完成前,电流会一直维持在一个较高的水平。工作完成后,芯片会关闭 Wi-Fi 相关模块,这时电流又会降低到一个较低水平。 + + 可以看出影响功耗表现的主要有三点:interval、period 和 base current。 + + - Interval 是 station Wi-Fi 相关模块工作的间隔,既可以由低功耗模式自定义,也可根据 Wi-Fi 协议省电机制(3.1 第一点介绍),由 DTIM 周期决定。可以看出在同等情下,interval 越大,功耗表现会更好,但是响应会更慢,影响通信的及时性。 + + - Period 可以看作每次 station Wi-Fi 工作的时间,这段时间的长度也会影响功耗的表现。period 不是一个固定的时长(3.1 第二点介绍),在保证 Wi-Fi 通信正常的情况下,period 持续时间越短,功耗表现越好。但是减少 period 时间,必然会影响通信的可靠性。 + + - Base current 是 Wi-Fi 相关模块不工作时芯片的电流,影响其大小的因素很多,不同的功耗模式下休眠策略不同。所以,在满足功能的情况下,优化配置降低该电流大小可以提高功耗表现,但同时关闭其余模块会影响相关功能和芯片的唤醒时间。 + + 知道了影响功耗的三点因素之后,要想降低功耗应从这三点入手,接下来介绍两种低功耗模式,Modem sleep、Auto Light-sleep。两种模式主要区别就是对三点因素的优化不同。 + + + Modem-sleep Mode + ++++++++++++++++++ + + Modem-sleep 模式主要工作原理基于 DTIM 机制,周期性的醒来处理 Wi-Fi 相关工作,又在周期间隔之间进入休眠,关闭 PHY(RF 模块)来降低功耗。同时通过 DTIM 机制,station 可以与 AP 保持 Wi-Fi 连接,数据传输。 + + Modem-sleep 模式会在 Wi-Fi task 结束后自动进入休眠无需调用 API,休眠时仅会关闭 Wi-Fi 相关模块 (PHY),其余模块均处在正常上电状态。 + + Modem-sleep 模式默认会根据 DTIM 周期或 listen interval(下文介绍)醒来,相当于系统自动设置了一个 Wi-Fi 唤醒源,因此用户无需再配置唤醒源,同时系统主动发包时也可以唤醒。 + + Modem-sleep 是一个开关型的模式,调用 API 开启后一直自动运行,其工作流程十分简单,具体如下图。 + + .. figure:: ../../_static/Low-power-modem-process.png + :align: center + + Modem sleep 工作流程图 + + + 根据上文的基本电流图,结合 Modem-sleep 的 工作原理,以 Min Modem(下文介绍)为例可得理想情况下电流变化图。 + + .. figure:: ../../_static/Low-power-modem-current.png + :align: center + + Min Modem-sleep 理想电流图 + + Modem-sleep 一般用于 CPU 持续处于工作状态并需要保持 Wi-Fi 连接的应用场景,例如,使用 {IDF_TARGET_NAME} 本地语音唤醒功能,CPU 需要持续采集和处理音频数据。 + + DFS+Modem sleep + ++++++++++++++++++ + + Modem sleep 模式休眠状态中 CPU 仍处在工作状态,而 DFS 机制主要作用于 CPU 和 APB 工作频率来降低功耗,因此 DFS + Modem sleep 可以进一步优化功耗表现,又因为 Wi-Fi task 会申请 ESP_PM_CPU_FREQ_MAX 电源锁来保证 Wi-Fi 任务快速运行,所以 DFS + Modem sleep 产生调频只会发生在 base current 阶段,即 Wi-Fi task 结束后。 + + 在 Wi-Fi 场景下,为了介绍的简化,让用户抓住主要的变化,DFS 可以进行一定的状态简化。具体来说,虽然 DFS 主要根据 CPU 和 APB 两把锁的最高需求来调频,但是 Wi-Fi 场景都需要 CPU 的频率最大化来工作,同时 Wi-Fi task 结束后,也可以理想化的认为,没有其余的工作要完成,这样就可以简单认为经过一段时间会释放两把锁进入空闲状态(IDLE 状态),也同时忽略这段时间锁的变化导致的电流变化,简化状态。 + + 在 Wi-Fi 场景下,DFS 最终简化为如下流程: + + .. figure:: ../../_static/Low-power-DFS-process.png + :align: center + + Wi-Fi场景 DFS 简化流程图 + + 在 Wi-Fi 工作的 active 状态与系统空闲的 IDLE 状态转换,Wi-Fi task 结束后,系统经过一段时间释放了所有锁进入 IDLE 状态,此时 DFS 机制降低频率到设定最低值,忽略了转换状态期间的调频动作,方便理解。 + + 简化过后的 DFS+Modem sleep 模式理想状态下的电流大小如下图所示: + + .. figure:: ../../_static/Low-power-DFS-modem-current.png + :align: center + + DFS+Modem sleep 模式理想电流图 + + + Auto Light-sleep+Wi-Fi 场景 + +++++++++++++++++++++++++++++++ + + Auto Light-sleep 模式在 Wi-Fi 场景下是 ESP-IDF 电源管理机制、DTIM 机制和 light-sleep 的结合。开启电源管理是其前置条件,auto 体现在系统进入 IDLE 状态超过设定值后自动进入 light-sleep。同时 auto light sleep 模式同样遵循 DTIM 机制,会自动苏醒,可以与 AP 保持 Wi-Fi 连接。 + + Auto Light-sleep 模式在 Wi-Fi 场景下休眠机制与纯系统下一样,仍然依赖于电源管理机制,进入休眠的条件为系统处于 IDLE 状态的时间超过设定时间,并且系统会提前判断空闲时间是否满足条件,若满足直接休眠。该过程为自动进行。休眠时会自动关闭 RF、8 MHz 振荡器、40 MHz 高速晶振、PLL,门控数字内核时钟,暂停 CPU 工作。 + + Auto Light-sleep 模式在 Wi-Fi 场景下遵循 DTIM 机制,自动在 DTIM 帧到来前苏醒,相当于系统自动设置了一个 Wi-Fi 唤醒源,因此用户无需再配置唤醒源。同时系统主动发包时也可以唤醒。 + + Auto Light-sleep 模式在 Wi-Fi 场景下工作流程较为复杂,但全程都是自动进行,具体如下图所示。 + + .. figure:: ../../_static/Low-power-wifi-auto-light-process.png + :align: center + + Auto Light-sleep 工作流程图 + + Auto Light-sleep 模式在 Wi-Fi 场景下经常与 modem sleep 同时开启,这里给出 modem+auto light-sleep 模式的理想电流图,关键节点均在图上标出。 + + .. figure:: ../../_static/Low-power-wifi-auto-light-current.png + :align: center + + modem+auto light-sleep 模式理想电流图 + + Auto Light-sleep 模式在 Wi-Fi 场景下可用于需要保持 Wi-Fi 连接,可以实时响应 AP 发来数据的场景。并且在未接收到命令时,CPU 可以处于空闲状态。比如 Wi-Fi 开关的应用,大部分时间 CPU 都是空闲的,直到收到控制命令,CPU 才需要进行 GPIO 的操作。 + + + Deep-sleep+Wi-Fi 场景 + +++++++++++++++++++++++++++++++++ + + Deep-sleep 模式在 Wi-Fi 场景下与纯系统下基本相同,详情可以参考 `Deep-sleep`_ 这里不再介绍。 + + + 如何配置 Wi-Fi 场景下低功耗模式 + +++++++++++++++++++++++++++++++++++++ + + 介绍完 Wi-Fi 场景下低功耗模式后,本节将介绍公共配置选项、每种模式独有的配置选项,以及相应低功耗模式 API 的使用说明,同时给出相应模式推荐的配置(包含纯系统下的低功耗推荐配置)以及该配置的具体表现。 + + 公共配置选项: + + - 功耗类: + + - Max Wi-Fi TX power (dBm) + 该参数表示最大 TX 功率,降低该参数会减小发包功耗,但会影响 Wi-Fi 性能,默认设置最大 20。 + + - IRAM 类: + + - Wi-Fi IRAM speed optimization + 如果使能该选项,一些 Wi-Fi 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加,默认开启。 + + - Wi-Fi RX IRAM speed optimization + 如果使能该选项,一些 Wi-Fi RX 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加,默认开启。 + + - Wi-Fi Sleep IRAM speed optimization + 如果使能该选项,一些 Wi-Fi sleep 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加,默认关闭。 + + - Wi-Fi 协议类: + + - Minimum active time + 该参数表示 Station 接收完一次数据后需要等待时间。当终端与 AP 进行通信时,AP 发送到终端的数据经常是突发形式的,为确保后续的突发数据能够正常接收到,需要等待一段时间。默认 50。 + + - Maximum keep alive time + 该参数表示周期性的发送 sleep null data 来通告 AP 维持连接的时间。在 DTIM 机制下,若 AP 长时间没有某个 station 的包,可能会断开连接,因此需要 station 需要周期发送 sleep null data 维持连接。默认 10。 + + - Send gratuitous ARP periodically + 如果使能该选项,Station 将周期性的发送 gratuitous ARP 请求更新 AP ARP 缓存表。如无该需求,可以关闭。 + + - Wi-Fi sleep optimize when beacon lost + 如果使能该选项,Station 在检测到已经错过或者丢失 beacon 时,会立即关闭 RF 进入低功耗状态。 + + Modem sleep 配置方法如下: + + - 可配置选项 + + - Min Modem + 该参数表示 station 按照 DTIM 周期工作,在每个 DTIM 前醒来接收 Beacon,这样不会漏掉广播信息,但是 DTIM 周期由 AP 决定,如果 DTIM 周期较短,省电效果会降低。 + + - Max Modem + 该参数表示 station 会自定义一个 listen interval,并以 listen interval 为周期醒来接受 Beacon。这样在 listen interval 较大时会省电,但是容易漏听 DTIM,错过广播数据。 + + + - 配置方法: + + - 调用 API,选择模式参数:: + + typedef enum { + WIFI_PS_NONE, + WIFI_PS_MIN_MODEM, + WIFI_PS_MAX_MODEM, + } wifi_ps_type_t; + esp_err_t esp_wifi_set_ps(wifi_ps_type_t type); + + 若选择 WIFI_PS_MAX_MODEM,还需配置 listen interval,示例如下:: + + #define LISTEN_INTERVAL 3 + wifi_config_t wifi_config = { + .sta = { + .ssid = "SSID", + .password = "Password", + .listen_interval = LISTEN_INTERVAL, + }, + }; + ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); + ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); + ESP_ERROR_CHECK(esp_wifi_start()); + + 配置推荐: + + 这里给出的配置推荐是 Min Modem sleep + DFS 开启的配置 + + .. list-table:: + :header-rows: 1 + :widths: 20 15 + + * - 配置名称 + - 设置情况 + + * - WIFI_PS_MIN_MODEM + - ON + + * - CONFIG_PM_ENABLE + - ON + + * - RTOS Tick rate (Hz) + - 1000 + + * - max_freq_mhz + - 160 + + * - min_freq_mhz + - 40 + + * - light_sleep_enable + - false + + 配置表现: + + .. include:: sleep-current/{IDF_TARGET_PATH_NAME}_modem_sleep.inc + + Auto Light-sleep + Wi-Fi 场景配置: + + Auto Light-sleep 在 Wi-Fi 场景下的配置比纯系统下少了唤醒源的配置要求,其余几乎与纯系统下配置一致,因此可配置选项、配置步骤、推荐配置的详细介绍可以参考上文 `Light-sleep`_。同时 Wi-Fi 相关配置保持默认。 + + 配置表现: + + 该配置表现为 Auto Light-sleep 纯系统推荐配置 + 默认的 Wi-Fi 相关配置在 Wi-Fi 场景的表现。 + + .. include:: sleep-current/{IDF_TARGET_PATH_NAME}_light_sleep.inc + + Deep-sleep + Wi-Fi 场景配置: + + Deep-sleep 模式在 Wi-Fi 场景下的配置与纯系统下配置基本一致,因此可配置选项、配置步骤、推荐配置的详细介绍可以参考上文 `Deep-sleep`_。同时 Wi-Fi 相关配置保持默认。 + + 配置表现: + + 该配置表现为 Deep-sleep 纯系统推荐配置 + 默认的 Wi-Fi 相关配置在 Wi-Fi 场景的表现。 + + .. only:: esp32 + + 平均电流约 5.0 μA + + .. only:: esp32s2 + + 平均电流约 5.0 μA + + .. only:: esp32s3 + + 平均电流约 6.9 μA + + .. only:: esp32c3 + + 平均电流约 4.8 μA + + .. only:: esp32c2 + + 平均电流约 4.9 μA + + diff --git a/docs/zh_CN/api-guides/performance/speed.rst b/docs/zh_CN/api-guides/performance/speed.rst index cd8cceacc9d8..8db36c737fb7 100644 --- a/docs/zh_CN/api-guides/performance/speed.rst +++ b/docs/zh_CN/api-guides/performance/speed.rst @@ -54,7 +54,7 @@ - 也可以使用标准 Unix 函数 ``gettimeofday()`` 和 ``utime()`` 来进行计时测量,尽管其开销略高一些。 - 此外,代码中包含 ``hal/cpu_hal.h`` 头文件,并调用 HAL 函数 ``cpu_hal_get_cycle_count()`` 可以返回已执行的 CPU 循环数。该函数开销较低,适用于高精度测量执行时间极短的代码。 - .. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE + .. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES CPU 周期是各核心独立计数的,因此本方法仅适用于测量中断处理程序或固定在单个核心上的任务。 @@ -159,7 +159,7 @@ ESP-IDF 启动的系统任务预设了固定优先级。启动时,一些任务 .. Note: 以下两个列表应保持一致,但第二个列表还展示了 CPU 亲和性。 -.. only:: CONFIG_FREERTOS_UNICORE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES .. list:: @@ -176,7 +176,7 @@ ESP-IDF 启动的系统任务预设了固定优先级。启动时,一些任务 - 如果使用 :doc:`/api-reference/protocols/mqtt` 组件,它会创建优先级默认为 5 的任务( :ref:`可配置 ` ),可通过 :ref:`CONFIG_MQTT_USE_CUSTOM_CONFIG` 调整,也可以在运行时通过 :cpp:class:`esp_mqtt_client_config_t` 结构体中的 ``task_prio`` 字段调整。 - 关于 ``mDNS`` 服务的任务优先级,参见 `性能优化 `__ 。 -.. only :: not CONFIG_FREERTOS_UNICORE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES .. list:: @@ -204,11 +204,11 @@ ESP-IDF 启动的系统任务预设了固定优先级。启动时,一些任务 设定应用程序任务优先级 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. only:: CONFIG_FREERTOS_UNICORE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES 由于 {IDF_TARGET_RF_TYPE} 操作饥饿可能导致系统不稳定,通常不建议让特定任务的优先级高于 {IDF_TARGET_RF_TYPE} 操作的内置优先级。对于非常短且无需网络的实时操作,可以使用中断服务程序或极受限的任务(仅运行极短时间)并设置为最高优先级 (24)。将特定任务优先级设为 19 不会妨碍较低层级的 {IDF_TARGET_RF_TYPE} 功能无延迟运行,但仍然会抢占 lwIP TCP/IP 堆栈以及其他非实时内部功能,这对于不执行网络操作的实时任务而言是最佳选项。lwIP TCP/IP 任务优先级 (18) 应高于所有执行 TCP/IP 网络操作的任务,以保证任务正常执行。 -.. only:: not CONFIG_FREERTOS_UNICORE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES 默认配置下,除了个别例外,尤其是 lwIP TCP/IP 任务,大多数内置任务都固定在核心 0 上执行。因此,应用程序可以方便地将高优先级任务放置在核心 1 上执行。优先级大于等于 19 的应用程序任务在核心 1 上运行时可以确保不会被任何内置任务抢占。为了进一步隔离各个 CPU 上运行的任务,配置 :ref:`lwIP 任务 ` ,可以使 lwIP 任务仅在核心 0 上运行,而非上述任一核心,这可能会根据其他任务的运行情况减少总 TCP/IP 吞吐量。 @@ -234,7 +234,7 @@ ESP-IDF 支持动态 :doc:`/api-reference/system/intr_alloc` 和中断抢占。 .. list:: - 调用 :cpp:func:`esp_intr_alloc` 时使用 ``ESP_INTR_FLAG_LEVEL2`` 或 ``ESP_INTR_FLAG_LEVEL3`` 等标志,可以为更重要的中断设定更高优先级。 - :not CONFIG_FREERTOS_UNICORE: - 将中断分配到不运行内置 {IDF_TARGET_RF_TYPE} 任务的 CPU 上执行,即默认情况下,将中断分配到核心 1 上执行,参见 :ref:`built-in-task-priorities` 。调用 :cpp:func:`esp_intr_alloc` 函数即可将中断分配到函数所在 CPU。 + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - 将中断分配到不运行内置 {IDF_TARGET_RF_TYPE} 任务的 CPU 上执行,即默认情况下,将中断分配到核心 1 上执行,参见 :ref:`built-in-task-priorities` 。调用 :cpp:func:`esp_intr_alloc` 函数即可将中断分配到函数所在 CPU。 - 如果确定整个中断处理程序可以在 IRAM 中运行(参见 :ref:`iram-safe-interrupt-handlers` ),那么在调用 :cpp:func:`esp_intr_alloc` 分配中断时,请设置 ``ESP_INTR_FLAG_IRAM`` 标志,这样可以防止在应用程序固件写入内置 SPI flash 时临时禁用中断。 - 即使是非 IRAM 安全的中断处理程序,如果需要频繁执行,可以考虑将处理程序的函数移到 IRAM 中,从而尽可能规避执行中断代码时发生 flash 缓存缺失的可能性(参见 :ref:`speed-targeted-optimizations` )。如果可以确保只有部分处理程序位于 IRAM 中,则无需添加 ``ESP_INTR_FLAG_IRAM`` 标志将程序标记为 IRAM 安全。 diff --git a/docs/zh_CN/api-guides/startup.rst b/docs/zh_CN/api-guides/startup.rst index 5dcfd3ca9511..54e58bc3b8a4 100644 --- a/docs/zh_CN/api-guides/startup.rst +++ b/docs/zh_CN/api-guides/startup.rst @@ -22,11 +22,11 @@ 一级引导程序 ~~~~~~~~~~~~ -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES SoC 复位后,PRO CPU 会立即开始运行,执行复位向量代码,而 APP CPU 仍然保持复位状态。在启动过程中,PRO CPU 会执行所有的初始化操作。APP CPU 的复位状态会在应用程序启动代码的 ``call_start_cpu0`` 函数中失效。复位向量代码位于 {IDF_TARGET_NAME} 芯片掩膜 ROM 处,且不能被修改。 -.. only:: CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES SoC 复位后,CPU 会立即开始运行,执行所有的初始化操作。复位向量代码位于 {IDF_TARGET_NAME} 芯片掩膜 ROM 处,且不能被修改。 @@ -76,7 +76,7 @@ - 对于在内部 :ref:`iram` 或 :ref:`dram` 中具有加载地址的段,将把数据从 flash 复制到它们的加载地址处。 - 对于一些加载地址位于 :ref:`drom` 或 :ref:`irom` 区域的段,通过配置 flash MMU,可为从 flash 到加载地址提供正确的映射。 -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES 请注意,二级引导程序同时为 PRO CPU 和 APP CPU 配置 flash MMU,但仅使能 PRO CPU 的 flash MMU。原因是二级引导程序代码已加载到 APP CPU 的高速缓存使用的内存区域中。因此使能 APP CPU 高速缓存的任务就交给了应用程序。 @@ -114,13 +114,13 @@ ESP-IDF 应用程序的入口是 :idf_file:`components/esp_system/port/cpu_start - 将 CPU 时钟设置为项目配置的频率。 :CONFIG_ESP_SYSTEM_MEMPROT_FEATURE: - 如果配置了内存保护,则初始化内存保护。 :esp32: - 根据应用程序头部设置重新配置主 SPI flash,这是为了与 ESP-IDF V4.0 之前的引导程序版本兼容,请参考 :ref:`bootloader-compatibility`。 - :not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE: - 如果应用程序被配置为在多个内核上运行,则启动另一个内核并等待其初始化(在类似的“端口层”初始化函数 ``call_start_cpu1`` 内)。 + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - 如果应用程序被配置为在多个内核上运行,则启动另一个内核并等待其初始化(在类似的“端口层”初始化函数 ``call_start_cpu1`` 内)。 -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES ``call_start_cpu0`` 完成运行后,将调用在 :idf_file:`components/esp_system/startup.c` 中找到的“系统层”初始化函数 ``start_cpu0``。其他内核也将完成端口层的初始化,并调用同一文件中的 ``start_other_cores``。 -.. only:: CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES ``call_start_cpu0`` 完成运行后,将调用在 :idf_file:`components/esp_system/startup.c` 中找到的“系统层”初始化函数 ``start_cpu0``。 @@ -156,13 +156,13 @@ ESP-IDF 应用程序的入口是 :idf_file:`components/esp_system/port/cpu_start 运行 ``app_main`` 的主任务有一个固定的 RTOS 优先级(比最小值高)和一个 :ref:`可配置的堆栈大小`。 -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES 主任务的内核亲和性也是可以配置的,请参考 :ref:`CONFIG_ESP_MAIN_TASK_AFFINITY`。 与普通的 FreeRTOS 任务(或嵌入式 C 的 ``main`` 函数)不同,``app_main`` 任务可以返回。如果``app_main`` 函数返回,那么主任务将会被删除。系统将继续运行其他的 RTOS 任务。因此可以将 ``app_main`` 实现为一个创建其他应用任务然后返回的函数,或主应用任务本身。 -.. only:: not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES APP CPU 的内核启动流程 ------------------------------------ diff --git a/docs/zh_CN/api-guides/tools/idf-docker-image.rst b/docs/zh_CN/api-guides/tools/idf-docker-image.rst index c15aab2e6566..3338748c8014 100644 --- a/docs/zh_CN/api-guides/tools/idf-docker-image.rst +++ b/docs/zh_CN/api-guides/tools/idf-docker-image.rst @@ -143,7 +143,8 @@ ESP-IDF 库中的 Docker 文件提供了以下构建参数,可用于构建自 - ``IDF_CLONE_URL``:克隆 ESP-IDF 存储库的 URL。在使用 ESP-IDF 分支时,可以将该参数设置为自定义 URL,默认值为 ``https://github.com/espressif/esp-idf.git``。 - ``IDF_CLONE_BRANCH_OR_TAG``:克隆 ESP-IDF 时使用的 git 分支或标签的名称。该参数将作为 ``git clone`` 命令的 ``--branch`` 参数传递,默认值为 ``master``。 - ``IDF_CHECKOUT_REF``:如果将此参数设置为非空值,在克隆之后会执行 ``git checkout $IDF_CHECKOUT_REF`` 命令。可以将此参数设置为特定 commit 的 SHA 值,以便切换到所需的版本分支或 commit。例如,在希望使用特定版本分支上的某个 commit 时,就可以将此参数设置为该 commit 的 SHA 值。 -- ``IDF_CLONE_SHALLOW``:如果将此参数设置为非空值,则会在执行 ``git clone`` 时使用 ``--depth=1 --shallow-submodules`` 参数。这可以极大减少下载的数据量及生成的 Docker 镜像大小。然而,如果需要切换到此类“浅层”存储库中的其他分支,必须先执行额外的 ``git fetch origin `` 命令。 +- ``IDF_CLONE_SHALLOW``:如果将此参数设置为非空值,则会在执行 ``git clone`` 时使用 ``--depth=1 --shallow-submodules`` 参数。浅克隆的深度可以使用 ``IDF_CLONE_SHALLOW_DEPTH`` 设置。浅克隆可以极大减少下载的数据量及生成的 Docker 镜像大小。然而,如果需要切换到此类“浅层”存储库中的其他分支,必须先执行额外的 ``git fetch origin `` 命令。 +- ``IDF_CLONE_SHALLOW_DEPTH``:此参数指定进行浅克隆时要使用的深度值。如未设置,将使用 ``--depth=1``。此参数仅在使用 ``IDF_CLONE_SHALLOW`` 时有效。如果要为分支构建 Docker 镜像,并且该镜像必须包含该分支上的最新标签,则需使用此参数。要确定所需的深度,请在特定的分支运行 ``git describe`` 命令,并注意偏移值。将偏移值加 1 后即可将其用作 ``IDF_CLONE_SHALLOW_DEPTH`` 参数的值。此过程将确保生成的镜像包含分支上的最新标签,且 Docker 镜像内部的 ``git describe`` 命令也会按预期工作。 - ``IDF_INSTALL_TARGETS``:以逗号分隔的 ESP-IDF 目标列表,用于安装工具链,或者使用 ``all`` 安装所有目标的工具链。选择特定目标可以减少下载的数据量和生成的 Docker 镜像的大小。该参数默认值为 ``all``。 要使用以上参数,请通过 ``--build-arg`` 命令行选项传递。例如,以下命令使用 ESP-IDF v4.4.1 的浅克隆以及仅适用于 ESP32-C3 的工具链构建了 Docker 镜像: diff --git a/docs/zh_CN/api-guides/wifi.rst b/docs/zh_CN/api-guides/wifi.rst index 0683933e7ae2..79830c3267b1 100644 --- a/docs/zh_CN/api-guides/wifi.rst +++ b/docs/zh_CN/api-guides/wifi.rst @@ -1727,6 +1727,8 @@ WPA2-Enterprise 是企业无线网络的安全认证机制。在连接到接入 {IDF_TARGET_NAME} Wi-Fi 节能模式 ----------------------------------------- +本小节将简单介绍Wi-Fi节能模式相关的概念和使用方式,更加详细的介绍请参考 :doc:`低功耗模式使用指南 <../api-guides/low-power-mode>`。 + station 睡眠 ++++++++++++++++++++++ @@ -3674,738 +3676,6 @@ Wi-Fi AMPDU 通常,应使能 AMPDU。禁用 AMPDU 通常用于调试目的。 -如何使用低功耗模式 ------------------------ - -对于物联网应用场景,终端的待机性能表现十分重要,本文档旨在介绍 {IDF_TARGET_NAME} 低功耗的基本原理,同时介绍 {IDF_TARGET_NAME} 支持的低功耗模式,需注意本文档主要针对 station mode。文档还会具体给出每种模式的配置步骤、推荐配置和功耗表现,以帮助用户根据实际需求快速配置适合的低功耗模式。 - -纯系统下低功耗模式介绍 -++++++++++++++++++++++++++++++++++ - -低功耗模式不仅涉及到系统相关问题,还涉及到芯片具体的工作场景,如处在 Wi-Fi 工作场景就会与处在蓝牙工作场景时产生不同。为此本节将首先介绍纯系统角度,即不涉及具体场景的低功耗模式,主要有 DFS、Light-sleep、Deep-sleep。纯系统下的低功耗模式主要思想就是在休眠时关闭或门控一些功能模块来降低功耗。 - -DFS -++++++++++++++++++++++++++++++++++ - -DFS (Dynamic frequency scaling) 即动态频率切换,是 ESP-IDF 中集成的电源管理机制的基础功能。DFS 可以根据应用程序持有电源锁的情况,调整外围总线 (APB) 频率和 CPU 频率。持有高性能锁就使用高频,空闲状态不持有电源锁时则使用低频来降低功耗,以此来尽可能减少运行应用程序的功耗。 - -DFS 的调频机制即根据持有电源锁的最大频率需求来调整频率,同时,freertos tick rates 的数值也会对 DFS 调频产生影响。系统任务调度的灵敏度越大,则意味着系统能更及时的根据需求调整频率。有关调频机制的详细信息,请参见 :doc:`电源管理 <../api-reference/system/power_management>`。 - -下图为 DFS 调频机制运行的理想电流情况。 - -.. figure:: ../../_static/Low-power-DFS-current.png - :align: center - - 理想 DFS 机制调频电流图 - -DFS 适用于 CPU 必须处于工作状态但是对低功耗有需求的场景,因此 DFS 经常与其他低功耗模式共同开启,下文会详细介绍。 - -Light-sleep -++++++++++++++++++++++++++++++++++ - -Light-sleep 模式是 {IDF_TARGET_NAME} 预设的一种低功耗模式,其核心思想就是在休眠时关闭或门控一些功能模块来降低功耗。从纯系统方面来说,Light-sleep 模式有两种进入方式,一种是通过 API 调用进入休眠,一种是自动进入的 auto 模式。两种模式都需要配置唤醒源进行唤醒,同时在进入休眠后会门控或关闭一些模块。这里主要介绍 Auto Light-sleep 模式。 - -Auto Light-sleep 模式是 ESP-IDF 电源管理机制和 Light-sleep 模式的结合。开启电源管理机制是其前置条件,auto 体现在系统进入空闲状态 (IDLE) 超过设定时间后,自动进入 Light-sleep。空闲状态下,应用程序释放所有电源锁,此时,DFS 将降频以减小功耗。 - -Auto Light-sleep 依赖于电源管理机制,系统经过提前判断,发现空闲时间超过设定时间时,则直接进入休眠。该过程为自动进行。休眠时会自动关闭 RF、8 MHz 振荡器、40 MHz 高速晶振、PLL、门控数字内核时钟,暂停 CPU 工作。 - -Auto Light-sleep 模式需配置唤醒源。该模式拥有多种唤醒源,支持相互组合,此时任何一个唤醒源都可以触发唤醒。唤醒后,会从进入休眠的位置继续执行程序。若不配置唤醒源,进入 Light-sleep 休眠后,芯片将一直处在睡眠状态,直到外部复位。具体唤醒源有 RTC 定时器、触摸传感器、外部唤醒 (ext0)、外部唤醒 (ext1)、ULP 协处理器、SDIO、GPIO、UART、Wi-Fi、BT 唤醒等。 - -Auto Light-sleep 模式工作流程相对复杂,但是进入休眠状态是自动进行,同时需注意在进入前配置好唤醒源,防止芯片一直处在休眠状态。 - -.. figure:: ../../_static/Low-power-auto-light-sleep-process.png - :align: center - - Auto Light-sleep 模式工作流程图 - -根据 Auto Light-sleep 的工作流程可得其理想电流图,关键节点均在图上标出。 - -.. figure:: ../../_static/Low-power-auto-light-sleep-current.png - :align: center - - Auto Light-sleep 模式模式理想电流图 - -.. note:: - 为更加清晰地展现出 Auto Light-sleep 的主要变化,图中省略了 DFS 降频过程。 - -Auto Light-sleep 模式适用于不需要实时响应外界需求的场景。 - -Deep-sleep -++++++++++++++++++++++++++++++++++ - -Deep-sleep 模式是为了追求更好的功耗表现所设计,休眠时仅保留 RTC 控制器、RTC 外设(可配置)、ULP 协处理器、RTC 高速内存、RTC 低速内存,其余模块全部关闭。与 Light-sleep 类似,Deep-sleep 同样通过 API 进入,且需要配置唤醒源进行唤醒。 - -Deep-sleep 通过调用 API 进入,休眠时会关闭除 RTC 控制器、RTC 外设、ULP 协处理器、RTC 高速内存、RTC 低速内存外的所有模块。 - -Deep-sleep 模式需配置唤醒源,其拥有多种唤醒源,这些唤醒源也可以组合在一起,此时任何一个唤醒源都可以触发唤醒。若不配置唤醒源进入 Deep-sleep 模式,芯片将一直处在睡眠状态,直到外部复位。具体唤醒源有 RTC 定时器、触摸传感器、外部唤醒 (ext0)、外部唤醒 (ext1)、ULP 协处理器、GPIO 唤醒等。 - -Deep-sleep 模式工作流程如下图所示: - -.. figure:: ../../_static/Low-power-deep-sleep-process.png - :align: center - - Deep-sleep 模式工作流程图 - -Deep-sleep 模式主要应用场景决定了系统很长时间才会苏醒一次,完成工作后又会继续进入 Deep-sleep,所以其理想电流图如下。 - -.. figure:: ../../_static/Low-power-deep-sleep-current.png - :align: center - - Deep-sleep 模式理想电流图 - -Deep-sleep 可以用于低功耗的传感器应用,或是大部分时间都不需要进行数据传输的情况,也就是通常所说的待机模式。设备可以每隔一段时间从 Deep-sleep 状态醒来测量数据并上传,之后重新进入 Deep-sleep;也可以将多个数据存储于 RTC memory,然后一次性发送出去。 - -如何配置纯系统下低功耗模式 -+++++++++++++++++++++++++++++++++++++ - -介绍完纯系统下的低功耗模式后,本节将介绍公共配置选项、每种模式独有的配置选项,以及相应低功耗模式 API 的使用说明,同时给出相应模式推荐的配置。 - -公共配置选项 -+++++++++++++ - -.. only:: esp32 or esp32s3 - - - 单双核工作模式 - 对于多核心芯片,可以选择单核工作模式。 - - - - RTOS Tick rate (Hz) - 该参数表示系统周期任务调度的频率。例如,当 RTOS Tick rate 配置为 1000 时,系统每毫秒都会进行一次任务调度;空闲时,系统也能够更敏锐的感知到空闲状态。 - - -DFS 配置 -+++++++++++++++++++++++ - -DFS 有如下可配置选项: - -- max_freq_mhz - 该参数表示最大 CPU 频率 (MHz),即 CPU 最高性能工作时候的频率,一般设置为芯片参数的最大值。 - -- min_freq_mhz - 该参数表示最小 CPU 频率 (MHz),即系统处在空闲状态时 CPU 的工作频率。该字段可设置为晶振 (XTAL) 频率值,或者 XTAL 频率值除以整数。 - -- light_sleep_enable - 使能该选项,系统将在空闲状态下自动进入 Light-sleep 状态,即 Auto Light-sleep 使能,上文已经具体介绍。 - -具体配置方法如下: - -- 1. 使能 CONFIG_PM_ENABLE -- 2. 配置 max_freq_mhz 和 min_freq_mhz,方式如下: - - :: - - esp_pm_config_t pm_config = { - .max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ, - .min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ, - .light_sleep_enable = flase - }; - ESP_ERROR_CHECK( esp_pm_configure(&pm_config) ); - -推荐配置: - -.. list-table:: - :header-rows: 1 - :widths: 20 20 - - * - 配置名称 - - 设置情况 - - * - CONFIG_PM_ENABLE - - ON - - * - RTOS Tick rate (Hz) - - 1000 - - * - max_freq_mhz - - 160 - - * - min_freq_mhz - - 40 - - * - light_sleep_enable - - false - -.. note:: - 上表中不涉及的配置均是默认。 - - -Light-sleep 配置 -+++++++++++++++++++ - -本节介绍 Auto Light-sleep 的推荐配置和配置步骤。 - -Auto Light-sleep 有如下可配置选项: - -- Minimum step to enter sleep mode - 该参数表示系统自动进入休眠的阈值。该参数单位为 RTOS Tick,故其表示的时间与 RTOS Tick rate 相关,例该参数值为 3,RTOS Tick rate 配置为 1000 Hz 时,即当系统空闲时间大于等于 3 ms 时进入 休眠。 - -- Put light sleep related codes in internal RAM - 如果使能该选项,一些 light-sleep 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加 1.8kB。 - -- Put RTOS IDLE related codes in internal RAM - 如果使能该选项,一些 RTOS IDLE 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加 260B。 - -- RTC slow clock source - 该参数表表示 RTC 慢速时钟源。系统休眠时计时器模块的时钟被门控,此时使用 RTC Timer 进行计时,唤醒后使用 RTC Timer 的计数值对系统时间进行补偿。 - -.. list-table:: - :header-rows: 1 - :widths: 20 20 20 - - * - 时钟源 - - 精度 - - 频偏 - - * - Internal 150kHz OSC - - 约6.7us/cycle - - 大 - - * - External 32kHz XTAL - - 约30.5us/cycle - - 小 - -- Disable all GPIO when chip at sleep - 如果使能该选项,系统将在休眠过程中禁用所有 GPIO 管脚,消除 GPIO 漏电,降低功耗,但是休眠过程中 GPIO 无法进行信号输入和输出。 - -.. only:: esp32c3 or esp32s3 - - - Power down MAC and baseband - 如果使能该选项,系统将在休眠时关闭 Wi-Fi 和蓝牙的 MAC 和 baseband 来降低功耗,休眠电流约降低 100 uA, 但是为保存上下文信息,将额外消耗 5.3 K DRAM。 - - - Power down CPU - 如果使能该选项,系统将在休眠时将关闭 CPU 来降低功耗,对于 esp32c3,休眠电流减小 100 uA 左右,对于 esp32s3,休眠电流减小 650 uA 左右。但是为保存上下文信息,对于 esp32c3,将消耗 1.6 KB 的 DRAM 空间,对于 esp32s3,将消耗 8.58 KB 的 DRAM 空间。 - - - Power down I/D-cache tag memory - 如果使能该选项,系统将在休眠时关闭 I/D cache tag memory 来降低功耗, 但是为保存 tag memory 信息,将额外消耗最大约 9 KB DRAM,同时因为 tag memory 信息特殊性,如需打开该选项,建议多进行测试。 - - - Power down flash in Light-sleep - 如果使能该选项,系统将在 Light-sleep 休眠时关闭 flash,降低系统功耗,该选项的前提是系统没有使用 PSRAM。 - -唤醒源: - -- RTC Timer Wakeup -- GPIO Wakeup -- UART Wakeup -- Touchpad Wakeup -- External Wakeup (ext0) -- External Wakeup (ext1) -- ULP Coprocessor Wakeup - -.. note:: - 以上仅列出可配置唤醒源,详细介绍请参考:doc:`睡眠模式 <../api-reference/system/sleep_modes>`。 - -配置方法: - -- 1. 配置唤醒源 -- 2. 使能 CONFIG_PM_ENABLE -- 3. 使能 CONFIG_FREERTOS_USE_TICKLESS_IDLE -- 4. 配置 DFS 参数 -- 5. light_sleep_enable = true,具体如下: - - :: - - esp_pm_config_t pm_config = { - .max_freq_mhz = CONFIG_EXAMPLE_MAX_CPU_FREQ_MHZ, - .min_freq_mhz = CONFIG_EXAMPLE_MIN_CPU_FREQ_MHZ, - #if CONFIG_FREERTOS_USE_TICKLESS_IDLE - .light_sleep_enable = true - #endif - }; - ESP_ERROR_CHECK( esp_pm_configure(&pm_config) ); - -- 6. 配置介绍的其余相关参数 - -推荐配置: - -.. only:: esp32c3 or esp32s3 - - .. list-table:: - :header-rows: 1 - :widths: 30 15 - - * - 配置名称 - - 设置情况 - - * - CONFIG_PM_ENABLE - - ON - - * - CONFIG_FREERTOS_USE_TICKLESS_IDLE - - ON - - * - max_freq_mhz - - 160 - - * - min_freq_mhz - - 40 - - * - RTOS Tick rate (Hz) - - 1000 - - * - light_sleep_enable - - true - - * - Minimum step to enter sleep mode - - 3 - - * - Put light sleep codes in IRAM - - OFF - - * - Put RTOS IDLE codes in IRAM - - OFF - - * - RTC slow clock source - - Internal 150kHz OSC - - * - Disable all GPIO when chip at sleep - - ON - - * - Power down MAC and baseband - - ON - - * - Power down I/D-cache tag memory - - ON - - * - Power down CPU - - ON - - * - Power down flash in light sleep - - OFF - - .. note:: - 上表中不涉及的配置均是默认 - -.. only:: esp32 or esp32s2 - - .. list-table:: - :header-rows: 1 - :widths: 30 15 - - * - 配置名称 - - 设置情况 - - * - CONFIG_PM_ENABLE - - ON - - * - CONFIG_FREERTOS_USE_TICKLESS_IDLE - - ON - - * - max_freq_mhz - - 160 - - * - min_freq_mhz - - 40 - - * - RTOS Tick rate (Hz) - - 1000 - - * - light_sleep_enable - - true - - * - Minimum step to enter sleep mode - - 3 - - * - Put light sleep codes in IRAM - - OFF - - * - Put RTOS IDLE codes in IRAM - - OFF - - * - RTC slow clock source - - Internal 150kHz OSC - - * - Disable all GPIO when chip at sleep - - ON - - .. note:: - 上表中不涉及的配置均是默认 - -.. only:: esp32c2 - - .. list-table:: - :header-rows: 1 - :widths: 30 15 - - * - 配置名称 - - 设置情况 - - * - CONFIG_PM_ENABLE - - ON - - * - CONFIG_FREERTOS_USE_TICKLESS_IDLE - - ON - - * - max_freq_mhz - - 120 - - * - min_freq_mhz - - 40 - - * - RTOS Tick rate (Hz) - - 1000 - - * - light_sleep_enable - - true - - * - Minimum step to enter sleep mode - - 3 - - * - Put light sleep codes in IRAM - - OFF - - * - Put RTOS IDLE codes in IRAM - - OFF - - * - RTC slow clock source - - Internal 150kHz OSC - - * - Disable all GPIO when chip at sleep - - ON - - * - Power down MAC and baseband - - ON - - * - Power down I/D-cache tag memory - - ON - - * - Power down CPU - - ON - - * - Power down flash in light sleep - - OFF - - .. note:: - 上表中不涉及的配置均是默认 - -Deep-sleep 配置 -++++++++++++++++++ - -对 Deep-sleep 模式来说,除了唤醒源相关配置,其余配置意义已经不大。 - -Deep-sleep 有如下可配置选项: - -- RTC Timer wakeup -- EXT0/1 wakeup -- Touchpad wakeup -- ULP wakeup - -.. note:: - 以上仅列出可配置唤醒源,详细介绍请参考:doc:`睡眠模式 <../api-reference/system/sleep_modes>`。 - -配置步骤: - -- 配置唤醒源 -- 调用 API,具体如下:: - - /* Enter deep sleep */ - esp_deep_sleep_start(); - -用户可以通过下列配置选项,让一些特定模块在休眠时保持开启状态: - -- Power up External 40 MHz XTAL - 在一些特殊应用中,部分模块对休眠时的时钟精度及稳定度有很高要求(例如 BT)。这种情况下,可以考虑在休眠过程中打开 External 40 MHz XTAL。 - 打开和关闭代码如下:: - - ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_ON)); - ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_XTAL, ESP_PD_OPTION_OFF)); - -- Power up Internal 8 MHz OSC - 在一些特殊应用中,部分模块(例如 LEDC)将 Internal 8 MHz OSC 作为时钟源,并且希望在 Light-sleep 休眠过程中也可以正常使用。这种情况下,可以考虑在休眠过程中打开 Internal 8 MHz OSC。 - 打开和关闭代码如下:: - - ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC8M, ESP_PD_OPTION_ON)); - ESP_ERROR_CHECK(esp_sleep_pd_config(ESP_PD_DOMAIN_RTC8M, ESP_PD_OPTION_OFF)); - - -Wi-Fi 场景下低功耗模式介绍 -++++++++++++++++++++++++++++++++++ - -上文介绍了纯系统方向下的低功耗模式,但在实际应用中还需结合具体应用场景。本节将结合纯系统下的功耗模式来介绍在 Wi-Fi 场景下的低功耗模式。因为 Wi-Fi 场景的复杂性,本节会会首先介绍 Wi-Fi 省电的基本原理,然后再介绍具体的低功耗模式,同时本节主要针对 station 模式。 - -Wi-Fi 省电的基本原理 -+++++++++++++++++++++ - -首先,在 station 的工作过程中,为在接收发送过程中避免冲突,需要长时间监听信道,能耗较大的 RF 模块会一直处于工作中,浪费电量。为此,Wi-Fi 协议引入省电模式。 - -省电模式的基本原理是通过减少不必要的监听时间来降低耗能。AP 会缓存进入省电模式的 station 的包,同时周期发送包含 TIM 信息的 Beacon 帧,TIM 会指示 AP 缓存的单播包。TIM 中,DTIM 较为特殊,其会缓存广播包,并以 n 个(由 AP 决定)TIM 为周期发送。对 station 来说,TIM 非必听,而 DTIM 为必听。因此,station 可以选择只在每一个 DTIM 帧前醒来打开 Wi-Fi 相关模块(RF 模块),而不必时刻处于监听状态,这样就能有效降低功耗。 - -.. figure:: ../../_static/Low-power-DTIM4.png - :align: center - - DTIM4 省电模式示意图 - -其次,station 从打开到再次关闭 Wi-Fi 相关模块的时间也会影响功耗。除必要的数据传输处理时间外,主要有四项配置会影响时间长短: - - - 时钟准确性导致的 time offset,主要原因是时钟或多或少都会与理想的时间存在偏移,同时偏移的正负不定。 - - 处理 Beacon 漏听后的时间,如漏听后持续监听时间、允许最多丢失 Beacon 数目等,这段时间存不存在以及存在多久都不定,但是可以配置范围。 - - 为了确保能够接受突发数据包而添加的 active 时间,可由配置决定。 - - ILDE 时间是具体某些功耗模式进入条件要求。因此在满足通信需求的情况下,降低工作时间可以改善功耗表现。 - -.. figure:: ../../_static/Low-power-time.png - :align: center - - 芯片工作时间组成图 - -此外,在 station 没有处于 Wi-Fi 接收或发送状态时,影响功耗的因素变成了芯片的其他模块。不同的功耗模式会配置不同的时钟源,或者动态调整一些模块的工作频率如 CPU,同时还会关闭不同数量的功能模块,这将有效降低芯片的功耗。其实也就是纯系统相关的模式,用户可根据需求自己选择合适的配置。 - -如果以时间为横轴,电流大小为纵轴建立坐标轴,那么处在低功耗模式下芯片的理想工作电流图可以简化成下图: - -.. figure:: ../../_static/Low-power-WiFi-base-current.png - :align: center - - 理想情况下 Wi-Fi 场景低功耗模式电流图 - -其中 station 要进行 Wi-Fi 通信时,Wi-Fi 相关模块 (PHY) 开启,电流会显著上升,在工作完成前,电流会一直维持在一个较高的水平。工作完成后,芯片会关闭 Wi-Fi 相关模块,这时电流又会降低到一个较低水平。 - -可以看出影响功耗表现的主要有三点:interval、period 和 base current。 - - - Interval 是 station Wi-Fi 相关模块工作的间隔,既可以由低功耗模式自定义,也可根据 Wi-Fi 协议省电机制(3.1 第一点介绍),由 DTIM 周期决定。可以看出在同等情下,interval 越大,功耗表现会更好,但是响应会更慢,影响通信的及时性。 - - - Period 可以看作每次 station Wi-Fi 工作的时间,这段时间的长度也会影响功耗的表现。period 不是一个固定的时长(3.1 第二点介绍),在保证 Wi-Fi 通信正常的情况下,period 持续时间越短,功耗表现越好。但是减少 period 时间,必然会影响通信的可靠性。 - - - Base current 是 Wi-Fi 相关模块不工作时芯片的电流,影响其大小的因素很多,不同的功耗模式下休眠策略不同。所以,在满足功能的情况下,优化配置降低该电流大小可以提高功耗表现,但同时关闭其余模块会影响相关功能和芯片的唤醒时间。 - -知道了影响功耗的三点因素之后,要想降低功耗应从这三点入手,接下来介绍两种低功耗模式,Modem sleep、Auto Light-sleep。两种模式主要区别就是对三点因素的优化不同。 - - -Modem-sleep Mode -++++++++++++++++++ - -Modem-sleep 模式主要工作原理基于 DTIM 机制,周期性的醒来处理 Wi-Fi 相关工作,又在周期间隔之间进入休眠,关闭 PHY(RF 模块)来降低功耗。同时通过 DTIM 机制,station 可以与 AP 保持 Wi-Fi 连接,数据传输。 - -Modem-sleep 模式会在 Wi-Fi task 结束后自动进入休眠无需调用 API,休眠时仅会关闭 Wi-Fi 相关模块 (PHY),其余模块均处在正常上电状态。 - -Modem-sleep 模式默认会根据 DTIM 周期或 listen interval(下文介绍)醒来,相当于系统自动设置了一个 Wi-Fi 唤醒源,因此用户无需再配置唤醒源,同时系统主动发包时也可以唤醒。 - -Modem-sleep 是一个开关型的模式,调用 API 开启后一直自动运行,其工作流程十分简单,具体如下图。 - -.. figure:: ../../_static/Low-power-modem-process.png - :align: center - - Modem sleep 工作流程图 - - -根据上文的基本电流图,结合 Modem-sleep 的 工作原理,以 Min Modem(下文介绍)为例可得理想情况下电流变化图。 - -.. figure:: ../../_static/Low-power-modem-current.png - :align: center - - Min Modem-sleep 理想电流图 - -Modem-sleep 一般用于 CPU 持续处于工作状态并需要保持 Wi-Fi 连接的应用场景,例如,使用 {IDF_TARGET_NAME} 本地语音唤醒功能,CPU 需要持续采集和处理音频数据。 - -DFS+Modem sleep -++++++++++++++++++ - -Modem sleep 模式休眠状态中 CPU 仍处在工作状态,而 DFS 机制主要作用于 CPU 和 APB 工作频率来降低功耗,因此 DFS + Modem sleep 可以进一步优化功耗表现,又因为 Wi-Fi task 会申请 ESP_PM_CPU_FREQ_MAX 电源锁来保证 Wi-Fi 任务快速运行,所以 DFS + Modem sleep 产生调频只会发生在 base current 阶段,即 Wi-Fi task 结束后。 - -在 Wi-Fi 场景下,为了介绍的简化,让用户抓住主要的变化,DFS 可以进行一定的状态简化。具体来说,虽然 DFS 主要根据 CPU 和 APB 两把锁的最高需求来调频,但是 Wi-Fi 场景都需要 CPU 的频率最大化来工作,同时 Wi-Fi task 结束后,也可以理想化的认为,没有其余的工作要完成,这样就可以简单认为经过一段时间会释放两把锁进入空闲状态(IDLE 状态),也同时忽略这段时间锁的变化导致的电流变化,简化状态。 - -在 Wi-Fi 场景下,DFS 最终简化为如下流程: - -.. figure:: ../../_static/Low-power-DFS-process.png - :align: center - - Wi-Fi场景 DFS 简化流程图 - -在 Wi-Fi 工作的 active 状态与系统空闲的 IDLE 状态转换,Wi-Fi task 结束后,系统经过一段时间释放了所有锁进入 IDLE 状态,此时 DFS 机制降低频率到设定最低值,忽略了转换状态期间的调频动作,方便理解。 - -简化过后的 DFS+Modem sleep 模式理想状态下的电流大小如下图所示: - -.. figure:: ../../_static/Low-power-DFS-modem-current.png - :align: center - - DFS+Modem sleep 模式理想电流图 - - -Auto Light-sleep+Wi-Fi 场景 -+++++++++++++++++++++++++++++++ - -Auto Light-sleep 模式在 Wi-Fi 场景下是 ESP-IDF 电源管理机制、DTIM 机制和 light-sleep 的结合。开启电源管理是其前置条件,auto 体现在系统进入 IDLE 状态超过设定值后自动进入 light-sleep。同时 auto light sleep 模式同样遵循 DTIM 机制,会自动苏醒,可以与 AP 保持 Wi-Fi 连接。 - -Auto Light-sleep 模式在 Wi-Fi 场景下休眠机制与纯系统下一样,仍然依赖于电源管理机制,进入休眠的条件为系统处于 IDLE 状态的时间超过设定时间,并且系统会提前判断空闲时间是否满足条件,若满足直接休眠。该过程为自动进行。休眠时会自动关闭 RF、8 MHz 振荡器、40 MHz 高速晶振、PLL,门控数字内核时钟,暂停 CPU 工作。 - -Auto Light-sleep 模式在 Wi-Fi 场景下遵循 DTIM 机制,自动在 DTIM 帧到来前苏醒,相当于系统自动设置了一个 Wi-Fi 唤醒源,因此用户无需再配置唤醒源。同时系统主动发包时也可以唤醒。 - -Auto Light-sleep 模式在 Wi-Fi 场景下工作流程较为复杂,但全程都是自动进行,具体如下图所示。 - -.. figure:: ../../_static/Low-power-wifi-auto-light-process.png - :align: center - - Auto Light-sleep 工作流程图 - -Auto Light-sleep 模式在 Wi-Fi 场景下经常与 modem sleep 同时开启,这里给出 modem+auto light-sleep 模式的理想电流图,关键节点均在图上标出。 - -.. figure:: ../../_static/Low-power-wifi-auto-light-current.png - :align: center - - modem+auto light-sleep 模式理想电流图 - -Auto Light-sleep 模式在 Wi-Fi 场景下可用于需要保持 Wi-Fi 连接,可以实时响应 AP 发来数据的场景。并且在未接收到命令时,CPU 可以处于空闲状态。比如 Wi-Fi 开关的应用,大部分时间 CPU 都是空闲的,直到收到控制命令,CPU 才需要进行 GPIO 的操作。 - - -Deep-sleep+Wi-Fi 场景 -+++++++++++++++++++++++++++++++++ - -Deep-sleep 模式在 Wi-Fi 场景下与纯系统下基本相同,详情可以参考 `Deep-sleep`_ 这里不再介绍。 - - -如何配置 Wi-Fi 场景下低功耗模式 -+++++++++++++++++++++++++++++++++++++ - -介绍完 Wi-Fi 场景下低功耗模式后,本节将介绍公共配置选项、每种模式独有的配置选项,以及相应低功耗模式 API 的使用说明,同时给出相应模式推荐的配置(包含纯系统下的低功耗推荐配置)以及该配置的具体表现。 - -公共配置选项: - -- 功耗类: - - - Max Wi-Fi TX power (dBm) - 该参数表示最大 TX 功率,降低该参数会减小发包功耗,但会影响 Wi-Fi 性能,默认设置最大 20。 - -- IRAM 类: - - - Wi-Fi IRAM speed optimization - 如果使能该选项,一些 Wi-Fi 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加,默认开启。 - - - Wi-Fi RX IRAM speed optimization - 如果使能该选项,一些 Wi-Fi RX 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加,默认开启。 - - - Wi-Fi Sleep IRAM speed optimization - 如果使能该选项,一些 Wi-Fi sleep 功能将被移至 IRAM,减少代码运行时间,降低系统功耗,IRAM 使用量将增加,默认关闭。 - -- Wi-Fi 协议类: - - - Minimum active time - 该参数表示 Station 接收完一次数据后需要等待时间。当终端与 AP 进行通信时,AP 发送到终端的数据经常是突发形式的,为确保后续的突发数据能够正常接收到,需要等待一段时间。默认 50。 - - - Maximum keep alive time - 该参数表示周期性的发送 sleep null data 来通告 AP 维持连接的时间。在 DTIM 机制下,若 AP 长时间没有某个 station 的包,可能会断开连接,因此需要 station 需要周期发送 sleep null data 维持连接。默认 10。 - - - Send gratuitous ARP periodically - 如果使能该选项,Station 将周期性的发送 gratuitous ARP 请求更新 AP ARP 缓存表。如无该需求,可以关闭。 - - - Wi-Fi sleep optimize when beacon lost - 如果使能该选项,Station 在检测到已经错过或者丢失 beacon 时,会立即关闭 RF 进入低功耗状态。 - -Modem sleep 配置方法如下: - -- 可配置选项 - - - Min Modem - 该参数表示 station 按照 DTIM 周期工作,在每个 DTIM 前醒来接收 Beacon,这样不会漏掉广播信息,但是 DTIM 周期由 AP 决定,如果 DTIM 周期较短,省电效果会降低。 - - - Max Modem - 该参数表示 station 会自定义一个 listen interval,并以 listen interval 为周期醒来接受 Beacon。这样在 listen interval 较大时会省电,但是容易漏听 DTIM,错过广播数据。 - - -- 配置方法: - - - 调用 API,选择模式参数:: - - typedef enum { - WIFI_PS_NONE, - WIFI_PS_MIN_MODEM, - WIFI_PS_MAX_MODEM, - } wifi_ps_type_t; - esp_err_t esp_wifi_set_ps(wifi_ps_type_t type); - - 若选择 WIFI_PS_MAX_MODEM,还需配置 listen interval,示例如下:: - - #define LISTEN_INTERVAL 3 - wifi_config_t wifi_config = { - .sta = { - .ssid = "SSID", - .password = "Password", - .listen_interval = LISTEN_INTERVAL, - }, - }; - ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); - ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config)); - ESP_ERROR_CHECK(esp_wifi_start()); - -配置推荐: - -这里给出的配置推荐是 Min Modem sleep + DFS 开启的配置 - -.. list-table:: - :header-rows: 1 - :widths: 20 15 - - * - 配置名称 - - 设置情况 - - * - WIFI_PS_MIN_MODEM - - ON - - * - CONFIG_PM_ENABLE - - ON - - * - RTOS Tick rate (Hz) - - 1000 - - * - max_freq_mhz - - 160 - - * - min_freq_mhz - - 40 - - * - light_sleep_enable - - false - -配置表现: - -.. include:: sleep-current/{IDF_TARGET_PATH_NAME}_modem_sleep.inc - -Auto Light-sleep + Wi-Fi 场景配置: - -Auto Light-sleep 在 Wi-Fi 场景下的配置比纯系统下少了唤醒源的配置要求,其余几乎与纯系统下配置一致,因此可配置选项、配置步骤、推荐配置的详细介绍可以参考上文 `Light-sleep`_。同时 Wi-Fi 相关配置保持默认。 - -配置表现: - -该配置表现为 Auto Light-sleep 纯系统推荐配置 + 默认的 Wi-Fi 相关配置在 Wi-Fi 场景的表现。 - -.. include:: sleep-current/{IDF_TARGET_PATH_NAME}_light_sleep.inc - -Deep-sleep + Wi-Fi 场景配置: - -Deep-sleep 模式在 Wi-Fi 场景下的配置与纯系统下配置基本一致,因此可配置选项、配置步骤、推荐配置的详细介绍可以参考上文 `Deep-sleep`_。同时 Wi-Fi 相关配置保持默认。 - -配置表现: - -该配置表现为 Deep-sleep 纯系统推荐配置 + 默认的 Wi-Fi 相关配置在 Wi-Fi 场景的表现。 - -.. only:: esp32 - - 平均电流约 5.0 μA - -.. only:: esp32s2 - - 平均电流约 5.0 μA - -.. only:: esp32s3 - - 平均电流约 6.9 μA - -.. only:: esp32c3 - - 平均电流约 4.8 μA - -.. only:: esp32c2 - - 平均电流约 4.9 μA - - -Wi-Fi 场景如何选择低功耗模式 -++++++++++++++++++++++++++++++++++ - -为方便用户选择合适的低功耗模式,现给出 Wi-Fi 场景下低功耗模式总结表,用户可根据需求选择。 - -.. include:: sleep-current/{IDF_TARGET_PATH_NAME}_summary.inc - -.. note:: - - 上表中所有电流均为平均电流 - - 故障排除 --------------- diff --git a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst index 3177abff4a5e..bdbb9f4d7e89 100644 --- a/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst +++ b/docs/zh_CN/api-reference/peripherals/spi_flash/spi_flash_concurrency.rst @@ -42,11 +42,11 @@ SPI1 flash 并发约束 同时启用 :ref:`CONFIG_SPIRAM_FETCH_INSTRUCTIONS` 和 :ref:`CONFIG_SPIRAM_RODATA` 选项后,不会禁用 cache。 -.. only:: not CONFIG_FREERTOS_UNICORE +.. only:: SOC_HP_CPU_HAS_MULTIPLE_CORES 为避免意外读取 flash cache,一个 CPU 在启动 flash 写入或擦除操作时,另一个 CPU 将阻塞。在 flash 操作完成前,会禁用所有在 CPU 上非 IRAM 安全的中断。 -.. only:: CONFIG_FREERTOS_UNICORE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES 为避免意外读取 flash cache,在 flash 操作完成前,所有 CPU 上,会禁用所有在 CPU 上非 IRAM 安全的中断。 diff --git a/docs/zh_CN/api-reference/storage/nvs_encryption.rst b/docs/zh_CN/api-reference/storage/nvs_encryption.rst index 589dfb143ec5..a5fb70084513 100644 --- a/docs/zh_CN/api-reference/storage/nvs_encryption.rst +++ b/docs/zh_CN/api-reference/storage/nvs_encryption.rst @@ -20,7 +20,13 @@ NVS 加密:基于 flash 加密的方案 在这个方案中,NVS 加密所需的密钥存储在另一个分区中,该分区用 :doc:`../../security/flash-encryption` 进行保护。因此,使用该方案时,必须先启用 :doc:`../../security/flash-encryption`。 -启用 :doc:`../../security/flash-encryption` 时,默认启用 NVS 加密。这是因为 Wi-Fi 驱动程序会将凭证(如 SSID 和密码)储存在默认的 NVS 分区中。如已启用平台级加密,那么同时默认启用 NVS 加密有其必要性。 +.. only:: SOC_HMAC_SUPPORTED + + 启用 :doc:`../../security/flash-encryption` 时需同时启用 NVS 加密,因为 Wi-Fi 驱动程序会将凭据(如 SSID 和密码)储存在默认的 NVS 分区中。如已启用平台级加密,那么则需要同时启用 NVS 加密。 + +.. only:: not SOC_HMAC_SUPPORTED + + 启用 :doc:`../../security/flash-encryption` 时,默认启用 NVS 加密。这是因为 Wi-Fi 驱动程序会将凭据(如 SSID 和密码)储存在默认的 NVS 分区中。如已启用平台级加密,那么则需要同时默认启用 NVS 加密。 要用这一方案进行 NVS 加密,分区表中必须包含 :ref:`nvs_encr_key_partition`。在分区表选项 ( ``menuconfig`` > ``Partition Table`` ) 中,有两个包含 :ref:`nvs_encr_key_partition` 的分区表,可通过项目配置菜单 ( ``idf.py menuconfig``) 进行选择。要了解如何配置和使用 NVS 加密功能,请参考示例 :example:`security/flash_encryption`。 diff --git a/docs/zh_CN/api-reference/system/freertos.rst b/docs/zh_CN/api-reference/system/freertos.rst index a2d88e48373f..f6663e237585 100644 --- a/docs/zh_CN/api-reference/system/freertos.rst +++ b/docs/zh_CN/api-reference/system/freertos.rst @@ -51,7 +51,7 @@ ESP-IDF FreeRTOS - :ref:`CONFIG_FREERTOS_UNICORE`:仅在 CPU0 上运行 FreeRTOS。注意,这 **不等同于运行原生 FreeRTOS。** 另外,此选项还可能影响除 :component:`freertos` 外其他组件的行为。关于在单核上运行 FreeRTOS 的更多内容,请参考 :ref:`freertos-smp-single-core` (使用 ESP-IDF FreeRTOS 时)或参考 Amazon SMP FreeRTOS 的官方文档,还可以在 ESP-IDF 组件中搜索 ``CONFIG_FREERTOS_UNICORE``。 -.. only:: CONFIG_FREERTOS_UNICORE +.. only:: not SOC_HP_CPU_HAS_MULTIPLE_CORES .. note:: 由于 {IDF_TARGET_NAME} 是一个单核 SoC,所以总是会启用 :ref:`CONFIG_FREERTOS_UNICORE` 配置。 diff --git a/docs/zh_CN/api-reference/system/index.rst b/docs/zh_CN/api-reference/system/index.rst index 92045e52dde6..6d5330f9d631 100644 --- a/docs/zh_CN/api-reference/system/index.rst +++ b/docs/zh_CN/api-reference/system/index.rst @@ -25,7 +25,7 @@ heap_debug esp_timer internal-unstable - :not CONFIG_FREERTOS_UNICORE or esp32p4: ipc + :SOC_HP_CPU_HAS_MULTIPLE_CORES: ipc intr_alloc log misc_system_api diff --git a/docs/zh_CN/api-reference/system/intr_alloc.rst b/docs/zh_CN/api-reference/system/intr_alloc.rst index 36f183751f6f..1ac547249b98 100644 --- a/docs/zh_CN/api-reference/system/intr_alloc.rst +++ b/docs/zh_CN/api-reference/system/intr_alloc.rst @@ -143,7 +143,7 @@ CPU 中断在大多数 Espressif SoC 上都是有限的资源。因此,一个 .. list:: - :not CONFIG_ESP_SYSTEM_SINGLE_CORE_MODE: - 在多核 SoC 上,尝试通过固定在第二个核的任务来初始化某些外设驱动程序。中断通常分配在运行外设驱动程序初始化函数的同一个内核上,因此,通过在第二个内核上运行初始化函数,就可以使用更多的中断输入。 + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - 在多核 SoC 上,尝试通过固定在第二个核的任务来初始化某些外设驱动程序。中断通常分配在运行外设驱动程序初始化函数的同一个内核上,因此,通过在第二个内核上运行初始化函数,就可以使用更多的中断输入。 - 找到可接受更高延迟的中断,并用 ``ESP_INTR_FLAG_SHARED`` flag (或与 ``ESP_INTR_FLAG_LOWMED`` 进行 OR 运算)分配这些中断。对两个或更多外设使用此 flag 能让它们使用单个中断输入,从而为其他外设节约中断输入。参见 :ref:`intr-alloc-shared-interrupts`。 :not SOC_CPU_HAS_FLEXIBLE_INTC: - 一些外设驱动程序可能默认使用 ``ESP_INTR_FLAG_LEVEL1`` flag 来分配中断,因此默认情况下不会使用优先级为 2 或 3 的中断。如果 :cpp:func:`esp_intr_dump` 显示某些优先级为 2 或 3 的中断可用,尝试在初始化驱动程序时将中断分配 flag 改为 ``ESP_INTR_FLAG_LEVEL2`` 或 ``ESP_INTR_FLAG_LEVEL3``。 - 检查是否有些外设驱动程序不需要一直启用,并按需将其初始化或取消初始化。这样可以减少同时分配的中断数量。 diff --git a/docs/zh_CN/api-reference/system/pthread.rst b/docs/zh_CN/api-reference/system/pthread.rst index 8a5f5e6bad27..ad23de102efb 100644 --- a/docs/zh_CN/api-reference/system/pthread.rst +++ b/docs/zh_CN/api-reference/system/pthread.rst @@ -189,7 +189,7 @@ ESP-IDF 扩展 .. list:: - 如果调用 ``pthread_create()`` 时未指定默认堆栈大小,可设置新线程的默认堆栈大小(覆盖 :ref:`CONFIG_PTHREAD_TASK_STACK_SIZE_DEFAULT`)。 - 新线程的 RTOS 优先级(覆盖 :ref:`CONFIG_PTHREAD_TASK_PRIO_DEFAULT`)。 - :not CONFIG_FREERTOS_UNICORE: - 新线程的内核亲和性/内核固定(覆盖 :ref:`CONFIG_PTHREAD_TASK_CORE_DEFAULT`)。 + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - 新线程的内核亲和性/内核固定(覆盖 :ref:`CONFIG_PTHREAD_TASK_CORE_DEFAULT`)。 - 新线程的 FreeRTOS 任务名称(覆盖 :ref:`CONFIG_PTHREAD_TASK_NAME_DEFAULT`) 此配置的作用范围是调用线程或 FreeRTOS 任务,这意味着 :cpp:func:`esp_pthread_set_cfg` 可以在不同的线程或任务中独立调用。如果在当前配置中设置了 ``inherit_cfg`` 标志,那么当一个线程递归调用 ``pthread_create()`` 时,任何新创建的线程都会继承该线程的配置,否则新线程将采用默认配置。 diff --git a/docs/zh_CN/api-reference/system/wdts.rst b/docs/zh_CN/api-reference/system/wdts.rst index bb582b962b0c..df6f18c0cb9c 100644 --- a/docs/zh_CN/api-reference/system/wdts.rst +++ b/docs/zh_CN/api-reference/system/wdts.rst @@ -113,7 +113,7 @@ TWDT 的默认超时时间可以通过 :ref:`CONFIG_ESP_TASK_WDT_TIMEOUT_S` 配 - :ref:`CONFIG_ESP_TASK_WDT_EN` - 启用 TWDT 功能。如果禁用此选项, TWDT 即使运行时已初始化也无法使用。 - :ref:`CONFIG_ESP_TASK_WDT_INIT` - TWDT 在启动期间自动初始化。禁用此选项时,仍可以调用 :cpp:func:`esp_task_wdt_init` 在运行时初始化 TWDT。 - :ref:`CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0` - {IDF_TARGET_IDLE_TASK}在启动时订阅了 TWDT。如果此选项被禁用,仍可以调用 :cpp:func:`esp_task_wdt_init` 再次订阅。 - :not CONFIG_FREERTOS_UNICORE: - :ref:`CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1` - CPU1 空闲任务在启动时订阅了 TWDT。 + :SOC_HP_CPU_HAS_MULTIPLE_CORES: - :ref:`CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU1` - CPU1 空闲任务在启动时订阅了 TWDT。 .. note:: diff --git a/docs/zh_CN/migration-guides/release-5.x/5.2/index.rst b/docs/zh_CN/migration-guides/release-5.x/5.2/index.rst index 3e1477075ae5..239b91a7ca65 100644 --- a/docs/zh_CN/migration-guides/release-5.x/5.2/index.rst +++ b/docs/zh_CN/migration-guides/release-5.x/5.2/index.rst @@ -9,5 +9,6 @@ gcc peripherals protocols + storage system wifi diff --git a/docs/zh_CN/migration-guides/release-5.x/5.2/storage.rst b/docs/zh_CN/migration-guides/release-5.x/5.2/storage.rst new file mode 100644 index 000000000000..0173765c92e9 --- /dev/null +++ b/docs/zh_CN/migration-guides/release-5.x/5.2/storage.rst @@ -0,0 +1,11 @@ +存储 +==== + +:link_to_translation:`en:[English]` + +NVS 加密 +-------- + +- 在集成 HMAC 外设 (``SOC_HMAC_SUPPORTED``) 的 SoC 上,启用 :doc:`../../../security/flash-encryption` 时将不再自动启用 :doc:`../../../api-reference/storage/nvs_encryption`。 +- 因此需显式启用 NVS 加密,并按照需要选择基于 flash 加密或基于 HMAC 外设的方案。即使未启用 flash 加密,也可选择基于 HMAC 外设的方案 (:ref:`CONFIG_NVS_SEC_KEY_PROTECTION_SCHEME`)。 +- 启用 flash 加密后,未集成 HMAC 外设的 SoC 仍会自动启用 NVS 加密。 diff --git a/examples/openthread/.build-test-rules.yml b/examples/openthread/.build-test-rules.yml index 0ad7d9b1a8b5..51217281f9e6 100644 --- a/examples/openthread/.build-test-rules.yml +++ b/examples/openthread/.build-test-rules.yml @@ -21,10 +21,8 @@ - esp_hw_support examples/openthread/ot_br: - disable: - - if: IDF_TARGET in ["esp32h2", "esp32p4"] - temporary: true - reason: target(s) not supported yet + enable: + - if: SOC_WIFI_SUPPORTED == 1 disable_test: - if: IDF_TARGET in ["esp32", "esp32c3", "esp32c2", "esp32c6", "esp32s2"] temporary: true @@ -47,11 +45,8 @@ examples/openthread/ot_rcp: examples/openthread/ot_sleepy_device/deep_sleep: enable: - - if: IDF_TARGET in ["esp32h2"] - disable_test: - - if: IDF_TARGET == "esp32h2" - temporary: true - reason: Unsupport + - if: SOC_IEEE802154_SUPPORTED == 1 + <<: [*openthread_dependencies, *openthread_sleep_dependencies] examples/openthread/ot_sleepy_device/light_sleep: enable: diff --git a/examples/openthread/ot_sleepy_device/deep_sleep/README.md b/examples/openthread/ot_sleepy_device/deep_sleep/README.md index 5ee3f7d9b2d3..211570037aa8 100644 --- a/examples/openthread/ot_sleepy_device/deep_sleep/README.md +++ b/examples/openthread/ot_sleepy_device/deep_sleep/README.md @@ -1,5 +1,5 @@ -| Supported Targets | ESP32-H2 | -| ----------------- | -------- | +| Supported Targets | ESP32-C6 | ESP32-H2 | +| ----------------- | -------- | -------- | # OpenThread Sleepy Device Example diff --git a/examples/security/.build-test-rules.yml b/examples/security/.build-test-rules.yml index 084469e45fb1..e24e4496914c 100644 --- a/examples/security/.build-test-rules.yml +++ b/examples/security/.build-test-rules.yml @@ -2,7 +2,7 @@ examples/security/flash_encryption: disable_test: - - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2", "esp32c2"] + - if: IDF_TARGET in ["esp32s2", "esp32s3", "esp32c6", "esp32h2", "esp32c2", "esp32p4"] temporary: true reason: lack of runners diff --git a/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32p4 b/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32p4 new file mode 100644 index 000000000000..8df40e73f4dd --- /dev/null +++ b/examples/system/efuse/sdkconfig.ci.virt_sb_v2_and_fe.esp32p4 @@ -0,0 +1,18 @@ +# FLASH_ENCRYPTION & SECURE_BOOT_V2 with EFUSE_VIRTUAL_KEEP_IN_FLASH + +CONFIG_IDF_TARGET="esp32p4" + +CONFIG_PARTITION_TABLE_OFFSET=0xD000 +CONFIG_PARTITION_TABLE_CUSTOM=y +CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="test/partitions_efuse_emul.csv" + +CONFIG_SECURE_BOOT=y +CONFIG_SECURE_BOOT_V2_ENABLED=y +CONFIG_SECURE_BOOT_SIGNING_KEY="test/secure_boot_signing_key.pem" +CONFIG_SECURE_ENABLE_SECURE_ROM_DL_MODE=y + +CONFIG_SECURE_FLASH_ENC_ENABLED=y + +# IMPORTANT: ONLY VIRTUAL eFuse MODE! +CONFIG_EFUSE_VIRTUAL=y +CONFIG_EFUSE_VIRTUAL_KEEP_IN_FLASH=y diff --git a/examples/zigbee/.build-test-rules.yml b/examples/zigbee/.build-test-rules.yml index bd0f8f99ecea..d733dc017fd3 100644 --- a/examples/zigbee/.build-test-rules.yml +++ b/examples/zigbee/.build-test-rules.yml @@ -6,22 +6,19 @@ - examples/zigbee/light_sample/**/* examples/zigbee/esp_zigbee_gateway: - disable: - - if: IDF_TARGET in ["esp32c2", "esp32h2", "esp32p4"] - temporary: true - reason: target(s) not supported yet + enable: + - if: SOC_WIFI_SUPPORTED == 1 and IDF_TARGET != "esp32c2" + reason: not supported esp32c2 <<: *zigbee_dependencies examples/zigbee/esp_zigbee_rcp: enable: - - if: IDF_TARGET in ["esp32c6", "esp32h2"] - reason: should able to run on esp32h2 and esp32c6 + - if: SOC_IEEE802154_SUPPORTED == 1 <<: *zigbee_dependencies examples/zigbee/light_sample: enable: - - if: IDF_TARGET in ["esp32c6", "esp32h2"] - reason: should able to run on esp32h2 and esp32c6 + - if: SOC_IEEE802154_SUPPORTED == 1 disable_test: - if: IDF_TARGET == "esp32c6" temporary: true diff --git a/tools/ci/check_public_headers_exceptions.txt b/tools/ci/check_public_headers_exceptions.txt index 7a33314af82a..c31900536994 100644 --- a/tools/ci/check_public_headers_exceptions.txt +++ b/tools/ci/check_public_headers_exceptions.txt @@ -100,6 +100,7 @@ components/esp_rom/include/esp32c2/rom/rtc.h components/esp_rom/include/esp32c6/rom/rtc.h components/esp_rom/include/esp32h2/rom/rtc.h components/esp_rom/include/esp32p4/rom/rtc.h +components/esp_rom/include/esp32c5/rom/rtc.h components/esp_rom/include/esp32/rom/sha.h components/esp_rom/include/esp32/rom/secure_boot.h components/esp_rom/include/esp32c3/rom/spi_flash.h diff --git a/tools/ci/exclude_check_tools_files.txt b/tools/ci/exclude_check_tools_files.txt index 01f0f5a95c77..c801f3f43c1a 100644 --- a/tools/ci/exclude_check_tools_files.txt +++ b/tools/ci/exclude_check_tools_files.txt @@ -5,7 +5,6 @@ tools/ci/check_*.txt tools/ci/check_*.sh tools/ci/check_copyright_config.yaml tools/ci/get_all_test_results.py -tools/ci/idf_unity_tester.py tools/gdb_panic_server.py tools/check_term.py tools/check_python_dependencies.py diff --git a/tools/ci/idf_unity_tester.py b/tools/ci/idf_unity_tester.py deleted file mode 100644 index fdd781268bf2..000000000000 --- a/tools/ci/idf_unity_tester.py +++ /dev/null @@ -1,397 +0,0 @@ -# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Apache-2.0 -import logging -import os -import time -from multiprocessing import Manager, Process, Semaphore -from multiprocessing.managers import SyncManager -from typing import List, Union - -from pexpect.exceptions import TIMEOUT -from pytest_embedded import Dut, unity, utils -from pytest_embedded_idf.dut import UnittestMenuCase - - -class BaseTester: - """ - The base class that providing shared methods - - Attributes: - dut (Dut): Object of the Device under test - test_menu (List[UnittestMenuCase]): The list of the cases - retry_times (int): The retry times when failed to start a case - args (Any): Not used - """ - - # The patterns that indicate the runner is ready come from 'unity_runner.c' - ready_pattern_list = ['Press ENTER to see the list of tests', - 'Enter test for running', - 'Enter next test, or \'enter\' to see menu'] - - def __init__(self, dut: Union[Dut, List[Dut]], **kwargs) -> None: # type: ignore - self.retry_times = 30 - if isinstance(dut, List): - for item in dut: - if isinstance(item, Dut): - self.dut = item - break - else: - self.dut = dut - for k, v in kwargs.items(): - setattr(self, k, v) - if 'test_menu' not in kwargs: - self.get_test_menu() - - def get_test_menu(self) -> None: - """ - Get the test menu of this test app - - Notes: - It will do a hard reset after getting the test menu to ensure - the patterns that indicate the case is ready not taken by the parser. - Please use this function to get the test menu while using this script - """ - self.dut.write('') - self.test_menu = self.dut.parse_test_menu() - self.dut.serial.hard_reset() - - -class NormalCaseTester(BaseTester): - """ - Tester of normal type case - - Attributes: - dut (Dut): Object of the Device under test - test_menu (List[UnittestMenuCase]): The list of the cases - retry_times (int): The retry times when failed to start a case - args (Any): Not used - """ - - def run_all_normal_cases(self, reset: bool = False, timeout: int = 90) -> None: - """ - Run all normal cases - - Args: - reset: whether do a hardware reset before running the case - timeout: timeout in second - """ - for case in self.test_menu: - self.run_normal_case(case, reset, timeout=timeout) - - def run_normal_case(self, case: UnittestMenuCase, reset: bool = False, timeout: int = 90) -> None: - """ - Run a specific normal case - - Notes: - Will skip if the case type is not normal - - Args: - case: the specific case that parsed in test menu - reset: whether do a hardware reset before running the case - timeout: timeout in second - """ - if case.type == 'normal': - if reset: - self.dut.serial.hard_reset() - self.dut.expect(self.ready_pattern_list, timeout=timeout) - # Retry if write not success - for retry in range(self.retry_times): - self.dut.write(str(case.index)) - try: - self.dut.expect_exact('Running {}...'.format(case.name), timeout=1) - break - except TIMEOUT as e: - if retry >= self.retry_times - 1: - raise e - self.dut.expect_unity_test_output(timeout=timeout) - - -class MultiStageCaseTester(BaseTester): - """ - Tester of multiple stage type case - - Attributes: - dut (Dut): Object of the Device under test - test_menu (List[UnittestMenuCase]): The list of the cases - retry_times (int): The retry times when failed to start a case - args (Any): Not used - """ - - def run_all_multi_stage_cases(self, reset: bool = False, timeout: int = 90) -> None: - """ - Run all multi_stage cases - - Args: - reset: whether do a hardware reset before running the case - timeout: timeout in second - """ - for case in self.test_menu: - self.run_multi_stage_case(case, reset, timeout=timeout) - - def run_multi_stage_case(self, case: UnittestMenuCase, reset: bool = False, timeout: int = 90) -> None: - """ - Run a specific multi_stage case - - Notes: - Will skip if the case type is not multi_stage - - Args: - case: the specific case that parsed in test menu - reset: whether do a hardware reset before running the case - timeout: timeout in second - """ - if case.type == 'multi_stage': - if reset: - self.dut.serial.hard_reset() - for sub_case in case.subcases: - self.dut.expect(self.ready_pattern_list, timeout=timeout) - # Retry if write not success - for retry in range(self.retry_times): - self.dut.write(str(case.index)) - try: - self.dut.expect_exact('Running {}...'.format(case.name), timeout=1) - break - except TIMEOUT as e: - if retry >= self.retry_times - 1: - raise e - self.dut.write(str(sub_case['index'])) - - self.dut.expect_unity_test_output(timeout=timeout) - - -class MultiDevResource: - """ - Resources of multi_dev dut - - Attributes: - dut (Dut): Object of the Device under test - sem (Semaphore): Semaphore of monitoring whether the case finished - recv_sig (List[str]): The list of received signals from other dut - thread (Process): The thread of monitoring the signals - """ - - def __init__(self, dut: Dut, manager: SyncManager) -> None: - self.dut = dut - self.sem = Semaphore() - self.recv_sig = manager.list() # type: list[str] - self.process: Process = None # type: ignore - - -class MultiDevCaseTester(BaseTester): - """ - Tester of multi_device case - - Attributes: - group (List[MultiDevResource]): The group of the devices' resources - dut (Dut): The first dut, mainly used to get the test menu only - test_menu (List[UnittestMenuCase]): The list of the cases - retry_times (int): The retry times when failed to start a case - """ - - # The signal pattens come from 'test_utils.c' - SEND_SIGNAL_PREFIX = 'Send signal: ' - WAIT_SIGNAL_PREFIX = 'Waiting for signal: ' - UNITY_SEND_SIGNAL_REGEX = SEND_SIGNAL_PREFIX + r'\[(.*?)\]!' - UNITY_WAIT_SIGNAL_REGEX = WAIT_SIGNAL_PREFIX + r'\[(.*?)\]!' - - def __init__(self, dut: Union[Dut, List[Dut]], **kwargs) -> None: # type: ignore - """ - Create the object for every dut and put them into the group - """ - super().__init__(dut, **kwargs) - self._manager = Manager() - self.group: List[MultiDevResource] = [] - if isinstance(dut, List): - for item in dut: - if isinstance(item, Dut): - dev_res = MultiDevResource(item, self._manager) - self.group.append(dev_res) - else: - dev_res = MultiDevResource(dut, self._manager) - self.group.append(dev_res) - - def _wait_multi_dev_case_finish(self, timeout: int = 60) -> None: - """ - Wait until all the sub-cases of this multi_device case finished - """ - for d in self.group: - if d.sem.acquire(timeout=timeout): - d.sem.release() - else: - raise TimeoutError('Wait case to finish timeout') - - def _start_sub_case_process(self, dev_res: MultiDevResource, case: UnittestMenuCase, sub_case_index: int, timeout: int = 60) -> None: - """ - Start the thread monitoring on the corresponding dut of the sub-case - """ - # Allocate the kwargs that pass to '_run' - _kwargs = {} - _kwargs['dut'] = dev_res.dut - _kwargs['dev_res'] = dev_res - _kwargs['case'] = case - _kwargs['sub_case_index'] = sub_case_index - _kwargs['timeout'] = timeout - - # Create the thread of the sub-case - dev_res.process = Process(target=self._run, kwargs=_kwargs, daemon=True) - dev_res.process.start() - # Process starts, acquire the semaphore to block '_wait_multi_dev_case_finish' - dev_res.sem.acquire() - - def _run(self, **kwargs) -> None: # type: ignore - """ - The thread target function - Will run for each case on each dut - - Call the wrapped function to trigger the case - Then keep listening on the dut for the signal - - - If the dut send a signal, it will be put into others' recv_sig - - If the dut waits for a signal, it block and keep polling for the recv_sig until get the signal it requires - - If the dut finished running the case, it will quite the loop and terminate the thread - """ - signal_pattern_list = [ - self.UNITY_SEND_SIGNAL_REGEX, # The dut send a signal - self.UNITY_WAIT_SIGNAL_REGEX, # The dut is blocked and waiting for a signal - unity.UNITY_SUMMARY_LINE_REGEX, # Means the case finished - ] - dut = kwargs['dut'] - dev_res = kwargs['dev_res'] - case = kwargs['case'] - sub_case_index = kwargs['sub_case_index'] - timeout = kwargs['timeout'] - # Start the case - dut.expect(self.ready_pattern_list) - # Retry at most 30 times if not write successfully - for retry in range(self.retry_times): - dut.write(str(case.index)) - try: - dut.expect_exact('Running {}...'.format(case.name), timeout=10) - break - except TIMEOUT as e: - if retry >= self.retry_times - 1: - dev_res.sem.release() - raise e - - dut.write(str(sub_case_index)) - - # Wait for the specific patterns, only exist when the sub-case finished - while True: - pat = dut.expect(signal_pattern_list, timeout=timeout) - if pat is not None: - match_str = pat.group().decode('utf-8') - - # Send a signal - if match_str.find(self.SEND_SIGNAL_PREFIX) >= 0: - send_sig = pat.group(1).decode('utf-8') - for d in self.group: - d.recv_sig.append(send_sig) - - # Waiting for a signal - elif match_str.find(self.WAIT_SIGNAL_PREFIX) >= 0: - wait_sig = pat.group(1).decode('utf-8') - while True: - if wait_sig in dev_res.recv_sig: - dev_res.recv_sig.remove(wait_sig) - dut.write('') - break - # Keep waiting the signal - else: - time.sleep(0.1) - - # Case finished - elif match_str.find('Tests') >= 0: - log = utils.remove_asci_color_code(dut.pexpect_proc.before) - dut.testsuite.add_unity_test_cases(log) - break - - # The case finished, release the semaphore to unblock the '_wait_multi_dev_case_finish' - # - # Manually to create the real test case junit report - # The child process attributes won't be reflected to the parent one. - junit_report = os.path.splitext(dut.logfile)[0] + f'_{case.index}_{sub_case_index}.xml' - dut.testsuite.dump(junit_report) - logging.info(f'Created unity output junit report: {junit_report}') - - dev_res.sem.release() - - def run_all_multi_dev_cases(self, reset: bool = False, timeout: int = 60) -> None: - """ - Run only multi_device cases - - Args: - reset: whether do a hardware reset before running the case - timeout: timeout in second - """ - for case in self.test_menu: - # Run multi_device case on every device - self.run_multi_dev_case(case, reset, timeout) - - def run_multi_dev_case(self, case: UnittestMenuCase, reset: bool = False, timeout: int = 60) -> None: - """ - Run a specific multi_device case - - Notes: - Will skip if the case type is not multi_device - - Args: - case: the specific case that parsed in test menu - reset: whether do a hardware reset before running the case - timeout: timeout in second - """ - if case.type == 'multi_device' and len(self.group) > 1: - if reset: - for dev_res in self.group: - dev_res.dut.serial.hard_reset() - # delay a few seconds to make sure the duts are ready. - time.sleep(5) - for sub_case in case.subcases: - if isinstance(sub_case['index'], str): - index = int(sub_case['index'], 10) - else: - index = sub_case['index'] - self._start_sub_case_process(dev_res=self.group[index - 1], case=case, - sub_case_index=index, timeout=timeout) - # Waiting all the devices to finish their test cases - self._wait_multi_dev_case_finish(timeout=timeout) - - -class CaseTester(NormalCaseTester, MultiStageCaseTester, MultiDevCaseTester): - """ - The Generic tester of all the types - - Attributes: - group (List[MultiDevResource]): The group of the devices' resources - dut (Dut): The first dut if there is more than one - test_menu (List[UnittestMenuCase]): The list of the cases - """ - - def run_all_cases(self, reset: bool = False, timeout: int = 60) -> None: - """ - Run all cases - - Args: - reset: whether do a hardware reset before running the case - timeout: timeout in second - """ - for case in self.test_menu: - self.run_case(case, reset, timeout=timeout) - - def run_case(self, case: UnittestMenuCase, reset: bool = False, timeout: int = 60) -> None: - """ - Run a specific case - - Args: - case: the specific case that parsed in test menu - reset: whether do a hardware reset before running the case - timeout: timeout in second, the case's timeout attribute has a higher priority than this param. - """ - _timeout = int(case.attributes.get('timeout', timeout)) - if case.type == 'normal': - self.run_normal_case(case, reset, timeout=_timeout) - elif case.type == 'multi_stage': - self.run_multi_stage_case(case, reset, timeout=_timeout) - elif case.type == 'multi_device': - # here we always do a hard reset between test cases - # since the buffer can't be kept between test cases (which run in different processes) - self.run_multi_dev_case(case, reset=True, timeout=_timeout) diff --git a/tools/cmake/project.cmake b/tools/cmake/project.cmake index 2ebb31ff35c5..e92e5855d5a1 100644 --- a/tools/cmake/project.cmake +++ b/tools/cmake/project.cmake @@ -64,29 +64,87 @@ endif() idf_build_set_property(__COMPONENT_MANAGER_INTERFACE_VERSION 2) # -# Get the project version from either a version file or the Git revision. This is passed -# to the idf_build_process call. Dependencies are also set here for when the version file -# changes (if it is used). +# Parse and store the VERSION argument provided to the project() command. # -function(__project_get_revision var) - set(_project_path "${CMAKE_CURRENT_LIST_DIR}") - if(NOT DEFINED PROJECT_VER) - if(EXISTS "${_project_path}/version.txt") - file(STRINGS "${_project_path}/version.txt" PROJECT_VER) - set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${_project_path}/version.txt") - else() - git_describe(PROJECT_VER_GIT "${_project_path}") - if(PROJECT_VER_GIT) - set(PROJECT_VER ${PROJECT_VER_GIT}) - else() - message(STATUS "Could not use 'git describe' to determine PROJECT_VER.") - set(PROJECT_VER 1) - endif() +function(__parse_and_store_version_arg) + # The project_name is the fisrt argument that was passed to the project() command + set(project_name ${ARGV0}) + + # Parse other arguments passed to the project() call + set(options) + set(oneValueArgs VERSION) + set(multiValueArgs) + cmake_parse_arguments(PROJECT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) + + # If the VERSION keyword exists but no version string is provided then raise a warning + if((NOT PROJECT_VERSION + OR PROJECT_VERSION STREQUAL "NOTFOUND") + AND NOT PROJECT_VERSION STREQUAL "0") + message(STATUS "VERSION keyword not followed by a value or was followed by a value that expanded to nothing.") + # Default the version to 1 in this case + set(project_ver 1) + else() + # Check if version is valid. cmake allows the version to be in the format [.[.[.]]]] + string(REGEX MATCH "^([0-9]+(\\.[0-9]+(\\.[0-9]+(\\.[0-9]+)?)?)?)?$" version_valid ${PROJECT_VERSION}) + if(NOT version_valid AND NOT PROJECT_VERSION STREQUAL "0") + message(SEND_ERROR "Version \"${PROJECT_VERSION}\" format invalid.") + return() + endif() + + # Split the version string into major, minor, patch, and tweak components + string(REPLACE "." ";" version_components ${PROJECT_VERSION}) + list(GET version_components 0 PROJECT_VERSION_MAJOR) + list(LENGTH version_components version_length) + if(version_length GREATER 1) + list(GET version_components 1 PROJECT_VERSION_MINOR) + endif() + if(version_length GREATER 2) + list(GET version_components 2 PROJECT_VERSION_PATCH) + endif() + if(version_length GREATER 3) + list(GET version_components 3 PROJECT_VERSION_TWEAK) + endif() + + # Store the version string in cmake specified variables to access the version + set(PROJECT_VERSION ${PROJECT_VERSION} PARENT_SCOPE) + set(PROJECT_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} PARENT_SCOPE) + if(PROJECT_VERSION_MINOR) + set(PROJECT_VERSION_MINOR ${PROJECT_VERSION_MINOR} PARENT_SCOPE) + endif() + if(PROJECT_VERSION_PATCH) + set(PROJECT_VERSION_PATCH ${PROJECT_VERSION_PATCH} PARENT_SCOPE) + endif() + if(PROJECT_VERSION_TWEAK) + set(PROJECT_VERSION_TWEAK ${PROJECT_VERSION_TWEAK} PARENT_SCOPE) + endif() + + # Also store the version string in the specified variables for the project_name + set(${project_name}_VERSION ${PROJECT_VERSION} PARENT_SCOPE) + set(${project_name}_VERSION_MAJOR ${PROJECT_VERSION_MAJOR} PARENT_SCOPE) + if(PROJECT_VERSION_MINOR) + set(${project_name}_VERSION_MINOR ${PROJECT_VERSION_MINOR} PARENT_SCOPE) + endif() + if(PROJECT_VERSION_PATCH) + set(${project_name}_VERSION_PATCH ${PROJECT_VERSION_PATCH} PARENT_SCOPE) + endif() + if(PROJECT_VERSION_TWEAK) + set(${project_name}_VERSION_TWEAK ${PROJECT_VERSION_TWEAK} PARENT_SCOPE) endif() endif() - set(${var} "${PROJECT_VER}" PARENT_SCOPE) endfunction() +# +# Get the project version from a version file. This is passed to the idf_build_process call. +# Dependencies are also set here for when the version file changes (if it is used). +# +function(__project_get_revision_from_version_file var) + set(_project_path "${CMAKE_CURRENT_LIST_DIR}") + if(EXISTS "${_project_path}/version.txt") + file(STRINGS "${_project_path}/version.txt" PROJECT_VER) + set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${_project_path}/version.txt") + endif() + set(${var} "${PROJECT_VER}" PARENT_SCOPE) +endfunction() # paths_with_spaces_to_list # @@ -598,7 +656,54 @@ macro(project project_name) set(build_dir ${CMAKE_BINARY_DIR}) endif() - __project_get_revision(project_ver) + # If PROJECT_VER has not been set yet, look for the version from various sources in the following order of priority: + # + # 1. version.txt file in the top level project directory + # 2. From the VERSION argument if passed to the project() macro + # 3. git describe if the project is in a git repository + # 4. Default to 1 if none of the above conditions are true + # + # PS: PROJECT_VER will get overidden later if CONFIG_APP_PROJECT_VER_FROM_CONFIG is defined. + # See components/esp_app_format/CMakeLists.txt. + if(NOT DEFINED PROJECT_VER) + # Read the version information from the version.txt file if it is present + __project_get_revision_from_version_file(project_ver) + + # If the version is not set from the version.txt file, check other sources for the version information + if(NOT project_ver) + # Check if version information was passed to project() via the VERSION argument + set(version_keyword_present FALSE) + foreach(arg ${ARGN}) + if(${arg} STREQUAL "VERSION") + set(version_keyword_present TRUE) + endif() + endforeach() + + if(version_keyword_present) + __parse_and_store_version_arg(${project_name} ${ARGN}) + set(project_ver ${PROJECT_VERSION}) + + # If the project() command is called from the top-level CMakeLists.txt, + # store the version in CMAKE_PROJECT_VERSION. + if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(CMAKE_PROJECT_VERSION ${PROJECT_VERSION}) + endif() + else() + # Use git describe to determine the version + git_describe(PROJECT_VER_GIT "${CMAKE_CURRENT_LIST_DIR}") + if(PROJECT_VER_GIT) + set(project_ver ${PROJECT_VER_GIT}) + else() + message(STATUS "Could not use 'git describe' to determine PROJECT_VER.") + # None of sources contain the version information. Default PROJECT_VER to 1. + set(project_ver 1) + endif() #if(PROJECT_VER_GIT) + endif() #if(version_keyword_present) + endif() #if(NOT project_ver) + else() + # PROJECT_VER has been set before calling project(). Copy it into project_ver for idf_build_process() later. + set(project_ver ${PROJECT_VER}) + endif() #if(NOT DEFINED PROJECT_VER) message(STATUS "Building ESP-IDF components for target ${IDF_TARGET}") diff --git a/tools/docker/Dockerfile b/tools/docker/Dockerfile index f81ede106753..e9f4516882c6 100644 --- a/tools/docker/Dockerfile +++ b/tools/docker/Dockerfile @@ -22,6 +22,7 @@ RUN : \ libglib2.0-0 \ libncurses-dev \ libpixman-1-0 \ + libsdl2-2.0-0 \ libslirp0 \ libusb-1.0-0-dev \ make \ @@ -44,12 +45,14 @@ RUN : \ # IDF_CLONE_BRANCH_OR_TAG=release/vX.Y # IDF_CHECKOUT_REF=. # Use IDF_CLONE_SHALLOW=1 to peform shallow clone (i.e. --depth=1 --shallow-submodules) +# Use IDF_CLONE_SHALLOW_DEPTH=X to define the depth if IDF_CLONE_SHALLOW is used (i.e. --depth=X) # Use IDF_INSTALL_TARGETS to install tools only for selected chip targets (CSV) ARG IDF_CLONE_URL=https://github.com/espressif/esp-idf.git ARG IDF_CLONE_BRANCH_OR_TAG=master ARG IDF_CHECKOUT_REF= ARG IDF_CLONE_SHALLOW= +ARG IDF_CLONE_SHALLOW_DEPTH=1 ARG IDF_INSTALL_TARGETS=all ENV IDF_PATH=/opt/esp/idf @@ -65,14 +68,14 @@ RUN if [ "$IDF_INSTALL_TARGETS" = "all" ]; then \ RUN echo IDF_CHECKOUT_REF=$IDF_CHECKOUT_REF IDF_CLONE_BRANCH_OR_TAG=$IDF_CLONE_BRANCH_OR_TAG && \ git clone --recursive \ - ${IDF_CLONE_SHALLOW:+--depth=1 --shallow-submodules} \ + ${IDF_CLONE_SHALLOW:+--depth=${IDF_CLONE_SHALLOW_DEPTH} --shallow-submodules} \ ${IDF_CLONE_BRANCH_OR_TAG:+-b $IDF_CLONE_BRANCH_OR_TAG} \ $IDF_CLONE_URL $IDF_PATH && \ git config --system --add safe.directory $IDF_PATH && \ if [ -n "$IDF_CHECKOUT_REF" ]; then \ cd $IDF_PATH && \ if [ -n "$IDF_CLONE_SHALLOW" ]; then \ - git fetch origin --depth=1 --recurse-submodules ${IDF_CHECKOUT_REF}; \ + git fetch origin --depth=${IDF_CLONE_SHALLOW_DEPTH} --recurse-submodules ${IDF_CHECKOUT_REF}; \ fi && \ git checkout $IDF_CHECKOUT_REF && \ git submodule update --init --recursive; \ diff --git a/tools/idf_py_actions/core_ext.py b/tools/idf_py_actions/core_ext.py index 3466b0e9534d..2b1fc96daaf8 100644 --- a/tools/idf_py_actions/core_ext.py +++ b/tools/idf_py_actions/core_ext.py @@ -19,7 +19,7 @@ from idf_py_actions.errors import FatalError from idf_py_actions.global_options import global_options from idf_py_actions.tools import (PropertyDict, TargetChoice, ensure_build_directory, generate_hints, get_target, - idf_version, merge_action_lists, run_target, yellow_print) + idf_version, merge_action_lists, print_warning, run_target, yellow_print) def action_extensions(base_actions: Dict, project_path: str) -> Any: @@ -33,7 +33,8 @@ def build_target(target_name: str, ctx: Context, args: PropertyDict) -> None: ensure_build_directory(args, ctx.info_name) run_target(target_name, args, force_progression=GENERATORS[args.generator].get('force_progression', False)) - def size_target(target_name: str, ctx: Context, args: PropertyDict, output_format: str, output_file: str) -> None: + def size_target(target_name: str, ctx: Context, args: PropertyDict, output_format: str, + output_file: str, legacy: bool) -> None: """ Builds the app and then executes a size-related target passed in 'target_name'. `tool_error_handler` handler is used to suppress errors during the build, @@ -44,6 +45,27 @@ def tool_error_handler(e: int, stdout: str, stderr: str) -> None: for hint in generate_hints(stdout, stderr): yellow_print(hint) + if not legacy and output_format != 'json': + try: + import esp_idf_size.ng # noqa: F401 + except ImportError: + print_warning('WARNING: refactored esp-idf-size not installed, using legacy mode') + legacy = True + else: + # Legacy mode is used only when explicitly requested with --legacy option + # or when "--format json" option is specified. Here we enable the + # esp-idf-size refactored version with ESP_IDF_SIZE_NG env. variable. + os.environ['ESP_IDF_SIZE_NG'] = '1' + # ESP_IDF_SIZE_FORCE_TERMINAL is set to force terminal control codes even + # if stdout is not attached to terminal. This is set to pass color codes + # from esp-idf-size to idf.py. + os.environ['ESP_IDF_SIZE_FORCE_TERMINAL'] = '1' + + if legacy and output_format in ['json2', 'raw', 'tree']: + # These formats are supported in new version only. + # We would get error from the esp-idf-size anyway, so print error early. + raise FatalError(f'Legacy esp-idf-size does not support {output_format} format') + os.environ['SIZE_OUTPUT_FORMAT'] = output_format if output_file: os.environ['SIZE_OUTPUT_FILE'] = os.path.abspath(output_file) @@ -354,9 +376,13 @@ def help_and_exit(action: str, ctx: Context, param: List, json_option: bool, add # if the user explicitly specified the format or not. If the format is not specified, then # the legacy OUTPUT_JSON CMake variable will be taken into account. size_options = [{'names': ['--format', 'output_format'], - 'type': click.Choice(['default', 'text', 'csv', 'json']), - 'help': 'Specify output format: text (same as "default"), csv or json.', + 'type': click.Choice(['default', 'text', 'csv', 'json', 'json2', 'tree', 'raw']), + 'help': 'Specify output format: text (same as "default"), csv, json, json2, tree or raw.', 'default': 'default'}, + {'names': ['--legacy', '-l'], + 'is_flag': True, + 'default': os.environ.get('ESP_IDF_SIZE_LEGACY', '0') == '1', + 'help': 'Use legacy esp-idf-size version'}, {'names': ['--output-file', 'output_file'], 'help': 'Print output to the specified file instead of to the standard output'}] diff --git a/tools/idf_size.py b/tools/idf_size.py index 322d527f6f00..342340002ca1 100755 --- a/tools/idf_size.py +++ b/tools/idf_size.py @@ -5,8 +5,30 @@ # SPDX-License-Identifier: Apache-2.0 # +import argparse +import os import subprocess import sys if __name__ == '__main__': - sys.exit(subprocess.run([sys.executable, '-m', 'esp_idf_size'] + sys.argv[1:]).returncode) + parser = argparse.ArgumentParser() + parser.add_argument('--format') + parser.add_argument('-l', '--legacy', action='store_true', default=os.environ.get('ESP_IDF_SIZE_LEGACY', '0') == '1') + args, rest = parser.parse_known_args() + + if not args.legacy and args.format != 'json': + try: + import esp_idf_size.ng # noqa: F401 + except ImportError: + print('warning: refactored esp-idf-size not installed, using legacy mode', file=sys.stderr) + args.legacy = True + else: + os.environ['ESP_IDF_SIZE_NG'] = '1' + + if args.legacy and args.format in ['json2', 'raw', 'tree']: + sys.exit(f'Legacy esp-idf-size does not support {args.format} format') + + if args.format is not None: + rest = ['--format', args.format] + rest + + sys.exit(subprocess.run([sys.executable, '-m', 'esp_idf_size'] + rest).returncode) diff --git a/tools/mocks/esp_wifi/global_symbols_mock.c b/tools/mocks/esp_wifi/global_symbols_mock.c index aa515dfec51f..3a00a4331777 100644 --- a/tools/mocks/esp_wifi/global_symbols_mock.c +++ b/tools/mocks/esp_wifi/global_symbols_mock.c @@ -13,5 +13,3 @@ const wpa_crypto_funcs_t g_wifi_default_wpa_crypto_funcs = { }; wifi_osi_funcs_t g_wifi_osi_funcs = { }; - -uint64_t g_wifi_feature_caps = 0; diff --git a/tools/test_apps/system/build_test/sdkconfig.ci.custom_mac b/tools/test_apps/system/build_test/sdkconfig.ci.custom_mac new file mode 100644 index 000000000000..a10cda2c780d --- /dev/null +++ b/tools/test_apps/system/build_test/sdkconfig.ci.custom_mac @@ -0,0 +1 @@ +CONFIG_ESP_MAC_USE_CUSTOM_MAC_AS_BASE_MAC=y diff --git a/tools/test_apps/system/panic/pytest_panic.py b/tools/test_apps/system/panic/pytest_panic.py index 3f110d4e0180..1d00a6b59c90 100644 --- a/tools/test_apps/system/panic/pytest_panic.py +++ b/tools/test_apps/system/panic/pytest_panic.py @@ -123,10 +123,19 @@ def test_task_wdt_cpu0(dut: PanicTestDut, config: str, test_func_name: str) -> N dut.expect_elf_sha256() dut.expect_none('Guru Meditation') + coredump_pattern = (PANIC_ABORT_PREFIX + + 'Task watchdog got triggered. ' + 'The following tasks/users did not reset the watchdog in time:\n - ') + if dut.is_multi_core: + coredump_pattern += 'IDLE0 (CPU 0)' + else: + coredump_pattern += 'IDLE (CPU 0)' + common_test( dut, config, expected_backtrace=get_default_backtrace(test_func_name), + expected_coredump=[coredump_pattern] ) @@ -151,10 +160,14 @@ def test_task_wdt_cpu1(dut: PanicTestDut, config: str, test_func_name: str) -> N dut.expect_elf_sha256() dut.expect_none('Guru Meditation') + coredump_pattern = (PANIC_ABORT_PREFIX + + 'Task watchdog got triggered. ' + 'The following tasks/users did not reset the watchdog in time:\n - IDLE1 (CPU 1)') common_test( dut, config, expected_backtrace=expected_backtrace, + expected_coredump=[coredump_pattern] ) @@ -183,10 +196,14 @@ def test_task_wdt_both_cpus(dut: PanicTestDut, config: str, test_func_name: str) dut.expect_elf_sha256() dut.expect_none('Guru Meditation') + coredump_pattern = (PANIC_ABORT_PREFIX + + 'Task watchdog got triggered. ' + 'The following tasks/users did not reset the watchdog in time:\n - IDLE1 (CPU 1)\n - IDLE0 (CPU 0)') common_test( dut, config, expected_backtrace=expected_backtrace, + expected_coredump=[coredump_pattern] ) diff --git a/tools/test_apps/system/panic/test_panic_util/panic_dut.py b/tools/test_apps/system/panic/test_panic_util/panic_dut.py index 64f9d413119b..61a5d134b0ce 100644 --- a/tools/test_apps/system/panic/test_panic_util/panic_dut.py +++ b/tools/test_apps/system/panic/test_panic_util/panic_dut.py @@ -51,6 +51,10 @@ def revert_log_level(self) -> None: def is_xtensa(self) -> bool: return self.target in self.XTENSA_TARGETS + @property + def is_multi_core(self) -> bool: + return self.target in ['esp32', 'esp32s3'] + def run_test_func(self, test_func_name: str) -> None: self.expect_exact('Enter test name:') self.write(test_func_name) diff --git a/tools/test_apps/system/ram_loadable_app/README.md b/tools/test_apps/system/ram_loadable_app/README.md index 0283938f981c..76930508c721 100644 --- a/tools/test_apps/system/ram_loadable_app/README.md +++ b/tools/test_apps/system/ram_loadable_app/README.md @@ -37,13 +37,13 @@ idf.py build esptool.py -p PORT --no-stub load_ram build/ram_loadable_app.bin -idf.py -p PORT monitor +idf.py -p PORT monitor --no-reset ``` (Replace PORT with the name of the serial port to use.) (To exit the serial monitor, type ``Ctrl-]``.) -(For ram_loadable_app, after the chip is reset, it will start from flash by default, so the program will be executed directly after loading to ram. Therefore, manually open idf.py monitor will lose part of the log at startup because the serial port cannot be opened in time, so it is recommended to use a separate serial converter to monitor the output of the UART TX pin) +(For ram_loadable_app, after the chip is reset, it will start from flash by default, so the program will be executed directly after loading to ram. This is the reason why we use `--no-reset`. Besides, manually opening idf.py monitor will lose part of the log at startup because the serial port cannot be opened in time, so it is recommended to use a separate serial converter to monitor the output of the UART TX pin) See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects. diff --git a/tools/test_build_system/conftest.py b/tools/test_build_system/conftest.py index 94e0348ffb70..7c84fe398724 100644 --- a/tools/test_build_system/conftest.py +++ b/tools/test_build_system/conftest.py @@ -38,21 +38,44 @@ def pytest_addoption(parser: pytest.Parser) -> None: ) -@pytest.fixture(name='session_work_dir', scope='session', autouse=True) -def fixture_session_work_dir(request: FixtureRequest) -> typing.Generator[Path, None, None]: +@pytest.fixture(scope='session') +def _session_work_dir(request: FixtureRequest) -> typing.Generator[typing.Tuple[Path, bool], None, None]: work_dir = request.config.getoption('--work-dir') + if work_dir: work_dir = os.path.join(work_dir, datetime.datetime.utcnow().strftime('%Y-%m-%d_%H-%M-%S')) logging.debug(f'using work directory: {work_dir}') os.makedirs(work_dir, exist_ok=True) clean_dir = None + is_temp_dir = False else: work_dir = mkdtemp() logging.debug(f'created temporary work directory: {work_dir}') clean_dir = work_dir + is_temp_dir = True + + # resolve allows using relative paths with --work-dir option + yield Path(work_dir).resolve(), is_temp_dir + + if clean_dir: + logging.debug(f'cleaning up {clean_dir}') + shutil.rmtree(clean_dir, ignore_errors=True) + + +@pytest.fixture(name='func_work_dir', autouse=True) +def work_dir(request: FixtureRequest, _session_work_dir: typing.Tuple[Path, bool]) -> typing.Generator[Path, None, None]: + session_work_dir, is_temp_dir = _session_work_dir + + if request._pyfuncitem.keywords.get('force_temp_work_dir') and not is_temp_dir: + work_dir = Path(mkdtemp()).resolve() + logging.debug('Force using temporary work directory') + clean_dir = work_dir + else: + work_dir = session_work_dir + clean_dir = None - # resolve allows to use relative paths with --work-dir option - yield Path(work_dir).resolve() + # resolve allows using relative paths with --work-dir option + yield work_dir if clean_dir: logging.debug(f'cleaning up {clean_dir}') @@ -60,7 +83,7 @@ def fixture_session_work_dir(request: FixtureRequest) -> typing.Generator[Path, @pytest.fixture -def test_app_copy(session_work_dir: Path, request: FixtureRequest) -> typing.Generator[Path, None, None]: +def test_app_copy(func_work_dir: Path, request: FixtureRequest) -> typing.Generator[Path, None, None]: # by default, use hello_world app and copy it to a temporary directory with # the name resembling that of the test copy_from = 'tools/test_build_system/build_test_app' @@ -74,7 +97,7 @@ def test_app_copy(session_work_dir: Path, request: FixtureRequest) -> typing.Gen copy_to = mark.args[1] path_from = Path(os.environ['IDF_PATH']) / copy_from - path_to = session_work_dir / copy_to + path_to = func_work_dir / copy_to # if the new directory inside the original directory, # make sure not to go into recursion. @@ -99,13 +122,13 @@ def test_app_copy(session_work_dir: Path, request: FixtureRequest) -> typing.Gen @pytest.fixture -def test_git_template_app(session_work_dir: Path, request: FixtureRequest) -> typing.Generator[Path, None, None]: +def test_git_template_app(func_work_dir: Path, request: FixtureRequest) -> typing.Generator[Path, None, None]: copy_to = request.node.name + '_app' - path_to = session_work_dir / copy_to + path_to = func_work_dir / copy_to - logging.debug(f'clonning git-teplate app to {path_to}') + logging.debug(f'cloning git-template app to {path_to}') path_to.mkdir() - # No need to clone full repository, just single master branch + # No need to clone full repository, just a single master branch subprocess.run(['git', 'clone', '--single-branch', '-b', 'master', '--depth', '1', 'https://github.com/espressif/esp-idf-template.git', '.'], cwd=path_to, stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -122,7 +145,7 @@ def test_git_template_app(session_work_dir: Path, request: FixtureRequest) -> ty @pytest.fixture -def idf_copy(session_work_dir: Path, request: FixtureRequest) -> typing.Generator[Path, None, None]: +def idf_copy(func_work_dir: Path, request: FixtureRequest) -> typing.Generator[Path, None, None]: copy_to = request.node.name + '_idf' # allow overriding the destination via pytest.mark.idf_copy() @@ -131,7 +154,7 @@ def idf_copy(session_work_dir: Path, request: FixtureRequest) -> typing.Generato copy_to = mark.args[0] path_from = EXT_IDF_PATH - path_to = session_work_dir / copy_to + path_to = func_work_dir / copy_to # if the new directory inside the original directory, # make sure not to go into recursion. diff --git a/tools/test_build_system/pytest.ini b/tools/test_build_system/pytest.ini index fad075f0bba2..0db692d0487c 100644 --- a/tools/test_build_system/pytest.ini +++ b/tools/test_build_system/pytest.ini @@ -16,3 +16,4 @@ junit_log_passing_tests = False markers = test_app_copy: specify relative path of the app to copy, and the prefix of the destination directory name idf_copy: specify the prefix of the destination directory where IDF should be copied + force_temp_work_dir: force temporary folder as the working directory diff --git a/tools/test_build_system/test_build.py b/tools/test_build_system/test_build.py index 35d59bf2be9c..5529aab27799 100644 --- a/tools/test_build_system/test_build.py +++ b/tools/test_build_system/test_build.py @@ -19,9 +19,9 @@ def assert_built(paths: Union[List[str], List[Path]]) -> None: assert os.path.exists(path) -def test_build_alternative_directories(idf_py: IdfPyFunc, session_work_dir: Path, test_app_copy: Path) -> None: +def test_build_alternative_directories(idf_py: IdfPyFunc, func_work_dir: Path, test_app_copy: Path) -> None: logging.info('Moving BUILD_DIR_BASE out of tree') - alt_build_dir = session_work_dir / 'alt_build' + alt_build_dir = func_work_dir / 'alt_build' idf_py('-B', str(alt_build_dir), 'build') assert os.listdir(alt_build_dir) != [], 'No files found in new build directory!' default_build_dir = test_app_copy / 'build' diff --git a/tools/test_build_system/test_git.py b/tools/test_build_system/test_git.py index 25109c0ce130..57cdf3e43171 100644 --- a/tools/test_build_system/test_git.py +++ b/tools/test_build_system/test_git.py @@ -8,7 +8,7 @@ import typing from pathlib import Path -from test_build_system_helpers import EnvDict, IdfPyFunc, run_idf_py +from test_build_system_helpers import EnvDict, run_idf_py def run_git_cmd(*args: str, @@ -25,13 +25,6 @@ def run_git_cmd(*args: str, stdout=subprocess.PIPE, stderr=subprocess.PIPE) -def test_get_version_from_git_describe(test_git_template_app: Path, idf_py: IdfPyFunc) -> None: - logging.info('Get the version of app from git describe. Project is not inside IDF and do not have a tag only a hash commit.') - idf_ret = idf_py('reconfigure') - git_ret = run_git_cmd('describe', '--always', '--tags', '--dirty', workdir=test_git_template_app) - assert f'App "app-template" version: {git_ret.stdout.decode("utf-8")}' in idf_ret.stdout, 'Project version should have a hash commit' - - # In this test, the action needs to be performed in ESP-IDF that is valid git directory # Copying ESP-IDF is not possible def test_git_custom_tag() -> None: diff --git a/tools/test_build_system/test_kconfig.py b/tools/test_build_system/test_kconfig.py index 4db2dfdf0a44..ddcdba2132f8 100644 --- a/tools/test_build_system/test_kconfig.py +++ b/tools/test_build_system/test_kconfig.py @@ -124,12 +124,3 @@ def test_kconfig_multiple_and_target_specific_options(idf_py: IdfPyFunc, test_ap idf_py('set-target', 'esp32s2') assert all([file_contains((test_app_copy / 'sdkconfig'), x) for x in ['CONFIG_TEST_NEW_OPTION=y', 'CONFIG_TEST_OLD_OPTION=y']]) - - -def test_kconfig_get_version_from_describe(idf_py: IdfPyFunc, test_app_copy: Path) -> None: - logging.info('Get the version of app from Kconfig option') - (test_app_copy / 'version.txt').write_text('project_version_from_txt') - (test_app_copy / 'sdkconfig.defaults').write_text('\n'.join(['CONFIG_APP_PROJECT_VER_FROM_CONFIG=y', - 'CONFIG_APP_PROJECT_VER="project_version_from_Kconfig"'])) - ret = idf_py('build') - assert 'App "build_test_app" version: project_version_from_Kconfig' in ret.stdout diff --git a/tools/test_build_system/test_versions.py b/tools/test_build_system/test_versions.py new file mode 100644 index 000000000000..b4109fd57440 --- /dev/null +++ b/tools/test_build_system/test_versions.py @@ -0,0 +1,182 @@ +# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD +# SPDX-License-Identifier: Apache-2.0 +import logging +import os +import subprocess +import typing +from pathlib import Path + +import pytest +from test_build_system_helpers import EnvDict, IdfPyFunc, append_to_file, replace_in_file + + +############################################################################################# +# Test Case: Test that the build-system can set the default version for an IDF app +# +# Test Steps: +# 1. Copy the base build_test_app +# 2. Run idf.py reconfigure +# 3. Verify that the app version takes the default value of 1 +# +# Note: This test must run outside a git repository for it to pass. Hence we force the test +# to use a temporary work directory. +############################################################################################# +@pytest.mark.force_temp_work_dir +def test_versions_get_default_version(idf_py: IdfPyFunc, test_app_copy: Path) -> None: + logging.info('Verify the default version of an app') + ret = idf_py('reconfigure') + assert 'App "build_test_app" version: 1' in ret.stdout + + +############################################################################################# +# Test Case: Test that the build-system can set the version of an IDF app from git describe +# +# Test Steps: +# 1. Clone the idf template app from https://github.com/espressif/esp-idf-template.git +# 2. Run idf.py reconfigure +# 3. Run git describe in the cloned app git repository +# 4. Verify that the app version is picked up from the git describe command +# +############################################################################################# +def test_versions_get_version_from_git_describe(idf_py: IdfPyFunc, + test_git_template_app: Path, + env: typing.Optional[EnvDict] = None) -> None: + logging.info('Verify that the version of app can be set from git describe') + idf_ret = idf_py('reconfigure') + env_dict = dict(**os.environ) + if env: + env_dict.update(env) + git_ret = subprocess.run(['git', 'describe', '--always', '--tags', '--dirty'], + cwd=test_git_template_app, env=env_dict, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + assert f'App "app-template" version: {git_ret.stdout.decode("utf-8")}' in idf_ret.stdout + + +############################################################################################# +# Test Case: Test that the build-system can set the version for an IDF app from the VERSION argument +# +# Test Steps: +# 1. Clone the idf template app from https://github.com/espressif/esp-idf-template.git +# 2. Replace the default project() command in the top level CMakeLists.txt file to call the version parsing +# function __parse_and_store_version_arg() +# 3. Append several calls to __parse_and_store_version_arg() with different inputs for the VERSION argument +# 4. Append a project() call with valid arguments at the end of the CMakeLists.txt file +# 5. Run idf.py reconfigure +# 6. Verify that cmake correctly flags invalid inputs for the VERSION argument and accepts valid inputs for the same +# +############################################################################################# +def test_versions_get_version_from_version_arg(idf_py: IdfPyFunc, test_git_template_app: Path) -> None: + logging.info('Verify that the VERSION argument in project() is correctly parsed by cmake') + + # empty VERSION argument + replace_in_file((test_git_template_app / 'CMakeLists.txt'), 'project(app-template)', + '__parse_and_store_version_arg(app-template VERSION)') + # Invalid VERSION argument format + append_to_file((test_git_template_app / 'CMakeLists.txt'), + '\n__parse_and_store_version_arg(app-tempplate VERSION 1..2)') + # Invalid VERSION argument format + append_to_file((test_git_template_app / 'CMakeLists.txt'), + '\n__parse_and_store_version_arg(app-template VERSION version_text)') + # Invalid VERSION argument format + append_to_file((test_git_template_app / 'CMakeLists.txt'), + '\n__parse_and_store_version_arg(app-template VERSION 1.2.3.4.5)') + append_to_file((test_git_template_app / 'CMakeLists.txt'), + '\n__parse_and_store_version_arg(app-template VERSION 0)') + # Valid VERSION argument format + append_to_file((test_git_template_app / 'CMakeLists.txt'), + '\n__parse_and_store_version_arg(app-template VERSION 0.1)') + # Valid VERSION argument format + append_to_file((test_git_template_app / 'CMakeLists.txt'), + '\n__parse_and_store_version_arg(app-template VERSION 0.1.2)') + # Valid VERSION argument format + append_to_file((test_git_template_app / 'CMakeLists.txt'), + '\n__parse_and_store_version_arg(app-template VERSION 0.1.2.3)') + # project() call with valid VERSION argument format + append_to_file((test_git_template_app / 'CMakeLists.txt'), + '\nproject(app-template VERSION 0.1.2.3)') + + with pytest.raises(subprocess.CalledProcessError) as e: + idf_py('reconfigure') + + assert 'VERSION keyword not followed by a value or was followed by a value that expanded to nothing.' in e.stdout + assert 'Version "1..2" format invalid' in e.stderr + assert 'Version "version_text" format invalid' in e.stderr + assert 'Version "1.2.3.4.5" format invalid' in e.stderr + assert 'Version "1.2.3.4.5" format invalid' in e.stderr + assert 'Version "0" format invalid' not in e.stderr + assert 'Version "0.1" format invalid' not in e.stderr + assert 'Version "0.1.2" format invalid' not in e.stderr + assert 'Version "0.1.2.3" format invalid' not in e.stderr + assert 'App "app-template" version: 0.1.2.3' in e.stdout + + +############################################################################################# +# Test Case: Test that the build-system can set the version of an IDF app from version.txt file +# +# Test Steps: +# 1. Clone the idf template app from https://github.com/espressif/esp-idf-template.git +# 2. Replace the default project() command in the top level CMakeLists.txt file to include VERSION argument +# 3. Copy version.txt file into the cloned app repository +# 4. Updated the version in version.txt file to a known value +# 5. Run idf.py reconfigure +# 6. Verify that the app version is picked up from the version.txt file +# +############################################################################################# +def test_versions_get_version_from_version_file(idf_py: IdfPyFunc, test_git_template_app: Path) -> None: + logging.info('Verify that the version of app can be set from version.txt file') + replace_in_file((test_git_template_app / 'CMakeLists.txt'), 'project(app-template)', + 'project(app-template VERSION 0.1.2.3)') + (test_git_template_app / 'version.txt').write_text('project_version_from_txt') + idf_ret = idf_py('reconfigure') + + assert f'App "app-template" version: project_version_from_txt' in idf_ret.stdout + + +############################################################################################# +# Test Case: Test that the build-system can set the version of an IDF app if PROJECT_VER is set in the CMakeLists.txt +# +# Test Steps: +# 1. Clone the idf template app from https://github.com/espressif/esp-idf-template.git +# 2. Update CMakeLists.txt file to set PROJECT_VER before calling project() +# 3. Replace the default project() command in the top level CMakeLists.txt file to include VERSION argument +# 4. Copy version.txt file into the cloned app repository +# 5. Updated the version in version.txt file to a known value +# 6. Run idf.py reconfigure +# 7. Verify that the app version is picked up from the CMakeLists.txt file +# +############################################################################################# +def test_versions_get_version_from_top_level_cmake(idf_py: IdfPyFunc, test_git_template_app: Path) -> None: + logging.info('Verify that the version of app can be set from PROJECT_VER in CMakeLists.txt') + replace_in_file((test_git_template_app / 'CMakeLists.txt'), 'project(app-template)', + 'set(PROJECT_VER project_version_from_CMakeLists)') + append_to_file((test_git_template_app / 'CMakeLists.txt'), 'project(app-template VERSION 0.1.2.3)') + (test_git_template_app / 'version.txt').write_text('project_version_from_txt') + idf_ret = idf_py('reconfigure') + + assert f'App "app-template" version: project_version_from_CMakeLists' in idf_ret.stdout + + +############################################################################################# +# Test Case: Test that the build-system can set the version of an IDF app from Kconfig option +# +# Test Steps: +# 1. Clone the idf template app from https://github.com/espressif/esp-idf-template.git +# 2. Update CMakeLists.txt file to set PROJECT_VER before calling project() +# 3. Replace the default project() command in the top level CMakeLists.txt file to include VERSION argument +# 4. Copy version.txt file into the cloned app repository +# 5. Updated the version in version.txt file to a known value +# 6. Run idf.py reconfigure +# 7. Updated sdkconfig.defaults to configure CONFIG_APP_PROJECT_VER_FROM_CONFIG and CONFIG_APP_PROJECT_VER +# 8. Run idf.py reconfigure +# 9. Verify that the app version is picked up from the Kconfig option +# +############################################################################################# +def test_versions_get_version_from_kconfig_option(idf_py: IdfPyFunc, test_git_template_app: Path) -> None: + logging.info('Verify that the version of app can be set from Kconfig option') + replace_in_file((test_git_template_app / 'CMakeLists.txt'), 'project(app-template)', + 'set(PROJECT_VER project_version_from_CMakeLists)') + append_to_file((test_git_template_app / 'CMakeLists.txt'), 'project(app-template VERSION 0.1.2.3)') + (test_git_template_app / 'sdkconfig.defaults').write_text('\n'.join(['CONFIG_APP_PROJECT_VER_FROM_CONFIG=y', + 'CONFIG_APP_PROJECT_VER="project_version_from_Kconfig"'])) + idf_ret = idf_py('reconfigure') + + assert f'App "app-template" version: project_version_from_Kconfig' in idf_ret.stdout diff --git a/tools/test_idf_tools/test_idf_tools.py b/tools/test_idf_tools/test_idf_tools.py index 2c21e46cba28..5f974895f0ec 100755 --- a/tools/test_idf_tools/test_idf_tools.py +++ b/tools/test_idf_tools/test_idf_tools.py @@ -85,9 +85,6 @@ def get_version_dict(): XTENSA_ELF_ARCHIVE_PATTERN = XTENSA_ELF + '-' \ + (XTENSA_ELF_VERSION[len('esp-'):] if XTENSA_ELF_VERSION.startswith('esp-') else XTENSA_ELF_VERSION) -QEMU_RISCV_ARCHIVE_PATTERN = 'esp-' + QEMU_RISCV -QEMU_XTENSA_ARCHIVE_PATTERN = 'esp-' + QEMU_XTENSA - class TestUsage(unittest.TestCase): @@ -375,8 +372,8 @@ def test_tools_for_qemu_with_required(self): self.assert_tool_installed(output, XTENSA_ESP_GDB, XTENSA_ESP_GDB_VERSION) self.assert_tool_installed(output, RISCV_ESP_GDB, RISCV_ESP_GDB_VERSION) self.assert_tool_installed(output, ESP_ROM_ELFS, ESP_ROM_ELFS_VERSION) - self.assert_tool_installed(output, QEMU_RISCV, QEMU_RISCV_VERSION, QEMU_RISCV_ARCHIVE_PATTERN) - self.assert_tool_installed(output, QEMU_XTENSA, QEMU_XTENSA_VERSION, QEMU_XTENSA_ARCHIVE_PATTERN) + self.assert_tool_installed(output, QEMU_RISCV, QEMU_RISCV_VERSION) + self.assert_tool_installed(output, QEMU_XTENSA, QEMU_XTENSA_VERSION) self.assertIn('Destination: {}'.format(os.path.join(self.temp_tools_dir, 'dist')), output) self.assertEqual(required_tools_installed, output.count('Done')) diff --git a/tools/test_sbom/pytest.ini b/tools/test_sbom/pytest.ini deleted file mode 100644 index d95e773e5cd3..000000000000 --- a/tools/test_sbom/pytest.ini +++ /dev/null @@ -1,12 +0,0 @@ -[pytest] -addopts = -s -p no:pytest_embedded - -# log related -log_cli = True -log_cli_level = INFO -log_cli_format = %(asctime)s %(levelname)s %(message)s -log_cli_date_format = %Y-%m-%d %H:%M:%S - -## log all to `system-out` when case fail -junit_logging = stdout -junit_log_passing_tests = False diff --git a/tools/test_sbom/test_submodules.py b/tools/test_sbom/test_submodules.py deleted file mode 100644 index 85f76ab85024..000000000000 --- a/tools/test_sbom/test_submodules.py +++ /dev/null @@ -1,74 +0,0 @@ -# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD -# SPDX-License-Identifier: Apache-2.0 -import os -from subprocess import run -from typing import Dict, List - - -def run_cmd(cmd: List[str]) -> str: - """Simple helper to run command and return it's stdout.""" - proc = run(cmd, capture_output=True, check=True, text=True) - return proc.stdout.strip() - - -def get_gitwdir() -> str: - """Return absolute path to the current git working tree.""" - return run_cmd(['git', 'rev-parse', '--show-toplevel']) - - -def get_submodules_config() -> Dict[str,Dict[str,str]]: - """Return dictionary, where key is submodule name and value - is a dictionary with variable:value pairs.""" - gitmodules_fn = os.path.join(get_gitwdir(), '.gitmodules') - gitmodules_data = run_cmd(['git', 'config', '--list', '--file', gitmodules_fn]) - prefix = 'submodule.' - config: Dict[str, Dict[str,str]] = {} - for line in gitmodules_data.splitlines(): - if not line.startswith(prefix): - continue - splitted = line.split('=', maxsplit=1) - if len(splitted) != 2: - continue - section, val = splitted - # remove "submodule." prefix - section = section[len(prefix):] - # split section into module name and variable - splitted = section.rsplit('.', maxsplit=1) - if len(splitted) != 2: - continue - module_name, var = splitted - if module_name not in config: - config[module_name] = {} - config[module_name][var] = val - - return config - - -def test_sha() -> None: - """ Check that submodule SHA in git-tree and .gitmodules match - if sbom-hash variable is available in the .gitmodules file. - """ - submodules = get_submodules_config() - - for name, variables in submodules.items(): - sbom_hash = variables.get('sbom-hash') - if not sbom_hash: - continue - module_path = variables.get('path') - if not module_path: - continue - output = run_cmd(['git', 'ls-tree', 'HEAD', module_path]) - if not output: - continue - module_hash = output.split()[2] - msg = (f'Submodule \"{name}\" SHA \"{module_hash}\" in git ' - f'tree does not match SHA \"{sbom_hash}\" recorded in .gitmodules. ' - f'Please update \"sbom-hash\" in .gitmodules for \"{name}\" ' - f'and also please do not forget to update version and other submodule ' - f'information if necessary. It is important to keep this information ' - f'up-to-date for SBOM generation.') - assert module_hash == sbom_hash, msg - - -if __name__ == '__main__': - test_sha() diff --git a/tools/tools.json b/tools/tools.json index b1f28e2ca27b..a1e844dfe13c 100644 --- a/tools/tools.json +++ b/tools/tools.json @@ -888,16 +888,36 @@ "qemu-system-xtensa", "--version" ], - "version_regex": "QEMU emulator version ([a-z0-9.-_]+)", + "version_regex": "QEMU emulator version [0-9.]+ \\(([a-z0-9.-_]+)\\)", "versions": [ { "linux-amd64": { - "sha256": "a7e5e779fd593cb15f6d197034dc2fb427ed9165a4743e2febc6f6a47dfcc618", - "size": 45962695, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.0.0-20230522/esp-qemu-xtensa-softmmu-develop_8.0.0_20230522-x86_64-linux-gnu.tar.bz2" + "sha256": "88176f41c2fb17448372b4a120109275270c0e6bc49af4938f9f82d48e02f126", + "size": 14537932, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.1.3-20231206/qemu-xtensa-softmmu-esp_develop_8.1.3_20231206-x86_64-linux-gnu.tar.xz" }, - "name": "8.0.0", - "status": "recommended" + "linux-arm64": { + "sha256": "37e15a038456e9692394e7ab7faf4d8e04b937476bb22c346e7ce0aaa579a003", + "size": 14084300, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.1.3-20231206/qemu-xtensa-softmmu-esp_develop_8.1.3_20231206-aarch64-linux-gnu.tar.xz" + }, + "macos": { + "sha256": "e9321b29f59aa5c5f8d713ddcde301e46348493cdbf2dc12df2e047e6f456b58", + "size": 3345216, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.1.3-20231206/qemu-xtensa-softmmu-esp_develop_8.1.3_20231206-x86_64-apple-darwin.tar.xz" + }, + "macos-arm64": { + "sha256": "ab5f2c0c7f9428dfdd970f1cd9cac66e9d455e4ba87308d42882f43580433cd6", + "size": 3150564, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.1.3-20231206/qemu-xtensa-softmmu-esp_develop_8.1.3_20231206-aarch64-apple-darwin.tar.xz" + }, + "name": "esp_develop_8.1.3_20231206", + "status": "recommended", + "win64": { + "sha256": "cc1b0f87317e92aad71b40c409f404ce6df83bec0752feb6429eae65af606ae5", + "size": 32314176, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.1.3-20231206/qemu-xtensa-softmmu-esp_develop_8.1.3_20231206-x86_64-w64-mingw32.tar.xz" + } } ] }, @@ -921,16 +941,36 @@ "qemu-system-riscv32", "--version" ], - "version_regex": "QEMU emulator version ([a-z0-9.-_]+)", + "version_regex": "QEMU emulator version [0-9.]+ \\(([a-z0-9.-_]+)\\)", "versions": [ { "linux-amd64": { - "sha256": "bc7607720ff3d7e3d39f3e1810b8795f376f4b9cf3783c8f2ed3f7f14ba74717", - "size": 47175493, - "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.0.0-20230522/esp-qemu-riscv32-softmmu-develop_8.0.0_20230522-x86_64-linux-gnu.tar.bz2" + "sha256": "88373441ce34d598da372e313f2ff0d6a6bed9a11f8152a2dde0be1cc89b917f", + "size": 15931252, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.1.3-20231206/qemu-riscv32-softmmu-esp_develop_8.1.3_20231206-x86_64-linux-gnu.tar.xz" }, - "name": "8.0.0", - "status": "recommended" + "linux-arm64": { + "sha256": "925be5f64c27fad9b982fb24870119fe2af7d1aa36b3607044f5db4d83633f8c", + "size": 15433748, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.1.3-20231206/qemu-riscv32-softmmu-esp_develop_8.1.3_20231206-aarch64-linux-gnu.tar.xz" + }, + "macos": { + "sha256": "02fb7a928fe2f35debb561a1531458ef756c1b7dc2226afdb464eba81392920b", + "size": 3431904, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.1.3-20231206/qemu-riscv32-softmmu-esp_develop_8.1.3_20231206-x86_64-apple-darwin.tar.xz" + }, + "macos-arm64": { + "sha256": "2a5836a02070964d05b947220906575e2f6a88dd68473eea72622705cb18105b", + "size": 3152032, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.1.3-20231206/qemu-riscv32-softmmu-esp_develop_8.1.3_20231206-aarch64-apple-darwin.tar.xz" + }, + "name": "esp_develop_8.1.3_20231206", + "status": "recommended", + "win64": { + "sha256": "8ecef3ccb770cce5b82c0683c318eedd6da288d878151c7d002d89ae64e7c1bb", + "size": 34976352, + "url": "https://github.com/espressif/qemu/releases/download/esp-develop-8.1.3-20231206/qemu-riscv32-softmmu-esp_develop_8.1.3_20231206-x86_64-w64-mingw32.tar.xz" + } } ] }