docs: Update the ELF guides

Rewrite parts of the two ELF guides to use scripts included in the
export archive and modernize some deprecated tools and Bash idioms.

Also add the new sphinx_collapse extension to the docs build config.

Signed-off-by: Niccolò Maggioni <nicco.maggioni+nuttx@gmail.com>
This commit is contained in:
Niccolò Maggioni 2025-06-11 02:12:08 +02:00 committed by Xiang Xiao
parent d651726b57
commit 2399702a28
5 changed files with 886 additions and 907 deletions

View file

@ -17,3 +17,4 @@ pytz = "*"
importlib-metadata = "*" importlib-metadata = "*"
sphinx-tags = "*" sphinx-tags = "*"
sphinx-design = "*" sphinx-design = "*"
sphinx-collapse = "*"

View file

@ -1,7 +1,7 @@
{ {
"_meta": { "_meta": {
"hash": { "hash": {
"sha256": "b44a6fa5a78afb4aaa44d290055bf273d4765907a822f399858891c57a2cdc7d" "sha256": "9e0b756323757643515c417299f5a8cc7587c39771b4634cb2b506c6c2100387"
}, },
"pipfile-spec": 6, "pipfile-spec": 6,
"requires": {}, "requires": {},
@ -24,146 +24,133 @@
}, },
"anyio": { "anyio": {
"hashes": [ "hashes": [
"sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028",
"sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d" "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.9'",
"version": "==4.6.2.post1" "version": "==4.9.0"
}, },
"babel": { "babel": {
"hashes": [ "hashes": [
"sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d",
"sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316" "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.16.0" "version": "==2.17.0"
}, },
"certifi": { "certifi": {
"hashes": [ "hashes": [
"sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6",
"sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9" "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3"
], ],
"markers": "python_version >= '3.6'", "markers": "python_version >= '3.6'",
"version": "==2024.8.30" "version": "==2025.4.26"
}, },
"charset-normalizer": { "charset-normalizer": {
"hashes": [ "hashes": [
"sha256:0099d79bdfcf5c1f0c2c72f91516702ebf8b0b8ddd8905f97a8aecf49712c621", "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4",
"sha256:0713f3adb9d03d49d365b70b84775d0a0d18e4ab08d12bc46baa6132ba78aaf6", "sha256:046595208aae0120559a67693ecc65dd75d46f7bf687f159127046628178dc45",
"sha256:07afec21bbbbf8a5cc3651aa96b980afe2526e7f048fdfb7f1014d84acc8b6d8", "sha256:0c29de6a1a95f24b9a1aa7aefd27d2487263f00dfd55a77719b530788f75cff7",
"sha256:0b309d1747110feb25d7ed6b01afdec269c647d382c857ef4663bbe6ad95a912", "sha256:0c8c57f84ccfc871a48a47321cfa49ae1df56cd1d965a09abe84066f6853b9c0",
"sha256:0d99dd8ff461990f12d6e42c7347fd9ab2532fb70e9621ba520f9e8637161d7c", "sha256:0f5d9ed7f254402c9e7d35d2f5972c9bbea9040e99cd2861bd77dc68263277c7",
"sha256:0de7b687289d3c1b3e8660d0741874abe7888100efe14bd0f9fd7141bcbda92b", "sha256:18dd2e350387c87dabe711b86f83c9c78af772c748904d372ade190b5c7c9d4d",
"sha256:1110e22af8ca26b90bd6364fe4c763329b0ebf1ee213ba32b68c73de5752323d", "sha256:1b1bde144d98e446b056ef98e59c256e9294f6b74d7af6846bf5ffdafd687a7d",
"sha256:130272c698667a982a5d0e626851ceff662565379baf0ff2cc58067b81d4f11d", "sha256:1c95a1e2902a8b722868587c0e1184ad5c55631de5afc0eb96bc4b0d738092c0",
"sha256:136815f06a3ae311fae551c3df1f998a1ebd01ddd424aa5603a4336997629e95", "sha256:1cad5f45b3146325bb38d6855642f6fd609c3f7cad4dbaf75549bf3b904d3184",
"sha256:14215b71a762336254351b00ec720a8e85cada43b987da5a042e4ce3e82bd68e", "sha256:21b2899062867b0e1fde9b724f8aecb1af14f2778d69aacd1a5a1853a597a5db",
"sha256:1db4e7fefefd0f548d73e2e2e041f9df5c59e178b4c72fbac4cc6f535cfb1565", "sha256:24498ba8ed6c2e0b56d4acbf83f2d989720a93b41d712ebd4f4979660db4417b",
"sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64", "sha256:25a23ea5c7edc53e0f29bae2c44fcb5a1aa10591aae107f2a2b2583a9c5cbc64",
"sha256:2006769bd1640bdf4d5641c69a3d63b71b81445473cac5ded39740a226fa88ab", "sha256:289200a18fa698949d2b39c671c2cc7a24d44096784e76614899a7ccf2574b7b",
"sha256:20587d20f557fe189b7947d8e7ec5afa110ccf72a3128d61a2a387c3313f46be", "sha256:28a1005facc94196e1fb3e82a3d442a9d9110b8434fc1ded7a24a2983c9888d8",
"sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e", "sha256:32fc0341d72e0f73f80acb0a2c94216bd704f4f0bce10aedea38f30502b271ff",
"sha256:27623ba66c183eca01bf9ff833875b459cad267aeeb044477fedac35e19ba907", "sha256:36b31da18b8890a76ec181c3cf44326bf2c48e36d393ca1b72b3f484113ea344",
"sha256:285e96d9d53422efc0d7a17c60e59f37fbf3dfa942073f666db4ac71e8d726d0", "sha256:3c21d4fca343c805a52c0c78edc01e3477f6dd1ad7c47653241cf2a206d4fc58",
"sha256:2de62e8801ddfff069cd5c504ce3bc9672b23266597d4e4f50eda28846c322f2", "sha256:3fddb7e2c84ac87ac3a947cb4e66d143ca5863ef48e4a5ecb83bd48619e4634e",
"sha256:2f6c34da58ea9c1a9515621f4d9ac379871a8f21168ba1b5e09d74250de5ad62", "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471",
"sha256:309a7de0a0ff3040acaebb35ec45d18db4b28232f21998851cfa709eeff49d62", "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148",
"sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23", "sha256:4e594135de17ab3866138f496755f302b72157d115086d100c3f19370839dd3a",
"sha256:3710a9751938947e6327ea9f3ea6332a09bf0ba0c09cae9cb1f250bd1f1549bc", "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836",
"sha256:3d59d125ffbd6d552765510e3f31ed75ebac2c7470c7274195b9161a32350284", "sha256:5a9979887252a82fefd3d3ed2a8e3b937a7a809f65dcb1e068b090e165bbe99e",
"sha256:40d3ff7fc90b98c637bda91c89d51264a3dcf210cade3a2c6f838c7268d7a4ca", "sha256:5baececa9ecba31eff645232d59845c07aa030f0c81ee70184a90d35099a0e63",
"sha256:425c5f215d0eecee9a56cdb703203dda90423247421bf0d67125add85d0c4455", "sha256:5bf4545e3b962767e5c06fe1738f951f77d27967cb2caa64c28be7c4563e162c",
"sha256:43193c5cda5d612f247172016c4bb71251c784d7a4d9314677186a838ad34858", "sha256:6333b3aa5a12c26b2a4d4e7335a28f1475e0e5e17d69d55141ee3cab736f66d1",
"sha256:44aeb140295a2f0659e113b31cfe92c9061622cadbc9e2a2f7b8ef6b1e29ef4b", "sha256:65c981bdbd3f57670af8b59777cbfae75364b483fa8a9f420f08094531d54a01",
"sha256:47334db71978b23ebcf3c0f9f5ee98b8d65992b65c9c4f2d34c2eaf5bcaf0594", "sha256:68a328e5f55ec37c57f19ebb1fdc56a248db2e3e9ad769919a58672958e8f366",
"sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc", "sha256:6a0289e4589e8bdfef02a80478f1dfcb14f0ab696b5a00e1f4b8a14a307a3c58",
"sha256:4a51b48f42d9358460b78725283f04bddaf44a9358197b889657deba38f329db", "sha256:6b66f92b17849b85cad91259efc341dce9c1af48e2173bf38a85c6329f1033e5",
"sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b", "sha256:6c9379d65defcab82d07b2a9dfbfc2e95bc8fe0ebb1b176a3190230a3ef0e07c",
"sha256:4ec9dd88a5b71abfc74e9df5ebe7921c35cbb3b641181a531ca65cdb5e8e4dea", "sha256:6fc1f5b51fa4cecaa18f2bd7a003f3dd039dd615cd69a2afd6d3b19aed6775f2",
"sha256:4f9fc98dad6c2eaa32fc3af1417d95b5e3d08aff968df0cd320066def971f9a6", "sha256:70f7172939fdf8790425ba31915bfbe8335030f05b9913d7ae00a87d4395620a",
"sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920", "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597",
"sha256:55f56e2ebd4e3bc50442fbc0888c9d8c94e4e06a933804e2af3e89e2f9c1c749", "sha256:7222ffd5e4de8e57e03ce2cef95a4c43c98fcb72ad86909abdfc2c17d227fc1b",
"sha256:5726cf76c982532c1863fb64d8c6dd0e4c90b6ece9feb06c9f202417a31f7dd7", "sha256:75d10d37a47afee94919c4fab4c22b9bc2a8bf7d4f46f87363bcf0573f3ff4f5",
"sha256:5d447056e2ca60382d460a604b6302d8db69476fd2015c81e7c35417cfabe4cd", "sha256:76af085e67e56c8816c3ccf256ebd136def2ed9654525348cfa744b6802b69eb",
"sha256:5ed2e36c3e9b4f21dd9422f6893dec0abf2cca553af509b10cd630f878d3eb99", "sha256:770cab594ecf99ae64c236bc9ee3439c3f46be49796e265ce0cc8bc17b10294f",
"sha256:5ff2ed8194587faf56555927b3aa10e6fb69d931e33953943bc4f837dfee2242", "sha256:7a6ab32f7210554a96cd9e33abe3ddd86732beeafc7a28e9955cdf22ffadbab0",
"sha256:62f60aebecfc7f4b82e3f639a7d1433a20ec32824db2199a11ad4f5e146ef5ee", "sha256:7c48ed483eb946e6c04ccbe02c6b4d1d48e51944b6db70f697e089c193404941",
"sha256:63bc5c4ae26e4bc6be6469943b8253c0fd4e4186c43ad46e713ea61a0ba49129", "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0",
"sha256:6b40e8d38afe634559e398cc32b1472f376a4099c75fe6299ae607e404c033b2", "sha256:8075c35cd58273fee266c58c0c9b670947c19df5fb98e7b66710e04ad4e9ff86",
"sha256:6b493a043635eb376e50eedf7818f2f322eabbaa974e948bd8bdd29eb7ef2a51", "sha256:8272b73e1c5603666618805fe821edba66892e2870058c94c53147602eab29c7",
"sha256:6dba5d19c4dfab08e58d5b36304b3f92f3bd5d42c1a3fa37b5ba5cdf6dfcbcee", "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7",
"sha256:6fd30dc99682dc2c603c2b315bded2799019cea829f8bf57dc6b61efde6611c8", "sha256:844da2b5728b5ce0e32d863af26f32b5ce61bc4273a9c720a9f3aa9df73b1455",
"sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b", "sha256:8755483f3c00d6c9a77f490c17e6ab0c8729e39e6390328e42521ef175380ae6",
"sha256:7706f5850360ac01d80c89bcef1640683cc12ed87f42579dab6c5d3ed6888613", "sha256:915f3849a011c1f593ab99092f3cecfcb4d65d8feb4a64cf1bf2d22074dc0ec4",
"sha256:7782afc9b6b42200f7362858f9e73b1f8316afb276d316336c0ec3bd73312742", "sha256:926ca93accd5d36ccdabd803392ddc3e03e6d4cd1cf17deff3b989ab8e9dbcf0",
"sha256:79983512b108e4a164b9c8d34de3992f76d48cadc9554c9e60b43f308988aabe", "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3",
"sha256:7f683ddc7eedd742e2889d2bfb96d69573fde1d92fcb811979cdb7165bb9c7d3", "sha256:98f862da73774290f251b9df8d11161b6cf25b599a66baf087c1ffe340e9bfd1",
"sha256:82357d85de703176b5587dbe6ade8ff67f9f69a41c0733cf2425378b49954de5", "sha256:9cbfacf36cb0ec2897ce0ebc5d08ca44213af24265bd56eca54bee7923c48fd6",
"sha256:84450ba661fb96e9fd67629b93d2941c871ca86fc38d835d19d4225ff946a631", "sha256:a370b3e078e418187da8c3674eddb9d983ec09445c99a3a263c2011993522981",
"sha256:86f4e8cca779080f66ff4f191a685ced73d2f72d50216f7112185dc02b90b9b7", "sha256:a955b438e62efdf7e0b7b52a64dc5c3396e2634baa62471768a64bc2adb73d5c",
"sha256:8cda06946eac330cbe6598f77bb54e690b4ca93f593dee1568ad22b04f347c15", "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980",
"sha256:8ce7fd6767a1cc5a92a639b391891bf1c268b03ec7e021c7d6d902285259685c", "sha256:aa88ca0b1932e93f2d961bf3addbb2db902198dca337d88c89e1559e066e7645",
"sha256:8ff4e7cdfdb1ab5698e675ca622e72d58a6fa2a8aa58195de0c0061288e6e3ea", "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7",
"sha256:9289fd5dddcf57bab41d044f1756550f9e7cf0c8e373b8cdf0ce8773dc4bd417", "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12",
"sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250", "sha256:b2680962a4848b3c4f155dc2ee64505a9c57186d0d56b43123b17ca3de18f0fa",
"sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88", "sha256:b2d318c11350e10662026ad0eb71bb51c7812fc8590825304ae0bdd4ac283acd",
"sha256:95c3c157765b031331dd4db3c775e58deaee050a3042fcad72cbc4189d7c8dca", "sha256:b33de11b92e9f75a2b545d6e9b6f37e398d86c3e9e9653c4864eb7e89c5773ef",
"sha256:980b4f289d1d90ca5efcf07958d3eb38ed9c0b7676bf2831a54d4f66f9c27dfa", "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f",
"sha256:9ae4ef0b3f6b41bad6366fb0ea4fc1d7ed051528e113a60fa2a65a9abb5b1d99", "sha256:be1e352acbe3c78727a16a455126d9ff83ea2dfdcbc83148d2982305a04714c2",
"sha256:9c98230f5042f4945f957d006edccc2af1e03ed5e37ce7c373f00a5a4daa6149", "sha256:bee093bf902e1d8fc0ac143c88902c3dfc8941f7ea1d6a8dd2bcb786d33db03d",
"sha256:9fa2566ca27d67c86569e8c85297aaf413ffab85a8960500f12ea34ff98e4c41", "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5",
"sha256:a14969b8691f7998e74663b77b4c36c0337cb1df552da83d5c9004a93afdb574", "sha256:c9e36a97bee9b86ef9a1cf7bb96747eb7a15c2f22bdb5b516434b00f2a599f02",
"sha256:a8aacce6e2e1edcb6ac625fb0f8c3a9570ccc7bfba1f63419b3769ccf6a00ed0", "sha256:cddf7bd982eaa998934a91f69d182aec997c6c468898efe6679af88283b498d3",
"sha256:a8e538f46104c815be19c975572d74afb53f29650ea2025bbfaef359d2de2f7f", "sha256:cf713fe9a71ef6fd5adf7a79670135081cd4431c2943864757f0fa3a65b1fafd",
"sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d", "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e",
"sha256:aa693779a8b50cd97570e5a0f343538a8dbd3e496fa5dcb87e29406ad0299654", "sha256:d41c4d287cfc69060fa91cae9683eacffad989f1a10811995fa309df656ec214",
"sha256:ab22fbd9765e6954bc0bcff24c25ff71dcbfdb185fcdaca49e81bac68fe724d3", "sha256:d524ba3f1581b35c03cb42beebab4a13e6cdad7b36246bd22541fa585a56cccd",
"sha256:ab2e5bef076f5a235c3774b4f4028a680432cded7cad37bba0fd90d64b187d19", "sha256:daac4765328a919a805fa5e2720f3e94767abd632ae410a9062dff5412bae65a",
"sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90", "sha256:db4c7bf0e07fc3b7d89ac2a5880a6a8062056801b83ff56d8464b70f65482b6c",
"sha256:af73657b7a68211996527dbfeffbb0864e043d270580c5aef06dc4b659a4b578", "sha256:dc7039885fa1baf9be153a0626e337aa7ec8bf96b0128605fb0d77788ddc1681",
"sha256:b197e7094f232959f8f20541ead1d9862ac5ebea1d58e9849c1bf979255dfac9", "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba",
"sha256:b295729485b06c1a0683af02a9e42d2caa9db04a373dc38a6a58cdd1e8abddf1", "sha256:dedb8adb91d11846ee08bec4c8236c8549ac721c245678282dcb06b221aab59f",
"sha256:b8831399554b92b72af5932cdbbd4ddc55c55f631bb13ff8fe4e6536a06c5c51", "sha256:e45ba65510e2647721e35323d6ef54c7974959f6081b58d4ef5d87c60c84919a",
"sha256:b8dcd239c743aa2f9c22ce674a145e0a25cb1566c495928440a181ca1ccf6719", "sha256:e53efc7c7cee4c1e70661e2e112ca46a575f90ed9ae3fef200f2a25e954f4b28",
"sha256:bcb4f8ea87d03bc51ad04add8ceaf9b0f085ac045ab4d74e73bbc2dc033f0236", "sha256:e635b87f01ebc977342e2697d05b56632f5f879a4f15955dfe8cef2448b51691",
"sha256:bd7af3717683bea4c87acd8c0d3d5b44d56120b26fd3f8a692bdd2d5260c620a", "sha256:e70e990b2137b29dc5564715de1e12701815dacc1d056308e2b17e9095372a82",
"sha256:bf4475b82be41b07cc5e5ff94810e6a01f276e37c2d55571e3fe175e467a1a1c", "sha256:e8082b26888e2f8b36a042a58307d5b917ef2b1cacab921ad3323ef91901c71a",
"sha256:c3e446d253bd88f6377260d07c895816ebf33ffffd56c1c792b13bff9c3e1ade", "sha256:e8323a9b031aa0393768b87f04b4164a40037fb2a3c11ac06a03ffecd3618027",
"sha256:c57516e58fd17d03ebe67e181a4e4e2ccab1168f8c2976c6a334d4f819fe5944", "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7",
"sha256:c94057af19bc953643a33581844649a7fdab902624d2eb739738a30e2b3e60fc", "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518",
"sha256:cab5d0b79d987c67f3b9e9c53f54a61360422a5a0bc075f43cab5621d530c3b6", "sha256:eba9904b0f38a143592d9fc0e19e2df0fa2e41c3c3745554761c5f6447eedabf",
"sha256:ce031db0408e487fd2775d745ce30a7cd2923667cf3b69d48d219f1d8f5ddeb6", "sha256:ef8de666d6179b009dce7bcb2ad4c4a779f113f12caf8dc77f0162c29d20490b",
"sha256:cee4373f4d3ad28f1ab6290684d8e2ebdb9e7a1b74fdc39e4c211995f77bec27", "sha256:efd387a49825780ff861998cd959767800d54f8308936b21025326de4b5a42b9",
"sha256:d5b054862739d276e09928de37c79ddeec42a6e1bfc55863be96a36ba22926f6", "sha256:f0aa37f3c979cf2546b73e8222bbfa3dc07a641585340179d768068e3455e544",
"sha256:dbe03226baf438ac4fda9e2d0715022fd579cb641c4cf639fa40d53b2fe6f3e2", "sha256:f4074c5a429281bf056ddd4c5d3b740ebca4d43ffffe2ef4bf4d2d05114299da",
"sha256:dc15e99b2d8a656f8e666854404f1ba54765871104e50c8e9813af8a7db07f12", "sha256:f69a27e45c43520f5487f27627059b64aaf160415589230992cec34c5e18a509",
"sha256:dcaf7c1524c0542ee2fc82cc8ec337f7a9f7edee2532421ab200d2b920fc97cf", "sha256:fb707f3e15060adf5b7ada797624a6c6e0138e2a26baa089df64c68ee98e040f",
"sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114", "sha256:fcbe676a55d7445b22c10967bceaaf0ee69407fbe0ece4d032b6eb8d4565982a",
"sha256:dd9a8bd8900e65504a305bf8ae6fa9fbc66de94178c420791d0293702fce2df7", "sha256:fdb20a30fe1175ecabed17cbf7812f7b804b8a315a25f24678bcdf120a90077f"
"sha256:de7376c29d95d6719048c194a9cf1a1b0393fbe8488a22008610b0361d834ecf",
"sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d",
"sha256:e91f541a85298cf35433bf66f3fab2a4a2cff05c127eeca4af174f6d497f0d4b",
"sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed",
"sha256:ee803480535c44e7f5ad00788526da7d85525cfefaf8acf8ab9a310000be4b03",
"sha256:f09cb5a7bbe1ecae6e87901a2eb23e0256bb524a79ccc53eb0b7629fbe7677c4",
"sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67",
"sha256:f1a2f519ae173b5b6a2c9d5fa3116ce16e48b3462c8b96dfdded11055e3d6365",
"sha256:f28f891ccd15c514a0981f3b9db9aa23d62fe1a99997512b0491d2ed323d229a",
"sha256:f3e73a4255342d4eb26ef6df01e3962e73aa29baa3124a8e824c5d3364a65748",
"sha256:f606a1881d2663630ea5b8ce2efe2111740df4b687bd78b34a8131baa007f79b",
"sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079",
"sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"
], ],
"markers": "python_full_version >= '3.7.0'", "markers": "python_version >= '3.7'",
"version": "==3.4.0" "version": "==3.4.2"
}, },
"click": { "click": {
"hashes": [ "hashes": [
"sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202",
"sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de" "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.10'",
"version": "==8.1.7" "version": "==8.2.1"
}, },
"colorama": { "colorama": {
"hashes": [ "hashes": [
@ -184,11 +171,11 @@
}, },
"h11": { "h11": {
"hashes": [ "hashes": [
"sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1",
"sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761" "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.8'",
"version": "==0.14.0" "version": "==0.16.0"
}, },
"idna": { "idna": {
"hashes": [ "hashes": [
@ -208,20 +195,20 @@
}, },
"importlib-metadata": { "importlib-metadata": {
"hashes": [ "hashes": [
"sha256:45e54197d28b7a7f1559e60b95e7c567032b602131fbd588f1497f47880aa68b", "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000",
"sha256:71522656f0abace1d072b9e5481a48f07c138e00f079c38c8f883823f9c26bd7" "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd"
], ],
"index": "pypi", "index": "pypi",
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.9'",
"version": "==8.5.0" "version": "==8.7.0"
}, },
"jinja2": { "jinja2": {
"hashes": [ "hashes": [
"sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369", "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d",
"sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d" "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"
], ],
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==3.1.4" "version": "==3.1.6"
}, },
"markdown-it-py": { "markdown-it-py": {
"hashes": [ "hashes": [
@ -295,7 +282,6 @@
"sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430",
"sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50" "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"
], ],
"index": "pypi",
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.9'",
"version": "==3.0.2" "version": "==3.0.2"
}, },
@ -326,27 +312,27 @@
}, },
"packaging": { "packaging": {
"hashes": [ "hashes": [
"sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484",
"sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f" "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==24.2" "version": "==25.0"
}, },
"pygments": { "pygments": {
"hashes": [ "hashes": [
"sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f",
"sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.18.0" "version": "==2.19.1"
}, },
"pytz": { "pytz": {
"hashes": [ "hashes": [
"sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a", "sha256:360b9e3dbb49a209c21ad61809c7fb453643e048b38924c765813546746e81c3",
"sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725" "sha256:5ddf76296dd8c44c26eb8f4b6f35488f3ccbf6fbbd7adee0b7262d43f0ec2f00"
], ],
"index": "pypi", "index": "pypi",
"version": "==2024.2" "version": "==2025.2"
}, },
"pyyaml": { "pyyaml": {
"hashes": [ "hashes": [
@ -409,11 +395,11 @@
}, },
"requests": { "requests": {
"hashes": [ "hashes": [
"sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c",
"sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6" "sha256:27d0316682c8a29834d3264820024b62a36942083d52caf2f14c0591336d3422"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.8'",
"version": "==2.32.3" "version": "==2.32.4"
}, },
"sniffio": { "sniffio": {
"hashes": [ "hashes": [
@ -425,10 +411,11 @@
}, },
"snowballstemmer": { "snowballstemmer": {
"hashes": [ "hashes": [
"sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", "sha256:6cd7b3897da8d6c9ffb968a6781fa6532dce9c3618a4b127d920dab764a19064",
"sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a" "sha256:6d5eeeec8e9f84d4d56b847692bacf79bc2c8e90c7f80ca4444ff8b6f2e52895"
], ],
"version": "==2.2.0" "markers": "python_version not in '3.0, 3.1, 3.2'",
"version": "==3.0.1"
}, },
"sphinx": { "sphinx": {
"hashes": [ "hashes": [
@ -448,6 +435,15 @@
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.9'",
"version": "==2024.10.3" "version": "==2024.10.3"
}, },
"sphinx-collapse": {
"hashes": [
"sha256:85fadb2ec8769b93fd04276538668fa96239ef60c20c4a9eaa3e480387a6e65b",
"sha256:cae141e6f03ecd52ed246a305a69e1b0d5d05e6cdf3fe803d40d583ad6ad895a"
],
"index": "pypi",
"markers": "python_version >= '3.7'",
"version": "==0.1.3"
},
"sphinx-copybutton": { "sphinx-copybutton": {
"hashes": [ "hashes": [
"sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd",
@ -457,6 +453,15 @@
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==0.5.2" "version": "==0.5.2"
}, },
"sphinx-design": {
"hashes": [
"sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c",
"sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632"
],
"index": "pypi",
"markers": "python_version >= '3.9'",
"version": "==0.6.1"
},
"sphinx-rtd-theme": { "sphinx-rtd-theme": {
"hashes": [ "hashes": [
"sha256:422ccc750c3a3a311de4ae327e82affdaf59eb695ba4936538552f3b00f4ee13", "sha256:422ccc750c3a3a311de4ae327e82affdaf59eb695ba4936538552f3b00f4ee13",
@ -475,6 +480,14 @@
"markers": "python_version >= '3.7'", "markers": "python_version >= '3.7'",
"version": "==3.4.7" "version": "==3.4.7"
}, },
"sphinx-tags": {
"hashes": [
"sha256:3065219bacf47567c706f2237d5665b22f3a5167367b4c4568bcda4371a5359d",
"sha256:af31203fe4e0ebd39cb95d4fef38720185def6af9fdb921b70275ff659a5dac5"
],
"index": "pypi",
"version": "==0.4"
},
"sphinxcontrib-applehelp": { "sphinxcontrib-applehelp": {
"hashes": [ "hashes": [
"sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1",
@ -533,199 +546,187 @@
}, },
"starlette": { "starlette": {
"hashes": [ "hashes": [
"sha256:0e4ab3d16522a255be6b28260b938eae2482f98ce5cc934cb08dce8dc3ba5835", "sha256:1f64887e94a447fed5f23309fb6890ef23349b7e478faa7b24a851cd4eb844af",
"sha256:44cedb2b7c77a9de33a8b74b2b90e9f50d11fcf25d8270ea525ad71a25374ff7" "sha256:9d052d4933683af40ffd47c7465433570b4949dc937e20ad1d73b34e72f10c37"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.9'",
"version": "==0.41.3" "version": "==0.47.0"
}, },
"urllib3": { "urllib3": {
"hashes": [ "hashes": [
"sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac", "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466",
"sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9" "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.9'",
"version": "==2.2.3" "version": "==2.4.0"
}, },
"uvicorn": { "uvicorn": {
"hashes": [ "hashes": [
"sha256:82ad92fd58da0d12af7482ecdb5f2470a04c9c9a53ced65b9bbb4a205377602e", "sha256:16246631db62bdfbf069b0645177d6e8a77ba950cfedbfd093acef9444e4d885",
"sha256:ee9519c246a72b1c084cea8d3b44ed6026e78a4a309cbedae9c37e4cb9fbb175" "sha256:35919a9a979d7a59334b6b10e05d77c1d0d574c50e0fc98b8b1a0f165708b55a"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.9'",
"version": "==0.32.1" "version": "==0.34.3"
}, },
"watchfiles": { "watchfiles": {
"hashes": [ "hashes": [
"sha256:01550ccf1d0aed6ea375ef259706af76ad009ef5b0203a3a4cce0f6024f9b68a", "sha256:0125f91f70e0732a9f8ee01e49515c35d38ba48db507a50c5bdcad9503af5827",
"sha256:01def80eb62bd5db99a798d5e1f5f940ca0a05986dcfae21d833af7a46f7ee22", "sha256:0a04059f4923ce4e856b4b4e5e783a70f49d9663d22a4c3b3298165996d1377f",
"sha256:07cdef0c84c03375f4e24642ef8d8178e533596b229d32d2bbd69e5128ede02a", "sha256:0b289572c33a0deae62daa57e44a25b99b783e5f7aed81b314232b3d3c81a11d",
"sha256:083dc77dbdeef09fa44bb0f4d1df571d2e12d8a8f985dccde71ac3ac9ac067a0", "sha256:10f6ae86d5cb647bf58f9f655fcf577f713915a5d69057a0371bc257e2553234",
"sha256:1cf1f6dd7825053f3d98f6d33f6464ebdd9ee95acd74ba2c34e183086900a827", "sha256:13bb21f8ba3248386337c9fa51c528868e6c34a707f729ab041c846d52a0c69a",
"sha256:21ab23fdc1208086d99ad3f69c231ba265628014d4aed31d4e8746bd59e88cd1", "sha256:15ac96dd567ad6c71c71f7b2c658cb22b7734901546cd50a475128ab557593ca",
"sha256:2dadf8a8014fde6addfd3c379e6ed1a981c8f0a48292d662e27cabfe4239c83c", "sha256:18b3bd29954bc4abeeb4e9d9cf0b30227f0f206c86657674f544cb032296acd5",
"sha256:2e28d91ef48eab0afb939fa446d8ebe77e2f7593f5f463fd2bb2b14132f95b6e", "sha256:1909e0a9cd95251b15bff4261de5dd7550885bd172e3536824bf1cf6b121e200",
"sha256:2efec17819b0046dde35d13fb8ac7a3ad877af41ae4640f4109d9154ed30a188", "sha256:1a2902ede862969077b97523987c38db28abbe09fb19866e711485d9fbf0d417",
"sha256:30bbd525c3262fd9f4b1865cb8d88e21161366561cd7c9e1194819e0a33ea86b", "sha256:1a7bac2bde1d661fb31f4d4e8e539e178774b76db3c2c17c4bb3e960a5de07a2",
"sha256:316449aefacf40147a9efaf3bd7c9bdd35aaba9ac5d708bd1eb5763c9a02bef5", "sha256:237f9be419e977a0f8f6b2e7b0475ababe78ff1ab06822df95d914a945eac827",
"sha256:327763da824817b38ad125dcd97595f942d720d32d879f6c4ddf843e3da3fe90", "sha256:266710eb6fddc1f5e51843c70e3bebfb0f5e77cf4f27129278c70554104d19ed",
"sha256:32aa53a9a63b7f01ed32e316e354e81e9da0e6267435c7243bf8ae0f10b428ef", "sha256:29c7fd632ccaf5517c16a5188e36f6612d6472ccf55382db6c7fe3fcccb7f59f",
"sha256:34e19e56d68b0dad5cff62273107cf5d9fbaf9d75c46277aa5d803b3ef8a9e9b", "sha256:2b7a21715fb12274a71d335cff6c71fe7f676b293d322722fe708a9ec81d91f5",
"sha256:3770e260b18e7f4e576edca4c0a639f704088602e0bc921c5c2e721e3acb8d15", "sha256:2cfb371be97d4db374cba381b9f911dd35bb5f4c58faa7b8b7106c8853e5d225",
"sha256:3d2e3ab79a1771c530233cadfd277fcc762656d50836c77abb2e5e72b88e3a48", "sha256:2cfcb3952350e95603f232a7a15f6c5f86c5375e46f0bd4ae70d43e3e063c13d",
"sha256:41face41f036fee09eba33a5b53a73e9a43d5cb2c53dad8e61fa6c9f91b5a51e", "sha256:2f1fefb2e90e89959447bc0420fddd1e76f625784340d64a2f7d5983ef9ad246",
"sha256:43e3e37c15a8b6fe00c1bce2473cfa8eb3484bbeecf3aefbf259227e487a03df", "sha256:360a398c3a19672cf93527f7e8d8b60d8275119c5d900f2e184d32483117a705",
"sha256:449f43f49c8ddca87c6b3980c9284cab6bd1f5c9d9a2b00012adaaccd5e7decd", "sha256:3e380c89983ce6e6fe2dd1e1921b9952fb4e6da882931abd1824c092ed495dec",
"sha256:4933a508d2f78099162da473841c652ad0de892719043d3f07cc83b33dfd9d91", "sha256:4a8ec1e4e16e2d5bafc9ba82f7aaecfeec990ca7cd27e84fb6f191804ed2fcfc",
"sha256:49d617df841a63b4445790a254013aea2120357ccacbed00253f9c2b5dc24e2d", "sha256:4ab626da2fc1ac277bbf752446470b367f84b50295264d2d313e28dc4405d663",
"sha256:49fb58bcaa343fedc6a9e91f90195b20ccb3135447dc9e4e2570c3a39565853e", "sha256:4b6227351e11c57ae997d222e13f5b6f1f0700d84b8c52304e8675d33a808382",
"sha256:4a7fa2bc0efef3e209a8199fd111b8969fe9db9c711acc46636686331eda7dd4", "sha256:554389562c29c2c182e3908b149095051f81d28c2fec79ad6c8997d7d63e0009",
"sha256:4abf4ad269856618f82dee296ac66b0cd1d71450fc3c98532d93798e73399b7a", "sha256:5c40fe7dd9e5f81e0847b1ea64e1f5dd79dd61afbedb57759df06767ac719b40",
"sha256:4b8693502d1967b00f2fb82fc1e744df128ba22f530e15b763c8d82baee15370", "sha256:68b2dddba7a4e6151384e252a5632efcaa9bc5d1c4b567f3cb621306b2ca9f63",
"sha256:4d28cea3c976499475f5b7a2fec6b3a36208656963c1a856d328aeae056fc5c1", "sha256:7ee32c9a9bee4d0b7bd7cbeb53cb185cf0b622ac761efaa2eba84006c3b3a614",
"sha256:5148c2f1ea043db13ce9b0c28456e18ecc8f14f41325aa624314095b6aa2e9ea", "sha256:830aa432ba5c491d52a15b51526c29e4a4b92bf4f92253787f9726fe01519487",
"sha256:54ca90a9ae6597ae6dc00e7ed0a040ef723f84ec517d3e7ce13e63e4bc82fa04", "sha256:832ccc221927c860e7286c55c9b6ebcc0265d5e072f49c7f6456c7798d2b39aa",
"sha256:551ec3ee2a3ac9cbcf48a4ec76e42c2ef938a7e905a35b42a1267fa4b1645896", "sha256:839ebd0df4a18c5b3c1b890145b5a3f5f64063c2a0d02b13c76d78fe5de34936",
"sha256:5c51749f3e4e269231510da426ce4a44beb98db2dce9097225c338f815b05d4f", "sha256:852de68acd6212cd6d33edf21e6f9e56e5d98c6add46f48244bd479d97c967c6",
"sha256:632676574429bee8c26be8af52af20e0c718cc7f5f67f3fb658c71928ccd4f7f", "sha256:85fbb6102b3296926d0c62cfc9347f6237fb9400aecd0ba6bbda94cae15f2b3b",
"sha256:6509ed3f467b79d95fc62a98229f79b1a60d1b93f101e1c61d10c95a46a84f43", "sha256:86c0df05b47a79d80351cd179893f2f9c1b1cae49d96e8b3290c7f4bd0ca0a92",
"sha256:6bdcfa3cd6fdbdd1a068a52820f46a815401cbc2cb187dd006cb076675e7b735", "sha256:894342d61d355446d02cd3988a7326af344143eb33a2fd5d38482a92072d9563",
"sha256:7138eff8baa883aeaa074359daabb8b6c1e73ffe69d5accdc907d62e50b1c0da", "sha256:8c0db396e6003d99bb2d7232c957b5f0b5634bbd1b24e381a5afcc880f7373fb",
"sha256:7211b463695d1e995ca3feb38b69227e46dbd03947172585ecb0588f19b0d87a", "sha256:8e637810586e6fe380c8bc1b3910accd7f1d3a9a7262c8a78d4c8fb3ba6a2b3d",
"sha256:73bde715f940bea845a95247ea3e5eb17769ba1010efdc938ffcb967c634fa61", "sha256:9475b0093767e1475095f2aeb1d219fb9664081d403d1dff81342df8cd707034",
"sha256:78470906a6be5199524641f538bd2c56bb809cd4bf29a566a75051610bc982c3", "sha256:95cf944fcfc394c5f9de794ce581914900f82ff1f855326f25ebcf24d5397418",
"sha256:7ae3e208b31be8ce7f4c2c0034f33406dd24fbce3467f77223d10cd86778471c", "sha256:974866e0db748ebf1eccab17862bc0f0303807ed9cda465d1324625b81293a18",
"sha256:7e4bd963a935aaf40b625c2499f3f4f6bbd0c3776f6d3bc7c853d04824ff1c9f", "sha256:9848b21ae152fe79c10dd0197304ada8f7b586d3ebc3f27f43c506e5a52a863c",
"sha256:82ae557a8c037c42a6ef26c494d0631cacca040934b101d001100ed93d43f361", "sha256:9f4571a783914feda92018ef3901dab8caf5b029325b5fe4558c074582815249",
"sha256:82b2509f08761f29a0fdad35f7e1638b8ab1adfa2666d41b794090361fb8b855", "sha256:a056c2f692d65bf1e99c41045e3bdcaea3cb9e6b5a53dcaf60a5f3bd95fc9763",
"sha256:8360f7314a070c30e4c976b183d1d8d1585a4a50c5cb603f431cebcbb4f66327", "sha256:a0dbcb1c2d8f2ab6e0a81c6699b236932bd264d4cef1ac475858d16c403de74d",
"sha256:85d5f0c7771dcc7a26c7a27145059b6bb0ce06e4e751ed76cdf123d7039b60b5", "sha256:a16512051a822a416b0d477d5f8c0e67b67c1a20d9acecb0aafa3aa4d6e7d256",
"sha256:88bcd4d0fe1d8ff43675360a72def210ebad3f3f72cabfeac08d825d2639b4ab", "sha256:a2014a2b18ad3ca53b1f6c23f8cd94a18ce930c1837bd891262c182640eb40a6",
"sha256:9301c689051a4857d5b10777da23fafb8e8e921bcf3abe6448a058d27fb67633", "sha256:a3904d88955fda461ea2531fcf6ef73584ca921415d5cfa44457a225f4a42bc1",
"sha256:951088d12d339690a92cef2ec5d3cfd957692834c72ffd570ea76a6790222777", "sha256:a74add8d7727e6404d5dc4dcd7fac65d4d82f95928bbee0cf5414c900e86773e",
"sha256:95cf3b95ea665ab03f5a54765fa41abf0529dbaf372c3b83d91ad2cfa695779b", "sha256:ab44e1580924d1ffd7b3938e02716d5ad190441965138b4aa1d1f31ea0877f04",
"sha256:96619302d4374de5e2345b2b622dc481257a99431277662c30f606f3e22f42be", "sha256:b551d4fb482fc57d852b4541f911ba28957d051c8776e79c3b4a51eb5e2a1b11",
"sha256:999928c6434372fde16c8f27143d3e97201160b48a614071261701615a2a156f", "sha256:b5eb568c2aa6018e26da9e6c86f3ec3fd958cee7f0311b35c2630fa4217d17f2",
"sha256:9a60e2bf9dc6afe7f743e7c9b149d1fdd6dbf35153c78fe3a14ae1a9aee3d98b", "sha256:b659576b950865fdad31fa491d31d37cf78b27113a7671d39f919828587b429b",
"sha256:9f895d785eb6164678ff4bb5cc60c5996b3ee6df3edb28dcdeba86a13ea0465e", "sha256:b6e76ceb1dd18c8e29c73f47d41866972e891fc4cc7ba014f487def72c1cf096",
"sha256:a2a9891723a735d3e2540651184be6fd5b96880c08ffe1a98bae5017e65b544b", "sha256:b7529b5dcc114679d43827d8c35a07c493ad6f083633d573d81c660abc5979e9",
"sha256:a974231b4fdd1bb7f62064a0565a6b107d27d21d9acb50c484d2cdba515b9366", "sha256:b9dca99744991fc9850d18015c4f0438865414e50069670f5f7eee08340d8b40",
"sha256:aa0fd7248cf533c259e59dc593a60973a73e881162b1a2f73360547132742823", "sha256:ba5552a1b07c8edbf197055bc9d518b8f0d98a1c6a73a293bc0726dce068ed01",
"sha256:acbfa31e315a8f14fe33e3542cbcafc55703b8f5dcbb7c1eecd30f141df50db3", "sha256:bfe0cbc787770e52a96c6fda6726ace75be7f840cb327e1b08d7d54eadc3bc85",
"sha256:afb72325b74fa7a428c009c1b8be4b4d7c2afedafb2982827ef2156646df2fe1", "sha256:c0901429650652d3f0da90bad42bdafc1f9143ff3605633c455c999a2d786cac",
"sha256:b3ef2c69c655db63deb96b3c3e587084612f9b1fa983df5e0c3379d41307467f", "sha256:cb1489f25b051a89fae574505cc26360c8e95e227a9500182a7fe0afcc500ce0",
"sha256:b52a65e4ea43c6d149c5f8ddb0bef8d4a1e779b77591a458a893eb416624a418", "sha256:cd47d063fbeabd4c6cae1d4bcaa38f0902f8dc5ed168072874ea11d0c7afc1ff",
"sha256:b665caeeda58625c3946ad7308fbd88a086ee51ccb706307e5b1fa91556ac886", "sha256:d363152c5e16b29d66cbde8fa614f9e313e6f94a8204eaab268db52231fe5358",
"sha256:b74fdffce9dfcf2dc296dec8743e5b0332d15df19ae464f0e249aa871fc1c571", "sha256:d5730f3aa35e646103b53389d5bc77edfbf578ab6dab2e005142b5b80a35ef25",
"sha256:b995bfa6bf01a9e09b884077a6d37070464b529d8682d7691c2d3b540d357a0c", "sha256:d6f9367b132078b2ceb8d066ff6c93a970a18c3029cea37bfd7b2d3dd2e5db8f",
"sha256:bd82010f8ab451dabe36054a1622870166a67cf3fce894f68895db6f74bbdc94", "sha256:dfd6ae1c385ab481766b3c61c44aca2b3cd775f6f7c0fa93d979ddec853d29d5",
"sha256:bdcd5538e27f188dd3c804b4a8d5f52a7fc7f87e7fd6b374b8e36a4ca03db428", "sha256:e0da39ff917af8b27a4bdc5a97ac577552a38aac0d260a859c1517ea3dc1a7c4",
"sha256:c79d7719d027b7a42817c5d96461a99b6a49979c143839fc37aa5748c322f234", "sha256:ecf6cd9f83d7c023b1aba15d13f705ca7b7d38675c121f3cc4a6e25bd0857ee9",
"sha256:cdab9555053399318b953a1fe1f586e945bc8d635ce9d05e617fd9fe3a4687d6", "sha256:ee0822ce1b8a14fe5a066f93edd20aada932acfe348bede8aa2149f1a4489512",
"sha256:ce72dba6a20e39a0c628258b5c308779b8697f7676c254a845715e2a1039b968", "sha256:f2e55a9b162e06e3f862fb61e399fe9f05d908d019d87bf5b496a04ef18a970a",
"sha256:d337193bbf3e45171c8025e291530fb7548a93c45253897cd764a6a71c937ed9", "sha256:f436601594f15bf406518af922a89dcaab416568edb6f65c4e5bbbad1ea45c11",
"sha256:d3dcb774e3568477275cc76554b5a565024b8ba3a0322f77c246bc7111c5bb9c", "sha256:f59b870db1f1ae5a9ac28245707d955c8721dd6565e7f411024fa374b5362d1d",
"sha256:d64ba08db72e5dfd5c33be1e1e687d5e4fcce09219e8aee893a4862034081d4e", "sha256:fc533aa50664ebd6c628b2f30591956519462f5d27f951ed03d6c82b2dfd9965",
"sha256:d7a2e3b7f5703ffbd500dabdefcbc9eafeff4b9444bbdd5d83d79eedf8428fab", "sha256:fe43139b2c0fdc4a14d4f8d5b5d967f7a2777fd3d38ecf5b1ec669b0d7e43c21",
"sha256:d831ee0a50946d24a53821819b2327d5751b0c938b12c0653ea5be7dea9c82ec", "sha256:fed1cd825158dcaae36acce7b2db33dcbfd12b30c34317a88b8ed80f0541cc57"
"sha256:d9018153cf57fc302a2a34cb7564870b859ed9a732d16b41a9b5cb2ebed2d444",
"sha256:e5171ef898299c657685306d8e1478a45e9303ddcd8ac5fed5bd52ad4ae0b69b",
"sha256:e94e98c7cb94cfa6e071d401ea3342767f28eb5a06a58fafdc0d2a4974f4f35c",
"sha256:ec39698c45b11d9694a1b635a70946a5bad066b593af863460a8e600f0dff1ca",
"sha256:ed9aba6e01ff6f2e8285e5aa4154e2970068fe0fc0998c4380d0e6278222269b",
"sha256:edf71b01dec9f766fb285b73930f95f730bb0943500ba0566ae234b5c1618c18",
"sha256:ee82c98bed9d97cd2f53bdb035e619309a098ea53ce525833e26b93f673bc318",
"sha256:f4c96283fca3ee09fb044f02156d9570d156698bc3734252175a38f0e8975f07",
"sha256:f7d9b87c4c55e3ea8881dfcbf6d61ea6775fffed1fedffaa60bd047d3c08c430",
"sha256:f83df90191d67af5a831da3a33dd7628b02a95450e168785586ed51e6d28943c",
"sha256:fca9433a45f18b7c779d2bae7beeec4f740d28b788b117a48368d95a3233ed83",
"sha256:fd92bbaa2ecdb7864b7600dcdb6f2f1db6e0346ed425fbd01085be04c63f0b05"
], ],
"markers": "python_version >= '3.8'", "markers": "python_version >= '3.9'",
"version": "==0.24.0" "version": "==1.0.5"
}, },
"websockets": { "websockets": {
"hashes": [ "hashes": [
"sha256:00fe5da3f037041da1ee0cf8e308374e236883f9842c7c465aa65098b1c9af59", "sha256:0701bc3cfcb9164d04a14b149fd74be7347a530ad3bbf15ab2c678a2cd3dd9a2",
"sha256:01bb2d4f0a6d04538d3c5dfd27c0643269656c28045a53439cbf1c004f90897a", "sha256:0a34631031a8f05657e8e90903e656959234f3a04552259458aac0b0f9ae6fd9",
"sha256:034feb9f4286476f273b9a245fb15f02c34d9586a5bc936aff108c3ba1b21beb", "sha256:0af68c55afbd5f07986df82831c7bff04846928ea8d1fd7f30052638788bc9b5",
"sha256:04a97aca96ca2acedf0d1f332c861c5a4486fdcba7bcef35873820f940c4231e", "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3",
"sha256:0d4290d559d68288da9f444089fd82490c8d2744309113fc26e2da6e48b65da6", "sha256:0f3c1e2ab208db911594ae5b4f79addeb3501604a165019dd221c0bdcabe4db8",
"sha256:1288369a6a84e81b90da5dbed48610cd7e5d60af62df9851ed1d1d23a9069f10", "sha256:0fdfe3e2a29e4db3659dbd5bbf04560cea53dd9610273917799f1cde46aa725e",
"sha256:14839f54786987ccd9d03ed7f334baec0f02272e7ec4f6e9d427ff584aeea8b4", "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1",
"sha256:1d045cbe1358d76b24d5e20e7b1878efe578d9897a25c24e6006eef788c0fdf0", "sha256:1234d4ef35db82f5446dca8e35a7da7964d02c127b095e172e54397fb6a6c256",
"sha256:1f874ba705deea77bcf64a9da42c1f5fc2466d8f14daf410bc7d4ceae0a9fcb0", "sha256:16b6c1b3e57799b9d38427dda63edcbe4926352c47cf88588c0be4ace18dac85",
"sha256:205f672a6c2c671a86d33f6d47c9b35781a998728d2c7c2a3e1cf3333fcb62b7", "sha256:2034693ad3097d5355bfdacfffcbd3ef5694f9718ab7f29c29689a9eae841880",
"sha256:2177ee3901075167f01c5e335a6685e71b162a54a89a56001f1c3e9e3d2ad250", "sha256:21c1fa28a6a7e3cbdc171c694398b6df4744613ce9b36b1a498e816787e28123",
"sha256:219c8187b3ceeadbf2afcf0f25a4918d02da7b944d703b97d12fb01510869078", "sha256:229cf1d3ca6c1804400b0a9790dc66528e08a6a1feec0d5040e8b9eb14422375",
"sha256:25225cc79cfebc95ba1d24cd3ab86aaa35bcd315d12fa4358939bd55e9bd74a5", "sha256:27ccee0071a0e75d22cb35849b1db43f2ecd3e161041ac1ee9d2352ddf72f065",
"sha256:3630b670d5057cd9e08b9c4dab6493670e8e762a24c2c94ef312783870736ab9", "sha256:363c6f671b761efcb30608d24925a382497c12c506b51661883c3e22337265ed",
"sha256:368a05465f49c5949e27afd6fbe0a77ce53082185bbb2ac096a3a8afaf4de52e", "sha256:39c1fec2c11dc8d89bba6b2bf1556af381611a173ac2b511cf7231622058af41",
"sha256:36ebd71db3b89e1f7b1a5deaa341a654852c3518ea7a8ddfdf69cc66acc2db1b", "sha256:3b1ac0d3e594bf121308112697cf4b32be538fb1444468fb0a6ae4feebc83411",
"sha256:39450e6215f7d9f6f7bc2a6da21d79374729f5d052333da4d5825af8a97e6735", "sha256:3be571a8b5afed347da347bfcf27ba12b069d9d7f42cb8c7028b5e98bbb12597",
"sha256:398b10c77d471c0aab20a845e7a60076b6390bfdaac7a6d2edb0d2c59d75e8d8", "sha256:3c714d2fc58b5ca3e285461a4cc0c9a66bd0e24c5da9911e30158286c9b5be7f",
"sha256:3c3deac3748ec73ef24fc7be0b68220d14d47d6647d2f85b2771cb35ea847aa1", "sha256:3d00075aa65772e7ce9e990cab3ff1de702aa09be3940d1dc88d5abf1ab8a09c",
"sha256:3f14a96a0034a27f9d47fd9788913924c89612225878f8078bb9d55f859272b0", "sha256:3e90baa811a5d73f3ca0bcbf32064d663ed81318ab225ee4f427ad4e26e5aff3",
"sha256:3fc753451d471cff90b8f467a1fc0ae64031cf2d81b7b34e1811b7e2691bc4bc", "sha256:47819cea040f31d670cc8d324bb6435c6f133b8c7a19ec3d61634e62f8d8f9eb",
"sha256:414ffe86f4d6f434a8c3b7913655a1a5383b617f9bf38720e7c0799fac3ab1c6", "sha256:47b099e1f4fbc95b701b6e85768e1fcdaf1630f3cbe4765fa216596f12310e2e",
"sha256:449d77d636f8d9c17952628cc7e3b8faf6e92a17ec581ec0c0256300717e1512", "sha256:4a9fac8e469d04ce6c25bb2610dc535235bd4aa14996b4e6dbebf5e007eba5ee",
"sha256:4b6caec8576e760f2c7dd878ba817653144d5f369200b6ddf9771d64385b84d4", "sha256:4b826973a4a2ae47ba357e4e82fa44a463b8f168e1ca775ac64521442b19e87f",
"sha256:4d4fc827a20abe6d544a119896f6b78ee13fe81cbfef416f3f2ddf09a03f0e2e", "sha256:4c2529b320eb9e35af0fa3016c187dffb84a3ecc572bcee7c3ce302bfeba52bf",
"sha256:5a42d3ecbb2db5080fc578314439b1d79eef71d323dc661aa616fb492436af5d", "sha256:54479983bd5fb469c38f2f5c7e3a24f9a4e70594cd68cd1fa6b9340dadaff7cf",
"sha256:5b918d288958dc3fa1c5a0b9aa3256cb2b2b84c54407f4813c45d52267600cd3", "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4",
"sha256:5ef440054124728cc49b01c33469de06755e5a7a4e83ef61934ad95fc327fbb0", "sha256:5756779642579d902eed757b21b0164cd6fe338506a8083eb58af5c372e39d9a",
"sha256:660c308dabd2b380807ab64b62985eaccf923a78ebc572bd485375b9ca2b7dc7", "sha256:592f1a9fe869c778694f0aa806ba0374e97648ab57936f092fd9d87f8bc03665",
"sha256:6a6c9bcf7cdc0fd41cc7b7944447982e8acfd9f0d560ea6d6845428ed0562058", "sha256:595b6c3969023ecf9041b2936ac3827e4623bfa3ccf007575f04c5a6aa318c22",
"sha256:6d24fc337fc055c9e83414c94e1ee0dee902a486d19d2a7f0929e49d7d604b09", "sha256:5a939de6b7b4e18ca683218320fc67ea886038265fd1ed30173f5ce3f8e85675",
"sha256:7048eb4415d46368ef29d32133134c513f507fff7d953c18c91104738a68c3b3", "sha256:5d54b09eba2bada6011aea5375542a157637b91029687eb4fdb2dab11059c1b4",
"sha256:77569d19a13015e840b81550922056acabc25e3f52782625bc6843cfa034e1da", "sha256:5df592cd503496351d6dc14f7cdad49f268d8e618f80dce0cd5a36b93c3fc08d",
"sha256:8149a0f5a72ca36720981418eeffeb5c2729ea55fa179091c81a0910a114a5d2", "sha256:5f4c04ead5aed67c8a1a20491d54cdfba5884507a48dd798ecaf13c74c4489f5",
"sha256:836bef7ae338a072e9d1863502026f01b14027250a4545672673057997d5c05a", "sha256:64dee438fed052b52e4f98f76c5790513235efaa1ef7f3f2192c392cd7c91b65",
"sha256:8621a07991add373c3c5c2cf89e1d277e49dc82ed72c75e3afc74bd0acc446f0", "sha256:66dd88c918e3287efc22409d426c8f729688d89a0c587c88971a0faa2c2f3792",
"sha256:87e31011b5c14a33b29f17eb48932e63e1dcd3fa31d72209848652310d3d1f0d", "sha256:678999709e68425ae2593acf2e3ebcbcf2e69885a5ee78f9eb80e6e371f1bf57",
"sha256:88cf9163ef674b5be5736a584c999e98daf3aabac6e536e43286eb74c126b9c7", "sha256:67f2b6de947f8c757db2db9c71527933ad0019737ec374a8a6be9a956786aaf9",
"sha256:8fda642151d5affdee8a430bd85496f2e2517be3a2b9d2484d633d5712b15c56", "sha256:693f0192126df6c2327cce3baa7c06f2a117575e32ab2308f7f8216c29d9e2e3",
"sha256:90b5d9dfbb6d07a84ed3e696012610b6da074d97453bd01e0e30744b472c8179", "sha256:746ee8dba912cd6fc889a8147168991d50ed70447bf18bcda7039f7d2e3d9151",
"sha256:90f4c7a069c733d95c308380aae314f2cb45bd8a904fb03eb36d1a4983a4993f", "sha256:756c56e867a90fb00177d530dca4b097dd753cde348448a1012ed6c5131f8b7d",
"sha256:9481a6de29105d73cf4515f2bef8eb71e17ac184c19d0b9918a3701c6c9c4f23", "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475",
"sha256:9607b9a442392e690a57909c362811184ea429585a71061cd5d3c2b98065c199", "sha256:7f493881579c90fc262d9cdbaa05a6b54b3811c2f300766748db79f098db9940",
"sha256:9777564c0a72a1d457f0848977a1cbe15cfa75fa2f67ce267441e465717dcf1a", "sha256:823c248b690b2fd9303ba00c4f66cd5e2d8c3ba4aa968b2779be9532a4dad431",
"sha256:a032855dc7db987dff813583d04f4950d14326665d7e714d584560b140ae6b8b", "sha256:82544de02076bafba038ce055ee6412d68da13ab47f0c60cab827346de828dee",
"sha256:a0adf84bc2e7c86e8a202537b4fd50e6f7f0e4a6b6bf64d7ccb96c4cd3330b29", "sha256:8dd8327c795b3e3f219760fa603dcae1dcc148172290a8ab15158cf85a953413",
"sha256:a35f704be14768cea9790d921c2c1cc4fc52700410b1c10948511039be824aac", "sha256:8fdc51055e6ff4adeb88d58a11042ec9a5eae317a0a53d12c062c8a8865909e8",
"sha256:a3dfff83ca578cada2d19e665e9c8368e1598d4e787422a460ec70e531dbdd58", "sha256:a625e06551975f4b7ea7102bc43895b90742746797e2e14b70ed61c43a90f09b",
"sha256:a4c805c6034206143fbabd2d259ec5e757f8b29d0a2f0bf3d2fe5d1f60147a4a", "sha256:abdc0c6c8c648b4805c5eacd131910d2a7f6455dfd3becab248ef108e89ab16a",
"sha256:a655bde548ca98f55b43711b0ceefd2a88a71af6350b0c168aa77562104f3f45", "sha256:ac017dd64572e5c3bd01939121e4d16cf30e5d7e110a119399cf3133b63ad054",
"sha256:ad2ab2547761d79926effe63de21479dfaf29834c50f98c4bf5b5480b5838434", "sha256:ac1e5c9054fe23226fb11e05a6e630837f074174c4c2f0fe442996112a6de4fb",
"sha256:b1f3628a0510bd58968c0f60447e7a692933589b791a6b572fcef374053ca280", "sha256:ac60e3b188ec7574cb761b08d50fcedf9d77f1530352db4eef1707fe9dee7205",
"sha256:b7e7ea2f782408c32d86b87a0d2c1fd8871b0399dd762364c731d86c86069a78", "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04",
"sha256:bc6ccf7d54c02ae47a48ddf9414c54d48af9c01076a2e1023e3b486b6e72c707", "sha256:b7643a03db5c95c799b89b31c036d5f27eeb4d259c798e878d6937d71832b1e4",
"sha256:bea45f19b7ca000380fbd4e02552be86343080120d074b87f25593ce1700ad58", "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa",
"sha256:cc1fc87428c1d18b643479caa7b15db7d544652e5bf610513d4a3478dbe823d0", "sha256:c338ffa0520bdb12fbc527265235639fb76e7bc7faafbb93f6ba80d9c06578a9",
"sha256:cd7c11968bc3860d5c78577f0dbc535257ccec41750675d58d8dc66aa47fe52c", "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122",
"sha256:ceada5be22fa5a5a4cdeec74e761c2ee7db287208f54c718f2df4b7e200b8d4a", "sha256:d08eb4c2b7d6c41da6ca0600c077e93f5adcfd979cd777d747e9ee624556da4b",
"sha256:cf5201a04550136ef870aa60ad3d29d2a59e452a7f96b94193bee6d73b8ad9a9", "sha256:d50fd1ee42388dcfb2b3676132c78116490976f1300da28eb629272d5d93e905",
"sha256:d9fd19ecc3a4d5ae82ddbfb30962cf6d874ff943e56e0c81f5169be2fda62979", "sha256:d591f8de75824cbb7acad4e05d2d710484f15f29d4a915092675ad3456f11770",
"sha256:ddaa4a390af911da6f680be8be4ff5aaf31c4c834c1a9147bc21cbcbca2d4370", "sha256:d5f6b181bb38171a8ad1d6aa58a67a6aa9d4b38d0f8c5f496b9e42561dfc62fe",
"sha256:df174ece723b228d3e8734a6f2a6febbd413ddec39b3dc592f5a4aa0aff28098", "sha256:d63efaa0cd96cf0c5fe4d581521d9fa87744540d4bc999ae6e08595a1014b45b",
"sha256:e0744623852f1497d825a49a99bfbec9bea4f3f946df6eb9d8a2f0c37a2fec2e", "sha256:d99e5546bf73dbad5bf3547174cd6cb8ba7273062a23808ffea025ecb1cf8562",
"sha256:e5dc25a9dbd1a7f61eca4b7cb04e74ae4b963d658f9e4f9aad9cd00b688692c8", "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561",
"sha256:e7591d6f440af7f73c4bd9404f3772bfee064e639d2b6cc8c94076e71b2471c1", "sha256:e8b56bdcdb4505c8078cb6c7157d9811a85790f2f2b3632c7d1462ab5783d215",
"sha256:eb6d38971c800ff02e4a6afd791bbe3b923a9a57ca9aeab7314c21c84bf9ff05", "sha256:ee443ef070bb3b6ed74514f5efaa37a252af57c90eb33b956d35c8e9c10a1931",
"sha256:ed907449fe5e021933e46a3e65d651f641975a768d0649fee59f10c2985529ed", "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9",
"sha256:f6cf0ad281c979306a6a34242b371e90e891bce504509fb6bb5246bbbf31e7b6", "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f",
"sha256:f95ba34d71e2fa0c5d225bde3b3bdb152e957150100e75c86bc7f3964c450d89" "sha256:fcd5cf9e305d7b8338754470cf69cf81f420459dbae8a3b40cee57417f4614a7"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.9'",
"version": "==14.1" "version": "==15.0.1"
}, },
"zipp": { "zipp": {
"hashes": [ "hashes": [
"sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", "sha256:071652d6115ed432f5ce1d34c336c0adfd6a884660d1e9712a256d3d3bd4b14e",
"sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931" "sha256:a07157588a12518c9d4034df3fbbee09c814741a33ff63c05fa29d26a2404166"
], ],
"markers": "python_version >= '3.9'", "markers": "python_version >= '3.9'",
"version": "==3.21.0" "version": "==3.23.0"
} }
}, },
"develop": {} "develop": {}

View file

@ -61,6 +61,7 @@ extensions = [
"warnings_filter", "warnings_filter",
"sphinx_tags", "sphinx_tags",
"sphinx_design", "sphinx_design",
"sphinx_collapse",
] ]
source_suffix = [".rst", ".md"] source_suffix = [".rst", ".md"]

View file

@ -2,135 +2,122 @@
ELF Programs No Symbol Tables ELF Programs No Symbol Tables
=============================== ===============================
.. warning:: You can easily extend the firmware in your released, embedded system using
Migrated from: ELF programs provided via a file system. For example, an SD card or, perhaps,
https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=139629542 downloaded into on-board SPI FLASH.
You can easily extend the firmware in your released, embedded system using ELF In order to support such post-release updates, your released firmware must
programs provided via a file system (for example, an SD card or downloaded into support execution of ELF programs loaded into RAM and symbol tables also
on-board SPI FLASH). In order to support such post-release updates, your provided via the file system (see `apps/examples/elf`).
released firmware would have to support execution of fully linked, relocatable
ELF programs loaded into RAM (see, for example, ``apps/examples/elf``).
The files shown in this Wiki page can be downloaded `here <https://cwiki.apache.org/confluence/download/attachments/139629402/elfprog-nosymtab.tar.gz?version=1&modificationDate=1576735520000&api=v2>`_. Alan Carvalho de Assis has also made a video based on this example and
published it in the `NuttX YouTube channel <https://www.youtube.com/watch?v=oL6KAgkTb8M>`_.
Alan Carvalho de Assis has also made a video based on this example in the
YouTube `NuttX Channel <https://www.youtube.com/watch?v=oL6KAgkTb8M>`_.
Creating the Export Package Creating the Export Package
=========================== ===========================
At the time that you release the firmware, you should create and save an At the time of firmware release, you should create and save an export package.
export package. The export package is all that you need to create This export package contains all the necessary files required to create
post-release, add-on modules for your embedded system. Let's illustrate this post-release add-on modules for your embedded system.
using the ``STM32F4-Discovery`` networking ``NSH`` configuration with the
``STM32F4DIS-BB`` baseboard. (This demonstration assumes that you also have
support for some externally modifiable media in the board configuration, such
as removable media like an SD card, or a USB FLASH stick, an internal file
system remotely accessible via USB MSC, FTP, or any remote file system (NFS).
The networking ``NSH`` configuration uses the SD card on the STM32 baseboard
for this demonstration. Other ``NSH`` configurations could be used, provided
that you supply the necessary file system support in some fashion.)
(No baseboard? You can add file system support to the basic ``STM32F4-Discovery`` For demonstration purposes, we'll use the STM32F4-Discovery with the network
board by following these instructions: NSH configuration. This setup assumes that you have the STM32F4DIS-BB
`USB FLASH drive <https://www.youtube.com/watch?v=5hB5ZXpRoS4>`_ baseboard. The demonstration also requires support for externally modifiable
or `SD card <https://www.youtube.com/watch?v=H28t4RbOXqI>`_.) media, such as:
.. code-block:: shell - Removable media, like an SD card or USB flash drive.
- An internal file system remotely accessible via USB MSC, FTP, or other
protocols.
- A remote file system, such as NFS.
In this demonstration, the networking NSH configuration uses the SD card on
the STM32 baseboard. Other NSH configurations can also be used, provided they
supply the necessary file system support.
.. tip::
No baseboard? You can add file system support to the basic STM32F4-Discovery
board by following these instructions: `USB FLASH drive <https://www.youtube.com/watch?v=5hB5ZXpRoS4>`__
or `SD card <https://www.youtube.com/watch?v=H28t4RbOXqI>`__.
Initialize the environment:
.. code-block:: console
$ make distclean $ make distclean
$ tools/configure.sh -c stm32f4discovery:netnsh $ tools/configure.sh -c stm32f4discovery:netnsh
$ make menuconfig $ make menuconfig
Your released firmware would have to have been built with a few important Edit the configuration:
configuration settings:
1. Disable networking (Only because it is not needed in this example): - Disable networking (it is not needed in this example):
``# CONFIG_NET is not set``.
.. code-block:: shell - Enable ELF binary support without external symbol tables:
``CONFIG_ELF=y``,
# CONFIG_NET is not set ``CONFIG_LIBC_EXECFUNCS=y``,
``# CONFIG_EXECFUNCS_HAVE_SYMTAB is not set``.
2. Enable basic ELF binary support with no built-in symbol table support: - Enable PATH variable support:
``CONFIG_LIBC_ENVPATH=y``,
.. code-block:: shell ``CONFIG_PATH_INITIAL="/addons"``,
``# CONFIG_DISABLE_ENVIRON not set``.
CONFIG_ELF=y - Enable execution of ELF files from NSH: ``CONFIG_NSH_FILE_APPS=y``.
CONFIG_LIBC_EXECFUNCS=y
# CONFIG_EXECFUNCS_HAVE_SYMTAB is not set
3. Enable PATH variable support:
.. code-block:: shell
CONFIG_BINFMT_EXEPATH=y
CONFIG_PATH_INITIAL="/bin"
# CONFIG_DISABLE_ENVIRON not set
4. Enable execution of ELF files from the ``NSH`` command line:
.. code-block:: shell
CONFIG_NSH_FILE_APPS=y
.. note:: .. note::
You must enable some application that uses ``printf()``. This is necessary You must enable some application that uses ``printf()``. This is necessary
to assure that the symbol ``printf()`` is included in the base system. to ensure that the symbol ``printf()`` is included in the base system.
Here we assume that you include the "Hello, World!" example from Here we assume that the "Hello, World!" example from ``apps/examples/hello``
``apps/examples/hello``: has been enabled with the configuration option ``CONFIG_EXAMPLES_HELLO=y``.
.. code-block:: shell Then, build the NuttX firmware image and the export package:
CONFIG_EXAMPLES_HELLO=y .. code-block:: console
Then we can build the NuttX firmware image and the export package:
.. code-block:: shell
$ make $ make
$ make export $ make export
When ``make export`` completes, you will find a ZIP'ed package in the top-level When ``make export`` completes, you will find a ZIP package in the top-level
NuttX directory called ``nuttx-export-x.y.zip`` (for version ``x.y``). The NuttX directory called ``nuttx-export-x.y.zip`` (where ``x.y`` corresponds to
version is determined by the ``.version`` file in the same directory. The the version determined by the ``.version`` file in the same directory).
content of this ZIP file is the following directory structure: The contents of this ZIP file are organized as follows:
.. code-block:: shell .. code-block:: text
nuttx-export-x.x nuttx-export-x.x
|- arch/ |- arch/
|- build/
|- include/ |- include/
|- libs/ |- libs/
|- registry/
|- scripts/
|- startup/ |- startup/
|- tools/
|- System.map |- System.map
`- .config `- .config
The Add-On Build Directory Preparing the Add-On Build Directory
========================== ====================================
In order to create the add-on ELF program, you will need (1) the export In order to create the add-on ELF program, you will need:
package, (2) the program build ``Makefile``, (3) a linker script used by the
``Makefile``, and (4) a Bash script to create a linker script. That 1. The export package.
``Makefile`` and Bash Script are discussed in the following paragraphs. 2. A Makefile to build the program.
3. A first linker script to use in the Makefile (``gnu-elf.ld``).
4. A Bash script to create a second linker script (``defines.ld``).
.. note:: .. note::
These example files implicitly assume a GNU tool chain is used and, in at These example files implicitly assume a GNU tool chain is used and, in at
least one place, that the target is an ARMv7-M platform. A non-GNU tool least one place, that the target is an ARMv7-M platform. A non-GNU tool
chain would probably require a significantly different ``Makefile`` and chain would probably require a significantly different Makefile and
linker script. There is at least one ARMv7-M specific change that would linker script. There is at least one ARMv7-M specific change that would
have to be made for other platforms in the script that creates the linker have to be made for other platforms in the script that creates the linker
script (``mkdefines.sh``). script (later on referred to as ``mkdefines.sh``).
Hello Example Hello Example
============= =============
To keep things manageable, let's use a concrete example. Suppose the ELF To keep things manageable, let's use a concrete example. Suppose the ELF
program that we wish to add to the release code is the single source file program that we wish to add to the release code is the simple
``hello.c``: source file ``hello.c``:
.. code-block:: c .. code-block:: c
@ -138,115 +125,115 @@ program that we wish to add to the release code is the single source file
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
printf("Hello from Add-On Program!\n"); printf("Hello from a fully linked Add-On Program!\n");
return 0; return 0;
} }
Let's say that we have a directory called ``addon`` and it contains the Let's say that we have a directory called ``addon`` that contains
``hello.c`` source file, a ``Makefile`` that will create the ELF program, and a the following:
Bash script called ``mkdefines.sh`` that will create a linker script.
1. The ``hello.c`` source file.
2. A Makefile to build the ELF program.
3. The export package ``nuttx-export-x.y.zip``.
4. A Bash script called ``mkdefines.sh`` that will create the second
(``defines.ld``) linker script.
Building the ELF Program Building the ELF Program
======================== ========================
The first step in creating the ELF program is to unzip the Export Package. We The first step in creating the ELF program is to unzip the export
start with our ``addon`` directory containing the following: package. Starting in the ``addon`` directory:
.. code-block:: shell .. code-block:: console
$ cd addon $ cd addon
$ ls $ ls
gnu-elf.ld hello.c Makefile mkdefines.sh nuttx-export-7.25.zip hello.c Makefile mkdefines.sh nuttx-export-x.y.zip
Where: Where:
- ``hello.c`` is the example source file.
- ``Makefile`` builds the ELF program.
- ``mkdefines.h`` is the Bash script that will create the linker script that will serve as the symbol table.
- ``nuttx-export-x.y.zip`` is the export package from NuttX version ``x.y``.
- ``gnu-elf.ld`` is the linker script. Unzip the export package and rename the folder for ease of use:
- ``hello.c`` is our example source file.
- ``Makefile`` will build our ELF program and symbol table.
- ``mksymtab.h`` is the Bash script that will create the symbol table for the
ELF program.
- ``nuttx-export-7.25.zip`` is the Export Package for NuttX-7.25.
We unzip the Export Package like: .. code-block:: console
.. code-block:: shell $ unzip nuttx-export-x.y.zip
$ mv nuttx-export-x.y nuttx-export
$ unzip nuttx-export-7.25.zip This creates a new directory called ``nuttx-export``, containing
all the content from the released NuttX code required to build
Then we have a new directory called ``nuttx-export-7.25`` that contains all of the ELF program.
the content from the released NuttX code that we need to build the ELF
program.
The Makefile The Makefile
============ ============
The ELF program is created simply as: The ELF program is created simply as:
.. code-block:: shell .. code-block:: console
$ make $ make
This uses the following ``Makefile`` to generate several files: This uses the following Makefile to generate several files:
- ``hello.o``: The compiled ``hello.c`` object. - ``hello.o``: The compiled ``hello.c`` object.
- ``hello.r``: A "partially linked" ELF object that still has undefined - ``hello.r``: A partially linked ELF object that still has undefined symbols.
symbols.
- ``hello``: The fully linked, relocatable ELF program. - ``hello``: The fully linked, relocatable ELF program.
- ``linker.ld``: A linker script created by ``mkdefines.sh``. - ``linker.ld``: The linker script created by ``mkdefines.sh``.
Only the resulting ``hello`` is needed. The Makefile used to create the ELF program is as follows:
Below is the ``Makefile`` used to create the ELF program: .. note::
.. code-block:: shell When copying the following contents, remember that Makefile indentations
must be made with proper tab characters and not just spaces.
include nuttx-export-7.25/build/Make.defs .. code-block:: makefile
# Long calls are need to call from RAM into FLASH include nuttx-export/scripts/Make.defs
# Long calls are needed to call from RAM into FLASH
ARCHCFLAGS += -mlong-calls ARCHCFLAGS += -mlong-calls
# You may want to check these options against the ones in "nuttx-export/scripts/Make.defs"
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
ARCHOPTIMIZATION = -Os -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer ARCHOPTIMIZATION = -Os -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer
ARCHINCLUDES = -I. -isystem nuttx-export-7.25/include ARCHINCLUDES = -I. -isystem nuttx-export/include
CFLAGS = $(ARCHCPUFLAGS) $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHINCLUDES) -pipe CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
CROSSDEV = arm-none-eabi-
CC = $(CROSSDEV)gcc
LD = $(CROSSDEV)ld
STRIP = $(CROSSDEV)strip --strip-unneeded
# Setup up linker command line options # Setup up linker command line options
LDRELFLAGS = -r LDRELFLAGS = --relocatable
LDELFFLAGS = -r -e main LDELFFLAGS = --relocatable -e main
LDELFFLAGS += -T defines.ld -T gnu-elf.ld LDELFFLAGS += -T defines.ld -T nuttx-export/scripts/gnu-elf.ld
# This might change in a different environment
OBJEXT ?= .o
# This is the generated ELF program # This is the generated ELF program
BIN = hello BIN = hello
REL = hello.r REL = hello.r
# These are the sources files that we use # These are the source files that we use
SRCS = hello.c SRCS = hello.c
OBJS = $(SRCS:.c=$(OBJEXT)) OBJS = $(SRCS:.c=$(OBJEXT))
# Build targets # Build targets
all: $(BIN)
.PHONY: clean .PHONY: clean
all: $(BIN)
$(OBJS): %$(OBJEXT): %.c $(OBJS): %$(OBJEXT): %.c
$(CC) -c $(CFLAGS) -o $@ $< $(CC) -c $(CFLAGS) -o $@ $<
System.map: nuttx-export-7.25/System.map System.map: nuttx-export/System.map
cat nuttx-export-7.25/System.map | sed -e "s/\r//g" >System.map cat nuttx-export/System.map | sed -e "s/\r//g" > System.map
$(REL): $(OBJS) $(REL): $(OBJS)
$(LD) $(LDRELFLAGS) -o $@ $< $(LD) $(LDRELFLAGS) -o $@ $<
@ -256,25 +243,30 @@ Below is the ``Makefile`` used to create the ELF program:
$(BIN): defines.ld $(REL) $(BIN): defines.ld $(REL)
$(LD) $(LDELFFLAGS) -o $@ $(REL) $(LD) $(LDELFFLAGS) -o $@ $(REL)
$(STRIP) $(REL) $(STRIP) $@
#$(CROSSDEV)objdump -f $@
clean: clean:
rm -f $(BIN) rm -f $(BIN)
rm -f $(REL) rm -f $(REL)
rm -f $(OBJS)
rm -f defines.ld rm -f defines.ld
rm -f System.map rm -f System.map
rm -f *.o
The Linker Script The Linker Script
================= =================
Two linker scripts are used. One is a normal file (we'll call it the main Two linker scripts are used: the main one, ``gnu-elf.ld``, is a normal file,
linker script), and the other, ``defines.ld``, is created on-the-fly as while ``defines.ld`` is created on-the-fly as described in the next section.
described in the next section.
The main linker script, ``gnu-elf.ld``, contains the following: The main linker script used in this example is the one from the exported
NuttX package: ``nuttx-export/scripts/gnu-elf.ld``.
.. code-block:: shell .. admonition:: Here is an alternative minimal (and possibly outdated) version
.. collapse:: Show content:
.. code-block:: text
SECTIONS SECTIONS
{ {
@ -342,17 +334,17 @@ The main linker script, ``gnu-elf.ld``, contains the following:
Creating the ``defines.ld`` Linker Script Creating the ``defines.ld`` Linker Script
========================================= =========================================
The additional linker script ``defines.ld`` is created through a three-step The additional linker script, ``defines.ld``, is created through a three-step
process: process:
1. The ``Makefile`` generates a partially linked ELF object, ``hello.r``. 1. The Makefile generates a partially linked ELF object, ``hello.r``.
2. The ``Makefile`` then invokes the ``mkdefines.sh`` script, which generates 2. The Makefile then invokes the ``mkdefines.sh`` script, which generates
the ``defines.ld`` linker script that provides values for all of the the ``defines.ld`` linker script that provides values for all of the
undefined symbols. undefined symbols.
3. Finally, the ``Makefile`` produces the fully linked, relocatable ``hello`` 3. Finally, the Makefile produces the fully linked, relocatable ``hello``
ELF object using the ``defines.ld`` linker script. ELF binary using the ``defines.ld`` linker script.
Below is the version of ``mkdefines.sh`` used in this demo: Here are the contents of the ``mkdefines.sh`` script used in this example:
.. code-block:: bash .. code-block:: bash
@ -366,7 +358,7 @@ Below is the version of ``mkdefines.sh`` used in this demo:
if [ -z "$sysmap" ]; then if [ -z "$sysmap" ]; then
echo "ERROR: Missing <system-map>" echo "ERROR: Missing <system-map>"
echo "" echo ""
echo $usage echo "$usage"
exit 1 exit 1
fi fi
@ -376,7 +368,7 @@ Below is the version of ``mkdefines.sh`` used in this demo:
if [ -z "$relprog" ]; then if [ -z "$relprog" ]; then
echo "ERROR: Missing <program-list>" echo "ERROR: Missing <program-list>"
echo "" echo ""
echo $usage echo "$usage"
exit 1 exit 1
fi fi
@ -385,46 +377,45 @@ Below is the version of ``mkdefines.sh`` used in this demo:
if [ ! -r "$sysmap" ]; then if [ ! -r "$sysmap" ]; then
echo "ERROR: $sysmap does not exist" echo "ERROR: $sysmap does not exist"
echo "" echo ""
echo $usage echo "$usage"
exit 1 exit 1
fi fi
if [ ! -r "$relprog" ]; then if [ ! -r "$relprog" ]; then
echo "ERROR: $relprog does not exist" echo "ERROR: $relprog does not exist"
echo "" echo ""
echo $usage echo "$usage"
exit 1 exit 1
fi fi
# Extract all of the undefined symbols from the partially linked file and create a # Extract all of the undefined symbols from the partially linked file and create a
# list of sorted, unique undefined variable names. # list of sorted, unique undefined variable names.
varlist=`nm $relprog | fgrep ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2 | sort - | uniq` varlist=$(nm "$relprog" | grep -F ' U ' | sed -e "s/^[ ]*//g" | cut -d' ' -f2 | sort - | uniq)
# Now output the linker script that provides a value for all of the undefined symbols # Now output the linker script that provides a value for all of the undefined symbols
for var in $varlist; do for var in $varlist; do
map=`grep " ${var}$" ${sysmap}` map=$(grep " ${var}$" "${sysmap}")
if [ -z "$map" ]; then if [ -z "$map" ]; then
echo "ERROR: Variable $var not found in $sysmap" echo "ERROR: Variable $var not found in $sysmap"
echo "" echo ""
echo $usage echo "$usage"
exit 1 exit 1
fi fi
varaddr=`echo ${map} | cut -d' ' -f1` varaddr=$(echo "${map}" | cut -d' ' -f1)
echo "${var} = 0x${varaddr} | 0x00000001;" echo "${var} = 0x${varaddr} | 0x00000001;"
done done
This script uses the ``nm`` utility to find all of the undefined symbols in the This script uses the ``nm`` utility to find all the undefined symbols in the
ELF object, then searches for the address of each undefined symbol in the ELF binary, then searches for the address of each undefined symbol in the
``System.map`` that was created when the released firmware was built. Finally, ``System.map`` file that was created when the firmware was built. Finally,
it uses the symbol name and the symbol address to create each symbol table it uses the symbols' names and addresses to create each symbol table entry.
entry.
.. note:: .. note::
- For the ARMv7-M architecture, bit 0 of the address must be set to indicate For the ARMv7-M architecture, bit 0 of the address must be set to indicate
thumb mode. If you are using a different architecture that requires thumb mode. If you are using a different architecture that requires
normal aligned addresses, you will need to change the following line by normal aligned addresses, you will need to change the following line by
eliminating the ORed value: eliminating the ORed value:
@ -433,106 +424,94 @@ entry.
echo "${var} = 0x${varaddr} | 0x00000001;" echo "${var} = 0x${varaddr} | 0x00000001;"
- If the new ELF module uses a symbol that is not provided in the base .. note::
firmware and, hence, not included in the ``System.map`` file, this script
If the new ELF binary uses a symbol that is not provided in the base
firmware (and hence not included in the ``System.map`` file) this script
will fail. In that case, you will need to provide the missing logic will fail. In that case, you will need to provide the missing logic
within the ELF program itself, if possible. within the ELF program itself, if possible.
- The technique as described here is only valid in the FLAT build mode. It .. important::
The technique described here is only valid in the FLAT build mode. It
could probably also be extended to work in the PROTECTED mode by could probably also be extended to work in the PROTECTED mode by
substituting ``User.map`` for ``System.map``. substituting ``User.map`` for ``System.map``.
Here is an example ``defines.ld`` created by ``mkdefines.sh``: Here is a short example of a ``defines.ld`` script created by ``mkdefines.sh``:
.. code-block:: shell .. code-block:: shell
printf = 0x0800aefc | 0x00000001; printf = 0x0800aefc | 0x00000001;
Replacing an NSH Built-In Function Replacing NSH Built-In Functions
================================== ================================
Files can be executed by ``NSH`` from the command line by simply typing the Files can be executed by NSH from the command line by simply typing the name
name of the ELF program. This requires: of the ELF program, given that the following requirements are met:
1. That the feature be enabled with``CONFIG_NSH_FILE_APP=y`` 1. The feature is enabled with ``CONFIG_NSH_FILE_APP=y``.
2. That support for the PATH variable is enabled (``CONFIG_BINFMT_EXEPATH=y`` and 2. Support for the PATH variable is enabled with ``CONFIG_LIBC_ENVPATH=y``.
``CONFIG_PATH_INITIAL`` set to the mount point of the file system that 3. The mount point of the file system that may contain ELF programs is
may contain ELF programs). set in ``CONFIG_PATH_INITIAL``.
Suppose, for example, I have a built-in application called ``hello``. Before Suppose, for example, that a built-in application called ``hello`` already
installing the new replacement ``hello`` ELF program in the file system, this exist. Before the installation of the new replacement ``hello`` ELF program in
is the version of ``hello`` that ``NSH`` will execute: the file system, this is the version of ``hello`` that NSH will execute:
.. code-block:: shell .. code-block:: text
nsh> hello nsh> hello
Hello, World! Hello, World!
nsh> nsh>
In the above configuration, ``NSH`` will first attempt to run the program called Now suppose that we add our custom ``hello`` binary to the file system inside
``hello`` from the file system. This will fail because we have not yet placed the appropriate path (see ``CONFIG_PATH_INITIAL`` above). When NSH will attempt
our custom ``hello`` ELF program in the file system. So instead, ``NSH`` will to run the program called ``hello``, it will prefer the new binary present on
fall back and execute the built-in application called ``hello``. the file system over the built-in version of the same program.
In this way, any command known to ``NSH`` can be replaced by an ELF program .. code-block:: text
installed in a mounted file system directory that is found via the PATH
variable.
Now suppose that we do add our custom ``hello`` to the file system. When
``NSH`` attempts to run the program called ``hello`` from the file system, it
will run successfully. The built-in version will be ignored. It has been
replaced with the version in the file system:
.. code-block:: shell
nsh> mount -t vfat /dev/mmcsd0 /bin nsh> mount -t vfat /dev/mmcsd0 /bin
nsh> hello nsh> hello
Hello from Add-On Program! Hello from a fully linked Add-On Program!
nsh> nsh>
Version Dependency Version Dependency
================== ==================
.. note:: .. warning::
This technique generates ELF programs using fixed addresses from the This technique generates ELF programs using fixed addresses from the
``System.map`` file of a versioned release. The generated ELF programs can ``System.map`` file of a versioned release. The generated ELF programs can
only be used with that specific firmware version. A crash will most likely only be used with that specific firmware version. A crash will most likely
result if used with a different firmware version, because the addresses happen if used with a different firmware version, because the addresses
from the ``System.map`` will not match the addresses in a different version from the ``System.map`` will not match.
of the firmware.
The alternative approach using :doc:`Symbol Tables <fully_linked_elf>` is more The alternative approach using :doc:`Symbol Tables <partially_linked_elf>` is
or less version independent. more or less version independent.
Tightly Coupled Memories Tightly Coupled Memories
======================== ========================
Most MCUs based on ARMv7-M family processors support some kind of Tightly Most MCUs based on ARMv7-M family processors support some kind of Tightly
Coupled Memory (TCM). These TCMs have somewhat different properties for Coupled Memory (TCM). These TCMs have somewhat different properties for
specialized operations. Depending on the bus matrix of the processor, you may specialized operations. Depending on the bus matrix of the processor, you
not be able to execute programs from TCM. For instance, the ``STM32 F4`` may not be able to execute programs from the TCM. For instance, the STM32F4
supports Core Coupled Memory (CCM), but since it is tied directly to the D-bus, supports Core Coupled Memory (CCM) but, since it is tied directly to the
it cannot be used to execute programs! On the other hand, the ``STM32F3`` has a D-bus, it cannot be used to execute programs. On the other hand, the STM32F3
CCM that is accessible to both the D-Bus and the I-Bus, in which case it has a CCM that is accessible to both the D-Bus and the I-Bus, in which case
should be possible to execute programs from this TCM. it should be possible to execute programs directly from this TCM.
.. image:: ./image/system_arch_stm32f42xx_and_f43xx.png .. image:: ./image/system_arch_stm32f42xx_and_f43xx.png
.. image:: ./image/system_arch_stm32f303xBC_and_f358xC.png .. image:: ./image/system_arch_stm32f303xBC_and_f358xC.png
When ELF programs are loaded into memory, the memory is allocated from the When ELF programs are loaded into memory, such memory is allocated from the
heap via a standard memory allocator. By default with the ``STM32 F4``, the heap via a standard memory allocator. With the STM32F4, the CCM is included
CCM is included in ``HEAP`` and will typically be allocated first. If CCM in the heap by default and will typically be allocated first. If CCM memory
memory is allocated to hold the ELF program, a hard-fault will occur is allocated to hold the loaded ELF program, then a hard-fault will occur
immediately when you try to execute the ELF program in memory. immediately when you try to execute it.
Therefore, on STM32F4 platforms it is necessary to include the
Therefore, it is necessary on ``STM32 F4`` platforms to include the following ``CONFIG_STM32_CCMEXCLUDE=y`` configuration setting. With it, the CCM
configuration setting: memory will be excluded from the heap and will never be allocated for
ELF program memory.
.. code-block:: shell
CONFIG_STM32_CCMEXCLUDE=y
With that setting, the CCM memory will be excluded from the heap, and so will
never be allocated for ELF program memory.

View file

@ -2,13 +2,6 @@
ELF Programs With Symbol Tables ELF Programs With Symbol Tables
================================= =================================
.. warning::
Migrated from:
https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=139629543
Updating a Release System with ELF Programs With Symbol Tables
================================================================
You can easily extend the firmware in your released, embedded system using You can easily extend the firmware in your released, embedded system using
ELF programs provided via a file system. For example, an SD card or, perhaps, ELF programs provided via a file system. For example, an SD card or, perhaps,
downloaded into on-board SPI FLASH. downloaded into on-board SPI FLASH.
@ -17,9 +10,6 @@ In order to support such post-release updates, your released firmware must
support execution of ELF programs loaded into RAM and symbol tables also support execution of ELF programs loaded into RAM and symbol tables also
provided via the file system (see `apps/examples/elf`). provided via the file system (see `apps/examples/elf`).
The files shown in this Wiki page can be downloaded
`here <https://cwiki.apache.org/confluence/download/attachments/139629402/elfprog-wsymtab.tar.gz?version=1&modificationDate=1576735523000&api=v2>`_
Creating a Symbol Table Creating a Symbol Table
======================= =======================
@ -42,7 +32,11 @@ compatible with the example provided here:
To enable this method, you must: To enable this method, you must:
- Set ``CONFIG_EXECFUNCS_HAVE_SYMTAB=y`` in your configuration. - Set ``CONFIG_EXECFUNCS_HAVE_SYMTAB=y`` in your configuration.
- Provide a symbol table with the global name ``CONFIG_EXECFUNCS_SYMTAB_ARRAY`` with the variable name ``CONFIG_EXECFUNCS_NSYMBOLS_VAR`` that holds the number of symbol entries. The default symbol table name is ``g_symtab``. - Provide a symbol table with the global name
``CONFIG_EXECFUNCS_SYMTAB_ARRAY`` with the variable name
``CONFIG_EXECFUNCS_NSYMBOLS_VAR`` that holds the number of symbol entries.
The default symbol table name is ``g_symtab``
and its length is ``g_nsymbols``.
In this example, let's illustrate this using an STM32F4-Discovery In this example, let's illustrate this using an STM32F4-Discovery
configuration. We will assume that you have modified the configuration. We will assume that you have modified the
@ -51,22 +45,24 @@ compatible with the example provided here:
.. code-block:: c .. code-block:: c
#include <stdio.h> #include <nuttx/compiler.h>
#include <nuttx/binfmt/symtab.h> #include <nuttx/symtab.h>
const struct symtab_s g_symtab[] = { const struct symtab_s g_symtab[] = {
{"printf", (FAR void *)printf} { "printf", (FAR const void *)printf }
}; };
int g_nsymbols = 1; int g_nsymbols = 1;
This is a simple symbol table containing only the symbol string "printf," This is a simple symbol table containing only the symbol string "printf",
whose value is the address of the function ``printf()``. whose value is the address of the function ``printf()``.
There is, of course, a lot more that could be said about generating symbol This example keeps things simple in order to focus on the core functionality,
tables. NuttX provides specialized tools in the ``tools/`` directory and but there is, of course, a lot more that could be said about generating symbol
instructions elsewhere for generating more extensive symbol tables. However, tables. NuttX provides specialized tools in the ``tools/`` directory for
this example keeps things simple to focus on the core functionality. generating more extensive symbol tables: you can start by taking a look at
``tools/mksymtab.c``. An example invocation of that tool could be:
``./tools/mksymtab -d ./libs/libc/libc.csv <path_to_generated_symtab.c>``.
2. **Application Logic** 2. **Application Logic**
Alternatively, the symbol table can be provided dynamically by the Alternatively, the symbol table can be provided dynamically by the
@ -76,20 +72,23 @@ compatible with the example provided here:
allows for application-level control. allows for application-level control.
To use this approach, you need to: To use this approach, you need to:
- Enable the configurations ``CONFIG_LIB_BOARDCTL=y`` and ``CONFIG_BOARDCTL_APP_SYMTAB=y``. - Enable the configurations ``CONFIG_BOARDCTL=y``
- Include application logic to provide the symbol table. If ``CONFIG_EXAMPLES_NSH_SYMTAB=y`` is set, NSH can handle this automatically. and ``CONFIG_BOARDCTL_APP_SYMTAB=y``.
- Include application logic to provide the symbol table.
If ``CONFIG_EXAMPLES_NSH_SYMTAB=y`` is set, NSH can handle this
automatically.
Export Package Creating the Export Package
============== ===========================
At the time of firmware release, you should create and save an export package. At the time of firmware release, you should create and save an export package.
This export package contains all the necessary files required to create This export package contains all the necessary files required to create
post-release add-on modules for your embedded system. post-release add-on modules for your embedded system.
For demonstration purposes, we use the STM32F4-Discovery with the network NSH For demonstration purposes, we'll use the STM32F4-Discovery with the network
configuration. This setup assumes that you have the STM32F4DIS-BB baseboard. NSH configuration. This setup assumes that you have the STM32F4DIS-BB
The demonstration also requires support for externally modifiable media, such baseboard. The demonstration also requires support for externally modifiable
as: media, such as:
- Removable media, like an SD card or USB flash drive. - Removable media, like an SD card or USB flash drive.
- An internal file system remotely accessible via USB MSC, FTP, or other - An internal file system remotely accessible via USB MSC, FTP, or other
@ -100,62 +99,70 @@ In this demonstration, the networking NSH configuration uses the SD card on
the STM32 baseboard. Other NSH configurations can also be used, provided they the STM32 baseboard. Other NSH configurations can also be used, provided they
supply the necessary file system support. supply the necessary file system support.
(No baseboard? You can add file system support to the basic ``STM32F4-Discovery`` .. tip::
board by following these instructions: No baseboard? You can add file system support to the basic STM32F4-Discovery
`USB FLASH drive <https://www.youtube.com/watch?v=5hB5ZXpRoS4>`_ board by following these instructions: `USB FLASH drive <https://www.youtube.com/watch?v=5hB5ZXpRoS4>`__
or `SD card <https://www.youtube.com/watch?v=H28t4RbOXqI>`_.) or `SD card <https://www.youtube.com/watch?v=H28t4RbOXqI>`__.
Example for STM32F4-Discovery: Initialize the environment:
.. code-block:: shell .. code-block:: console
$ make distclean $ make distclean
$ tools/configure.sh -c stm32f4discovery:netnsh $ tools/configure.sh -c stm32f4discovery:netnsh
$ make menuconfig $ make menuconfig
Required configurations: Edit the configuration:
- Disable networking: ``# CONFIG_NET is not set`` - Disable networking (it is not needed in this example):
- Enable ELF binary support: ``CONFIG_ELF=y``, ``CONFIG_LIBC_EXECFUNCS=y``, ``# CONFIG_NET is not set``.
``CONFIG_EXECFUNCS_HAVE_SYMTAB=y``, ``CONFIG_EXECFUNCS_SYMTAB_ARRAY="g_symtab"`` and - Enable ELF binary support with external symbol tables:
``CONFIG_EXECFUNCS_NSYMBOLS_VAR="g_nsymbols"`` ``CONFIG_ELF=y``,
- Enable PATH variable support: ``CONFIG_BINFMT_EXEPATH=y``, ``CONFIG_LIBC_EXECFUNCS=y``,
``CONFIG_PATH_INITIAL="/bin"`` ``CONFIG_EXECFUNCS_HAVE_SYMTAB=y``,
- Enable execution from NSH: ``CONFIG_NSH_FILE_APPS=y`` ``CONFIG_EXECFUNCS_SYMTAB_ARRAY="g_symtab"``,
``CONFIG_EXECFUNCS_NSYMBOLS_VAR="g_nsymbols"``.
- Enable PATH variable support:
``CONFIG_LIBC_ENVPATH=y``,
``CONFIG_PATH_INITIAL="/addons"``,
``# CONFIG_DISABLE_ENVIRON not set``.
- Enable execution of ELF files from NSH: ``CONFIG_NSH_FILE_APPS=y``.
Then, build the NuttX firmware image and the export package: Then, build the NuttX firmware image and the export package:
.. code-block:: shell .. code-block:: console
$ make $ make
$ make export $ make export
When ``make export`` completes, you will find a ZIP package in the top-level When ``make export`` completes, you will find a ZIP package in the top-level
NuttX directory called ``nuttx-export-x.y.zip`` (where x.y corresponds to the NuttX directory called ``nuttx-export-x.y.zip`` (where ``x.y`` corresponds to
version, determined by the .version file in the same directory). The contents the version determined by the ``.version`` file in the same directory).
of this ZIP file are organized as follows: The contents of this ZIP file are organized as follows:
.. code-block:: text .. code-block:: text
nuttx-export-x.x nuttx-export-x.x
|- arch/ |- arch/
|- build/
|- include/ |- include/
|- libs/ |- libs/
|- registry/
|- scripts/
|- startup/ |- startup/
|- tools/
|- System.map |- System.map
`- .config `- .config
Add-On Build Directory Preparing the Add-On Build Directory
====================== ====================================
In order to create the add-on ELF program, you will need: In order to create the add-on ELF program, you will need:
1. The export package. 1. The export package.
2. A program build Makefile. 2. A Makefile to build the program.
3. A linker script used by the Makefile. 3. A linker script to use in the Makefile.
The example Makefile discussed below assumes the use of a GNU toolchain. Note The example Makefile shown below assumes the use of a GNU toolchain. Note
that non-GNU toolchains would likely require a significantly different that non-GNU toolchains would likely require a significantly different
Makefile and linker script. Makefile and linker script.
@ -172,17 +179,16 @@ source file ``hello.c``:
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
printf("Hello from Add-On Program!\n"); printf("Hello from a partially linked Add-On Program!\n");
return 0; return 0;
} }
Let's say that we have a directory called ``addon`` that contains the following: Let's say that we have a directory called ``addon`` that contains
the following:
1. The ``hello.c`` source file. 1. The ``hello.c`` source file.
2. A Makefile to build the ELF program. 2. A Makefile to build the ELF program.
3. A linker script called ``gnu-elf.ld`` needed by the Makefile. 3. The export package ``nuttx-export-x.y.zip``.
4. The export package ``nuttx-export-7.25.zip``.
Building the ELF Program Building the ELF Program
======================== ========================
@ -190,72 +196,69 @@ Building the ELF Program
The first step in creating the ELF program is to unzip the export The first step in creating the ELF program is to unzip the export
package. Starting in the ``addon`` directory: package. Starting in the ``addon`` directory:
.. code-block:: shell .. code-block:: console
$ cd addon $ cd addon
$ ls $ ls
gnu-elf.ld hello.c Makefile nuttx-export-7.25.zip hello.c Makefile nuttx-export-x.y.zip
Where: Where:
- ``gnu-elf.ld`` is the linker script.
- ``hello.c`` is the example source file. - ``hello.c`` is the example source file.
- ``Makefile`` builds the ELF program. - ``Makefile`` builds the ELF program.
- ``nuttx-export-7.25.zip`` is the export package from NuttX 7.25. - ``nuttx-export-x.y.zip`` is the export package from NuttX version ``x.y``.
Unzip the export package as follows: Unzip the export package and rename the folder for ease of use:
.. code-block:: shell .. code-block:: console
$ unzip nuttx-export-7.25.zip $ unzip nuttx-export-x.y.zip
$ mv nuttx-export-x.y nuttx-export
This creates a new directory called ``nuttx-export-7.25``, containing This creates a new directory called ``nuttx-export``, containing
all the content from the released NuttX code required to build all the content from the released NuttX code required to build
the ELF program. the ELF program.
The Makefile The Makefile
============ ============
To build the ELF program, simply run: To build the ELF program, simply run:
.. code-block:: shell .. code-block:: console
$ make $ make
This uses the following Makefile to generate several files: This uses the following Makefile to generate several files:
- ``hello.o``: The compiled object file for ``hello.c``.
- ``hello``: The linked ELF program.
Only the resulting ``hello`` file is needed. - ``hello.o``: The compiled object file for ``hello.c``.
- ``hello``: The partially linked ELF program.
The Makefile used to create the ELF program is as follows: The Makefile used to create the ELF program is as follows:
.. code-block:: shell .. note::
include nuttx-export-7.25/build/Make.defs When copying the following contents, remember that Makefile indentations
must be made with proper tab characters and not just spaces.
# Long calls are need to call from RAM into FLASH .. code-block:: makefile
include nuttx-export/scripts/Make.defs
# Long calls are needed to call from RAM into FLASH
ARCHCFLAGS += -mlong-calls ARCHCFLAGS += -mlong-calls
# You may want to check these options against the ones in "nuttx-export/scripts/Make.defs"
ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef ARCHWARNINGS = -Wall -Wstrict-prototypes -Wshadow -Wundef
ARCHOPTIMIZATION = -Os -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer ARCHOPTIMIZATION = -Os -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer
ARCHINCLUDES = -I. -isystem nuttx-export-7.25/include ARCHINCLUDES = -I. -isystem nuttx-export/include
CFLAGS = $(ARCHCPUFLAGS) $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHINCLUDES) -pipe CFLAGS = $(ARCHCFLAGS) $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRADEFINES)
CROSSDEV = arm-none-eabi-
CC = $(CROSSDEV)gcc
LD = $(CROSSDEV)ld
STRIP = $(CROSSDEV)strip --strip-unneeded
# Setup up linker command line options # Setup up linker command line options
LDELFFLAGS = -r -e main LDELFFLAGS = --relocatable -e main
LDELFFLAGS += -T gnu-elf.ld LDELFFLAGS += -T nuttx-export/scripts/gnu-elf.ld
# This might change in a different environment
OBJEXT ?= .o
# This is the generated ELF program # This is the generated ELF program
@ -268,27 +271,33 @@ The Makefile used to create the ELF program is as follows:
# Build targets # Build targets
all: $(BIN)
.PHONY: clean .PHONY: clean
all: $(BIN)
$(OBJS): %$(OBJEXT): %.c $(OBJS): %$(OBJEXT): %.c
$(CC) -c $(CFLAGS) $< -o $@ $(CC) -c $(CFLAGS) -o $@ $<
$(BIN): $(OBJS) $(BIN): $(OBJS)
$(LD) $(LDELFFLAGS) -o $@ $^ $(LD) $(LDELFFLAGS) -o $@ $^
$(STRIP) $(BIN) $(STRIP) $@
#$(CROSSDEV)objdump -f $@
clean: clean:
rm -f $(BIN) rm -f $(BIN)
rm -f *.o rm -f $(OBJS)
The Linker Script The Linker Script
================= =================
The linker script that I am using in this example, gnu-elf.ld, The linker script used in this example is the one from the exported
contains the following: NuttX package: ``nuttx-export/scripts/gnu-elf.ld``.
.. code-block:: shell .. admonition:: Here is an alternative minimal (and possibly outdated) version
.. collapse:: Show content:
.. code-block:: text
SECTIONS SECTIONS
{ {
@ -337,8 +346,6 @@ contains the following:
_ebss = . ; _ebss = . ;
} }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) } .stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) } .stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) } .stab.excl 0 : { *(.stab.excl) }
@ -357,49 +364,45 @@ Replacing NSH Built-In Functions
================================ ================================
Files can be executed by NSH from the command line by simply typing the name Files can be executed by NSH from the command line by simply typing the name
of the ELF program. This requires (1) that the feature be enabled with of the ELF program, given that the following requirements are met:
``CONFIG_NSH_FILE_APP=y`` and (2) that support for the PATH variable is
enabled with ``CONFIG_BINFMT_EXEPATH=y`` and ``CONFIG_PATH_INITIAL`` set to 1. The feature is enabled with ``CONFIG_NSH_FILE_APP=y``.
the mount point of the file system that may contain ELF programs. 2. Support for the PATH variable is enabled with ``CONFIG_LIBC_ENVPATH=y``.
3. The mount point of the file system that may contain ELF programs is
set in ``CONFIG_PATH_INITIAL``.
In this example, there is no application in the base firmware called In this example, there is no application in the base firmware called
``hello``. So attempts to run ``hello`` will fail: ``hello``. So attempts to run ``hello`` will fail:
.. code-block:: shell .. code-block:: text
nsh> hello nsh> hello
nsh: hello: command not found nsh: hello: command not found
nsh> nsh>
But if we mount the SD card containing the ``hello`` image that we created But if we mount the SD card containing the ``hello`` binary that we created
above, then we can successfully execute the ``hello`` command: above, then we can successfully execute the ``hello`` command:
.. code-block:: shell .. code-block:: text
nsh> mount -t vfat /dev/mmcsd0 /bin nsh> mount -t vfat /dev/mmcsd0 /addons
nsh> ls /bin nsh> ls /addons
/bin: /addons:
System Volume Information/
hello hello
nsh> hello nsh> hello
Hello from Add-On Program! Hello from a partially linked Add-On Program!
nsh> nsh>
Here we showed how you can add a new command to NSH to a product without This showed that you can add a new NSH command to a product without
modifying the base firmware. We can also replace or update an existing modifying the base firmware, but you can also replace or update an existing
built-in application in this way: built-in application: in the above configuration, NSH will first attempt to
run the program called ``hello`` from the file system; this will fail because
In the above configuration, NSH will first attempt to run the program called the custom ``hello`` ELF program is not yet available. So instead, NSH will
``hello`` from the file system. This will fail because we have not yet put fallback and execute the built-in application called ``hello``. This way,
our custom ``hello`` ELF program in the file system. So instead, NSH will
fallback and execute the built-in application called ``hello``. In this way,
any command known to NSH can be replaced from an ELF program installed in a any command known to NSH can be replaced from an ELF program installed in a
mounted file system directory that can be found via the PATH variable. mounted file system directory specified in the PATH environment variable:
after adding the custom ``hello`` binary to the file system, NSH will prefer it
After we do add our custom ``hello`` to the file system, when NSH attempts to over the built-in version when attempting to run the program called ``hello``.
run the program called ``hello`` from the file system it will run
successfully. The built-in version will be ignored. It has been replaced with
the version in the file system.
Tightly Coupled Memories Tightly Coupled Memories
======================== ========================
@ -408,27 +411,21 @@ Most MCUs based on ARMv7-M family processors support some kind of Tightly
Coupled Memory (TCM). These TCMs have somewhat different properties for Coupled Memory (TCM). These TCMs have somewhat different properties for
specialized operations. Depending on the bus matrix of the processor, you specialized operations. Depending on the bus matrix of the processor, you
may not be able to execute programs from the TCM. For instance, the STM32F4 may not be able to execute programs from the TCM. For instance, the STM32F4
supports Core Coupled Memory (CCM), but since it is tied directly to the supports Core Coupled Memory (CCM) but, since it is tied directly to the
D-bus, it cannot be used to execute programs! On the other hand, the STM32F3 D-bus, it cannot be used to execute programs. On the other hand, the STM32F3
has a CCM that is accessible to both the D-Bus and the I-Bus, in which case has a CCM that is accessible to both the D-Bus and the I-Bus, in which case
it should be possible to execute programs from this TCM. it should be possible to execute programs directly from this TCM.
.. image:: ./image/system_arch_stm32f42xx_and_f43xx.png .. image:: ./image/system_arch_stm32f42xx_and_f43xx.png
.. image:: ./image/system_arch_stm32f303xBC_and_f358xC.png .. image:: ./image/system_arch_stm32f303xBC_and_f358xC.png
When ELF programs are loaded into memory, the memory is allocated from the When ELF programs are loaded into memory, such memory is allocated from the
heap via a standard memory allocator. By default with the STM32 F4, the CCM heap via a standard memory allocator. With the STM32F4, the CCM is included
is included in the heap and will typically be allocated first. If CCM memory in the heap by default and will typically be allocated first. If CCM memory
is allocated to hold the ELF program in memory, then a hard-fault will occur is allocated to hold the loaded ELF program, then a hard-fault will occur
immediately when you try to execute the ELF program in memory. immediately when you try to execute it.
Therefore, on STM32F4 platforms it is necessary to include the
Therefore, it is necessary on STM32 F4 platforms to include the following ``CONFIG_STM32_CCMEXCLUDE=y`` configuration setting. With it, the CCM
configuration setting: memory will be excluded from the heap and will never be allocated for
ELF program memory.
.. code-block:: shell
CONFIG_STM32_CCMEXCLUDE=y
With that setting, the CCM memory will be excluded from the heap and so will
never be allocated for ELF program memory.