Add nuttx to the system framework, which is 10.1.0

This commit is contained in:
TangYiwen123
2021-06-09 14:33:15 +08:00
parent 06c351e27c
commit 804bd57aa0
5000 changed files with 1488544 additions and 0 deletions
@@ -0,0 +1,45 @@
##############################################################################
# Documentation/Makefile
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
##############################################################################
# Minimal makefile for Sphinx documentation
#
# You can set these variables from the command line, and also
# from the environment for the first two.
SPHINXOPTS ?= -j auto -A nuttx_versions="latest,${NUTTX_VERSIONS}"
SPHINXBUILD ?= sphinx-build
SOURCEDIR = .
BUILDDIR = _build
# Put it first so that "make" without argument is like "make help".
help:
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
.PHONY: help Makefile
html: clean
autobuild: clean
sphinx-autobuild . _build -j=8
# Catch-all target: route all unknown targets to Sphinx using the new
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
%: Makefile
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@@ -0,0 +1,16 @@
[[source]]
name = "pypi"
url = "https://pypi.org/simple"
verify_ssl = true
[dev-packages]
[packages]
m2r2 = "*"
sphinx_rtd_theme = "*"
Sphinx = "*"
sphinx-tabs = "*"
sphinx-autobuild = "*"
[requires]
python_version = "3"
+359
View File
@@ -0,0 +1,359 @@
{
"_meta": {
"hash": {
"sha256": "8ad727a80d09508d59d310d13ca0024f27c5083c24c9754754b49bea36d73b9c"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"alabaster": {
"hashes": [
"sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359",
"sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"
],
"version": "==0.7.12"
},
"babel": {
"hashes": [
"sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5",
"sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.9.0"
},
"certifi": {
"hashes": [
"sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c",
"sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"
],
"version": "==2020.12.5"
},
"chardet": {
"hashes": [
"sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa",
"sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==4.0.0"
},
"colorama": {
"hashes": [
"sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b",
"sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==0.4.4"
},
"docutils": {
"hashes": [
"sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af",
"sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==0.16"
},
"idna": {
"hashes": [
"sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6",
"sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.10"
},
"imagesize": {
"hashes": [
"sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1",
"sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.2.0"
},
"jinja2": {
"hashes": [
"sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419",
"sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==2.11.3"
},
"livereload": {
"hashes": [
"sha256:776f2f865e59fde56490a56bcc6773b6917366bce0c267c60ee8aaf1a0959869"
],
"version": "==2.6.3"
},
"m2r2": {
"hashes": [
"sha256:a1b87b00f4d5163a3616253fca4c045f8351818cd803ba2e24af8897442a0eae",
"sha256:fbf72ade9f648d41658f97c5267687431612451f36b65761a138fbc276294df5"
],
"index": "pypi",
"version": "==0.2.7"
},
"markupsafe": {
"hashes": [
"sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473",
"sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161",
"sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235",
"sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5",
"sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42",
"sha256:195d7d2c4fbb0ee8139a6cf67194f3973a6b3042d742ebe0a9ed36d8b6f0c07f",
"sha256:22c178a091fc6630d0d045bdb5992d2dfe14e3259760e713c490da5323866c39",
"sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff",
"sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b",
"sha256:2beec1e0de6924ea551859edb9e7679da6e4870d32cb766240ce17e0a0ba2014",
"sha256:3b8a6499709d29c2e2399569d96719a1b21dcd94410a586a18526b143ec8470f",
"sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1",
"sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e",
"sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183",
"sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66",
"sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b",
"sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1",
"sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15",
"sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1",
"sha256:6f1e273a344928347c1290119b493a1f0303c52f5a5eae5f16d74f48c15d4a85",
"sha256:6fffc775d90dcc9aed1b89219549b329a9250d918fd0b8fa8d93d154918422e1",
"sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e",
"sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b",
"sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905",
"sha256:7fed13866cf14bba33e7176717346713881f56d9d2bcebab207f7a036f41b850",
"sha256:84dee80c15f1b560d55bcfe6d47b27d070b4681c699c572af2e3c7cc90a3b8e0",
"sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735",
"sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d",
"sha256:98bae9582248d6cf62321dcb52aaf5d9adf0bad3b40582925ef7c7f0ed85fceb",
"sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e",
"sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d",
"sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c",
"sha256:a6a744282b7718a2a62d2ed9d993cad6f5f585605ad352c11de459f4108df0a1",
"sha256:acf08ac40292838b3cbbb06cfe9b2cb9ec78fce8baca31ddb87aaac2e2dc3bc2",
"sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21",
"sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2",
"sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5",
"sha256:b1dba4527182c95a0db8b6060cc98ac49b9e2f5e64320e2b56e47cb2831978c7",
"sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b",
"sha256:b7d644ddb4dbd407d31ffb699f1d140bc35478da613b441c582aeb7c43838dd8",
"sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6",
"sha256:bf5aa3cbcfdf57fa2ee9cd1822c862ef23037f5c832ad09cfea57fa846dec193",
"sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f",
"sha256:caabedc8323f1e93231b52fc32bdcde6db817623d33e100708d9a68e1f53b26b",
"sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f",
"sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2",
"sha256:d53bc011414228441014aa71dbec320c66468c1030aae3a6e29778a3382d96e5",
"sha256:d73a845f227b0bfe8a7455ee623525ee656a9e2e749e4742706d80a6065d5e2c",
"sha256:d9be0ba6c527163cbed5e0857c451fcd092ce83947944d6c14bc95441203f032",
"sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7",
"sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be",
"sha256:feb7b34d6325451ef96bc0e36e1a6c0c1c64bc1fbec4b854f4529e51887b1621"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.1.1"
},
"mistune": {
"hashes": [
"sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e",
"sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"
],
"version": "==0.8.4"
},
"packaging": {
"hashes": [
"sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5",
"sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==20.9"
},
"pygments": {
"hashes": [
"sha256:2656e1a6edcdabf4275f9a3640db59fd5de107d88e8663c5d4e9a0fa62f77f94",
"sha256:534ef71d539ae97d4c3a4cf7d6f110f214b0e687e92f9cb9d2a3b0d3101289c8"
],
"markers": "python_version >= '3.5'",
"version": "==2.8.1"
},
"pyparsing": {
"hashes": [
"sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1",
"sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"
],
"markers": "python_version >= '2.6' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==2.4.7"
},
"pytz": {
"hashes": [
"sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da",
"sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"
],
"version": "==2021.1"
},
"requests": {
"hashes": [
"sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804",
"sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'",
"version": "==2.25.1"
},
"six": {
"hashes": [
"sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259",
"sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'",
"version": "==1.15.0"
},
"snowballstemmer": {
"hashes": [
"sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2",
"sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914"
],
"version": "==2.1.0"
},
"sphinx": {
"hashes": [
"sha256:3f01732296465648da43dec8fb40dc451ba79eb3e2cc5c6d79005fd98197107d",
"sha256:ce9c228456131bab09a3d7d10ae58474de562a6f79abb3dc811ae401cf8c1abc"
],
"index": "pypi",
"version": "==3.5.3"
},
"sphinx-autobuild": {
"hashes": [
"sha256:8fe8cbfdb75db04475232f05187c776f46f6e9e04cacf1e49ce81bdac649ccac",
"sha256:de1ca3b66e271d2b5b5140c35034c89e47f263f2cd5db302c9217065f7443f05"
],
"index": "pypi",
"version": "==2021.3.14"
},
"sphinx-rtd-theme": {
"hashes": [
"sha256:32bd3b5d13dc8186d7a42fc816a23d32e83a4827d7d9882948e7b837c232da5a",
"sha256:4a05bdbe8b1446d77a01e20a23ebc6777c74f43237035e76be89699308987d6f"
],
"index": "pypi",
"version": "==0.5.2"
},
"sphinx-tabs": {
"hashes": [
"sha256:0b5a8dd71d87197a01eef3b9d1e1a70513f4dd45e8af7783d1ab74c3fb2cbc6c",
"sha256:9d8db61afe9499aa84b33bc1c0d891f8a0df88ae513739f5babde15430c1fdaf"
],
"index": "pypi",
"version": "==2.1.0"
},
"sphinxcontrib-applehelp": {
"hashes": [
"sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a",
"sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"
],
"markers": "python_version >= '3.5'",
"version": "==1.0.2"
},
"sphinxcontrib-devhelp": {
"hashes": [
"sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e",
"sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"
],
"markers": "python_version >= '3.5'",
"version": "==1.0.2"
},
"sphinxcontrib-htmlhelp": {
"hashes": [
"sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f",
"sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b"
],
"markers": "python_version >= '3.5'",
"version": "==1.0.3"
},
"sphinxcontrib-jsmath": {
"hashes": [
"sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178",
"sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"
],
"markers": "python_version >= '3.5'",
"version": "==1.0.1"
},
"sphinxcontrib-qthelp": {
"hashes": [
"sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72",
"sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"
],
"markers": "python_version >= '3.5'",
"version": "==1.0.3"
},
"sphinxcontrib-serializinghtml": {
"hashes": [
"sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc",
"sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"
],
"markers": "python_version >= '3.5'",
"version": "==1.1.4"
},
"tornado": {
"hashes": [
"sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb",
"sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c",
"sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288",
"sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95",
"sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558",
"sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe",
"sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791",
"sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d",
"sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326",
"sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b",
"sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4",
"sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c",
"sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910",
"sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5",
"sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c",
"sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0",
"sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675",
"sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd",
"sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f",
"sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c",
"sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea",
"sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6",
"sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05",
"sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd",
"sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575",
"sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a",
"sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37",
"sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795",
"sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f",
"sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32",
"sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c",
"sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01",
"sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4",
"sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2",
"sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921",
"sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085",
"sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df",
"sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102",
"sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5",
"sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68",
"sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5"
],
"markers": "python_version >= '3.5'",
"version": "==6.1"
},
"urllib3": {
"hashes": [
"sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df",
"sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
"version": "==1.26.4"
}
},
"develop": {}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

@@ -0,0 +1,93 @@
/****************************************************************************
* Documentation/_static/custom.css
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/* Make content wider */
.wy-nav-content {
max-width: 1000px !important;
}
/* Make links inside C definitions more visible */
.c a:link {
color: black;
}
/* override table width restrictions */
@media screen and (min-width: 767px) {
.wy-table-responsive table td {
/* !important prevents the common CSS stylesheets from overriding
this as on RTD they are loaded after this stylesheet */
white-space: normal !important;
}
.wy-table-responsive {
overflow: visible !important;
}
}
/* remove useless padding on the sidebar */
.wy-nav-side
{
padding-bottom: 0em !important;
}
/* define some classes to be used */
table.valign-top td {
vertical-align: top !important;
}
/* Make <kbd> elements look nice */
kbd {
margin: 0px 0.1em;
padding: 0.1em 0.6em;
border-radius: 3px;
border: 1px solid rgb(204, 204, 204);
color: rgb(51, 51, 51);
line-height: 1.4;
font-family: Arial,Helvetica,sans-serif;
font-size: 10px;
display: inline-block;
box-shadow: 0px 1px 0px rgba(0,0,0,0.2), inset 0px 0px 0px 2px #ffffff;
background-color: rgb(247, 247, 247);
-moz-box-shadow: 0 1px 0px rgba(0, 0, 0, 0.2), 0 0 0 2px #ffffff inset;
-webkit-box-shadow: 0 1px 0px rgba(0, 0, 0, 0.2), 0 0 0 2px #ffffff inset;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
text-shadow: 0 1px 0 #fff;
}
span.menuselection
{
margin: 0px 0.1em;
padding: 0.1em 0.1em;
border-radius: 3px;
border: 1px solid rgb(204, 204, 204);
}
div.version-selector
{
margin-bottom: 1em;
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

@@ -0,0 +1,49 @@
<!--
Documentation/_templates/layout.html
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership. The
ASF licenses this file to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance with the
License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
License for the specific language governing permissions and limitations
under the License.
-->
{% extends "!layout.html" %}
{% block sidebartitle %}
{% if logo and theme_logo_only %}
<a href="{{ pathto(master_doc) }}">
{% else %}
<a href="{{ pathto(master_doc) }}" class="icon icon-home"> {{ project }}
{% endif %}
{% if logo %}
{# Not strictly valid HTML, but it's the only way to display/scale
it properly, without weird scripting or heaps of work
#}
<img src="{{ pathto('_static/' + logo, 1) }}" class="logo" alt="{{ _('Logo') }}"/>
{% endif %}
</a>
<!-- this version selector is quite ugly, should be probably replaced by something
more modern -->
<div class="version-selector">
<select onchange="javascript:location.href = this.value;">
{% for nuttx_version in nuttx_versions.split(',') %}
<option value="{{ url_root }}../{{ nuttx_version }}" {% if nuttx_version == version %}selected="selected"{% endif %}>{{ nuttx_version }}</option>
{% endfor %}
</select>
</div>
{% include "searchbox.html" %}
{% endblock %}
@@ -0,0 +1,15 @@
.. todo::
Applications included in ``apps`` repo should be documented here. This should also include information
on how to create a given application.
Applications
============
NuttX ships a large number of applications covering a wide spectrum of functionality. These can be found in the `apps <https://github.com/apache/incubator-nuttx-apps>`_ repository. At the moment, these are documented in their individual README files so you can find more information at the repository.
.. toctree::
:maxdepth: 2
:caption: Contents:
nsh/index.rst
@@ -0,0 +1,204 @@
***************************
NSH "Built-In" Applications
***************************
**Overview.** In addition to these commands that are a part of NSH,
external programs can also be executed as NSH commands. These external
programs are called "Built-In" Applications for historic reasons. That
terminology is somewhat confusing because the actual NSH commands as
described above are truly "built-into" NSH whereas these applications
are really external to NuttX.
These applications are built-into NSH in the sense that they can be
executed by simply typing the name of the application at the NSH prompt.
Built-in application support is enabled with these configuration option:
- ``CONFIG_BUILTIN``: Enable NuttX support for builtin applications.
- ``CONFIG_NSH_BUILTIN_APPS``: Enable NSH support for builtin
applications.
When these configuration options are set, you will also be able to see
the built-in applications if you enter "nsh> help". They will appear at
the bottom of the list of NSH commands under::
Builtin Apps:
Note that no detailed help information beyond the name of the built-in
application is provided.
Built-In Applications
~~~~~~~~~~~~~~~~~~~~~
**Overview.** The underlying logic that supports the NSH built-in
applications is called "Built-In Applications". The builtin application
logic can be found at ``apps/builtin``. This logic simply does the
following:
#. It supports registration mechanism so that builtin applications can
dynamically register themselves at build time, and
#. Utility functions to look up, list, and execute the builtin
applications.
**Built-In Application Utility Functions**. The utility functions
exported by the builtin application logic are prototyped in
``nuttx/include/nuttx/lib/builtin.h`` and ``apps/include/builtin.h``.
These utility functions include:
- ``int builtin_isavail(FAR const char *appname);`` Checks for
availability of application registered as ``appname`` during build
time.
- ``const char *builtin_getname(int index);`` Returns a pointer to a
name of built-in application pointed by the ``index``. This is the
utility function that is used by NSH in order to list the available
built-in applications when "``nsh> help``" is entered.
- ``int exec_builtin(FAR const char *appname, FAR const char **argv);``
Executes built-in builtin application registered during compile time.
This is the utility function used by NSH to execute the built-in
application.
**Autogenerated Header Files**. Application entry points with their
requirements are gathered together in two files when NuttX is first
built:
#. ``apps/builtin/builtin_proto.h``: Prototypes of application task
entry points.
#. ``apps/builtin/builtin_list.h``: Application specific information and
start-up requirements
**Registration of Built-In Applications**. The NuttX build occurs in
several phases as different build targets are executed: (1) *context*
when the configuration is established, (2) *depend* when target
dependencies are generated, and (3) *default* (``all``) when the normal
compilation and link operations are performed. Built-in application
information is collected during the make *context* build phase.
An example application that can be "built-in" is be found in the
``apps/examples/hello directory``. Let's walk through this specific
cause to illustrate the general way that built-in applications are
created and how they register themselves so that they can be used from
NSH.
``apps/examples/hello``. The main routine for apps/examples/hello can be
found in ``apps/examples/hello/main.c``. The main routine is:
.. code-block:: c
int hello_main(int argc, char *argv[])
{
printf("Hello, World!!\n");
return 0;
}
This is the built in function that will be registered during the
*context* build phase of the NuttX build. That registration is performed
by logic in ``apps/examples/hello/Makefile``. But the build system gets
to that logic through a rather tortuous path:
#. The top-level context make target is in ``nuttx/Makefile``. All build
targets depend upon the *context* build target. For the ``apps/``
directory, this build target will execute the *context* target in the
``apps/Makefile``.
#. The ``apps/Makefile`` will, in turn, execute the *context* targets in
all of the configured sub-directories. In our case will include the
``Makefile`` in ``apps/examples``.
#. And finally, the ``apps/examples/Makefile`` will execute the
*context* target in all configured ``example``\ sub-directories,
getting us finally to ``apps/examples/Makefile`` which is covered
below.
**NOTE**: Since this context build phase can only be executed one time,
any subsequent configuration changes that you make will, then, not be
reflected in the build sequence. That is a common area of confusion.
Before you can instantiate the new configuration, you have to first get
rid of the old configuration. The most drastic way to this is::
make distclean
But then you will have to re-configuration NuttX from scratch. But if
you only want to re-build the configuration in the ``apps/``
sub-directory, then there is a less labor-intensive way to do that. The
following NuttX make command will remove the configuration only from the
``apps/`` directory and will let you continue without re-configuring
everything::
make apps_distclean
Logic for the ``context`` target in ``apps/examples/hello/Makefile``
registers the ``hello_main()`` application in the ``builtin``'s
``builtin_proto.h``\ and ``builtin_list.h`` files. That logic that does
that in ``apps/examples/hello/Makefile`` is abstracted below:
#. First, the ``Makefile`` includes ``apps/Make.defs``::
include $(APPDIR)/Make.defs
This defines a macro called ``REGISTER`` that adds data to the
*builtin* header files::
define REGISTER
@echo "Register: $1"
@echo "{ \"$1\", $2, $3, $4 }," >> "$(APPDIR)/builtin/builtin_list.h"
@echo "EXTERN int $4(int argc, char *argv[]);" >> "$(APPDIR)/builtin/builtin_proto.h"
endef
When this macro runs, you will see the output in the build
"``Register: hello``", that is a sure sign that the registration was
successful.
#. The make file then defines the application name (``hello``), the task
priority (default), and the stack size that will be allocated in the
task runs (2K)::
APPNAME = hello
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 2048
#. And finally, the ``Makefile`` invokes the ``REGISTER`` macro to added
the ``hello_main()`` builtin application. Then, when the system build
completes, the ``hello`` command can be executed from the NSH command
line. When the ``hello`` command is executed, it will start the task
with entry point ``hello_main()`` with the default priority and with
a stack size of 2K::
context:
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
**Other Uses of Built-In Application.** The primary purpose of builtin
applications is to support command line execution of applications from
NSH. However, there is one other use of builtin applications that should
be mentioned.
#. **binfs**. *binfs* is a tiny file system located at
``apps/builtin/binfs.c``. This provides an alternative what of
visualizing installed builtin applications. Without *binfs*, you can
see the installed builtin applications using the NSH help command.
*binfs* will create a tiny pseudo-file system mounted at ``/bin``.
Using *binfs*, you can see the available builtin applications by
listing the contents of ``/bin`` directory. This gives some
superficial Unix-like compatibility, but does not really add any new
functionality.
Synchronous Built-In Applications
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
By default, built-in commands started from the NSH command line will run
asynchronously with NSH. If you want to force NSH to execute commands
then wait for the command to execute, you can enable that feature by
adding the following to the NuttX configuration file::
CONFIG_SCHED_WAITPID=y
This configuration option enables support for the standard ``waitpid()``
RTOS interface. When that interface is enabled, NSH will use it to wait,
sleeping until the built-in application executes to completion.
Of course, even with ``CONFIG_SCHED_WAITPID=y`` defined, specific
applications can still be forced to run asynchronously by adding the
ampersand (&) after the NSH command.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,488 @@
.. |br| raw:: html
<br/>
======================
Configuration Settings
======================
The availability of the above commands depends upon features that may or
may not be enabled in the NuttX configuration file. The following
:ref:`cmdtable <cmddependencies>` indicates the dependency of each command on
NuttX configuration settings. General configuration settings are
discussed in the NuttX Porting Guide.
Configuration settings specific to NSH as discussed at the
:ref:`cmdbottom <nshconfiguration>` of this document.
Note that in addition to general NuttX configuration settings, each NSH
command can be individually disabled via the settings in the rightmost
column. All of these settings make the configuration of NSH potentially
complex but also allow it to squeeze into very small memory footprints.
.. _cmddependencies:
Command Dependencies on Configuration Settings
==============================================
====================== =========================================== ======================
Command Depends on Configuration Can Be Disabled with
====================== =========================================== ======================
``[`` ! ``CONFIG_NSH_DISABLESCRIPT`` ``CONFIG_NSH_DISABLE_TEST``
:ref:`cmdaddroute` ``CONFIG_NET`` && ``CONFIG_NET_ROUTE`` ``CONFIG_NSH_DISABLE_ADDROUTE``
:ref:`cmdarp` ``CONFIG_NET`` && ``CONFIG_NET_ARP`` ``CONFIG_NSH_DISABLE_ARP``
:ref:`cmdbase64dec` ``CONFIG_NETUTILS_CODECS`` && ``CONFIG_NSH_DISABLE_BASE64DEC``
``CONFIG_CODECS_BASE64``
:ref:`cmdbase64enc` ``CONFIG_NETUTILS_CODECS`` && ``CONFIG_NSH_DISABLE_BASE64ENC``
``CONFIG_CODECS_BASE64``
:ref:`cmdbasename` . ``CONFIG_NSH_DISABLE_BASENAME``
:ref:`cmdbreak` ! ``CONFIG_NSH_DISABLESCRIPT`` && .
! ``CONFIG_NSH_DISABLE_LOOPS``  
:ref:`cmdcat` ``CONFIG_NSH_DISABLE_CAT`` .
:ref:`cmdcd` ! ``CONFIG_DISABLE_ENVIRON`` ``CONFIG_NSH_DISABLE_CD``
:ref:`cmdcmp` ``CONFIG_NSH_DISABLE_CMP`` .
:ref:`cmdcp` ``CONFIG_NSH_DISABLE_CP`` .
:ref:`cmddate` ``CONFIG_NSH_DISABLE_DATE`` .
:ref:`cmddd` ``CONFIG_NSH_DISABLE_DD`` .
:ref:`cmddelroute` ``CONFIG_NET`` && ``CONFIG_NET_ROUTE`` ``CONFIG_NSH_DISABLE_DELROUTE``
:ref:`cmddf` ! ``CONFIG_DISABLE_MOUNTPOINT`` ``CONFIG_NSH_DISABLE_DF``
:ref:`cmddirname` ``CONFIG_NSH_DISABLE_DIRNAME`` .
:ref:`cmddmesg` ``CONFIG_RAMLOG_SYSLOG`` ``CONFIG_NSH_DISABLE_DMESG``
:ref:`cmdecho` ``CONFIG_NSH_DISABLE_ECHO`` .
:ref:`cmdenv` ``CONFIG_FS_PROCFS`` && ``CONFIG_NSH_DISABLE_ENV``
! ``CONFIG_DISABLE_ENVIRON`` && |br|
! ``CONFIG_PROCFS_EXCLUDE_ENVIRON``
:ref:`cmdexec` ``CONFIG_NSH_DISABLE_EXEC`` .
:ref:`cmdexit` ``CONFIG_NSH_DISABLE_EXIT`` .
:ref:`cmdexport` ``CONFIG_NSH_VARS`` &&
! ``CONFIG_DISABLE_ENVIRON`` ``CONFIG_NSH_DISABLE_EXPORT``
:ref:`cmdfree` ``CONFIG_NSH_DISABLE_FREE`` .
:ref:`cmdget` ``CONFIG_NET`` && ``CONFIG_NET_UDP`` && ``CONFIG_NSH_DISABLE_GET``
*MTU* >= 58\ [#1]_
:ref:`cmdhelp` [#3]_ ``CONFIG_NSH_DISABLE_HELP`` .
:ref:`cmdhexdump` ``CONFIG_NSH_DISABLE_HEXDUMP`` .
:ref:`cmdifconfig` ``CONFIG_NET`` && ``CONFIG_FS_PROCFS`` && ``CONFIG_NSH_DISABLE_IFCONFIG``
! ``CONFIG_FS_PROCFS_EXCLUDE_NET``
:ref:`cmdifdown` ``CONFIG_NET`` && ``CONFIG_FS_PROCFS`` && ``CONFIG_NSH_DISABLE_IFUPDOWN``
! ``CONFIG_FS_PROCFS_EXCLUDE_NET``
:ref:`cmdifup` ``CONFIG_NET`` && ``CONFIG_FS_PROCFS`` &&
! ``CONFIG_FS_PROCFS_EXCLUDE_NET`` ``CONFIG_NSH_DISABLE_IFUPDOWN``
:ref:`cmdinsmod` ``CONFIG_MODULE`` ``CONFIG_NSH_DISABLE_MODCMDS``
:ref:`cmdirqinfo` ! ``CONFIG_DISABLE_MOUNTPOINT`` && .
``CONFIG_FS_PROCFS`` && |br|
``CONFIG_SCHED_IRQMONITOR``
:ref:`cmdkill` ``CONFIG_NSH_DISABLE_KILL`` .
:ref:`cmdlosetup` ! ``CONFIG_DISABLE_MOUNTPOINT`` && ``CONFIG_NSH_DISABLE_LOSETUP``
``CONFIG_DEV_LOOP``
:ref:`cmdln` ``CONFIG_PSEUDOFS_SOFTLINKS`` ``CONFIG_NSH_DISABLE_LN``
:ref:`cmdls` ``CONFIG_NSH_DISABLE_LS`` .
:ref:`cmdlsmod` ``CONFIG_MODULE`` && ``CONFIG_FS_PROCFS`` ``CONFIG_NSH_DISABLE_MODCMDS``
&& |br|
! ``CONFIG_FS_PROCFS_EXCLUDE_MODULE``
:ref:`cmdmd5` ``CONFIG_NETUTILS_CODECS`` && ``CONFIG_NSH_DISABLE_MD5``
``CONFIG_CODECS_HASH_MD5``
:ref:`cmdmx` . ``CONFIG_NSH_DISABLE_MB``, |br|
``CONFIG_NSH_DISABLE_MH``, |br|
``CONFIG_NSH_DISABLE_MW``
:ref:`cmdmkdir` (! ``CONFIG_DISABLE_MOUNTPOINT`` \|\| ``CONFIG_NSH_DISABLE_MKDIR``
! ``CONFIG_DISABLE_PSEUDOFS_OPERATIONS``)
:ref:`cmdmkfatfs` ! ``CONFIG_DISABLE_MOUNTPOINT`` && ``CONFIG_NSH_DISABLE_MKFATFS``
``CONFIG_FSUTILS_MKFATFS``
:ref:`cmdmkfifo` ``CONFIG_PIPES`` && ``CONFIG_NSH_DISABLE_MKFIFO``
``CONFIG_DEV_FIFO_SIZE`` > 0
:ref:`cmdmkrd` ! ``CONFIG_DISABLE_MOUNTPOINT`` ``CONFIG_NSH_DISABLE_MKRD``
:ref:`cmdmount` ! ``CONFIG_DISABLE_MOUNTPOINT`` ``CONFIG_NSH_DISABLE_MOUNT``
:ref:`cmdmv` ! ``CONFIG_DISABLE_MOUNTPOINT`` \|\| ``CONFIG_NSH_DISABLE_MV``
! ``CONFIG_DISABLE_PSEUDOFS_OPERATIONS``
:ref:`cmdnfsmount` ! ``CONFIG_DISABLE_MOUNTPOINT`` && ``CONFIG_NSH_DISABLE_NFSMOUNT``
``CONFIG_NET`` && ``CONFIG_NFS``
:ref:`cmdnslookup` ``CONFIG_LIBC_NETDB`` && ``CONFIG_NSH_DISABLE_NSLOOKUP``
``CONFIG_NETDB_DNSCLIENT``
:ref:`cmdpasswd` ! ``CONFIG_DISABLE_MOUNTPOINT`` && ``CONFIG_NSH_DISABLE_PASSWD``
``CONFIG_NSH_LOGIN_PASSWD``
:ref:`cmdpmconfig` ``CONFIG_PM`` ``CONFIG_NSH_DISABLE_PMCONFIG``
:ref:`cmdpoweroff` ``CONFIG_BOARDCTL_POWEROFF`` ``CONFIG_NSH_DISABLE_POWEROFF``
:ref:`cmdps` ``CONFIG_FS_PROCFS`` && ``CONFIG_NSH_DISABLE_PS``
! ``CONFIG_FS_PROCFS_EXCLUDE_PROC``
:ref:`cmdput` ``CONFIG_NET`` && ``CONFIG_NET_UDP`` && ``CONFIG_NSH_DISABLE_PUT``
``MTU >= 558`` [#1]_, [#2]_
:ref:`cmdpwd` ! ``CONFIG_DISABLE_ENVIRON`` ``CONFIG_NSH_DISABLE_PWD``
:ref:`cmdreadlink` ``CONFIG_PSEUDOFS_SOFTLINKS`` ``CONFIG_NSH_DISABLE_READLINK``
:ref:`cmdreboot` ``CONFIG_BOARD_RESET`` ``CONFIG_NSH_DISABLE_REBOOT``
:ref:`cmdrm` ! ``CONFIG_DISABLE_MOUNTPOINT`` \|\| ``CONFIG_NSH_DISABLE_RM``
! ``CONFIG_DISABLE_PSEUDOFS_OPERATIONS``
:ref:`cmdrmdir` ! ``CONFIG_DISABLE_MOUNTPOINT`` \|\
! ``CONFIG_DISABLE_PSEUDOFS_OPERATIONS`` ``CONFIG_NSH_DISABLE_RMDIR``
:ref:`cmdrmmod` ``CONFIG_MODULE`` ``CONFIG_NSH_DISABLE_MODCMDS``
:ref:`cmdroute` ``CONFIG_FS_PROCFS`` && ``CONFIG_NSH_DISABLE_ROUTE``
``CONFIG_FS_PROCFS_EXCLUDE_NET`` && |br|
! ``CONFIG_FS_PROCFS_EXCLUDE_ROUTE`` &&
``CONFIG_NET_ROUTE`` && |br|
! ``CONFIG_NSH_DISABLE_ROUTE`` && |br|
(``CONFIG_NET_IPv4`` \|\
``CONFIG_NET_IPv6``)
:ref:`cmdrptun` ``CONFIG_RPTUN`` ``CONFIG_NSH_DISABLE_RPTUN``
:ref:`cmdset` ``CONFIG_NSH_VARS`` \|\| ``CONFIG_NSH_DISABLE_SET``
! ``CONFIG_DISABLE_ENVIRON``
:ref:`cmdshutdown` ``CONFIG_BOARDCTL_POWEROFF`` \|\| ``CONFIG_NSH_DISABLE_SHUTDOWN``
``CONFIG_BOARD_RESET``
:ref:`cmdsleep` . ``CONFIG_NSH_DISABLE_SLEEP``
``cmdsource`` ``CONFIG_FILE_STREAM`` && ``CONFIG_NSH_DISABLE_SOURCE``
! ``CONFIG_NSH_DISABLESCRIPT``
:ref:`cmdtelnetd` ``CONFIG_NSH_TELNET`` ``CONFIG_NSH_DISABLE_TELNETD``
:ref:`cmdtest` ! ``CONFIG_NSH_DISABLESCRIPT`` ``CONFIG_NSH_DISABLE_TEST``
:ref:`cmdtime` . ``CONFIG_NSH_DISABLE_TIME``
:ref:`cmdtruncate` ! ``CONFIG_DISABLE_MOUNTPOINT`` ``CONFIG_NSH_DISABLE_TRUNCATE``
:ref:`cmdumount` ! ``CONFIG_DISABLE_MOUNTPOINT`` ``CONFIG_NSH_DISABLE_UMOUNT``
:ref:`cmduname` . ``CONFIG_NSH_DISABLE_UNAME``
:ref:`cmdunset` ``CONFIG_NSH_VARS`` \|\| ``CONFIG_NSH_DISABLE_UNSET``
! ``CONFIG_DISABLE_ENVIRON``
:ref:`cmdurldecode` ! ``CONFIG_NETUTILS_CODECS`` && ``CONFIG_NSH_DISABLE_URLDECODE``
``CONFIG_CODECS_URLCODE``
:ref:`cmdurlencode` ! ``CONFIG_NETUTILS_CODECS`` && ``CONFIG_NSH_DISABLE_URLENCODE``
``CONFIG_CODECS_URLCODE``
:ref:`cmduseradd` ! ``CONFIG_DISABLE_MOUNTPOINT`` && ``CONFIG_NSH_DISABLE_USERADD``
``CONFIG_NSH_LOGIN_PASSWD``
:ref:`cmduserdel` ! ``CONFIG_DISABLE_MOUNTPOINT`` && ``CONFIG_NSH_DISABLE_USERDEL``
``CONFIG_NSH_LOGIN_PASSWD``
:ref:`cmdusleep` . ``CONFIG_NSH_DISABLE_USLEEP``
:ref:`cmdwget` ``CONFIG_NET`` && ``CONFIG_NET_TCP`` ``CONFIG_NSH_DISABLE_WGET``
:ref:`cmdxd` . ``CONFIG_NSH_DISABLE_XD``
====================== =========================================== ======================
.. [#1] Because of hardware padding, the actual required packet size may be larger
.. [#2] Special TFTP server start-up options will probably be required to permit creation of files for the correct operation of the ``put`` command.
.. [#3] Verbose help output can be suppressed by defining ``CONFIG_NSH_HELP_TERSE``. In that case, the help command is still available but will be slightly smaller.
Built-In Command Dependencies on Configuration Settings
=======================================================
All built-in applications require that support for NSH built-in
applications has been enabled. This support is enabled with
``CONFIG_BUILTIN=y`` and ``CONFIG_NSH_BUILTIN_APPS=y``.
============= ==================================================================================================
Command Depends on Configuration
============= ==================================================================================================
``ping`` ``CONFIG_NET`` && ``CONFIG_NET_ICMP`` && ``CONFIG_NET_ICMP_SOCKET`` && ``CONFIG_SYSTEM_PING``
``ping6`` ``CONFIG_NET`` && ``CONFIG_NET_ICMPv6`` && ``CONFIG_NET_ICMPv6_SOCKET`` && ``CONFIG_SYSTEM_PING6``
============= ==================================================================================================
.. _nshconfiguration:
NSH-Specific Configuration Settings
===================================
The behavior of NSH can be modified with the following settings in the
``boards/<arch>/<chip>/<board>/defconfig`` file:
=================================== ==================================
Configuration Description
=================================== ==================================
``CONFIG_NSH_READLINE`` Selects the minimal implementation of ``readline()``.
This minimal implementation provides on backspace for command
line editing. It expects some minimal VT100 command support from the terminal.
``CONFIG_NSH_CLE`` Selects the more extensive, EMACS-like command line editor.
Select this option only if (1) you don't mind a modest increase
in the FLASH footprint, and (2) you work with a terminal that
supports extensive VT100 editing commands. Selecting this option
will add probably 1.5-2KB to the FLASH footprint.
``CONFIG_NSH_BUILTIN_APPS`` Support external registered, "builtin" applications that can
be executed from the NSH command line (see apps/README.txt for
more information). This required ``CONFIG_BUILTIN`` to enable
NuttX support for "builtin" applications.
``CONFIG_NSH_FILEIOSIZE`` Size of a static I/O buffer used for file access (ignored if there
is no file system). Default is 1024.
``CONFIG_NSH_STRERROR`` ``strerror(errno)`` makes more readable output but
``strerror()`` is very large and will not be used unless this
setting is *y*. This setting depends upon the ``strerror()``
having been enabled with ``CONFIG_LIBC_STRERROR``.
``CONFIG_NSH_LINELEN`` The maximum length of one command line and of one output line.
Default: 80
``CONFIG_NSH_DISABLE_SEMICOLON`` By default, you can enter multiple NSH commands on a line
with each command separated by a semicolon. You can disable this
feature to save a little memory on FLASH challenged platforms.
Default: n
``CONFIG_NSH_CMDPARMS`` If selected, then the output from commands, from file applications,
and from NSH built-in commands can be used as arguments to other
commands. The entity to be executed is identified by
enclosing the command line in back quotes. For example::
set FOO `myprogram $BAR`
will execute the program named ``myprogram`` passing it the
value of the environment variable ``BAR``. The value of the
environment variable ``FOO`` is then set output of ``myprogram``
on ``stdout``. Because this feature commits significant
resources, it is disabled by default. The ``CONFIG_NSH_CMDPARMS`` interim
output will be retained in a temporary file. Full path to a
directory where temporary files can be created is taken from
``CONFIG_LIBC_TMPDIR`` and it defaults to ``/tmp`` if
``CONFIG_LIBC_TMPDIR`` is not set.
``CONFIG_NSH_MAXARGUMENTS`` The maximum number of NSH command arguments. Default: 6
``CONFIG_NSH_ARGCAT`` Support concatenation of strings with environment variables or
command output. For example::
set FOO XYZ
set BAR 123
set FOOBAR ABC_${FOO}_${BAR}
would set the environment variable ``FOO`` to ``XYZ``,
``BAR`` to ``123`` and ``FOOBAR`` to ``ABC_XYZ_123``. If
``CONFIG_NSH_ARGCAT`` is not selected, then a slightly small
FLASH footprint results but then also only simple environment
variables like ``$FOO`` can be used on the command line.
``CONFIG_NSH_VARS`` By default, there are no internal NSH variables. NSH will use OS
environment variables for all variable storage. If this option,
NSH will also support local NSH variables. These variables are,
for the most part, transparent and work just like the OS
environment variables. The difference is that when you
create new tasks, all of environment variables are
inherited by the created tasks. NSH local variables are not.
If this option is enabled (and ``CONFIG_DISABLE_ENVIRON`` is not),
then a new command called 'export' is enabled. The export
command works very must like the set command except that is
operates on environment variables. When CONFIG_NSH_VARS
is enabled, there are changes in the behavior of certain commands.
See following :ref:`cmdtable <nsh_vars_table>`.
``CONFIG_NSH_QUOTE`` Enables back-slash quoting of certain characters within the
command. This option is useful for the case where an NSH script
is used to dynamically generate a new NSH script. In that case,
commands must be treated as simple text strings without
interpretation of any special characters. Special characters
such as ``$``, :literal:`\``, ``"``, and others must be
retained intact as part of the test string. This option is
currently only available is ``CONFIG_NSH_ARGCAT`` is also
selected.
``CONFIG_NSH_NESTDEPTH`` The maximum number of nested ``if-then[-else]-fi`` <#conditional>`__
sequences that are permissible. Default: 3
``CONFIG_NSH_DISABLESCRIPT`` This can be set to *y* to suppress support for scripting.
This setting disables the ```sh`` <#cmdsh>`__,
```test`` <#cmdtest>`__, and ```[`` <#cmtest>`__ commands and
the ```if-then[-else]-fi`` <#conditional>`__
construct. This would only be set on systems where a minimal
footprint is a necessity and scripting is not.
``CONFIG_NSH_DISABLE_ITEF`` If scripting is enabled, then then this option can be selected
to suppress support for ``if-then-else-fi`` sequences in
scripts. This would only be set on systems where some minimal
scripting is required but ``if-then-else-fi`` is not.
``CONFIG_NSH_DISABLE_LOOPS`` If scripting is enabled, then then this option can be selected
suppress support ``for while-do-done`` and
``until-do-done`` sequences in scripts. This would only be set
on systems where some minimal scripting is required but looping
is not.
``CONFIG_NSH_DISABLEBG`` This can be set to *y* to suppress support for background
commands. This setting disables the ```nice`` <#cmdoverview>`__
command prefix and the ```&`` <#cmdoverview>`__ command
suffix. This would only be set on systems where a minimal footprint
is a necessity and background command execution is not.
``CONFIG_NSH_MMCSDMINOR`` If the architecture supports an MMC/SD slot and if the NSH
architecture specific logic is present, this option will provide
the MMC/SD minor number, i.e., the MMC/SD block driver will be
registered as ``/dev/mmcsd``\ *N* where *N* is the minor number.
Default is zero.
``CONFIG_NSH_ROMFSETC`` Mount a ROMFS file system at ``/etc`` and provide a startup
script at ``/etc/init.d/rcS``.
The default startup script will mount a FAT FS RAMDISK at
``/tmp`` but the logic is `easily extensible <#startupscript>`__.
``CONFIG_NSH_CONSOLE`` If ``CONFIG_NSH_CONSOLE`` is set to *y*, then a serial console
front-end is selected.
Normally, the serial console device is a UART and RS-232
interface. However, if ``CONFIG_USBDEV`` is defined,
then a USB serial device may, instead, be used if the one of
the following are defined:
- ``CONFIG_PL2303`` and ``CONFIG_PL2303_CONSOLE``.
Sets up the Prolifics PL2303 emulation as a console device
at ``/dev/console``.
- ``CONFIG_CDCACM`` and ``CONFIG_CDCACM_CONSOLE``.
Sets up the CDC/ACM serial device as a console device at
``/dev/console``.
- ``CONFIG_NSH_USBCONSOLE``. If defined, then an arbitrary USB
device may be used to as the NSH console. In this case,
``CONFIG_NSH_USBCONDEV`` must be defined to indicate which
USB device to use as the console. The advantage of
using a device other that ``/dev/console`` is that
normal debug output can then use ``/dev/console`` while NSH
uses ``CONFIG_NSH_USBCONDEV``.
``CONFIG_NSH_USBCONDEV``. If ``CONFIG_NSH_USBCONSOLE`` is
set to 'y', then ``CONFIG_NSH_USBCONDEV`` must also be set to select the USB
device used to support the NSH console. This should be set to
the quoted name of a readable/write-able USB driver
such as: ``CONFIG_NSH_USBCONDEV="/dev/ttyACM0"``.
If there are more than one USB slots, then a USB device minor
number may also need to be provided:
- ``CONFIG_NSH_UBSDEV_MINOR``: The minor device number of the USB device. Default: 0
If USB tracing is enabled (``CONFIG_USBDEV_TRACE``), then
NSH will initialize USB tracing as requested by the following.
Default: Only USB errors are traced.
- ``CONFIG_NSH_USBDEV_TRACEINIT``: Show initialization events
- ``CONFIG_NSH_USBDEV_TRACECLASS``: Show class driver events
- ``CONFIG_NSH_USBDEV_TRACETRANSFERS``: Show data transfer events
- ``CONFIG_NSH_USBDEV_TRACECONTROLLER``: Show controller events
- ``CONFIG_NSH_USBDEV_TRACEINTERRUPTS``: Show interrupt-related events.
``CONFIG_NSH_ALTCONDEV`` and If ``CONFIG_NSH_CONSOLE`` is set ``CONFIG_NSH_CONDEV``
to *y*, then ``CONFIG_NSH_ALTCONDEV`` may also
be selected to enable use of an alternate character device to
support the NSH console. If ``CONFIG_NSH_ALTCONDEV`` is
selected, then ``CONFIG_NSH_CONDEV`` holds the
quoted name of a readable/write-able character
driver such as: ``CONFIG_NSH_CONDEV="/dev/ttyS1"``.
This is useful, for example, to separate the NSH command line
from the system console when the system console is used to provide
debug output. Default: ``stdin`` and ``stdout`` (probably
"``/dev/console``")
- **NOTE 1:** When any other device other than
``/dev/console`` is used for a user interface, (1) linefeeds
(``\n``) will not be expanded to carriage return / linefeeds
(``\r\n``). You will need to configure your terminal
program to account for this.
And (2) input is not automatically echoed so you
will have to turn local echo on.
- **NOTE 2:** This option forces the console of all sessions to
use NSH_CONDEV. Hence, this option only makes sense for a
system that supports only a single session. This option
is, in particular, incompatible with Telnet
sessions because each Telnet session must use a different
console device.
``CONFIG_NSH_TELNET`` If ``CONFIG_NSH_TELNET`` is set to *y*, then a TELNET server
front-end is selected. When this option is provided, you may log
into NuttX remotely using telnet in order to access NSH.
``CONFIG_NSH_ARCHINIT`` Set ``CONFIG_NSH_ARCHINIT`` if your board provides architecture
specific initialization via the board-specific function
``board_app_initialize()``. This function will be called early in
NSH initialization to allow board logic to do such things as
configure MMC/SD slots.
=================================== ==================================
.. _nsh_vars_table:
================== =================================== =============================================
CMD w/o ``CONFIG_NSH_VARS`` w/``CONFIG_NSH_VARS``
================== =================================== =============================================
``set <a> <b>`` Set environment variable <a> to <b> Set NSH variable <a> to <b> (Unless the NSH variable has been *promoted* via
``export``, in which case the env ironment variable of the same name is set to <b>).
``set`` Causes an error. Lists all NSH variables.
``unset <a>`` Unsets environment variable <a> Unsets both environment variable *and* NSH variable with and name <a>
``export <a> <b>`` Causes an error, Unsets NSH variable <a>. Sets environment variable <a> to <b>.
``export <a>`` Causes an error. Sets environment variable <a> to the value of NSH variable <a> (or "" if the
NSH variable has not been set). Unsets NSH local variable <a>.
``env`` Lists all environment variables Lists all environment variables (*only*)
================== =================================== =============================================
If Telnet is selected for the NSH console, then we must configure the
resources used by the Telnet daemon and by the Telnet clients.
====================================== ================================
Configuration Description
====================================== ================================
``CONFIG_NSH_TELNETD_PORT`` The telnet daemon will listen on this TCP port number for connections. Default: 23
``CONFIG_NSH_TELNETD_DAEMONPRIO`` Priority of the Telnet daemon. Default: ``SCHED_PRIORITY_DEFAULT``
``CONFIG_NSH_TELNETD_DAEMONSTACKSIZE`` Stack size allocated for the Telnet daemon. Default: 2048
``CONFIG_NSH_TELNETD_CLIENTPRIO`` Priority of the Telnet client. Default: ``SCHED_PRIORITY_DEFAULT``
``CONFIG_NSH_TELNETD_CLIENTSTACKSIZE`` Stack size allocated for the Telnet client. Default: 2048
====================================== ================================
One or both of ``CONFIG_NSH_CONSOLE`` and ``CONFIG_NSH_TELNET`` must be
defined. If ``CONFIG_NSH_TELNET`` is selected, then there some other
configuration settings that apply:
====================================== ================================
Configuration Description
====================================== ================================
``CONFIG_NET=y`` Of course, networking must be enabled.
``CONFIG_NET_TCP=y`` TCP/IP support is required for telnet (as well as various other
TCP-related configuration settings).
``CONFIG_NSH_IOBUFFER_SIZE`` Determines the size of the I/O buffer to use for sending/ receiving
TELNET commands/responses
``CONFIG_NSH_DHCPC`` Obtain the IP address via DHCP.
``CONFIG_NSH_IPADDR`` If ``CONFIG_NSH_DHCPC`` is NOT set, then the static IP address must be
provided.
``CONFIG_NSH_DRIPADDR`` Default router IP address
``CONFIG_NSH_NETMASK`` Network mask
``CONFIG_NSH_NOMAC`` Set if your Ethernet hardware has no built-in MAC address. If set, a
bogus MAC will be assigned.
``CONFIG_NSH_MAX_ROUNDTRIP`` This is the maximum round trip for a response to a ICMP ECHO request. It
is in units of deciseconds. The default is 20 (2 seconds).
====================================== ================================
If you use DHCPC, then some special configuration network options are
required. These include:
============================================== ============================================================
Configuration Description
============================================== ============================================================
``CONFIG_NET=y`` Of course, networking must be enabled.
``CONFIG_NET_UDP=y`` UDP support is required for DHCP (as well as various other
UDP-related configuration settings).
``CONFIG_NET_BROADCAST=y`` UDP broadcast support is needed.
``CONFIG_NET_ETH_PKTSIZE=650`` (or larger) Per RFC2131 (p. 9), the DHCP client must be prepared to receive
DHCP messages of up to 576 bytes (excluding Ethernet, IP, or
UDP headers and FCS). NOTE: Note that the actual MTU setting
will depend upon the specific link protocol. Here Ethernet
is indicated.
============================================== ============================================================
If ``CONFIG_NSH_ROMFSETC`` is selected, then the following additional
configuration setting apply:
============================== ==============================================================
Configuration Description
============================== ==============================================================
``CONFIG_NSH_ARCHROMFS`` May be defined to specify an alternative ROMFS image
that can be found at ``boards/<arch>/<chip>/<board>/include/nsh_romfsimg.h``.
``CONFIG_NSH_ROMFSMOUNTPT`` The default mountpoint for the ROMFS volume is ``"/etc"``,
but that can be changed with this setting. This must be a
absolute path beginning with '``/``' and enclosed in quotes.
``CONFIG_NSH_INITSCRIPT`` This is the relative path to the startup script within the
mountpoint. The default is ``"init.d/rcS"``. This is a relative
path and must not start with '``/``' but must be enclosed in quotes.
``CONFIG_NSH_ROMFSDEVNO`` This is the minor number of the ROMFS block device.
The default is '``0``' corresponding to ``/dev/ram0``.
``CONFIG_NSH_ROMFSSECTSIZE`` This is the sector size to use with the ROMFS volume. Since the
default volume is very small, this defaults to 64 but should
be increased if the ROMFS volume were to be become large.
Any value selected must be a power of 2.
============================== ==============================================================
When the default ``rcS`` file used when ``CONFIG_NSH_ROMFSETC`` is
selected, it will mount a FAT FS under ``/tmp``. The following
selections describe that FAT FS.
============================== =======================================================
Configuration Description
============================== =======================================================
``CONFIG_NSH_FATDEVNO`` This is the minor number of the FAT FS block device.
The default is '``1``' corresponding to ``/dev/ram1``.
``CONFIG_NSH_FATSECTSIZE`` This is the sector size use with the FAT FS. Default is 512.
============================== =======================================================
@@ -0,0 +1,213 @@
*************************
Customizing the NuttShell
*************************
**Overview.** The NuttShell (NSH) is a simple shell application that may
be used with NuttX. It supports a variety of commands and is (very)
loosely based on the Bash shell and the common utilities used with Bash
shell programming. The paragraphs in this appendix will focus on
customizing NSH: Adding new commands, changing the initialization
sequence, etc.
The NSH Library and NSH Initialization
**************************************
**Overview.** NSH is implemented as a library that can be found at
``apps/nshlib``. As a library, it can be custom built into any
application that follows the NSH initialization sequence described
below. As an example, the code at ``apps/examples/nsh/nsh_main.c``
illustrates how to start NSH and the logic there was intended to be
incorporated into your own custom code. Although code was generated
simply as an example, in the end most people just use this example code
as their application ``main()`` function. That initialization performed
by that example is discussed in the following paragraphs.
NSH Initialization sequence
~~~~~~~~~~~~~~~~~~~~~~~~~~~
The NSH start-up sequence is very simple. As an example, the code at
``apps/system/nsh/nsh_main.c`` illustrates how to start NSH. It simple
does the following:
#. This function calls ``nsh_initialize()`` which initializes the NSH
library. ``nsh_initialize()`` is described in more detail below.
#. If the Telnetconsole is enabled, it calls ``nsh_telnetstart()`` which
resides in the NSH library. ``nsh_telnetstart()`` will start the
Telnet daemon that will listen for Telnet connections and start
remote NSH sessions.
#. If a local console is enabled (probably on a serial port), then
``nsh_consolemain()`` is called. ``nsh_consolemain()`` also resides
in the NSH library. ``nsh_consolemain()`` does not return so that
finished the entire NSH initialization sequence.
``nsh_initialize()``
~~~~~~~~~~~~~~~~~~~~
The NSH initialization function, ``nsh_initialize()``, be found in
``apps/nshlib/nsh_init.c``. It does only three things:
#. ``nsh_romfsetc()``: If so configured, it executes an NSH start-up
script that can be found at ``/etc/init.d/rcS`` in the target file
system. The ``nsh_romfsetc()`` function can be found in
``apps/nshlib/nsh_romfsetc.c``. This function will (1) register a
ROMFS file system, then (2) mount the ROMFS file system. ``/etc`` is
the default location where a read-only, ROMFS file system is mounted
by ``nsh_romfsetc()``.
The ROMFS image is, itself, just built into the firmware. By default,
this ``rcS`` start-up script contains the following logic::
# Create a RAMDISK and mount it at XXXRDMOUNTPOINTXXX
mkrd -m XXXMKRDMINORXXX -s XXMKRDSECTORSIZEXXX XXMKRDBLOCKSXXX
mkfatfs /dev/ramXXXMKRDMINORXXX
mount -t vfat /dev/ramXXXMKRDMINORXXX XXXRDMOUNTPOINTXXX
Where the ``XXXX*XXXX`` strings get replaced in the template when the
ROMFS image is created:
- ``XXXMKRDMINORXXX`` will become the RAM device minor number.
Default: 0
- ``XXMKRDSECTORSIZEXXX`` will become the RAM device sector size
- ``XXMKRDBLOCKSXXX`` will become the number of sectors in the
device.
- ``XXXRDMOUNTPOINTXXX`` will become the configured mount point.
Default: ``/etc``
By default, the substituted values would yield an ``rcS`` file like::
# Create a RAMDISK and mount it at /tmp
mkrd -m 1 -s 512 1024
mkfatfs /dev/ram1
mount -t vfat /dev/ram1 /tmp
This script will, then:
- Create a RAMDISK of size 512*1024 bytes at ``/dev/ram1``,
- Format a FAT file system on the RAM disk at ``/dev/ram1``, and
then
- Mount the FAT file system at a configured mountpoint, ``/tmp``.
This ``rcS`` template file can be found at
``apps/nshlib/rcS.template``. The resulting ROMFS file system can be
found in ``apps/nshlib/nsh_romfsimg.h``.
#. ``board_app_initialize()``: Next any architecture-specific NSH
initialization will be performed (if any). For the STM3240G-EVAL,
this architecture specific initialization can be found at
``boards/arm/stm32/stm3240g-eval/src/stm32_appinit.c``. This it does
things like: (1) Initialize SPI devices, (2) Initialize SDIO, and (3)
mount any SD cards that may be inserted.
#. ``nsh_netinit()``: The ``nsh_netinit()`` function can be found in
``apps/nshlib/nsh_netinit.c``.
NSH Commands
************
**Overview.** NSH supports a variety of commands as part of the NSH
program. All of the NSH commands are listed in the NSH documentation
`above <#cmdoverview>`__. Not all of these commands may be available at
any time, however. Many commands depend upon certain NuttX configuration
options. You can enter the help command at the NSH prompt to see the
commands actual available:
For example, if network support is disabled, then all network-related
commands will be missing from the list of commands presented by
'``nsh> help``'. You can see the specific command dependencies in the
table `above <#cmddependencies>`__.
Adding New NSH Commands
~~~~~~~~~~~~~~~~~~~~~~~
New commands can be added to the NSH very easily. You simply need to add
two things:
#. The implementation of your command, and
#. A new entry in the NSH command table
**Implementation of Your Command.** For example, if you want to add a
new a new command called ``mycmd`` to NSH, you would first implement the
``mycmd`` code in a function with this prototype:
.. code-block:: c
int cmd_mycmd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv);
The ``argc`` and ``argv`` are used to pass command line arguments to the
NSH command. Command line parameters are passed in a very standard way:
``argv[0]`` will be the name of the command, and ``argv[1]`` through
``argv[argc-1]`` are the additional arguments provided on the NSH
command line.
The first parameter, ``vtbl``, is special. This is a pointer to
session-specific state information. You don't need to know the contents
of the state information, but you do need to pass this ``vtbl`` argument
when you interact with the NSH logic. The only use you will need to make
of the ``vtbl`` argument will be for outputting data to the console. You
don't use ``printf()`` within NSH commands. Instead you would use:
.. code-block:: c
void nsh_output(FAR struct nsh_vtbl_s *vtbl, const char *fmt, ...);
So if you only wanted to output "Hello, World!" on the console, then
your whole command implementation might be:
.. code-block:: c
int cmd_mycmd(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
{
nsh_output(vtbl, "Hello, World!");
return 0;
}
The prototype for the new command should be placed in
``apps/examples/nshlib/nsh.h``.
**Adding You Command to the NSH Command Table**. All of the commands
support by NSH appear in a single table called:
.. code-block:: c
const struct cmdmap_s g_cmdmap[]
That table can be found in the file
``apps/examples/nshlib/nsh_parse.c``. The structure ``cmdmap_s`` is also
defined in ``apps/nshlib/nsh_parse.c``:
.. code-block:: c
struct cmdmap_s
{
const char *cmd; /* Name of the command */
cmd_t handler; /* Function that handles the command */
uint8_t minargs; /* Minimum number of arguments (including command) */
uint8_t maxargs; /* Maximum number of arguments (including command) */
const char *usage; /* Usage instructions for 'help' command */
};
This structure provides everything that you need to describe your
command: Its name (``cmd``), the function that handles the command
(``cmd_mycmd()``), the minimum and maximum number of arguments needed by
the command, and a string describing the command line arguments. That
last string is what is printed when enter "``nsh> help``".
So, for you sample command, you would add the following the to the
``g_cmdmap[]`` table:
.. code-block:: c
{ "mycmd", cmd_mycmd, 1, 1, NULL },
This entry is particularly simply because ``mycmd`` is so simple. Look
at the other commands in ``g_cmdmap[]`` for more complex examples.
@@ -0,0 +1,19 @@
===============
NuttShell (NSH)
===============
The NuttShell is a very complete shell system to be used in NuttX, similar to bash and other similar options. It supports a rich set of included commands, scripting and the ability to run your own applications as "builtin" (part of the same NuttX binary). NSH is implemented as an application where most of the functionality is part of the library called `nshlib`.
As such, NSH is completely optional and can be disabled so that NuttX directly starts a given task instead of the main ``nsh`` application.
.. toctree::
:maxdepth: 2
:caption: Contents
nsh.rst
commands.rst
config.rst
customizing.rst
builtin.rst
installation.rst
login.rst
@@ -0,0 +1,184 @@
******************************
Customizing NSH Initialization
******************************
**Ways to Customize NSH Initialization**. There are three ways to
customize the NSH start-up behavior. Here they are presented in order of
increasing difficulty:
#. You can extend the initialization logic in
``boards/arm/stm32/stm3240g-eval/src/stm32_appinit.c``. The logic
there is called each time that NSH is started and is good place in
particular for any device-related initialization.
#. You replace the sample code at ``apps/examples/nsh/nsh_main.c`` with
whatever start-up logic that you want. NSH is a library at
``apps/nshlib``. ``apps.examples/nsh`` is just a tiny, example
start-up function (``CONFIG_USER_ENTRYPOINT``\ ()) that that runs
immediately and illustrates how to start NSH If you want something
else to run immediately then you can write your write your own custom
``CONFIG_USER_ENTRYPOINT``\ () function and then start other tasks
from your custom ``CONFIG_USER_ENTRYPOINT``\ ().
#. NSH also supports a start-up script that executed when NSH first
runs. This mechanism has the advantage that the start-up script can
contain any NSH commands and so can do a lot of work with very little
coding. The disadvantage is that is is considerably more complex to
create the start-up script. It is sufficiently complex that is
deserves its own paragraph
NuttShell Start up Scripts
~~~~~~~~~~~~~~~~~~~~~~~~~~
First of all you should look at `NSH Start-Up Script <#startupscript>`__
paragraph. Most everything you need to know can be found there. That
information will be repeated and extended here for completeness.
**NSH Start-Up Script**. NSH supports options to provide a start up
script for NSH. The start-up script contains any command support by NSH
(i.e., that you see when you enter 'nsh> help'). In general this
capability is enabled with ``CONFIG_NSH_ROMFSETC=y``, but has several
other related configuration options as described with the `NSH-specific
configuration settings <#nshconfiguration>`__ paragraph. This capability
also depends on:
- ``CONFIG_DISABLE_MOUNTPOINT=n``. If mount point support is disabled,
then you cannot mount *any* file systems.
- ``CONFIG_FS_ROMFS`` enabled. This option enables ROMFS file system
support.
**Default Start-Up Behavior**. The implementation that is provided is
intended to provide great flexibility for the use of Start-Up files.
This paragraph will discuss the general behavior when all of the
configuration options are set to the default values.
In this default case, enabling ``CONFIG_NSH_ROMFSETC`` will cause NSH to
behave as follows at NSH start-up time:
- NSH will create a read-only RAM disk (a ROM disk), containing a tiny
ROMFS file system containing the following::
`--init.d/
`-- rcS
Where ``rcS`` is the NSH start-up script.
- NSH will then mount the ROMFS file system at ``/etc``, resulting in::
|--dev/
| `-- ram0
`--etc/
`--init.d/
`-- rcS
- By default, the contents of ``rcS`` script are::
# Create a RAMDISK and mount it at /tmp
mkrd -m 1 -s 512 1024
mkfatfs /dev/ram1
mount -t vfat /dev/ram1 /tmp
- NSH will execute the script at ``/etc/init.d/rcS`` at start-up
(before the first NSH prompt). After execution of the script, the
root FS will look like::
|--dev/
| |-- ram0
| `-- ram1
|--etc/
| `--init.d/
| `-- rcS
`--tmp/
**Example Configurations**. Here are some configurations that have
``CONFIG_NSH_ROMFSETC=y`` in the NuttX configuration file. They might
provide useful examples:
- ``boards/arm/stm32/hymini-stm32v/nsh2``
- ``boards/arm/dm320/ntosd-dm320/nsh``
- ``boards/sim/sim/sim/nsh``
- ``boards/sim/sim/sim/nsh2``
- ``boards/sim/sim/sim/nx``
- ``boards/sim/sim/sim/nx11``
- ``boards/sim/sim/sim/touchscreen``
In most of these cases, the configuration sets up the *default*
``/etc/init.d/rcS`` script. The default script is here:
``apps/nshlib/rcS.template``. (The funny values in the template like
``XXXMKRDMINORXXX`` get replaced via ``sed`` at build time). This
default configuration creates a ramdisk and mounts it at ``/tmp`` as
discussed above.
If that default behavior is not what you want, then you can provide your
own custom ``rcS`` script by defining ``CONFIG_NSH_ARCHROMFS=y`` in the
configuration file.
**Modifying the ROMFS Image**. The contents of the ``/etc`` directory
are retained in the file ``apps/nshlib/nsh_romfsimg.h`` OR, if
``CONFIG_NSH_ARCHROMFS`` is defined,
``include/arch/board/nsh_romfsimg.h``. In order to modify the start-up
behavior, there are three things to study:
#. **Configuration Options.** The additional ``CONFIG_NSH_ROMFSETC``
configuration options discussed with the other `NSH-specific
configuration settings <#nshconfiguration>`__.
#. ``tools/mkromfsimg.sh`` **Script**. The script
``tools/mkromfsimg.sh`` creates ``nsh_romfsimg.h``. It is not
automatically executed. If you want to change the configuration
settings associated with creating and mounting the ``/tmp``
directory, then it will be necessary to re-generate this header file
using the ``tools/mkromfsimg.sh`` script.
The behavior of this script depends upon several things:
#. The configuration settings then installed configuration.
#. The ``genromfs`` tool(available from
`http://romfs.sourceforge.net <http://romfs.sourceforge.net/>`__)
or included within the NuttX buildroot toolchain. There is also a
snapshot available in the NuttX tools repository
`here <https://bitbucket.org/nuttx/tools/src/master/genromfs-0.5.2.tar.gz>`__.
#. The ``xxd`` tool that is used to generate the C header files (xxd
is a normal part of a complete Linux or Cygwin installation,
usually as part of the ``vi`` package).
#. The file ``apps/nshlib/rcS.template`` (OR, if
``CONFIG_NSH_ARCHROMFS`` is defined
``include/arch/board/rcs.template``.
#. ``rcS.template``. The file ``apps/nshlib/rcS.template`` contains the
general form of the ``rcS`` file; configured values are plugged into
this template file to produce the final ``rcS`` file.
To generate a custom ``rcS`` file a copy of ``rcS.template`` needs to
be placed at ``tools/`` and changed according to the desired start-up
behaviour. Running ``tools/mkromfsimg.h`` creates ``nsh_romfsimg.h``
which needs to be copied to ``apps/nshlib`` OR if
``CONFIG_NSH_ARCHROMFS`` is defined to
``boards/<arch>/<chip>/<board>/include``.
``rcS.template``. The default ``rcS.template``,
``apps/nshlib/rcS.template``, generates the standard, default
``apps/nshlib/nsh_romfsimg.h`` file.
If ``CONFIG_NSH_ARCHROMFS`` is defined in the NuttX configuration file,
then a custom, board-specific ``nsh_romfsimg.h`` file residing in
``boards/<arch>/<chip>/<board>/include``\ will be used. NOTE when the OS
is configured, ``include/arch/board`` will be linked to
``boards/<arch>/<chip>/<board>/include``.
All of the startup-behavior is contained in ``rcS.template``. The role
of ``mkromfsimg.sh`` script is to (1) apply the specific configuration
settings to ``rcS.template`` to create the final ``rcS``, and (2) to
generate the header file ``nsh_romfsimg.h`` containing the ROMFS file
system image. To do this, ``mkromfsimg.sh`` uses two tools that must be
installed in your system:
#. The ``genromfs`` tool that is used to generate the ROMFS file system
image.
#. The ``xxd`` tool that is used to create the C header file.
@@ -0,0 +1,261 @@
***********
Shell Login
***********
Enabling Shell Logins
*********************
NuttShell sessions can be protected by requiring that the user supply
username and password credentials at the beginning of the session.
Logins can be enabled for standard USB or serial consoles with::
CONFIG_NSH_CONSOLE_LOGIN=y
Logins for Telnet sessions can be enabled separately with::
CONFIG_NSH_TELNET_LOGIN=y
Logins can be enabled for either or both session types. On a successful
login, the user will have access to the NSH session::
login: admin
password:
User Logged-in!
NuttShell (NSH)
nsh>
After each failed login attempt, a delay can be set up. The purpose of
this delay is to discourage attempts to crack the password by brute
force. That delay is configured with::
CONFIG_NSH_LOGIN_FAILDELAY=0
This setting provides the login failure delay in units of milliseconds.
The system will pause this amount of time after each failed login
attempt. After a certain number of failed login attempts, the session
will be closed. That number is controlled by::
CONFIG_NSH_LOGIN_FAILCOUNT=3
Verification of Credentials
***************************
There are three ways that NSH can be configured to verify user
credentials at login time:
#. The simplest implementation simply uses fixed login credentials and
is selected with::
CONFIG_NSH_LOGIN_FIXED=y
The fixed login credentials are selected via::
CONFIG_NSH_LOGIN_USERNAME=admin
CONFIG_NSH_LOGIN_PASSWORD="Administrator"
This is not very flexible since there can be only one user and the
password is fixed in the FLASH image. This option is also not very
secure because a malicious user could get the password by just
looking at the ``.text`` stings in the flash image.
#. NSH can also be configured to defer the entire user credential
verification to platform-specific logic with this setting::
CONFIG_NSH_LOGIN_PLATFORM=y
In this case, NSH will call a platform-specific function to perform
the verification of user credentials. The platform-specific logic
must provide a function with the following prototype:
.. code-block:: c
int platform_user_verify(FAR const char *username, FAR const char *password);
which is prototyped an described in ``apps/include/nsh.h`` and which
may be included like:
.. code-block:: c
#include <apps/nsh.h>
An appropriate place to implement this function might be in the
directory ``apps/platform/<board>``.
#. A final option is to use a password file contained encrypted password
information. This final option is selected with the following and
described in more detail in the following paragraph::
CONFIG_NSH_LOGIN_PASSWD=y
Password Files
**************
NuttX can also be configured to support a password file, by default at
``/etc/passwd``. This option enables support for a password file::
CONFIG_NSH_LOGIN_PASSWD=y
This options requires that you have selected ``CONFIG_FSUTILS_PASSWD=y``
to enable the access methods of ``apps/fsutils/passwd``::
CONFIG_FSUTILS_PASSWD=y
And this determines the location of the password file in a mounted
volume::
CONFIG_FSUTILS_PASSWD_PATH="/etc/passwd"
``/etc/passwd`` is a *standard* location, but you will need to locate
the password where ever you have a mounted volume.
The password file can be a fixed list of users in a ROMFS file system or
a modifiable list maintained in a file in some writable file system. If
the password file lies in a read-only file system like ROMFS, then you
should also indicate that the password file is read-only.
CONFIG_FSUTILS_PASSWD_READONLY=y
If the password file is writable, then additional NSH commands will be
enabled to modify the password file: ```useradd`` <#cmduseradd>`__,
```userdel`` <#cmduserdel>`__, and ```passwd`` <#cmdpasswd>`__. If you
do not wish you have these commands available, then they should be
specifically disabled.
The password file logic requires a few additional settings:
#. The size of dynamically allocated and freed buffer that is used for
file access::
CONFIG_FSUTILS_PASSWD_IOBUFFER_SIZE=512
#. And the 128-bit encryption key. The password file currently uses the
Tiny Encryption Algorithm (TEA), but could be extended to use
something more powerful.
CONFIG_FSUTILS_PASSWD_KEY1=0x12345678
CONFIG_FSUTILS_PASSWD_KEY2=0x9abcdef0
CONFIG_FSUTILS_PASSWD_KEY3=0x12345678
CONFIG_FSUTILS_PASSWD_KEY4=0x9abcdef0
Password can only be decrypted with access to this key. Note that this
key could potentially be fished out of your FLASH image, but without any
symbolic information, that would be a difficult job since the TEA KEY is
binary data and not distinguishable from other binary data in the FLASH
image.
If the password file is enabled (``CONFIG_NSH_LOGIN_PASSWD=y``), then
the fixed user credentials will not be used for the NSH session login.
Instead, the password file will be consulted to verify the user
credentials.
Creating a Password File for a ROMFS File System
************************************************
What we want to accomplish is a ROMFS file system, mounted at ``/etc``
and containing the password file, ``passwd`` like::
NuttShell (NSH)
nsh> ls -Rl /etc
/etc:
dr-xr-xr-x 0 .
dr-xr-xr-x 0 init.d/
-r--r--r-- 39 passwd
/etc/init.d:
dr-xr-xr-x 0 ..
-r--r--r-- 110 rcS
nsh>
Where ``/etc/init.d/rcS`` is the start-up script; ``/etc/passwd`` is a
the password file. Note that here we assume that you are already using a
start-up script. We can then piggyback the passwd file into the ``/etc``
file system already mounted for the NSH start up file as described above
`above <#custinit>`__.
I use the sim/nsh configuration to create a new password file, but other
configurations could also be used. That configuration already supports a
ROMFS file system, passwords, and login prompts. First, I make these
changes to that configuration.
#. Disable logins:
.. code-block:: diff
- CONFIG_NSH_CONSOLE_LOGIN=y
+ # CONFIG_NSH_CONSOLE_LOGIN is not set
# CONFIG_NSH_TELNET_LOGIN is not set
#. Move the password file to a write-able file system:
.. code-block:: diff
- CONFIG_FSUTILS_PASSWD_PATH="/etc/passwd"
+ CONFIG_FSUTILS_PASSWD_PATH="/tmp/passwd"
#. Make the password file modifiable
.. code-block:: diff
- CONFIG_FSUTILS_PASSWD_READONLY=y
# CONFIG_FSUTILS_PASSWD_READONLY is not set
Now rebuild the simulation. No login should be required to enter the
shell and you should find the ```useradd`` <#cmduseradd>`__,
```userdel`` <#cmduserdel>`__, and ```passwd`` <#cmdpasswd>`__ commands
available in the help summary, provided that they are enabled. Make
certain that the ``useradd`` command is not disabled::
# CONFIG_NSH_DISABLE_USERADD is not set
Use the NSH ```useradd`` <#cmduseradd>`__ command to add new uses with
new user passwords like::
nsh> useradd <username> <password>
Do this as many times as you would like. Each time that you do this a
new entry with an encrypted password will be added to the ``passwd``
file at ``/tmp/passwd``. You can see the content of the password file
like::
nsh> cat /tmp/passwd
When you are finished, you can simply copy the ``/tmp/passwd`` content
from the ``cat`` command and paste it into an editor. Make sure to
remove any carriage returns that may have ended up on the file if you
are using Windows.
Then create/re-create the ``nsh_romfsimg.h`` file as described below.
#. The content on the ``nsh_romfsimg.h`` header file is generated from a
template directory structure. Create the directory structure::
mkdir etc
mkdir etc/init.d
And copy your existing startup script into ``etc/init.c`` as ``rcS``.
#. Save your new password file in the ``etc/`` directory as ``passwd``.
#. Create the new ROMFS image::
genromfs -f romfs_img -d etc -V MyVolName
#. Convert the ROMFS image to a C header file::
xxd -i romfs_img >nsh_romfsimg.h
#. Edit ``nsh_romfsimg.h``: Mark both data definitions as ``const`` so
that the data will be stored in FLASH.
#. Edit nsh_romfsimg.h, mark both data definitions as ``const`` so that
that will be stored in FLASH.
There is a good example of how to do this in the NSH simulation
configuration at
`boards/sim/sim/sim/configs/nsh <https://github.com/apache/incubator-nuttx/blob/master/boards/sim/sim/sim/configs/nsh/>`__.
The ROMFS support files are provided at
`boards/sim/include <https://github.com/apache/incubator-nuttx/blob/master/boards/sim/sim/sim/include/>`__
and the
`README.txt <https://github.com/apache/incubator-nuttx/blob/master/boards/sim/sim/sim/README.txt>`__
file at the location provides detailed information about creating and
modifying the ROMFS file system.
@@ -0,0 +1,361 @@
.. include:: /substitutions.rst
.. _nsh:
********
Overview
********
**The NSH Library**. The ``apps/nshlib`` sub-directory contains the
NuttShell (NSH) library. This library can easily to linked to
produce a NSH application (See as an example
``apps/examples/nsh``). The NSH Library provides a simple shell
application for NuttX.
Console/NSH Front End
*********************
**NSH Consoles**. Using settings in the configuration file, NSH may be
configured to use (1) the serial stdin/out, (2) a USB serial
device (such as CDC/ACM), or (3) a telnet connection as the
console. Or, perhaps even all at once since or BOTH. An indefinite
number of telnet sessions are supported.
**Start-Up prompt**. When NSH is started, you will see the a welcome
message such the following on the selected console:
.. code-block::
NuttShell (NSH)
nsh>
The greeting may also include NuttX versioning information if you
are using a versioned copy of NuttX. ``nsh>`` is the NSH prompt
and indicates that you may enter a command from the console.
**USB console startup**. When using a USB console, the start-up
sequence differs a little: In this case, you are required to press
*ENTER* three times. Then NSH prompt will appear as described
above. This is required for the following reasons:
#. This assures that the USB connection is stable. The USB
connection may be made, broken, and re-established a few times
if the USB cable is not yet fully seated. Waiting for *ENTER*
to be pressed three times assures that the connection is
stable.
#. The establishment of the connection is two step process: First,
the USB serial connection is made with the host PC. Then the
application that uses the serial interface is started on the
host. When the serial connection is established on the host,
the host operating system may send several *AT* modem commands
to the host depending upon how the host serial port is
configured. By waiting for *ENTER* to be pressed three
consecutive times, all of these modem commands will go to the
bit-bucket and will not be interpreted as NSH command input.
#. Similarly, in the second step when the applications is started,
there may be additional *AT* modem commands sent out the serial
port. Most serial terminal programs will do this unless they
are specifically configured to suppress the modem command
output. Waiting for the *ENTER* input eliminates the invalid
command errors from both (2) and (3).
#. Finally, if NSH did not wait for some positive indication that
the serial terminal program is up and running, then the output
of the NSH greeting and initial NSH prompt would be lost.
**Extended Command Line Editing**. By default, NuttX uses a simple
command line editor that allows command entry after the ``nsh>``
and supports only the *backspace* key for editing. However, a more
complete command line editor can be selected by setting
``CONFIG_NSH_CLE=y`` in the NuttX configuration file. When that
option is selected, the following EMACS-like line editing commands
are supported:
===================== ================================================
Key Binding Editor Action
===================== ================================================
``^A`` Move cursor to start of the line
``^B`` Move left one character
``^D`` or *Del* Delete a single character at the cursor position
``^E`` Move cursor to end of current line
``^F`` Move right one character
``^H`` or *Backspace* Delete character, left (backspace)
``^K`` Delete to the end of the line
``^U`` Delete the entire line
===================== ================================================
Command Overview
****************
**Simple, Re-directed, and Background Commands**. The NuttShell
(NSH) is a simple shell application. NSH supports the following
commands forms:
=============================== ======================================
Simple command ``<cmd>``
Command with re-directed output ``<cmd> > <file> <cmd> >> <file>``
Background command ``<cmd> &``
Re-directed background command ``<cmd> > <file> & <cmd> >> <file> &``
=============================== ======================================
Where:
* ``<cmd>`` is any one of the simple commands listed later.
* ``<file>`` is the full or relative path to any writable object in the file system name space (file or character driver). Such objects will be referred to simply as files throughout this document.
``nice`` **'d Background Commands**. NSH executes at the
mid-priority (128). Backgrounded commands can be made to execute
at higher or lower priorities using ``nice``::
[nice [-d <niceness>>]] <cmd> [> <file>|>> <file>] [&]
Where ``<niceness>`` is any value between -20 and 19 where lower
(more negative values) correspond to higher priorities. The
default niceness is 10.
**Multiple commands per line**. NSH will accept multiple commands
per command line with each command separated with the semi-colon
character (;).
**Optional Syntax Extensions** Because these features commit
significant resources, they are disabled by default.
- ``CONFIG_NSH_CMDPARMS``: If selected, then the output from
commands, from file applications, and from NSH built-in
commands can be used as arguments to other commands. The entity
to be executed is identified by enclosing the command line in
back quotes. For example,
.. code-block:: bash
set FOO myprogram $BAR
Will execute the program named ``myprogram`` passing it the
value of the environment variable ``BAR``. The value of the
environment variable ``FOO`` is then set output of
``myprogram`` on ``stdout``.
- ``CONFIG_NSH_ARGCAT``: Support concatenation of strings
with environment variables or command output. For example:
.. code-block:: bash
set FOO XYZ
set BAR 123
set FOOBAR ABC_${FOO}_${BAR}
would set the environment variable ``FOO`` to ``XYZ``, ``BAR``
to ``123`` and ``FOOBAR`` to ``ABC_XYZ_123``. If
``CONFIG_NSH_ARGCAT`` is not selected, then a slightly smaller
FLASH footprint results but then also only simple environment
variables like ``$FOO`` can be used on the command line.
- ``CONFIG_NSH_QUOTE``: Enables back-slash quoting of certain
characters within the command. This option is useful for the
case where an NSH script is used to dynamically generate a new
NSH script. In that case, commands must be treated as simple
text strings without interpretation of any special characters.
Special characters such as ``$``, :literal:`\``, ``"``, and
others must be retained intact as part of the test string. This
option is currently only available is ``CONFIG_NSH_ARGCAT`` is
also selected.
Conditional Command Execution
*****************************
An ``if-then[-else]-fi`` construct is also supported in order to
support conditional execution of commands. This works from the
command line but is primarily intended for use within NSH scripts
(see the ```sh`` <#cmdsh>`__ command). The syntax is as follows:
.. code-block:: bash
if [!] <cmd>
then
[sequence of <cmd>]
else
[sequence of <cmd>]
fi
Where ``<cmd>`` is a `simple command <#cmdoverview>`__. The
command success value of zero is treated true; a non-zero command
failure value is treated false. The ```test`` <#cmdtest>`__
command is frequently used for comparisons.
Looping
*******
**Looping Constructs**. ``while-do-done`` and ``until-do-done``
looping constructs are also supported. These work from the command
line but are primarily intended for use within NSH scripts (see
the ```sh`` <#cmdsh>`__ command).
- ``while-do-done``: Execute ``[sequence of <cmd>]`` as long
as ``<cmd>`` has an exit status of zero. The syntax is as
follows:
.. code-block:: bash
while <cmd>
do
[sequence of <cmd>]
done
- ``until-do-done``: Execute ``[sequence of <cmd>]`` as long
as ``<cmd>`` has a non-zero exit status. The syntax is as
follows:
.. code-block::
until <cmd>
do
[sequence of <cmd>]
done
Where ``<cmd>`` is a `simple command <#cmdoverview>`__. The
command success value of zero is treated true; a non-zero command
failure value is treated false. The ```test`` <#cmdtest>`__
command is frequently used for comparisons.
**The** ``break`` **Command**. A ``break`` command is also supported.
The ``break`` command is only meaningful within the body of the a
``while`` or ``until`` loop, between the ``do`` and ``done`` tokens.
If the ``break`` command is executed within the body of a loop,
the loop will immediately terminate and execution will continue
with the next command immediately following the ``done`` token.
Built-In Variables
******************
====== ====================================================
``$?`` The result of the last simple command execution. |br|
On backgrounded commands, this variable holds only |br|
the result of spawning the background command.
====== ====================================================
Current Working Directory
*************************
``cd`` **and** ``pwd``. All path arguments to commands may be
either an absolute path or a path relative to the current working
directory. The current working directory is set using the
``cd`` command and can be queried either by using the
``pwd`` command or by using the ``echo $PWD`` command.
Environment Variables
*********************
========== ================================================
``PATH`` The default path in the file systems to look |br|
for executable, binary programs working directory
``PWD`` The current working directory
``OLDPWD`` The previous working directory
========== ================================================
NSH Start-Up Script
*******************
**NSH Start-Up Script**. NSH supports options to provide a start
up script for NSH. In general this capability is enabled with
``CONFIG_NSH_ROMFSETC``, but has several other related
configuration options as described with the `NSH-specific
configuration settings <#nshconfiguration>`__. This capability
also depends on:
- ``CONFIG_DISABLE_MOUNTPOINT`` not set
- ``CONFIG_FS_ROMFS`` enabled
**Default Start-Up Behavior**. The implementation that is provided
is intended to provide great flexibility for the use of Start-Up
files. This paragraph will discuss the general behavior when all
of the configuration options are set to the default values.
In this default case, enabling ``CONFIG_NSH_ROMFSETC`` will cause
NSH to behave as follows at NSH startup time:
- NSH will create a read-only RAM disk (a ROM disk), containing a
tiny ROMFS file system containing the following::
`--init.d/
`-- rcS
Where rcS is the NSH start-up script.
- NSH will then mount the ROMFS file system at ``/etc``,
resulting in::
|--dev/
| `-- ram0
`--etc/
`--init.d/
`-- rcS
- By default, the contents of rcS script are::
# Create a RAMDISK and mount it at XXXRDMOUNTPOINTXXX
mkrd -m 1 -s 512 1024
mkfatfs /dev/ram1
mount -t vfat /dev/ram1 /tmp
- NSH will execute the script at ``/etc/init.d/rcS`` at start-up
(before the first NSH prompt). After execution of the script,
the root FS will look like::
|--dev/
| |-- ram0
| `-- ram1
|--etc/
| `--init.d/
| `-- rcS
`--tmp/
**Modifying the ROMFS Image**. The contents of the ``/etc``
directory are retained in the file ``apps/nshlib/nsh_romfsimg.h``
OR, if ``CONFIG_NSH_ARCHROMFS`` is defined,
``include/arch/board/rcs.template``). In order to modify the
start-up behavior, there are three things to study:
#. **Configuration Options.** The additional
``CONFIG_NSH_ROMFSETC`` configuration options discussed with
the other `NSH-specific configuration
settings <#nshconfiguration>`__.
#. `tools/mkromfsimg.sh`` **Script**. The script
``tools/mkromfsimg.sh`` creates ``nsh_romfsimg.h``. It is not
automatically executed. If you want to change the configuration
settings associated with creating and mounting the ``/tmp``
directory, then it will be necessary to re-generate this header
file using the ``tools/mkromfsimg.sh`` script.
The behavior of this script depends upon three things:
- The configuration settings then installed configuration.
- The ``genromfs`` tool (available from
http://romfs.sourceforge.net).
- The file ``apps/nshlib/rcS.template`` (OR, if
``CONFIG_NSH_ARCHROMFS`` is defined
``include/arch/board/rcs.template``.
#. ``rcS.template``: The file ``apps/nshlib/rcS.template``
contains the general form of the ``rcS`` file; configured
values are plugged into this template file to produce the final
``rcS`` file.
.. note::
``apps/nshlib/rcS.template`` generates the standard,
default ``nsh_romfsimg.h`` file. If ``CONFIG_NSH_ARCHROMFS`` is
defined in the NuttX configuration file, then a custom,
board-specific ``nsh_romfsimg.h`` file residing in the
``boards/<arch>/<chip>/<board>/include`` directory will be used.
NOTE when the OS is configured, ``include/arch/board`` will be
linked to ``boards/<arch>/<chip>/<board>/include``.
All of the startup-behavior is contained in ``rcS.template``. The
role of ``mkromfsimg.sh`` is to (1) apply the specific
configuration settings to ``rcS.template`` to create the final
``rcS``, and (2) to generate the header file ``nsh_romfsimg.h``
containing the ROMFS file system image.
**Further Information**. See the section on `Customizing the
NuttShell <#customizingnsh>`__ for additional, more detailed
information about the NSH start-up script and how to modify it.
@@ -0,0 +1,360 @@
.. _binfmt:
=============
Binary Loader
=============
The purpose of a *binary loader* is to load and
execute modules in various *binary formats* that reside in a file
system. Loading refers instantiating the binary module in some fashion,
usually copy all or some of the binary module into memory and then
linking the module with other components. In most architectures, it is
the base FLASH code that is the primary component that the binary module
must link with because that is where the RTOS and primary tasks reside.
Program modules can then be executed after they have been loaded.
**Binary Formats**. The binary loader provides generic support for
different binary formats. It supports a *registration interface* that
allows the number of support binary formats to be loaded at run time.
Each binary format provides a common, interface for use by the binary
loader. When asked to load a binary, the binary loader will query each
registered binary format, providing it with the path of the binary
object to be loaded. The binary loader will stop when first binary
format the recognizes the binary object and successfully loads it or
when all registered binary formats have attempt loading the binary
object and failed.
At present, the following binary formats are support by NuttX:
- **ELF**. Standard ELF formatted files.
- **NXFLAT**. NuttX NXFLAT formatted files. More information about the
NXFLAT binary format can be found in the :ref:`NXFLAT
documentation <nxflat>`.
**Executables and Libraries** The generic binary loader logic does not
care what it is that it being loaded. It could load an executable
program or a library. There are no strict rules, but a library will tend
to export symbols and a program will tend to import symbols: The program
will use the symbols exported by the library. However, at this point in
time, none of the supported binary formats support exporting of symbols.
**binfmt**. In the NuttX source code, the short name ``binfmt`` is used
to refer to the NuttX binary loader. This is the name of the directory
containing the binary loader and the name of the header files and
variables used by the binary loader.
The name ``binfmt`` is the same name used by the Linux binary loader.
However, the NuttX binary loader is an independent development and
shares nothing with the Linux binary loader other the same name and the
same basic functionality.
Binary Loader Interface
=======================
Header Files
------------
The interface to the binary loader is described in the header file
``include/nuttx/binfmt/binfmt.h``.
A brief summary of the data structurs and interfaces prototyped in that
header file are listed below.
Data Structures
---------------
When a binary format registers with the binary loader, it provides a
pointer to a write-able instance of :c:struct:`binfmt_s`.
.. c:struct:: binfmt_s
.. code-block:: c
struct binfmt_s
{
FAR struct binfmt_s *next; /* Supports a singly-linked list */
int (*load)(FAR struct binary_s *bin); /* Verify and load binary into memory */
};
The ``load`` method is used to load the binary format into memory. It
returns either ``OK`` (0) meaning that the binary object was loaded
successfully, or a negated ``errno`` indicating why the object was not
loaded.
.. c:struct:: binary_s
The type ``struct binary_s`` is use both to (1) describe the binary
object to be loaded, and if successfully loaded, (2) to provide
information about where and how the binary object was loaded. That
structure is shown below:
.. code-block:: c
struct symtab_s;
struct binary_s
{
/* Information provided to the loader to load and bind a module */
FAR const char *filename; /* Full path to the binary to be loaded */
FAR const char **argv; /* Argument list */
FAR const struct symtab_s *exports; /* Table of exported symbols */
int nexports; /* The number of symbols in exports[] */
/* Information provided from the loader (if successful) describing the
* resources used by the loaded module.
*/
main_t entrypt; /* Entry point into a program module */
FAR void *mapped; /* Memory-mapped, address space */
FAR void *alloc[BINFMT_NALLOC]; /* Allocated address spaces */
/* Constructors/destructors */
#ifdef CONFIG_BINFMT_CONSTRUCTORS
FAR binfmt_ctor_t *ctors; /* Pointer to a list of constructors */
FAR binfmt_dtor_t *dtors; /* Pointer to a list of destructors */
uint16_t nctors; /* Number of constructors in the list */
uint16_t ndtors; /* Number of destructors in the list */
#endif
/* Address environment.
*
* addrenv - This is the handle created by up_addrenv_create() that can be
* used to manage the tasks address space.
*/
#ifdef CONFIG_ARCH_ADDRENV
group_addrenv_t addrenv; /* Task group address environment */
#endif
size_t mapsize; /* Size of the mapped address region (needed for munmap) */
/* Start-up information that is provided by the loader, but may be modified
* by the caller between load_module() and exec_module() calls.
*/
uint8_t priority; /* Task execution priority */
size_t stacksize; /* Size of the stack in bytes (unallocated) */
};
Where the types ``binfmt_ctor_t`` and ``binfmt_dtor_t`` define the type
of one C++ constructor or destructor:
.. code-block:: c
typedef FAR void (*binfmt_ctor_t)(void);
typedef FAR void (*binfmt_dtor_t)(void);
Function Interfaces
-------------------
Binary format management
~~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: int register_binfmt(FAR struct binfmt_s *binfmt)
Register a loader for a binary format.
:return: This is a NuttX internal function so it follows the convention
that 0 (OK) is returned on success and a negated errno is returned on
failure.
.. c:function:: int unregister_binfmt(FAR struct binfmt_s *binfmt)
Register a loader for a binary format.
:return:
This is a NuttX internal function so it follows the convention
that 0 (OK) is returned on success and a negated errno is returned on
failure.
Basic module management
~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: int load_module(FAR struct binary_s *bin)
Load a module into memory, bind it to an exported symbol take,
and prep the module for execution.
:param bin:
The ``filename`` field will be used
in order to locate the module to be loaded from the file system.
The filename must be the full, absolute path to the file to be executed
unless ``CONFIG_LIB_ENVPATH`` is defined. In that case, filename may be
a relative path; a set of candidate absolute paths will be generated using
the ``PATH`` environment variable and ``load_module()`` will attempt to load each
file that is found at those absolute paths.
:return:
This is a NuttX internal function so it follows the convention that 0 (``OK``)
is returned on success and a negated ``errno`` is returned on failure.
.. c:function:: int unload_module(FAR struct binary_s *bin)
Unload a (non-executing) module from memory. If the module has been started
(via :c:func:`exec_module`) and has not exited, calling this will be fatal.
However, this function must be called after the module exist. How this is
done is up to your logic. Perhaps you register it to be called by :c:func:`on_exit`?
:return:
This is a NuttX internal function so it follows the convention that 0 (``OK``)
is returned on success and a negated ``errno`` is returned on failure.
.. c:function:: int exec_module(FAR const struct binary_s *bin);
Execute a module that has been loaded into memory by :c:func:`load_module`.
:return:
This is a NuttX internal function so it follows the convention that 0 (``OK``)
is returned on success and a negated ``errno`` is returned on failure.
.. tip::
The function :c:func:`exec` is a convenience function that wraps
:c:func:`load_module` and :c:func:`exec_module` into one call.
``PATH`` traversal logic
~~~~~~~~~~~~~~~~~~~~~~~~
.. c:function:: ENVPATH_HANDLE envpath_init(void);
Initialize for the traversal of each value in the ``PATH`` variable. The
usage is sequence is as follows:
#. Call :c:func:`envpath_init` to initialize for the traversal.
``envpath_init()`` will return an opaque handle that can then be
provided to :c:func:`envpath_next` and :c:func:`envpath_release`.
#. Call :c:func:`envpath_next` repeatedly to examine every file that lies in
the directories of the ``PATH`` variable.
#. Call :c:func:`envpath_release` to free resources set aside by
:c:func:`envpath_init`.
:return:
On success, :c:func:`envpath_init` return a non-``NULL``, opaque handle
that may subsequently be used in calls to :c:func:`envpath_next` and
:c:func:`envpath_release`. On error, a ``NULL`` handle value will be returned.
The most likely cause of an error would be that there is no value
associated with the ``PATH`` variable.
.. c:function:: FAR char *envpath_next(ENVPATH_HANDLE handle, FAR const char *relpath)
Traverse all possible values in the PATH variable in attempt to find the
full path to an executable file when only a relative path is provided.
:param handle: The handle value returned by :c:func:`envpath_init`.
:param relpath: The relative path to the file to be found.
:return:
On success, a non-``NULL`` pointer to a null-terminated string is provided.
This is the full path to a file that exists in the file system.
This function will verify that the file exists (but will not verify that it is marked executable).
.. note::
The string pointer return in the success case points to allocated memory.
This memory must be freed by the called by calling :c:func:`kmm_free`.
``NULL`` relpath from any absolute path in the ``PATH`` variable.
In this case, there is no point in calling :c:func:`envpath_next` further;
:c:func:`envpath_release` must be called to release resources set aside by
:c:func:`envpath_init`.
.. c:function:: void envpath_release(ENVPATH_HANDLE handle)
Release all resources set aside by envpath_init when the
handle value was created. The handle value is invalid on
return from this function. Attempts to all :c:func:`envpath_next`
or :c:func:`envpath_release` with such a stale handle will result
in undefined (i.e., not good) behavior.
:param handle: The handle value returned by :c:func:`envpath_init`.
Symbol Tables
=============
**Symbol Tables**. Symbol tables are lists of name value mappings: The
name is a string that identifies a symbol, and the value is an address
in memory where the symbol of that name has been positioned. In most
NuttX architectures symbol tables are required, as a minimum, in order
to dynamically link the loaded binary object with the base code on
FLASH. Since the binary object was separately built and separately
linked, these symbols will appear as *undefined* symbols in the binary
object. The binary loader will use the symbol table to look up the
symbol by its name and to provide the address associated with the symbol
as needed to perform the dynamic linking of the binary object to the
base FLASH code.
Some toolchains will prefix symbols with an underscore. To support these
toolchains the ``CONFIG_SYMTAB_DECORATED`` setting may be defined. This
will cause a leading underscore to be ignored on *undefined* symbols
during dynamic linking.
Symbol Table Header Files
-------------------------
The interface to the symbol table logic is described in the header file
``include/nuttx/binfmt/symtab.h``.
A brief summary of the data structurs and interfaces prototyped in that
header file are listed below.
Symbol Table Data Structures
----------------------------
.. c:struct:: symbtab_s
Describes one entry in the symbol table.
.. code-block:: c
struct symtab_s
{
FAR const char *sym_name; /* A pointer to the symbol name string */
FAR const void *sym_value; /* The value associated with the string */
};
A symbol table is a fixed size array of ``struct symtab_s``. The
information is intentionally minimal and supports only:
#. Function pointers as ``sym_values``. Of other kinds of values need to
be supported, then typing information would also need to be included
in the structure.
#. Fixed size arrays. There is no explicit provisional for dynamically
adding or removing entries from the symbol table (realloc might be
used for that purpose if needed). The intention is to support only
fixed size arrays completely defined at compilation or link time.
Symbol Table Function Interfaces
--------------------------------
.. c:function:: FAR const struct symtab_s *symtab_findbyname(FAR const struct symtab_s *symtab, FAR const char *name, int nsyms);
Find the symbol in the symbol table with the matching name.
The implementation will be linear with respect to ``nsyms`` if
``CONFIG_SYMTAB_ORDEREDBYNAME`` is not selected, and logarithmic
if it is.
:return:
A reference to the symbol table entry if an entry with
the matching name is found; NULL is returned if the entry is not found.
.. c:function:: FAR const struct symtab_s *symtab_findbyvalue(FAR const struct symtab_s *symtab, FAR void *value, int nsyms);
Find the symbol in the symbol table whose value closest
(but not greater than), the provided value. This version assumes
that table is not ordered with respect to symbol value and, hence,
access time will be linear with respect to ``nsyms``.
:return:
A reference to the symbol table entry if an entry with the matching
value is found; ``NULL`` is returned if the entry is not found.
Configuration Variables
=======================
- ``CONFIG_BINFMT_DISABLE``: By default, support for loadable binary formats is built.
This logic may be suppressed be defining this setting.
- ``CONFIG_BINFMT_CONSTRUCTORS``: Build in support for C++ constructors in loaded modules.
- ``CONFIG_SYMTAB_ORDEREDBYNAME``: Symbol tables are order by name (rather than value).
- ``CONFIG_SYMTAB_DECORATED``: Symbols will have a leading underscore in object files.
Additional configuration options may be required for the each enabled
binary format.
@@ -0,0 +1,41 @@
====================
Block Device Drivers
====================
Block device drivers have these properties:
- ``include/nuttx/fs/fs.h``. All structures and APIs needed
to work with block drivers are provided in this header file.
- ``struct block_operations``. Each block device driver must
implement an instance of ``struct block_operations``. That
structure defines a call table with the following methods:
- ``int register_blockdriver(const char *path, const struct block_operations *bops, mode_t mode, void *priv);``.
Each block driver registers itself by calling
``register_blockdriver()``, passing it the ``path`` where it
will appear in the :ref:`pseudo file system <file_system_overview>` and
it's initialized instance of ``struct block_operations``.
- **User Access**. Users do not normally access block drivers
directly, rather, they access block drivers indirectly through
the ``mount()`` API. The ``mount()`` API binds a block driver
instance with a file system and with a mountpoint. Then the
user may use the block driver to access the file system on the
underlying media. *Example*: See the ``cmd_mount()``
implementation in ``apps/nshlib/nsh_fscmds.c``.
- **Accessing a Character Driver as a Block Device**. See the
loop device at ``drivers/loop.c``. *Example*: See the
``cmd_losetup()`` implementation in
``apps/nshlib/nsh_fscmds.c``.
- **Accessing a Block Driver as Character Device**. See the
Block-to-Character (BCH) conversion logic in ``drivers/bch/``.
*Example*: See the ``cmd_dd()`` implementation in
``apps/nshlib/nsh_ddcmd.c``.
- **Examples**. ``drivers/loop.c``,
``drivers/mmcsd/mmcsd_spi.c``, ``drivers/ramdisk.c``, etc.
@@ -0,0 +1,55 @@
========================
Analog (ADC/DAC) Drivers
========================
The NuttX analog drivers are split into two parts:
#. An "upper half", generic driver that provides the common analog
interface to application level code, and
#. A "lower half", platform-specific driver that implements the
low-level controls to implement the analog functionality.
- General header files for the NuttX analog drivers reside in
``include/nuttx/analog/``. These header files includes both the
application level interface to the analog driver as well as the
interface between the "upper half" and "lower half" drivers.
- Common analog logic and share-able analog drivers reside in the
``drivers/analog/``.
- Platform-specific drivers reside in
``arch/``\ *<architecture>*\ ``/src/``\ *<hardware>* directory
for the specific processor *<architecture>* and for the
specific *<chip>* analog peripheral devices.
ADC Drivers
-----------
- ``include/nuttx/analog/adc.h``. All structures and APIs needed
to work with ADC drivers are provided in this header file. This
header file includes:
#. Structures and interface descriptions needed to develop a
low-level, architecture-specific, ADC driver.
#. To register the ADC driver with a common ADC character
driver.
#. Interfaces needed for interfacing user programs with the
common ADC character driver.
- ``drivers/analog/adc.c``. The implementation of the common ADC
character driver.
DAC Drivers
-----------
- ``include/nuttx/analog/dac.h``. All structures and APIs needed
to work with DAC drivers are provided in this header file. This
header file includes:
#. Structures and interface descriptions needed to develop a
low-level, architecture-specific, DAC driver.
#. To register the DAC driver with a common DAC character
driver.
#. Interfaces needed for interfacing user programs with the
common DAC character driver.
- ``drivers/analog/dac.c``. The implementation of the common DAC
character driver.
@@ -0,0 +1,36 @@
===========
CAN Drivers
===========
NuttX supports only a very low-level CAN driver. This driver
supports only the data exchange and does not include any
high-level CAN protocol. The NuttX CAN driver is split into two
parts:
#. An "upper half", generic driver that provides the common CAN
interface to application level code, and
#. A "lower half", platform-specific driver that implements the
low-level timer controls to implement the CAN functionality.
Files supporting CAN can be found in the following locations:
- **Interface Definition**. The header file for the NuttX CAN
driver resides at ``include/nuttx/can/can.h``. This header file
includes both the application level interface to the CAN driver
as well as the interface between the "upper half" and "lower
half" drivers. The CAN module uses a standard character driver
framework.
- **"Upper Half" Driver**. The generic, "upper half" CAN driver
resides at ``drivers/can.c``.
- **"Lower Half" Drivers**. Platform-specific CAN drivers reside
in ``arch/``\ *<architecture>*\ ``/src/``\ *<hardware>*
directory for the specific processor *<architecture>* and for
the specific *<chip>* CAN peripheral devices.
**Usage Note**: When reading from the CAN driver multiple messages
may be returned, depending on (1) the size the returned can
messages, and (2) the size of the buffer provided to receive CAN
messages. *Never assume that a single message will be returned*...
if you do this, *you will lose CAN data* under conditions where
your read buffer can hold more than one small message. Below is an
example about how you should think of the CAN read operation:
@@ -0,0 +1,48 @@
====================
FOC Driver Interface
====================
Field Oriented Control (FOC) is a common technique to control
either synchronous or asynchronous alternating current machines.
The main goal of FOC is to control direct current (Id) and
quadrature current (Iq) in powered device.
The device on the kernel side is responsible for the following:
#. update PWM duty cycles
#. return ADC current samples
#. synchronize user-space with PWM events
The Nuttx FOC driver is split into two parts:
#. An "upper half", generic driver that provides the common FOC
interface to application level code,
#. A "lower half", platform-specific driver that implemets
the low-level logic to implement the FOC functionality
Files supporting FOC can be found in the following locations:
- ``include/nuttx/motor/foc/foc.h``.
"Upper-half" FOC interface available for the user-space.
- ``include/nuttx/motor/foc/foc_lower.h``.
"Lower-half" FOC interface.
- ``drivers/motor/foc/foc_dev.c``.
The generic "upper half" FOC driver.
The majority of the functionality available to the application
is implemented in driver ioctl calls. Supported ioctl commands:
- ``MTRIOC_START`` - Start the FOC device, arg: none.
- ``MTRIOC_STOP`` - Stop the FOC device, arg: none.
- ``MTRIOC_GET_STATE`` - Get the FOC device state,
arg: ``struct foc_state_s`` pointer.
This is a blocking operation that is used to synchronize the user space
application with ADC samples.
- ``MTRIOC_CLEAR_FAULT`` - Clear the FOC device fault state,
arg: none.
- ``MTRIOC_SET_PARAMS`` - Set the FOC device operation parameters,
arg: ``struct foc_params_s`` pointer.
- ``MTRIOC_SET_CONFIG`` - Set the FOC device configuration,
arg: ``struct foc_cfg_s`` pointer.
- ``MTRIOC_GET_INFO`` - Get the FOC device info,
arg: ``struct foc_info_s`` pointer.
@@ -0,0 +1,68 @@
.. _chardev:
========================
Character Device Drivers
========================
Character device drivers have these properties:
- ``include/nuttx/fs/fs.h``. All structures and APIs needed
to work with character drivers are provided in this header
file.
- ``struct file_operations``. Each character device driver
must implement an instance of ``struct file_operations``. That
structure defines a call table with the following methods:
- ``int register_driver(const char *path, const struct file_operations *fops, mode_t mode, void *priv);``.
Each character driver registers itself by calling
``register_driver()``, passing it the ``path`` where it will
appear in the :ref:`pseudo file system <file_system_overview>` and it's
initialized instance of ``struct file_operations``.
- **User Access**. After it has been registered, the character
driver can be accessed by user code using the standard driver
operations including
``open()``, ``close()``, ``read()``, ``write()``, etc.
- **Specialized Character Drivers**. Within the common character
driver framework, there are different specific varieties of
*specialized* character drivers. The unique requirements of the
underlying device hardware often mandates some customization of
the character driver. These customizations tend to take the
form of:
- Device-specific ``ioctl()`` commands used to performed
specialized operations on the device. These ``ioctl()`` will
be documented in header files under ``include/nuttx`` that
detail the specific device interface.
- Specialized I/O formats. Some devices will require that
``read()`` and/or ``write()`` operations use data conforming
to a specific format, rather than a plain stream of bytes.
These specialized I/O formats will be documented in header
files under ``include/nuttx`` that detail the specific
device interface. The typical representation of the I/O
format will be a C structure definition.
The specialized character drivers support by NuttX are
documented in the following paragraphs.
- **Examples**: ``drivers/dev_null.c``, ``drivers/fifo.c``,
``drivers/serial.c``, etc.
.. toctree::
:caption: Supported Drivers
serial.rst
touchscreen.rst
analog.rst
pwm.rst
can.rst
quadrature.rst
timer.rst
rtc.rst
watchdog.rst
keypad.rst
note.rst
foc.rst
@@ -0,0 +1,143 @@
=======================
Keyboard/Keypad Drivers
=======================
**Keypads vs. Keyboards** Keyboards and keypads are really the
same devices for NuttX. A keypad is thought of as simply a
keyboard with fewer keys.
**Special Commands**. In NuttX, a keyboard/keypad driver is simply
a character driver that may have an (optional) encoding/decoding
layer on the data returned by the character driver. A keyboard may
return simple text data (alphabetic, numeric, and punctuation) or
control characters (enter, control-C, etc.) when a key is pressed.
We can think about this the "normal" keyboard data stream.
However, in addition, most keyboards support actions that cannot
be represented as text or control data. Such actions include
things like cursor controls (home, up arrow, page down, etc.),
editing functions (insert, delete, etc.), volume controls, (mute,
volume up, etc.) and other special functions. In this case, some
special encoding may be required to multiplex the normal text data
and special command key press data streams.
**Key Press and Release Events** Sometimes the time that a key is
released is needed by applications as well. Thus, in addition to
normal and special key press events, it may also be necessary to
encode normal and special key release events.
**Encoding/Decoding** Layer. An optional encoding/decoding layer
can be used with the basic character driver to encode the keyboard
events into the text data stream. The function interfaces that
comprise that encoding/decoding layer are defined in the header
file ``include/nuttx/input/kbd_code.h``. These functions provide
an matched set of (a) driver encoding interfaces, and (b)
application decoding interfaces.
#. **Driver Encoding Interfaces**. These are interfaces used by
the keyboard/keypad driver to encode keyboard events and data.
- ``kbd_press()``
**Function Prototype:**
**Description:**
**Input Parameters:**
- ``ch``: The character to be added to the output stream.
- ``stream``: An instance of ``lib_outstream_s`` to perform
the actual low-level put operation.
**Returned Value:**
- ``kbd_release()``
**Function Prototype:**
**Description:**
**Input Parameters:**
- ``ch``: The character associated with the key that was
released.
- ``stream``: An instance of ``lib_outstream_s`` to perform
the actual low-level put operation.
**Returned Value:**
- ``kbd_specpress()``
**Function Prototype:**
**Description:**
**Input Parameters:**
- ``keycode``: The command to be added to the output
stream. The enumeration ``enum kbd_keycode_e keycode``
identifies all commands known to the system.
- ``stream``: An instance of ``lib_outstream_s`` to perform
the actual low-level put operation.
**Returned Value:**
- ``kbd_specrel()``
**Function Prototype:**
**Description:**
**Input Parameters:**
- ``keycode``: The command to be added to the output
stream. The enumeration ``enum kbd_keycode_e keycode``
identifies all commands known to the system.
- ``stream``: An instance of ``lib_outstream_s`` to perform
the actual low-level put operation.
**Returned Value:**
#. **Application Decoding Interfaces**. These are user interfaces
to decode the values returned by the keyboard/keypad driver.
- ``kbd_decode()``
**Function Prototype:**
**Description:**
**Input Parameters:**
- ``stream``: An instance of ``lib_instream_s`` to perform
the actual low-level get operation.
- ``pch``: The location to save the returned value. This
may be either a normal, character code or a special
command (i.e., a value from ``enum kbd_getstate_s``.
- ``state``: A user provided buffer to support parsing.
This structure should be cleared the first time that
``kbd_decode()`` is called.
**Returned Value:**
- ``KBD_PRESS`` (0)**: Indicates the successful receipt
of normal, keyboard data. This corresponds to a keypress
event. The returned value in ``pch`` is a simple byte of
text or control data.
- ``KBD_RELEASE`` (1)**: Indicates a key release event.
The returned value in ``pch`` is the byte of text or
control data corresponding to the released key.
- ``KBD_SPECPRESS`` (2)**: Indicates the successful
receipt of a special keyboard command. The returned value
in ``pch`` is a value from ``enum kbd_getstate_s``.
- ``KBD_SPECREL`` (3)**: Indicates a special command key
release event. The returned value in ``pch`` is a value
from ``enum kbd_getstate_s``.
- ``KBD_ERROR`` (``EOF``)**: An error has getting the
next character (reported by the ``stream``). Normally
indicates the end of file.
**I/O Streams**. Notice the use of the abstract I/O streams in
these interfaces. These stream interfaces are defined in
``include/nuttx/streams.h``.
@@ -0,0 +1,296 @@
=====================
Note Driver Interface
=====================
Note driver is the interface to access the instrumentation data.
The following devices are provided.
- :ref:`notectl`
- :ref:`noteram`
.. _notectl:
Notectl Device (``/dev/notectl``)
=================================
``/dev/notectl`` is the device to control an instrumentation filter in NuttX kernel.
The device has only ioctl function to control the filter.
``/dev/notectl`` Header Files
-----------------------------
The header file ``include/nuttx/note/notectl_driver.h`` provides the interface definitions of the device.
``/dev/notectl`` Data Structures
--------------------------------
.. c:struct:: note_filter_mode_s
.. code-block:: c
struct note_filter_mode_s
{
unsigned int flag; /* Filter mode flag */
#ifdef CONFIG_SMP
unsigned int cpuset; /* The set of monitored CPUs */
#endif
};
- ``flag`` : Filter mode flag. The bitwise OR of the following defines are available.
.. c:macro:: NOTE_FILTER_MODE_FLAG_ENABLE
Enable instrumentation
.. c:macro:: NOTE_FILTER_MODE_FLAG_SYSCALL
Enable syscall instrumentation
.. c:macro:: NOTE_FILTER_MODE_FLAG_IRQ
Enable IRQ instrumentaiton
- ``cpuset`` : (SMP only) Monitor only CPUs in the bitset. Bit 0=CPU0, Bit1=CPU1, etc.
.. c:struct:: note_filter_syscall_s
.. code-block:: c
struct note_filter_syscall_s
{
uint8_t syscall_mask[];
};
- ``syscall_mask`` : A bitmap array of the syscall filter. If a bit is set, the corresponding syscall is not recorded.
The following helper macros are available:
.. c:macro:: NOTE_FILTER_SYSCALLMASK_SET(nr, s)
Set syscall number `nr` as masked. `s` specifies the variable of `struct note_filter_syscall_s`
.. c:macro:: NOTE_FILTER_SYSCALLMASK_CLR(nr, s)
Set syscall number `nr` as unmasked.
.. c:macro:: NOTE_FILTER_SYSCALLMASK_ISSET(nr, s)
Check whether syscall number `nr` is masked or not. True if masked.
.. c:macro:: NOTE_FILTER_SYSCALLMASK_ZERO(s)
Clear all masks.
.. c:struct:: note_filter_irq_s
.. code-block:: c
struct note_filter_irq_s
{
uint8_t irq_mask[];
};
- ``irq_mask`` : A bitmap array of the IRQ filter. If a bit is set, the corresponding IRQ is not recorded.
The following helper macros are available:
.. c:macro:: NOTE_FILTER_IRQMASK_SET(nr, s)
Set IRQ number `nr` as masked. `s` specifies the variable of `struct note_filter_irq_s`
.. c:macro:: NOTE_FILTER_IRQMASK_CLR(nr, s)
Set IRQ number `nr` as unmasked.
.. c:macro:: NOTE_FILTER_IRQMASK_ISSET(nr, s)
Check whether IRQ number `nr` is masked or not. True if masked.
.. c:macro:: NOTE_FILTER_IRQMASK_ZERO(s)
Clear all masks.
``/dev/notectl`` Ioctls
-----------------------
.. c:macro:: NOTECTL_GETMODE
Get note filter mode
:argument: A writable pointer to :c:struct:`note_filter_mode_s`
:return: If success, 0 (``OK``) is returned and current note filter mode is stored into the given pointer.
If failed, a negated ``errno`` is returned.
.. c:macro:: NOTECTL_SETMODE
Set note filter mode
:argument: A read-only pointer to :c:struct:`note_filter_mode_s`
:return: If success, 0 (``OK``) is returned and the given filter mode is set as the current settings.
If failed, a negated ``errno`` is returned.
.. c:macro:: NOTECTL_GETSYSCALLFILTER
Get syscall filter setting
:argument: A writable pointer to :c:struct:`note_filter_syscall_s`
:return: If success, 0 (``OK``) is returned and current syscall filter mode is stored into the given pointer.
If failed, a negated ``errno`` is returned.
.. c:macro:: NOTECTL_SETSYSCALLFILTER
Set syscall filter setting
:argument: A read-only pointer to :c:struct:`note_filter_syscall_s`
:return: If success, 0 (``OK``) is returned and the given syscall filter mode is set as the current settings.
If failed, a negated ``errno`` is returned.
.. c:macro:: NOTECTL_GETIRQFILTER
Get IRQ filter setting
:argument: A writable pointer to :c:struct:`note_filter_irq_s`
:return: If success, 0 (``OK``) is returned and current IRQ filter mode is stored into the given pointer.
If failed, a negated ``errno`` is returned.
.. c:macro:: NOTECTL_SETIRQFILTER
Set IRQ filter setting
:argument: A read-only pointer to :c:struct:`note_filter_irq_s`
:return: If success, 0 (``OK``) is returned and the given IRQ filter mode is set as the current settings.
If failed, a negated ``errno`` is returned.
.. _noteram:
Noteram Device (``/dev/note``)
==============================
``/dev/note`` is the device to get the trace (instrumentation) data.
The device has read function to get the data and ioctl function to control the buffer mode.
``/dev/note`` Header Files
--------------------------
The header file ``include/nuttx/note/noteram_driver.h`` provides the interface definitions of the device.
``/dev/note`` Data Structures
--------------------------------
.. c:struct:: noteram_get_taskname_s
.. code-block:: c
struct noteram_get_taskname_s
{
pid_t pid;
char taskname[CONFIG_TASK_NAME_SIZE + 1];
};
- ``pid`` : Task ID to get the task name.
- ``taskname`` : The task name string corresponding to given pid.
``/dev/note`` Ioctls
--------------------
.. c:macro:: NOTERAM_CLEAR
Clear all contents of the circular buffer
:argument: Ignored
:return: Always returns 0.
.. c:macro:: NOTERAM_GETMODE
Get overwrite mode
:argument: A writable pointer to ``unsigned int``.
The overwrite mode takes one of the following values.
.. c:macro:: NOTERAM_MODE_OVERWRITE_DISABLE
Overwrite mode is disabled. When the buffer is full, accepting the data will be stopped.
.. c:macro:: NOTERAM_MODE_OVERWRITE_ENABLE
Overwrite mode is enabled.
.. c:macro:: NOTERAM_MODE_OVERWRITE_OVERFLOW
Overwrite mode is disabled and the buffer is already full.
:return: If success, 0 (``OK``) is returned and current overwrite mode is stored into the given pointer.
If failed, a negated ``errno`` is returned.
.. c:macro:: NOTERAM_SETMODE
Set overwrite mode
:argument: A read-only pointer to ``unsigned int``.
:return: If success, 0 (``OK``) is returned and the given overwriter mode is set as the current settings.
If failed, a negated ``errno`` is returned.
.. c:macro:: NOTERAM_GETTASKNAME
Get task name string
:argument: A writable pointer to :c:struct:`noteram_get_taskname_s`
:return: If success, 0 (``OK``) is returned and the task name corresponding to given pid is stored into the given pointer.
If failed, a negated ``errno`` is returned.
Filter control APIs
===================
The following APIs are the functions to control note filters directly.
These are kernel APIs and application can use them only in FLAT build.
The header file ``include/nuttx/sched_note.h`` is needed to use the following APIs.
API description
---------------
.. c:function:: void sched_note_filter_mode(struct note_filter_mode_s *oldm, struct note_filter_mode_s *newm);
Set and get note filter mode.
(Same as :c:macro:`NOTECTL_GETMODE` / :c:macro:`NOTECTL_SETMODE` ioctls)
:param oldm: A writable pointer to :c:struct:`note_filter_mode_s` to get current filter mode.
If 0, no data is written.
:param newm: A read-only pointer to :c:struct:`note_filter_mode_s` which holds the new filter mode.
If 0, the filter mode is not updated.
:return: None
.. c:function:: void sched_note_filter_syscall(struct note_filter_syscall_s *oldf, struct note_filter_syscall_s *newf);
Set and get syscall filter setting.
(Same as :c:macro:`NOTECTL_GETSYSCALLFILTER` / :c:macro:`NOTECTL_SETSYSCALLFILTER` ioctls)
:param oldf: A writable pointer to :c:struct:`note_filter_syscall_s` to get current syscall filter setting.
If 0, no data is written.
:param newf: A read-only pointer to :c:struct:`note_filter_syscall_s` of the new syscall filter setting.
If 0, the setting is not updated.
:return: None
.. c:function:: void sched_note_filter_irq(struct note_filter_irq_s *oldf, struct note_filter_irq_s *newf);
Set and get IRQ filter setting.
(Same as :c:macro:`NOTECTL_GETIRQFILTER` / :c:macro:`NOTECTL_SETIRQFILTER` ioctls)
:param oldf: A writable pointer to :c:struct:`note_filter_irq_s` to get current IRQ filter setting.
If 0, no data is written.
:param newf: A read-only pointer to :c:struct:`note_filter_irq_s` of the new IRQ filter setting.
If 0, the setting is not updated.
:return: None
@@ -0,0 +1,34 @@
===========
PWM Drivers
===========
For the purposes of this driver, a PWM device is any device that
generates periodic output pulses of controlled frequency and pulse
width. Such a device might be used, for example, to perform
pulse-width modulated output or frequency/pulse-count modulated
output (such as might be needed to control a stepper motor).
The NuttX PWM driver is split into two parts:
#. An "upper half", generic driver that provides the common PWM
interface to application level code, and
#. A "lower half", platform-specific driver that implements the
low-level timer controls to implement the PWM functionality.
Files supporting PWM can be found in the following locations:
- **Interface Definition**. The header file for the NuttX PWM
driver reside at ``include/nuttx/timers/pwm.h``. This header
file includes both the application level interface to the PWM
driver as well as the interface between the "upper half" and
"lower half" drivers. The PWM module uses a standard character
driver framework. However, since the PWM driver is a device
control interface and not a data transfer interface, the
majority of the functionality available to the application is
implemented in driver ioctl calls.
- **"Upper Half" Driver**. The generic, "upper half" PWM driver
resides at ``drivers/timers/pwm.c``.
- **"Lower Half" Drivers**. Platform-specific PWM drivers reside
in ``arch/``\ *<architecture>*\ ``/src/``\ *<hardware>*
directory for the specific processor *<architecture>* and for
the specific *<chip>* PWM peripheral devices.
@@ -0,0 +1,29 @@
Quadrature Encoder Drivers
==========================
NuttX supports a low-level, two-part Quadrature Encoder driver.
#. An "upper half", generic driver that provides the common
Quadrature Encoder interface to application level code, and
#. A "lower half", platform-specific driver that implements the
low-level timer controls to implement the Quadrature Encoder
functionality.
Files supporting the Quadrature Encoder can be found in the
following locations:
- **Interface Definition**. The header file for the NuttX
Quadrature Encoder driver reside at
``include/nuttx/sensors/qencoder.h``. This header file includes
both the application level interface to the Quadrature Encoder
driver as well as the interface between the "upper half" and
"lower half" drivers. The Quadrature Encoder module uses a
standard character driver framework.
- **"Upper Half" Driver**. The generic, "upper half" Quadrature
Encoder driver resides at ``drivers/sensors/qencoder.c``.
- **"Lower Half" Drivers**. Platform-specific Quadrature Encoder
drivers reside in
``arch/``\ *<architecture>*\ ``/src/``\ *<hardware>* directory
for the specific processor *<architecture>* and for the
specific *<chip>* Quadrature Encoder peripheral devices.
@@ -0,0 +1,25 @@
RTC Drivers
===========
NuttX supports a low-level, two-part RealTime Clock (RTC) driver.
#. An "upper half", generic driver that provides the common RTC
interface to application level code, and
#. A "lower half", platform-specific driver that implements the
low-level timer controls to implement the RTC functionality.
Files supporting the RTC driver can be found in the following
locations:
- **Interface Definition**. The header file for the NuttX RTC
driver reside at ``include/nuttx/timers/rtc.h``. This header
file includes both the application level interface to the RTC
driver as well as the interface between the "upper half" and
"lower half" drivers. The RTC driver uses a standard character
driver framework.
- **"Upper Half" Driver**. The generic, "upper half" RTC driver
resides at ``drivers/timers/rtc.c``.
- **"Lower Half" Drivers**. Platform-specific RTC drivers reside
in ``arch/``\ *<architecture>*\ ``/src/``\ *<hardware>*
directory for the specific processor *<architecture>* and for
the specific *<chip>* RTC peripheral devices.
@@ -0,0 +1,29 @@
=====================
Serial Device Drivers
=====================
- ``include/nuttx/serial/serial.h``. All structures and APIs
needed to work with serial drivers are provided in this header
file.
- ``struct uart_ops_s``. Each serial device driver must
implement an instance of ``struct uart_ops_s``. That structure
defines a call table with the following methods:
- ``int uart_register(FAR const char *path, FAR uart_dev_t *dev);``.
A serial driver may register itself by calling
``uart_register()``, passing it the ``path`` where it will
appear in the :ref:`pseudo file system <file_system_overview>` and it's
initialized instance of ``struct uart_ops_s``. By convention,
serial device drivers are registered at paths like
``/dev/ttyS0``, ``/dev/ttyS1``, etc. See the
``uart_register()`` implementation in ``drivers/serial.c``.
- **User Access**. Serial drivers are, ultimately, normal
`character drivers <#chardrivers>`__ and are accessed as other
character drivers.
- **Examples**: ``arch/arm/src/stm32/stm32_serial.c``,
``arch/arm/src/lpc214x/lpc214x_serial.c``,
``arch/z16/src/z16f/z16f_serial.c``, etc.
@@ -0,0 +1,333 @@
Timer Drivers
=============
Files supporting the timer driver can be found in the following
locations:
- **Interface Definition**. The header file for the NuttX timer
driver reside at ``include/nuttx/timers/timer.h``. This header
file includes both the application level interface to the timer
driver as well as the interface between the "upper half" and
"lower half" drivers. The timer driver uses a standard
character driver framework.
- **"Upper Half" Driver**. The generic, "upper half" timer driver
resides at ``drivers/timers/timer.c``.
- **"Lower Half" Drivers**. Platform-specific timer drivers
reside in ``arch/``\ *<architecture>*\ ``/src/``\ *<hardware>*
directory for the specific processor *<architecture>* and for
the specific *<chip>* timer peripheral devices.
There are two ways to enable Timer Support along with the Timer Example. The first is faster and simpler. Just run the following command to use a ready config file with timer support and example included. You need to check if there's a timer config file for your specific chip. You may check it at the specific board's path: ``/boards/<arch>/<chip>/<variant>/config``.
.. code-block:: console
$ ./tools/configure.sh <variant>:timer
And the second way is creating your own config file. To do so, follow the next instructions.
Enabling the Timer Support and Example in ``menuconfing``
----------------------------------------------------------
1. Select Timer Instances
To select these timers browse in the ``menuconfig`` using the following path:
Go into menu :menuselection:`System Type --> <Chip> Peripheral Selection` and press :kbd:`Enter`.
Then select one or more timers according to availability.
2. Enable the Timer Support
Go into menu :menuselection:`Device Drivers --> Timer Driver Support` and press :kbd:`Enter`. Then enable:
- [x] Timer Support
- [x] Timer Arch Implementation
3. Include the Timer Example
Go into menu :menuselection:`Application Configuration --> Examples` and press :kbd:`Enter`. Then select the Timer Example.
- [x] Timer example
Below the option, it is possible to manually configure some parameters as the standard timer device path, the timeout, the sample rate in which the counter will be read, the number of samples to be executed, and other parameters.
Timer Example
--------------
The previously selected example will basically consult the timer status, set a timer alarm interval, set a timer signal handler function to be notified at the alarm, which only increments a variable, and then it will start the timer. The application will periodically consult the timer status at the sample rate previously configured through the ``menuconfig`` to follow the time left until the timer expires. After the samples have been read, the application stops de timer.
The `example code <https://github.com/apache/incubator-nuttx-apps/blob/master/examples/timer/timer_main.c>`_ may be explored, its path is at ``/examples/timer/timer_main.c`` in the apps' repository.
In NuttX, the timer driver is a character driver and when a chip supports multiple timers, each one is accessible through its respective file in ``/dev`` directory. Each timer is registered using a unique numeric identifier (i.e. ``/dev/timer0``, ``/dev/timer1``, ...).
Use the following command to run the example:
.. code-block:: console
`nsh> timer`
This command will use the timer 0. To use the others, specify it through a parameter (where x is the timer number):
.. code-block:: console
`nsh> timer -d /dev/timerx`
Application Level Interface
----------------------------
The first necessary thing to be done in order to use the timer driver in an application is to include the header file for the NuttX timer driver. It contains the Application Level Interface to the timer driver. To do so, include:
.. code-block:: c
#include <nuttx/timers/timer.h>
At an application level, the timer functionalities may be accessed through ``ioctl`` systems calls. The available ``ioctl`` commands are:
* :c:macro:`TCIOC_START`
* :c:macro:`TCIOC_STOP`
* :c:macro:`TCIOC_GETSTATUS`
* :c:macro:`TCIOC_SETTIMEOUT`
* :c:macro:`TCIOC_NOTIFICATION`
* :c:macro:`TCIOC_MAXTIMEOUT`
These ``ioctl`` commands internally call lower-half layer operations and the parameters are forwarded to these ops through the ``ioctl`` system call. The return of a system call is the return of an operation.
These ``struct timer_ops_s`` keeps pointers to the implementation of each operation. Following is the struct.
.. c:struct:: timer_ops_s
.. code-block:: c
struct timer_ops_s
{
/* Required methods *******************************************************/
/* Start the timer, resetting the time to the current timeout */
CODE int (*start)(FAR struct timer_lowerhalf_s *lower);
/* Stop the timer */
CODE int (*stop)(FAR struct timer_lowerhalf_s *lower);
/* Get the current timer status */
CODE int (*getstatus)(FAR struct timer_lowerhalf_s *lower,
FAR struct timer_status_s *status);
/* Set a new timeout value (and reset the timer) */
CODE int (*settimeout)(FAR struct timer_lowerhalf_s *lower,
uint32_t timeout);
/* Call the NuttX INTERNAL timeout callback on timeout.
* NOTE: Providing callback==NULL disable.
* NOT to call back into applications.
*/
CODE void (*setcallback)(FAR struct timer_lowerhalf_s *lower,
CODE tccb_t callback, FAR void *arg);
/* Any ioctl commands that are not recognized by the "upper-half" driver
* are forwarded to the lower half driver through this method.
*/
CODE int (*ioctl)(FAR struct timer_lowerhalf_s *lower, int cmd,
unsigned long arg);
/* Get the maximum supported timeout value */
CODE int (*maxtimeout)(FAR struct timer_lowerhalf_s *lower,
FAR uint32_t *maxtimeout);
};
Since ``ioctl`` system calls expect a file descriptor, before using these commands, it's necessary to open the timer device special file in order to get a file descriptor. The following snippet demonstrates how to do so:
.. code-block:: c
/* Open the timer device */
printf("Open %s\n", devname);
fd = open(devname, O_RDONLY);
if (fd < 0)
{
fprintf(stderr, "ERROR: Failed to open %s: %d\n",
devname, errno);
return EXIT_FAILURE;
}
.. c:macro:: TCIOC_START
The ``TCIOC_START`` command calls the ``start`` operation, which is described below.
.. c:function:: int start(void)
The start operation configures the timer, enables the interrupt if ``TCIOC_NOTIFICATION`` has already been called and finally starts the timer.
:return: A Linux System Error Code for failing or 0 for success.
This command may be used like so:
.. code-block:: c
/* Start the timer */
printf("Start the timer\n");
ret = ioctl(fd, TCIOC_START, 0);
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to start the timer: %d\n", errno);
close(fd);
return EXIT_FAILURE;
}
.. c:macro:: TCIOC_STOP
The ``TCIOC_STOP`` command calls the ``stop`` operation, which is described below.
.. c:function:: int stop(void)
The stop operation stops the timer and disables the interrupt.
:return: A Linux System Error Code for failing or 0 for success.
This command may be used like so:
.. code-block:: c
/* Stop the timer */
printf("\nStop the timer\n");
ret = ioctl(fd, TCIOC_STOP, 0);
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to stop the timer: %d\n", errno);
close(fd);
return EXIT_FAILURE;
}
.. c:macro:: TCIOC_GETSTATUS
The ``TCIOC_GETSTATUS`` command calls the ``getstatus`` operation, which is described below.
.. c:function:: int getstatus(FAR struct timer_status_s *status)
The getstatus operation gathers the timer's current information.
:param status: A writable pointer to a struct ``timer_status_s``. This struct contains 3 fields: ``flags`` (``uint32_t``), ``timeout`` (``uint32_t``) and ``timeleft`` (``uint32_t``). Bit 0 from `flags` indicates the timer's status, 1 indicates that the timer is running, zero it is stopped. Bit 1 from `flags` indicates if there's a callback registered. The `timeout` indicates the time interval that was configured to trigger an alarm, it is in microseconds. The `timeleft` interval indicates how many microseconds it's missing to trigger the alarm. The following snippet demonstrates how to use it and how to access these fields.
:return: A Linux System Error Code for failing or 0 for success.
This command may be used like so:
.. code-block:: c
/* Get timer status */
ret = ioctl(fd, TCIOC_GETSTATUS, (unsigned long)((uintptr_t)&status));
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to get timer status: %d\n", errno);
close(fd);
exit(EXIT_FAILURE);
}
/* Print the timer status */
printf(" flags: %08lx timeout: %lu timeleft: %lu\n",
(unsigned long)status.flags, (unsigned long)status.timeout,
(unsigned long)status.timeleft);
.. c:macro:: TCIOC_SETTIMEOUT
The ``TCIOC_SETTIMEOUT`` command calls the ``settimeout`` operation, which is described below.
.. c:function:: int settimeout(uint32_t timeout)
The getstatus operation sets a timeout interval to trigger the alarm and then trigger an interrupt. It defines the timer interval in which the handler will be called.
:param timeout: An argument of type ``uint32_t`` with the timeout value in microseconds.
:return: A Linux System Error Code for failing or 0 for success.
This command may be used like so:
.. code-block:: c
/* Set the timer interval */
printf("Set timer interval to %lu\n",
(unsigned long)CONFIG_EXAMPLES_TIMER_INTERVAL);
ret = ioctl(fd, TCIOC_SETTIMEOUT, CONFIG_EXAMPLES_TIMER_INTERVAL);
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to set the timer interval: %d\n", errno);
close(fd);
return EXIT_FAILURE;
}
.. c:macro:: TCIOC_NOTIFICATION
The ``TCIOC_NOTIFICATION`` is used to configure the timer callback to notify the application via a signal when the timer expires. This command calls the ``setcallback`` operation. Which will not be described here, since the application does not set a callback directly. Instead, the user should configure a signal handler to catch notifications, and then, configure a timer notifier to notify and to signal the previously configured signal handler. For a better performance, a separate pthread may be configured to wait on sigwaitinfo() for timer events.
In any case, this command expects a read-only pointer to a struct `timer_notify_s`. This struct contains 2 fields: ``pid`` (``pid_t``), that indicates the ID of the task/thread to receive the signal and ``event`` (``struct sigevent``), which describes the way a task will be notified.
This command may be used like so:
.. code-block:: c
printf("Configure the notification\n");
notify.pid = getpid();
notify.event.sigev_notify = SIGEV_SIGNAL;
notify.event.sigev_signo = CONFIG_EXAMPLES_TIMER_SIGNO;
notify.event.sigev_value.sival_ptr = NULL;
ret = ioctl(fd, TCIOC_NOTIFICATION, (unsigned long)((uintptr_t)&notify));
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to set the timer handler: %d\n", errno);
close(fd);
return EXIT_FAILURE;
}
.. c:macro:: TCIOC_MAXTIMEOUT
The ``TCIOC_MAXTIMEOUT`` command calls the ``maxtimeout`` operation, which is described below.
.. c:function:: int maxtimeout(uint32_t *status)
The maxtimeout operation gets the maximum timeout value that can be configured.
:param maxtimeout: A writable pointer to a variable of ``uint32_t`` type in which the value will be stored.
:return: A Linux System Error Code for failing or 0 for success.
This command may be used like so:
.. code-block:: c
/* Get the maximum timer timeout */
printf("Get the maximum timer timeout\n");
ret = ioctl(fd, TCIOC_MAXTIMEOUT, (uint32_t*)(&max_timeout));
if (ret < 0)
{
fprintf(stderr, "ERROR: Failed to reat the timer's maximum timeout: %d\n", errno);
close(fd);
return EXIT_FAILURE;
}
/* Print the maximum supported timeout */
printf("Maximum supported timeout: %" PRIu32 "\n", max_timeout);
Those snippets were taken from the Example which provides a great resource to demonstrate how to use those ``ioctl`` commands.
@@ -0,0 +1,38 @@
==========================
Touchscreen Device Drivers
==========================
NuttX supports a two-part touchscreen driver architecture.
#. An "upper half", generic driver that provides the common
touchscreen interface to application level code, and
#. A "lower half", platform-specific driver that implements the
low-level touchscreen controls to implement the touchscreen
functionality.
Files supporting the touchscreen controller (TSC) driver can be
found in the following locations:
- **Interface Definition**. The header files for NuttX
touchscreen drivers reside in the
``include/nuttx/include/input`` directory. The interface
between the touchscreen controller "upper half" and "lower
half" drivers are *not* common, but vary from
controller-to-controller. Because of this, each touchscreen
driver has its own unique header file that describes the "upper
half"/"lower half" interface in that directory. The application
level interface to each touchscreen driver, on the other hand,
*is* the same for each touchscreen driver and is described
``include/nuttx/include/input/touchscreen.h``. The touchscreen
driver uses a standard character driver framework but read
operations return specially formatted data.
- **"Upper Half" Driver**. The controller-specific, "upper half"
touchscreen drivers reside in the directory ``drivers/input``.
- **"Lower Half" Drivers**. Platform-specific touchscreen drivers
reside in either: (1) The
``arch/``\ *<architecture>*\ ``/src/``\ *<hardware>* directory
for the processor architectures that have build in touchscreen
controllers or (2) the
``boards/``\ *<arch>*\ ``/``\ *<chip>*\ ``/``\ *<board>*\ ``/src/``
directory for boards that use an external touchscreen
controller chip.
@@ -0,0 +1,204 @@
======================
Watchdog Timer Drivers
======================
NuttX supports a low-level, two-part watchdog timer driver.
#. An "upper half", generic driver that provides the common
watchdog timer interface to application level code, and
#. A "lower half", platform-specific driver that implements the
low-level timer controls to implement the watchdog timer
functionality.
Files supporting the watchdog timer driver can be found in the
following locations:
- **Interface Definition**. The header file for the NuttX
watchdog timer driver reside at
``include/nuttx/timers/watchdog.h``. This header file includes
both the application level interface to the watchdog timer
driver as well as the interface between the "upper half" and
"lower half" drivers. The watchdog timer driver uses a standard
character driver framework.
- **"Upper Half" Driver**. The generic, "upper half" watchdog
timer driver resides at ``drivers/timers/watchdog.c``.
- **"Lower Half" Drivers**. Platform-specific watchdog timer
drivers reside in
``arch/``\ *<architecture>*\ ``/src/``\ *<hardware>* directory
for the specific processor *<architecture>* and for the
specific *<chip>* watchdog timer peripheral devices.
There are two ways to enable Watchdog Timer Support along with the Watchdog Example. The first is faster and simpler. Just run the following command to use a ready config file with watchdog timer support and example included. You need to check if there's a watchdog config file for your specific chip. You may check it at the specific board's path: ``/boards/<arch>/<chip>/<board>/config``.
.. code-block:: console
$ ./tools/configure.sh <board>:watchdog
And the second way is creating your own config file. To do so, follow the next instructions.
Enabling the Watchdog Support and Example in ``menuconfing``
------------------------------------------------------------
1. Select Watchdog Timer Instances
To select these wdts browse in the ``menuconfig`` using the following path:
Go into menu :menuselection:`System Type --> <Chip> Peripheral Selection` and press :kbd:`Enter`. Then select one or more watchdog timers according to availability of your chip.
2. Enable the Watchdog Timer Support
Go into menu :menuselection:`Device Drivers --> Timer Driver Support` and press :kbd:`Enter`. Then enable:
- [x] Watchdog Timer Support
3. Include the Watchdog Timer Example
Go into menu :menuselection:`Application Configuration --> Examples` and press :kbd:`Enter`. Then select the Watchdog Timer example.
- [x] Watchdog Timer example
Below the option, it is possible to manually configure some standard parameters that will be used by the example, but they also can be passed as command line arguments later.
The parameters are the following: the standard timer device path (which defines the WDT instance), the timeout period (which is the period on which the watchdog will expire),
the ping delay (which is the interval period between feeding the dog) and the ping time (which is the total interval that the example will feed the dog, after this interval,
the dog will starve and the chip will trigger an interrupt or reset.
4. Include the Debug Watchdog Feature
In order to get the watchdog timer status, you need to enable it. For production code and for your application you may disable it.
Go into menu :menuselection:`Build Setup --> Debug Options` and press :kbd:`Enter`. Then enable:
- [x] Enable Debug Features
- [x] Watchdog Timer Debug Features
Watchdog Timer Example
----------------------
The previously selected example will basically do the following:
* Open the watchdog device
* Set the watchdog timeout
* Start the watchdog timer
* Ping (feed the dog) during the ``pingtime`` with a delay of ``pingdelay`` and print out the wdt status in case debug was enabled.
* Enter into an endless loop without pinging. It will cause the watchdog timer to reset the chip on timeout, i.e., after timer expiration.
The `example code <https://github.com/apache/incubator-nuttx-apps/blob/master/examples/watchdog/watchdog_main.c>`_ may be explored, its path is at ``/examples/watchdog/watchdog_main.c`` in the apps' repository.
In NuttX, the watchdog timer driver is a character driver and when a chip supports multiple watchdog timers, each one is accessible through its respective special file in ``/dev`` directory. Each watchdog timer is registered using a unique numeric identifier (i.e. ``/dev/watchdog0``, ``/dev/watchdog1``, ...).
Use the following command to run the example:
.. code-block:: console
nsh> wdog
This command will use the watchdog timer 0. To use the others, specify it through a parameter (where x is the timer number):
.. code-block:: console
nsh> wdog -i /dev/watchdogx
Application Level Interface
----------------------------
The first necessary thing to be done in order to use the watchdog timer driver in an application is to include the header file for the NuttX Watchdog timer driver. It contains the Application Level Interface to the timer driver. To do so, include:
.. code-block:: c
#include <nuttx/timers/watchdog.h>
At an application level, the watchdog timer functionalities may be accessed through ``ioctl`` systems calls. These ``ioctl`` commands internally call lower-half layer operations and the parameters are forwarded to these operations through the ``ioctl`` system call. The example provides a great resource to demonstrate how to use those ``ioctl`` commands. The available ``ioctl`` commands are:
.. c:macro:: WDIOC_START
This command starts the watchdog timer.
.. c:macro:: WDIOC_STOP
This command stops the watchdog timer.
.. c:macro:: WDIOC_GETSTATUS
This command gets the status of the watchdog timer. It receives a writeable pointer to struct ``watchdog_status_s`` as parameter. The lower-half driver writes the current status in this struct.
.. c:struct:: watchdog_status_s
.. code-block:: c
struct watchdog_status_s
{
uint32_t flags; /* See WDFLAGS_* definitions above */
uint32_t timeout; /* The current timeout setting (in milliseconds) */
uint32_t timeleft; /* Time left until the watchdog expiration
* (in milliseconds) */
};
.. c:macro:: WDIOC_SETTIMEOUT
This command sets the timeout value, i.e., the value that will trigger the reset or interrupt. The argument is a ``uint32_t`` value in miliseconds.
.. c:macro:: WDIOC_CAPTURE
This command registers an user callback that will be triggered on timeout. It receives as argument a pointer to struct ``watchdog_capture_s``. If the user callback is NULL, then it configures only to reset. Not all chips support interrupt on timeout. This command is optional, i.e., if it's not used, the standard behaviour is to reset on timeout.
.. c:struct:: watchdog_capture_s
.. code-block:: c
struct watchdog_capture_s
{
CODE xcpt_t newhandler; /* The new watchdog capture handler */
CODE xcpt_t oldhandler; /* The previous watchdog capture handler (if any) */
};
.. c:macro:: WDIOC_KEEPALIVE
This command resets the watchdog timer AKA '**ping**", "**kick**", "**pet**", "**feed**" the dog".
Enable Built in System Monitoring to reset the watchdog
-------------------------------------------------------
The auto-monitor provides an OS-internal mechanism to automatically start and repeatedly reset the watchdog.
To enable it, follow the next instructions:
1. Select a Watchdog Timer Instance
To select the wdt browse in the ``menuconfig`` using the following path:
Go into menu :menuselection:`System Type --> <Chip> Peripheral Selection` and press :kbd:`Enter`. Then select one watchdog timer.
2. Enable the Auto-monitor option
Go into menu :menuselection:`Device Drivers --> Timer Driver Support` and press :kbd:`Enter`. Then enable:
- [x] Watchdog Timer Support
Then press :kbd:`Enter` again to enter into the Watchdog Timer Support menu. And finally enable the Auto-monitor option:
- [x] Auto-monitor
After selecting the option you may want to configure some parameters:
* **Timeout**: It is the watchdog timer expiration time in seconds.
* **Keep a live interval**: This is the interval in which the watchdog will be fed. It is in seconds. It can't be bigger than the timeout. If this interval is equal to timeout interval, than this interval will automatically change to half timeout.
* **Keep alive by**: This is a choice to determine who is going to feed the dog. There are 4 possible choices that are described as follows.
``Capture callback``: This choice registers a watchdog timer callback to reset the watchdog every time it expires, i.e., on timeout.
``Timer callback``: This choice also uses a timer callback to reset the watchdog, but it will reset the watchdog every "keep a live interval".
``Worker callback``: This choice uses a Work Queue to reset the watchdog every "keep a live interval". This choice depends on having the Low or High Priority Work Queue enabled.
If only the High Priority Work Queue is enabled, this one will be used, otherwise Low Priority Work Queue is used.
So, before enabling it, go into menu :menuselection:`RTOS Features --> Work queue support` and press :kbd:`Enter`.
- [x] Low priority (kernel) worker thread
``Idle callback``: This choice sets an Idle callback to feed the dog. It depends on the PM module, because this callback is triggered by the PM state change. To enable it do the following:
Go into menu :menuselection:`Device Drivers` and enable:
- [x] Power Management Support
After selecting one of these choices, the chip will keep itself alive by one of these options.
@@ -0,0 +1,32 @@
==============
Device Drivers
==============
NuttX supports a variety of device drivers, which can be broadly
divided in three classes:
.. toctree::
:maxdepth: 1
character/index.rst
block/index.rst
special/index.rst
.. note::
Device driver support depends on the *in-memory*, *pseudo*
file system that is enabled by default.
Lower-half and upper-half
=========================
Drivers in NuttX generally work in two distinct layers:
* An *upper half* which registers itself to NuttX using
a call such as :c:func:`register_driver` or
:c:func:`register_blockdriver` and implements the corresponding
high-level interface (`read`, `write`, `close`, etc.).
implements the interface. This *upper half* calls into
the *lower half* via callbacks.
* A "lower half" which is typically hardware-specific. This is
usually implemented at the architecture or board level.
@@ -0,0 +1,17 @@
=======================
Ethernet Device Drivers
=======================
- ``include/nuttx/net/netdev.h``. All structures and APIs
needed to work with Ethernet drivers are provided in this
header file. The structure ``struct net_driver_s`` defines the
interface and is passed to the network via
``netdev_register()``.
- ``int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype);``.
Each Ethernet driver registers itself by calling
``netdev_register()``.
- **Examples**: ``drivers/net/dm90x0.c``,
``arch/drivers/arm/src/c5471/c5471_ethernet.c``,
``arch/z80/src/ez80/ez80_emac.c``, etc.
@@ -0,0 +1,34 @@
====================
Frame Buffer Drivers
====================
- ``include/nuttx/video/fb.h``. All structures and APIs
needed to work with frame buffer drivers are provided in this
header file.
- ``struct fb_vtable_s``. Each frame buffer device driver
must implement an instance of ``struct fb_vtable_s``. That
structure defines a call table with the following methods:
Get information about the video controller configuration and
the configuration of each color plane.
The following are provided only if the video hardware supports
RGB color mapping:
The following are provided only if the video hardware supports
a hardware cursor:
- **Binding Frame Buffer Drivers**. Frame buffer drivers are not
normally directly accessed by user code, but are usually bound
to another, higher level device driver. In general, the binding
sequence is:
#. Get an instance of ``struct fb_vtable_s`` from the
hardware-specific frame buffer device driver, and
#. Provide that instance to the initialization method of the
higher level device driver.
- **Examples**: ``arch/sim/src/up_framebuffer.c``. See also the
usage of the frame buffer driver in the ``graphics/``
directory.
@@ -0,0 +1,22 @@
==================
I2C Device Drivers
==================
- ``include/nuttx/i2c/i2c.h``. All structures and APIs needed
to work with I2C drivers are provided in this header file.
- ``struct i2c_ops_s``. Each I2C device driver must implement
an instance of ``struct i2c_ops_s``. That structure defines a
call table with the following methods:
- **Binding I2C Drivers**. I2C drivers are not normally directly
accessed by user code, but are usually bound to another, higher
level device driver. In general, the binding sequence is:
#. Get an instance of ``struct i2c_master_s`` from the
hardware-specific I2C device driver, and
#. Provide that instance to the initialization method of the
higher level device driver.
- **Examples**: ``arch/z80/src/ez80/ez80_i2c.c``,
``arch/z80/src/z8/z8_i2c.c``, etc.
@@ -0,0 +1,36 @@
==========================
Specialized Device Drivers
==========================
All device drivers that are accessible to application logic are
either: (1) Character device drivers that can be accessed via the
standard driver operations (``open()``, ``close()``, ``read()``,
``write()``, etc.), or (2) block drivers that can be accessing
only as part of mounting a file system or other special use cases
as described in the preceding paragraph.
In addition to this, there are also specialized "drivers" that can
be used only within the OS logic itself and are not accessible to
application logic. These specialized drivers are discussed in the
following section.
.. note::
While special drivers are *internal*, in some cases there are also
character/block drivers that sit on top of these special drivers
and thus expose them to applications.
.. toctree::
:caption: Supported Drivers
syslog.rst
spi.rst
i2c.rst
ethernet.rst
socketcan.rst
framebuffer.rst
lcd.rst
mtd.rst
sdio.rst
usbhost.rst
usbdev.rst
@@ -0,0 +1,47 @@
===========
LCD Drivers
===========
- ``include/nuttx/lcd/lcd.h``. Structures and APIs needed to
work with LCD drivers are provided in this header file. This
header file also depends on some of the same definitions used
for the frame buffer driver as provided in
``include/nuttx/video/fb.h``.
- ``struct lcd_dev_s``. Each LCD device driver must implement
an instance of ``struct lcd_dev_s``. That structure defines a
call table with the following methods:
Get information about the LCD video controller configuration
and the configuration of each LCD color plane.
The following are provided only if the video hardware supports
RGB color mapping:
The following are provided only if the video hardware supports
a hardware cursor:
Get the LCD panel power status (0: full off -
``CONFIG_LCD_MAXPOWER``: full on). On backlit LCDs, this
setting may correspond to the backlight setting.
Enable/disable LCD panel power (0: full off -
``CONFIG_LCD_MAXPOWER``: full on). On backlit LCDs, this
setting may correspond to the backlight setting.
Get the current contrast setting (0-CONFIG_LCD_MAXCONTRAST) \*/
Set LCD panel contrast (0-CONFIG_LCD_MAXCONTRAST)
- **Binding LCD Drivers**. LCD drivers are not normally directly
accessed by user code, but are usually bound to another, higher
level device driver. In general, the binding sequence is:
#. Get an instance of ``struct lcd_dev_s`` from the
hardware-specific LCD device driver, and
#. Provide that instance to the initialization method of the
higher level device driver.
- **Examples**: ``drivers/lcd/p14201.c``,
``boards/arm/sam34/sam3u-ek/src/up_lcd.c.`` See also the usage
of the LCD driver in the ``graphics/`` directory.
@@ -0,0 +1,47 @@
================================
Memory Technology Device Drivers
================================
- ``include/nuttx/mtd/mtd.h``. All structures and APIs needed
to work with MTD drivers are provided in this header file.
- ``struct mtd_dev_s``. Each MTD device driver must implement
an instance of ``struct mtd_dev_s``. That structure defines a
call table with the following methods:
Erase the specified erase blocks (units are erase blocks):
Read/write from the specified read/write blocks:
Some devices may support byte oriented reads (optional). Most
MTD devices are inherently block oriented so byte-oriented
accesses are not supported. It is recommended that low-level
drivers not support read() if it requires buffering.
Some devices may also support byte oriented writes (optional).
Most MTD devices are inherently block oriented so byte-oriented
accesses are not supported. It is recommended that low-level
drivers not support read() if it requires buffering. This
interface is only available if ``CONFIG_MTD_BYTE_WRITE`` is
defined.
Support other, less frequently used commands:
- ``MTDIOC_GEOMETRY``: Get MTD geometry
- ``MTDIOC_XIPBASE:``: Convert block to physical address for
eXecute-In-Place
- ``MTDIOC_BULKERASE``: Erase the entire device
is provided via a single ``ioctl`` method (see
``include/nuttx/fs/ioctl.h``):
- **Binding MTD Drivers**. MTD drivers are not normally directly
accessed by user code, but are usually bound to another, higher
level device driver. In general, the binding sequence is:
#. Get an instance of ``struct mtd_dev_s`` from the
hardware-specific MTD device driver, and
#. Provide that instance to the initialization method of the
higher level device driver.
- **Examples**: ``drivers/mtd/m25px.c`` and ``drivers/mtd/ftl.c``
@@ -0,0 +1,33 @@
===================
SDIO Device Drivers
===================
- ``include/nuttx/sdio.h``. All structures and APIs needed to
work with SDIO drivers are provided in this header file.
- ``struct sdio_dev_s``. Each SDIO device driver must
implement an instance of ``struct sdio_dev_s``. That structure
defines a call table with the following methods:
Mutual exclusion:
Initialization/setup:
Command/Status/Data Transfer:
Event/Callback support:
DMA support:
- **Binding SDIO Drivers**. SDIO drivers are not normally
directly accessed by user code, but are usually bound to
another, higher level device driver. In general, the binding
sequence is:
#. Get an instance of ``struct sdio_dev_s`` from the
hardware-specific SDIO device driver, and
#. Provide that instance to the initialization method of the
higher level device driver.
- **Examples**: ``arch/arm/src/stm32/stm32_sdio.c`` and
``drivers/mmcsd/mmcsd_sdio.c``
@@ -0,0 +1,66 @@
========================
SocketCAN Device Drivers
========================
- ``include/nuttx/net/netdev.h``. All structures and APIs
needed to work with drivers are provided in this header file.
The structure struct net_driver_s defines the interface and is
passed to the network via netdev_register().
- ``include/nuttx/can.h``. CAN & CAN FD frame data
structures.
- ``int netdev_register(FAR struct net_driver_s *dev, enum net_lltype_e lltype)'``.
Each driver registers itself by calling netdev_register().
- ``Include/nuttx/net/can.h``. contains lookup tables for CAN
dlc to CAN FD len sizes named
.. code-block:: c
extern const uint8_t can_dlc_to_len[16];
extern const uint8_t len_to_can_dlc[65];
- **Initialization sequence is as follows**.
#. up_netinitialize(void) is called on startup of NuttX in this
function you call your own init function to initialize your
CAN driver
#. In your own init function you create the net_driver_s
structure set required init values and register the required
callbacks for SocketCAN
#. Then you ensure that the CAN interface is in down mode
(usually done by calling the d_ifdown function)
#. Register the net_driver_s using netdev_register
- **Receive sequence is as follows**.
#. Device generates interrupt
#. Process this interrupt in your interrupt handler
#. When a new CAN frame has been received you process this
frame
#. When the CAN frame is a normal CAN frame you allocate the
can_frame struct, when it's a CAN FD frame you allocate a
canfd_frame struct (note you can of course preallocate and
just use the pointer).
#. Copy the frame from the driver to the struct you've
allocated in the previous step.
#. Point the net_driver_s d_buf pointer to the allocated
can_frame
#. Call the ``can_input(FAR struct net_driver_s *dev)``
function ``include/nuttx/net/can.h``
- **Transmit sequence is as follows**.
#. Socket layer executes d_txavail callback
#. An example of the txavail function can be found in
``arch/arm/src/s32k1xx/s32k1xx_flexcan.c``
#. An example of the txpoll function can be found in
``arch/arm/src/s32k1xx/s32k1xx_flexcan.c``
#. In your ``transmit(struct driver_s *priv)`` function you
check the length of ``net_driver_s.d_len`` whether it
matches the size of a ``struct can_frame`` or
``struct canfd_frame`` then you cast the content of the
``net_driver_s.d_buf`` pointer to the correct CAN frame
struct
@@ -0,0 +1,25 @@
==================
SPI Device Drivers
==================
- ``include/nuttx/spi/spi.h``. All structures and APIs needed
to work with SPI drivers are provided in this header file.
- ``struct spi_ops_s``. Each SPI device driver must implement
an instance of ``struct spi_ops_s``. That structure defines a
call table with the following methods:
- **Binding SPI Drivers**. SPI drivers are not normally directly
accessed by user code, but are usually bound to another, higher
level device driver. See for example,
``int mmcsd_spislotinitialize(int minor, int slotno, FAR struct spi_dev_s *spi)``
in ``drivers/mmcsd/mmcsd_spi.c``. In general, the binding
sequence is:
#. Get an instance of ``struct spi_dev_s`` from the
hardware-specific SPI device driver, and
#. Provide that instance to the initialization method of the
higher level device driver.
- **Examples**: ``drivers/loop.c``,
``drivers/mmcsd/mmcsd_spi.c``, ``drivers/ramdisk.c``, etc.
@@ -0,0 +1,511 @@
======
SYSLOG
======
SYSLOG Interfaces
=================
Standard SYSLOG Interfaces
--------------------------
The NuttX SYSLOG is an architecture for getting debug and status
information from the system. The syslogging interfaces are defined
in the header file ``include/syslog.h``. The primary interface to
SYSLOG sub-system is the function ``syslog()`` and, to a lesser
extent, its companion ``vsyslog()``:
.. c::function:: int syslog(int priority, FAR const IPTR char *format, ...);
Generates a log message. The
priority argument is formed by ORing the facility and the level
values (see ``include/syslog.h``). The remaining arguments are a
format, as in ``printf()`` and any arguments to the format.
The NuttX implementation does not support any special formatting
characters beyond those supported by ``printf()``.
.. c::function:: void vsyslog(int priority, FAR const IPTR char *src, va_list ap);
Performs the same task as :c:func:`syslog`
with the difference that it takes a set of arguments which have
been obtained using the ``stdarg`` variable argument list macros.
.. c::function:: int setlogmask(int mask);
The additional setlogmask() interface can use use to filter SYSLOG output.
This function sets the logmask and returns the previous mask.
If the mask argument is zero, the current logmask is not modified.
The SYSLOG priorities are: ``LOG_EMERG``, ``LOG_ALERT``, ``LOG_CRIT``,
``LOG_ERR``, ``LOG_WARNING``, ``LOG_NOTICE``, ``LOG_INFO``, and ``LOG_DEBUG``.
The bit corresponding to a priority ``p`` is ``LOG_MASK(p)``; ``LOG_UPTO(p)``
provides the mask of all priorities in the above list up to and including ``p``.
Per *OpenGroup.org* "If the ``maskpri`` argument is 0,
the current log mask is not modified." In this implementation,
the value zero is permitted in order to disable all SYSLOG levels.
.. note::
REVISIT: Per POSIX the SYSLOG mask should be a per-process value but
in NuttX, the scope of the mask is dependent on the nature of the build:
- *Flat Build*: There is one, global SYSLOG mask that controls
all output.
- *Protected Build*: There are two SYSLOG masks. One within the
kernel that controls only kernel output. And one in user-space
that controls only user SYSLOG output.
- *Kernel Build*: The kernel build is compliant with the POSIX
requirement: There will be one mask for for each user process,
controlling the SYSLOG output only form that process. There
will be a separate mask accessible only in the kernel code to
control kernel SYSLOG output.
The above are all standard interfaces as defined at
`OpenGroup.org <http://pubs.opengroup.org/onlinepubs/009695399/functions/closelog.html>`__.
Those interfaces are available for use by application software.
The remaining interfaces discussed in this section are non-standard, OS-internal interfaces.
Debug Interfaces
----------------
In NuttX, syslog output is really synonymous to debug output and,
therefore, the debugging interface macros defined in the header
file ``include/debug.h`` are also syslogging interfaces. Those
macros are simply wrappers around ``syslog()``. The debugging
interfaces differ from the syslog interfaces in that:
- They do not take a priority parameter; the priority is inherent
in the debug macro name.
- They decorate the output stream with information such as the
file name
- They can each be disabled via configuration options.
Each debug macro has a base name that represents the priority and
a prefix that represents the sub-system. Each macro is
individually initialized by both priority and sub-system. For
example, ``uerr()`` is the macro used for error level messages
from the USB subsystem and is enabled with
``CONFIG_DEBUG_USB_ERROR``.
The base debug macro names, their priority, and configuration
variable are summarized below:
- ``info()``. The ``info()`` macro is the lowest priority
(``LOG_INFO``) and is intended to provide general information
about the flow of program execution so that you can get an
overview of the behavior of the program. ``info()`` is often
very chatty and voluminous and usually more information than
you may want to see. The ``info()`` macro is controlled via
CONFIG_DEBUG_subsystem_INFO
- ``warn()``. The ``warn()`` macro has medium priority
(``LOG_WARN``) and is controlled by
``CONFIG_DEBUG_subsystem_WARN``. The ``warn()`` is intended to
note exceptional or unexpected conditions that might be
potential errors or, perhaps, minor errors that easily
recovered.
- ``err()``. This is a high priority debug macro (``LOG_ERROR``)
and controlled by ``CONFIG_DEBUG_subsystem_ERROR``. The
``err()`` is reserved to indicate important error conditions.
- ``alert()``. The highest priority debug macro (``LOG_EMERG``)
and is controlled by ``CONFIG_DEBUG_ALERT``. The ``alert()``
macro is reserved for use solely by assertion and crash
handling logic. It also differs from the other macros in that
it cannot be enabled or disabled per subsystem.
SYSLOG Channels
===============
SYSLOG Channel Interfaces
-------------------------
In the NuttX SYSLOG implementation, the underlying device logic
the supports the SYSLOG output is referred to as a SYSLOG
*channel*. Each SYSLOG channel is represented by an interface
defined in ``include/nuttx/syslog/syslog.h``:
.. code-block:: c
/* This structure provides the interface to a SYSLOG device */
typedef CODE int (*syslog_putc_t)(int ch);
typedef CODE int (*syslog_flush_t)(void);
struct syslog_channel_s
{
/* I/O redirection methods */
syslog_putc_t sc_putc; /* Normal buffered output */
syslog_putc_t sc_force; /* Low-level output for interrupt handlers */
syslog_flush_t sc_flush; /* Flush buffered output (on crash) */
/* Implementation specific logic may follow */
};
The channel interface is instantiated by calling
:c:func:`syslog_channel()`.
.. c:function:: int syslog_channel(FAR const struct syslog_channel_s *channel);
Configure the SYSLOG function to use the provided
channel to generate SYSLOG output.
``syslog_channel()`` is a non-standard, internal OS interface and
is not available to applications. It may be called numerous times
as necessary to change channel interfaces. By default, all system
log output goes to console (``/dev/console``).
:param channel: Describes the interface to the channel to be used.
:return:
Zero (OK)is returned on success. A negated errno value is
returned on any failure.
SYSLOG Channel Initialization
-----------------------------
The initial, default SYSLOG channel is established with statically
initialized global variables so that some level of SYSLOG output
may be available immediately upon reset. This initialized data is
in the file ``drivers/syslog/syslog_channel.c``. The initial
SYSLOG capability is determined by the selected SYSLOG channel:
- *In-Memory Buffer (RAMLOG)*. Full SYSLOG capability as
available at reset.
- *Serial Console*. If the serial implementation provides the
low-level character output function ``up_putc()``, then that
low level serial output is available as soon as the serial
device has been configured.
- For all other SYSLOG channels, all SYSLOG output goes to the
bit- bucket until the SYSLOG channel device has been
initialized.
The syslog channel device is initialized when the bring-up logic
calls :c:func:`syslog_initialize()`.
.. c:function:: int syslog_initialize(void)
.. code-block:: c
#include <nuttx/syslog/syslog.h>
#ifndef CONFIG_ARCH_SYSLOG
int syslog_initialize(void);
#else
# define syslog_initialize()
#endif
One power up, the SYSLOG facility is non-existent
or limited to very low-level output. This function is called later
in the initialization sequence after full driver support has been
initialized. It installs the configured SYSLOG drivers and enables
full SYSLOG capability.
This function performs these basic operations:
- Initialize the SYSLOG device
- Call :c:func:`syslog_channel` to begin using that device.
- If ``CONFIG_ARCH_SYSLOG`` is selected, then the
architecture-specific logic will provide its own SYSLOG device
initialize which must include as a minimum a call to
:c:func:`syslog_channel` to use the device.
:return:
Zero (``OK``) is returned on success; a
negated ``errno`` value is returned on any failure.
Different types of SYSLOG devices have different OS initialization
requirements. Some are available immediately at reset, some are
available after some basic OS initialization, and some only after
OS is fully initialized.
There are other types of SYSLOG channel devices that may require
even further initialization. For example, the file SYSLOG channel
(described below) cannot be initialized until the necessary file
systems have been mounted.
Interrupt Level SYSLOG Output
-----------------------------
As a general statement, SYSLOG output only supports *normal*
output from NuttX tasks. However, for debugging purposes, it is
also useful to get SYSLOG output from interrupt level logic. In an
embedded system, that is often where the most critical operations
are performed.
There are three conditions under which SYSLOG output generated
from interrupt level processing can a included the SYSLOG output
stream:
#. **Low-Level Serial Output**. If you are using a SYSLOG console
channel (``CONFIG_SYSLOG_CONSOLE``) and if the underlying
architecture supports the low-level ``up_putc()``
interface(\ ``CONFIG_ARCH_LOWPUTC``), then the SYSLOG logic
will direct the output to ``up_putc()`` which is capable of
generating the serial output within the context of an interrupt
handler.
There are a few issues in doing this however:
- ``up_putc()`` is able to generate debug output in any
context because it disables serial interrupts and polls the
hardware directly. These polls may take many milliseconds
and during that time, all interrupts are disable within the
interrupt handler. This, of course, interferes with the
real-time behavior of the RTOS.
- The output generated by ``up_putc()`` is immediate and in
real-time. The normal SYSLOG output, on the other hand, is
buffered in the serial driver and may be delayed with
respect to the immediate output by many lines. Therefore,
the interrupt level SYSLOG output provided through
``up_putc()`` is grossly out of synchronization with other
debug output
#. **In-Memory Buffering**. If the RAMLOG SYSLOG channel is
supported, then all SYSLOG output is buffered in memory.
Interrupt level SYSLOG output is no different than normal
SYSLOG output in this case.
#. **Serialization Buffer**. A final option is the use of an
*interrupt buffer* to buffer the interrupt level SYSLOG output.
In this case:
- SYSLOG output generated from interrupt level process in not
sent to the SYSLOG channel immediately. Rather, it is
buffered in the interrupt serialization buffer.
- Later, when the next normal syslog output is generated, it
will first empty the content of the interrupt buffer to the
SYSLOG device in the proper context. It will then be
followed by the normal syslog output. In this case, the
interrupt level SYSLOG output will interrupt the normal
output stream and the interrupt level SYSLOG output will be
inserted into the correct position in the SYSLOG output when
the next normal SYSLOG output is generated.
The SYSLOG interrupt buffer is enabled with
``CONFIG_SYSLOG_INTBUFFER``. When the interrupt buffer is
enabled, you must also provide the size of the interrupt buffer
with ``CONFIG_SYSLOG_INTBUFSIZE``.
SYSLOG Channel Options
======================
SYSLOG Console Device
---------------------
The typical SYSLOG device is the system console. If you are using
a serial console, for example, then the SYSLOG output will appear
on that serial port.
This SYSLOG channel is automatically selected by
``syslog_initialize()`` in the LATE initialization phase based on
configuration options. The configuration options that affect this
channel selection include:
- ``CONFIG_DEV_CONSOLE``. This setting indicates that the system
supports a console device, i.e., that the character device
``/dev/console`` exists.
- ``CONFIG_SERIAL_CONSOLE``. This configuration option is
automatically selected when a UART or USART is configured as
the system console. There is no user selection.
- ``CONFIG_SYSLOG_CONSOLE``. This configuration option is
manually selected from the SYSLOG menu. This is the option that
actually enables the SYSLOG console device. It depends on
``CONFIG_DEV_CONSOLE``.
- ``CONFIG_ARCH_LOWPUTC``. This is an indication from the
architecture configuration that the platform supports the
``up_putc()`` interface. ``up_putc()`` is a very low level UART
interface that can even be used from interrupt handling.
Interrupt level SYSLOG output will be lost unless: (1) the
interrupt buffer is enabled to support serialization, or (2) a
serial console is used and ``up_putc()`` is supported.
.. note::
The console channel uses the fixed character device at
``/dev/console``. The console channel is not synonymous with
``stdout`` (or file descriptor 1). ``stdout`` is the current
output from a task when, say, ``printf()`` if used. Initially,
``stdout`` does, indeed, use the ``/dev/console`` device. However,
``stdout`` may subsequently be redirected to some other device or
file. This is always the case, for example, when a transient
device is used for a console -- such as a USB console or a Telnet
console. The SYSLOG channel is not redirected as ``stdout`` is;
the SYSLOG channel will stayed fixed (unless it is explicitly
changed via ``syslog_channel()``).
References: ``drivers/syslog/syslog_consolechannel.c`` and
``drivers/syslog/syslog_device.c``
SYSLOG Character Device
-----------------------
The system console device, ``/dev/console``, is a character driver
with some special properties. However, any character driver may be
used as the SYSLOG output channel. For example, suppose you have a
serial console on ``/dev/ttyS0`` and you want SYSLOG output on
``/dev/ttyS1``. Or suppose you support only a Telnet console but
want to capture debug output ``/dev/ttyS0``.
This SYSLOG device channel is selected with ``CONFIG_SYSLOG_CHAR``
and has no other dependencies. Differences from the SYSLOG console
channel include:
- ``CONFIG_SYSLOG_DEVPATH``. This configuration option string
must be set provide the full path to the character device to be
used.
- The forced SYSLOG output always goes to the bit-bucket. This
means that interrupt level SYSLOG output will be lost unless
the interrupt buffer is enabled to support serialization.
- ``CONFIG_SYSLOG_CHAR_CRLF``. If ``CONFIG_SYSLOG_CHAR_CRLF`` is
selected, then linefeeds in the SYSLOG output will be expanded
to Carriage Return plus Linefeed. Since the character device is
not a console device, the addition of carriage returns to line
feeds would not be performed otherwise. You would probably want
this expansion if you use a serial terminal program with the
character device output.
References: ``drivers/syslog/syslog_devchannel.c`` and
``drivers/syslog/syslog_device.c``
SYSLOG File Device
------------------
Files can also be used as the sink for SYSLOG output. There is,
however, a very fundamental difference in using a file as opposed
the system console, a RAM buffer, or character device: You must
first mount the file system that supports the SYSLOG file. That
difference means that the file SYSLOG channel cannot be supported
during the boot-up phase but can be instantiated later when board
level logic configures the application environment, including
mounting of the file systems.
The interface ``syslog_file_channel()`` is used to configure the
SYSLOG file channel:
.. c:function:: int syslog_file_channel(FAR const char *devpath);
Configure to use a file in a mounted file system
at ``devpath`` as the SYSLOG channel.
This tiny function is simply a wrapper around
``syslog_dev_initialize()`` and ``syslog_channel()``. It calls
``syslog_dev_initialize()`` to configure the character file at
``devpath`` then calls ``syslog_channel()`` to use that device as
the SYSLOG output channel.
File SYSLOG channels differ from other SYSLOG channels in that
they cannot be established until after fully booting and mounting
the target file system. This function would need to be called from
board-specific bring-up logic AFTER mounting the file system
containing ``devpath``.
SYSLOG data generated prior to calling ``syslog_file_channel()``
will, of course, not be included in the file.
NOTE interrupt level SYSLOG output will be lost in this case
unless the interrupt buffer is used.
:param devpath:
The full path to the file to be used for SYSLOG
output. This may be an existing file or not. If the file
exists, ``syslog_file_channel()`` will append new SYSLOG data
to the end of the file. If it does not, then
``syslog_file_channel()`` will create the file.
:return:
Zero (``OK``) is returned on success; a
negated ``errno`` value is returned on any failure.
References: ``drivers/syslog/syslog_filechannel.c``,
``drivers/syslog/syslog_device.c``, and
``include/nuttx/syslog/syslog.h``.
SYSLOG RAMLOG Device
--------------------
The RAMLOG is a standalone feature that can be used to buffer any
character data in memory. There are, however, special
configurations that can be used to configure the RAMLOG as a
SYSLOG channel. The RAMLOG functionality is described in a more
general way in the following paragraphs.
RAM Logging Device
==================
The RAM logging driver is a driver that was intended to support
debugging output (SYSLOG) when the normal serial output is not
available. For example, if you are using a Telnet or USB serial
console, the debug output will get lost -- or worse. For example,
what if you want to debug the network over Telnet?
The RAM logging driver can also accept debug output data from
interrupt handler with no special serialization buffering. As an
added benefit, the RAM logging driver is much less invasive. Since
no actual I/O is performed with the debug output is generated, the
RAM logger tends to be much faster and will interfere much less
when used with time critical drivers.
The RAM logging driver is similar to a pipe in that it saves the
debugging output in a circular buffer in RAM. It differs from a
pipe in numerous details as needed to support logging.
This driver is built when ``CONFIG_RAMLOG`` is defined in the
NuttX configuration.
``dmesg`` command
-----------------
When the RAMLOG (with SYSLOG) is enabled, a new NuttShell (NSH)
command will appear: ``dmesg``. The ``dmesg`` command will dump
the contents of the circular buffer to the console (and also clear
the circular buffer).
RAMLOG Configuration options
----------------------------
- ``CONFIG_RAMLOG``: Enables the RAM logging feature
- ``CONFIG_RAMLOG_SYSLOG``: Use the RAM logging device for the
SYSLOG interface. If this feature is enabled, then all debug
output will be re-directed to the circular buffer in RAM. This
RAM log can be viewed from NSH using the ``dmesg`` command.
NOTE: Unlike the limited, generic character driver SYSLOG
device, the RAMLOG *can* be used to capture debug output from
interrupt level handlers.
- ``CONFIG_RAMLOG_NPOLLWAITERS``: The number of threads than can
be waiting for this driver on ``poll()``. Default: 4
- ``CONFIG_RAMLOG_BUFSIZE``: The size of the circular buffer to
use. Default: 1024 bytes.
Other miscellaneous settings
- ``CONFIG_RAMLOG_CRLF``: Pre-pend a carriage return before every
linefeed that goes into the RAM log.
- ``CONFIG_RAMLOG_NONBLOCKING``: Reading from the RAMLOG will
never block if the RAMLOG is empty. If the RAMLOG is empty,
then zero is returned (usually interpreted as end-of-file). If
you do not define this, the NSH ``dmesg`` command will lock up
when called! So you probably do want this!
- ``CONFIG_RAMLOG_NPOLLWAITERS``: The maximum number of threads
that may be waiting on the poll method.
@@ -0,0 +1,50 @@
=======================
USB Device-Side Drivers
=======================
- ``include/nuttx/usb/usbdev.h``. All structures and APIs
needed to work with USB device-side drivers are provided in
this header file.
- ``include/nuttx/usb/usbdev_trace.h``. Declarations needed
to work with the NuttX USB device driver trace capability. That
USB trace capability is detailed in :ref:`separate
document <usbtrace>`.
- ``struct usbdev_s``. Each USB device controller driver must
implement an instance of ``struct usbdev_s``. This structure is
defined in ``include/nuttx/usb/usbdev.h``.
**Examples**: ``arch/arm/src/dm320/dm320_usbdev.c``,
``arch/arm/src/lpc17xx_40xx/lpc17_40_usbdev.c``,
``arch/arm/src/lpc214x/lpc214x_usbdev.c``,
``arch/arm/src/lpc313x/lpc313x_usbdev.c``, and
``arch/arm/src/stm32/stm32_usbdev.c``.
- ``struct usbdevclass_driver_s``. Each USB device class
driver must implement an instance of
``struct usbdevclass_driver_s``. This structure is also defined
in ``include/nuttx/usb/usbdev.h``.
**Examples**: ``drivers/usbdev/pl2303.c`` and
``drivers/usbdev/usbmsc.c``
- **Binding USB Device-Side Drivers**. USB device-side controller
drivers are not normally directly accessed by user code, but
are usually bound to another, higher level USB device class
driver. The class driver is then configured to export the USB
device functionality. In general, the binding sequence is:
#. Each USB device class driver includes an initialization
entry point that is called from the application at
initialization time.
**Examples**: The function ``usbdev_serialinitialize()`` in
the file ``drivers/usbdev/pl2303.c`` and the function
in the file ``drivers/usbdev/usbmsc.c``
#. These initialization functions called the driver API,
``usbdev_register()``. This driver function will *bind* the
USB class driver to the USB device controller driver,
completing the initialization.
@@ -0,0 +1,108 @@
=====================
USB Host-Side Drivers
=====================
- ``include/nuttx/usb/usbhost.h``. All structures and APIs
needed to work with USB host-side drivers are provided in this
header file.
- ``struct usbhost_driver_s`` and
``struct usbhost_connection_s``. Each USB host controller
driver must implement an instance of
``struct usbhost_driver_s`` and
``struct usbhost_connection_s``: ``struct usbhost_driver_s``
provides the interface between the USB host driver and the USB
class driver; ``struct usbhost_connection_s`` provides the
interface between the USB host driver and platform-specific
connection management and device enumeration logic. These
structures are defined in ``include/nuttx/usb/usbhost.h``.
**Examples**: ``arch/arm/src/lpc17xx_40xx/lpc17_40_usbhost.c``,
``arch/arm/src/stm32/stm32_otgfshost.c``,
``arch/arm/src/sama5/sam_ohci.c``, and
``arch/arm/src/sama5/sam_ehci.c``.
- ``struct usbhost_class_s``. Each USB host class driver must
implement an instance of ``struct usbhost_class_s``. This
structure is also defined in ``include/nuttx/usb/usbhost.h``.
**Examples**: ``drivers/usbhost/usbhost_storage.c``
- **USB Host Class Driver Registry**. The NuttX USB host
infrastructure includes a *registry*. During its
initialization, each USB host class driver must call the
interface, ``usbhost_registerclass()`` in order add its
interface to the registry. Later, when a USB device is
connected, the USB host controller will look up the USB host
class driver that is needed to support the connected device in
this registry.
**Examples**: ``drivers/usbhost/usbhost_registry.c``,
``drivers/usbhost/usbhost_registerclass.c``, and
``drivers/usbhost/usbhost_findclass.c``,
- **Detection and Enumeration of Connected Devices**. Each USB
host device controller supports two methods that are used to
detect and enumeration newly connected devices (and also detect
disconnected devices):
- ``int (*wait)(FAR struct usbhost_connection_s *drvr, FAR const bool *connected);``
Wait for a device to be connected or disconnected.
- ``int (*enumerate)(FAR struct usbhost_connection_s *drvr, int rhpndx);``
Enumerate the device connected to a root hub port. As part
of this enumeration process, the driver will (1) get the
device's configuration descriptor, (2) extract the class ID
info from the configuration descriptor, (3) call
``usbhost_findclass(``) to find the class that supports this
device, (4) call the ``create()`` method on the
``struct usbhost_registry_s interface`` to get a class
instance, and finally (5) call the ``connect()`` method of
the ``struct usbhost_class_s`` interface. After that, the
class is in charge of the sequence of operations.
- **Binding USB Host-Side Drivers**. USB host-side controller
drivers are not normally directly accessed by user code, but
are usually bound to another, higher level USB host class
driver. The class driver exports the standard NuttX device
interface so that the connected USB device can be accessed just
as with other, similar, on-board devices. For example, the USB
host mass storage class driver
(``drivers/usbhost/usbhost_storage.c``) will register a
standard, NuttX block driver interface (like ``/dev/sda``) that
can be used to mount a file system just as with any other other
block driver instance. In general, the binding sequence is:
#. Each USB host class driver includes an initialization entry
point that is called from the application at initialization
time. This driver calls ``usbhost_registerclass()`` during
this initialization in order to makes itself available in
the event the device that it supports is connected.
**Examples**: The function ``usbhost_msc_initialize()`` in
the file ``drivers/usbhost/usbhost_storage.c``
#. Each application must include a *waiter* thread thread that
(1) calls the USB host controller driver's ``wait()`` to
detect the connection of a device, and then (2) call the USB
host controller driver's ``enumerate`` method to bind the
registered USB host class driver to the USB host controller
driver.
**Examples**: The function ``nsh_waiter()`` in the file
``boards/arm/lpc17xx_40xx/olimex-lpc1766stk/src/lpc17_40_appinit.c``.
#. As part of its operation during the binding operation, the
USB host class driver will register an instances of a
standard NuttX driver under the ``/dev`` directory. To
repeat the above example, the USB host mass storage class
driver (``drivers/usbhost/usbhost_storage.c``) will register
a standard, NuttX block driver interface (like ``/dev/sda``)
that can be used to mount a file system just as with any
other other block driver instance.
**Examples**: See the call to ``register_blockdriver()`` in
the function ``usbhost_initvolume()`` in the file
``drivers/usbhost/usbhost_storage.c``.
@@ -0,0 +1,43 @@
=================
NuttX File System
=================
**Overview**. NuttX includes an optional, scalable file system.
This file-system may be omitted altogether; NuttX does not depend
on the presence of any file system.
**Pseudo Root File System**. A simple *in-memory*, *pseudo* file
system can be enabled by default. This is an *in-memory* file
system because it does not require any storage medium or block
driver support. Rather, file system contents are generated
on-the-fly as referenced via standard file system operations
(open, close, read, write, etc.). In this sense, the file system
is *pseudo* file system (in the same sense that the Linux
``/proc`` file system is also referred to as a pseudo file
system).
Any user supplied data or logic can be accessed via the
pseudo-file system. Built in support is provided for character and
block `drivers <#DeviceDrivers>`__ in the ``/dev`` pseudo file
system directory.
**Mounted File Systems** The simple in-memory file system can be
extended my mounting block devices that provide access to true
file systems backed up via some mass storage device. NuttX
supports the standard ``mount()`` command that allows a block
driver to be bound to a mountpoint within the pseudo file system
and to a file system. At present, NuttX supports the standard VFAT
and ROMFS file systems, a special, wear-leveling NuttX FLASH File
System (NXFFS), as well as a Network File System client (NFS
version 3, UDP).
**Comparison to Linux** From a programming perspective, the NuttX
file system appears very similar to a Linux file system. However,
there is a fundamental difference: The NuttX root file system is a
pseudo file system and true file systems may be mounted in the
pseudo file system. In the typical Linux installation by
comparison, the Linux root file system is a true file system and
pseudo file systems may be mounted in the true, root file system.
The approach selected by NuttX is intended to support greater
scalability from the very tiny platform to the moderate platform.
@@ -0,0 +1,17 @@
OS Components
=============
NuttX is very feature-rich RTOS and is thus composed of various different subsystems. The following sections explain how each of these main RTOS components work and can be used. For detailed documentation on the specific API used in this case, you can head to the :doc:`reference <../reference/index>`.
.. toctree::
:maxdepth: 2
:caption: Contents:
power.rst
binfmt.rst
drivers/index.rst
filesystem.rst
nxflat.rst
nxgraphics/index.rst
nxwidgets.rst
paging.rst
@@ -0,0 +1,404 @@
.. _nxflat:
======
NXFLAT
======
Overview
========
Functionality
-------------
NXFLAT is a customized and simplified version of binary format
implemented a few years ago called
`XFLAT <http://xflat.sourceforge.net/>`__ With the NXFLAT binary format
you will be able to do the following:
- Place separately linked programs in a file system, and
- Execute those programs by dynamically linking them to the base NuttX
code.
This allows you to extend the NuttX base code after it has been written
into FLASH. One motivation for implementing NXFLAT is support clean CGI
under an HTTPD server.
This feature is especially attractive when combined with the NuttX ROMFS
support: ROMFS allows you to execute programs in place (XIP) in flash
without copying anything other than the .data section to RAM. In fact,
the initial NXFLAT release only worked on ROMFS. Later extensions also
support execution NXFLAT binaries from an SRAM copy as well.
This NuttX feature includes:
- A dynamic loader that is built into the NuttX core (See
`GIT <https://github.com/apache/incubator-nuttx/blob/master/binfmt/>`__).
- Minor changes to RTOS to support position independent code, and
- A linker to bind ELF binaries to produce the NXFLAT binary format
(See GIT).
Background
----------
NXFLAT is derived from `XFLAT <http://xflat.sourceforge.net/>`__. XFLAT
is a toolchain add that provides full shared library and XIP executable
support for processors that have no Memory Management Unit
(MMU:sup:`1`). NXFLAT is greatly simplified for the deeply embedded
environment targeted by NuttX:
- NXFLAT does not support shared libraries, because
- NXFLAT does not support *exportation* of symbol values from a module
Rather, the NXFLAT module only *imports* symbol values. In the NXFLAT
model, the (PIC:sup:`2`) NXFLAT module resides in a FLASH file system
and when it is loaded at run time, it is dynamically linked only to the
(non-PIC) base NuttX code: The base NuttX *exports* a symbol table; the
NXFLAT module *imports* those symbol value to dynamically bind the
module to the base code.
Limitations
-----------
- **ROMFS (or RAM mapping) Only**:
The current NXFLAT release will work only with either (1) NXFLAT
executable modules residing on a ROMFS file system, or (2) executables
residing on other file systems provided that CONFIG_FS_RAMMAP is
defined. This limitation is because the loader depends on the capability
to mmap() the code segment. See the NuttX User Guide for further information.
NUTTX does not provide any general kind of file mapping capability.
In fact, true file mapping is only possible with MCUs that provide an MMU1.
Without an MMU, file system may support eXecution In Place (XIP) to mimic
file mapping. Only the ROMFS file system supports that kind of XIP execution
need by NXFLAT.
It is also possible to simulate file mapping by allocating memory, copying
the NXFLAT binary file into memory, and executing from the copy of the
executable file in RAM. That capability can be enabled with the CONFIG_FS_RAMMAP
configuration option. With that option enabled, NXFLAT will work that kind
of file system but will require copying of all NXFLAT executables to RAM.
- **GCC/ARM/Cortex-M3/4 Only**:
At present, the NXFLAT toolchain is only available for ARM and Cortex-M3/4 (thumb2) targets.
- **Read-Only Data in RAM**:
With older GCC compilers (at least up to 4.3.3), read-only data must
reside in RAM. In code generated by GCC, all data references are
indexed by the PIC2 base register (that is usually R10 or sl for the
ARM processors). The includes read-only data (.rodata). Embedded
firmware developers normally like to keep .rodata in FLASH with
the code sections. But because all data is referenced with the
PIC base register, all of that data must lie in RAM. A NXFLAT
change to work around this is under investigation3.
Newer GCC compilers (at least from 4.6.3), read-only data is
no long GOT-relative, but is now accessed PC-relative.
With PC relative addressing, read-only data must reside in the I-Space.
- **Globally Scoped Function Function Pointers**:
If a function pointer is taken to a statically defined function,
then (at least for ARM) GCC will generate a relocation that NXFLAT
cannot handle. The workaround is make all such functions global in
scope. A fix would involve a change to the GCC compiler as described
in Appendix B.
- **Special Handling of Callbacks**:
Callbacks through function pointers must be avoided or, when
then cannot be avoided, handled very specially. The reason
for this is that the PIC module requires setting of a special
value in a PIC register. If the callback does not set the PIC
register, then the called back function will fail because it
will be unable to correctly access data memory. Special logic
is in place to handle some NuttX callbacks: Signal callbacks
and watchdog timer callbacks. But other callbacks (like those
used with qsort() must be avoided in an NXFLAT module.
Supported Processors
--------------------
As mentioned `above <#limitations>`__, the NXFLAT toolchain is only
available for ARM and Cortex-M3 (thumb2) targets. Furthermore, NXFLAT
has only been tested on the Eagle-100 LMS6918 Cortex-M3 board.
Development Status
------------------
The initial release of NXFLAT was made in NuttX version 0.4.9. Testing
is limited to the tests found under ``apps/examples/nxflat`` in the
source tree. Some known problems exist (see the
`TODO <https://github.com/apache/incubator-nuttx/blob/master/TODO>`__ list). As
such, NXFLAT is currently in an early alpha phase.
NXFLAT Toolchain
================
Building the NXFLAT Toolchain
-----------------------------
In order to use NXFLAT, you must use special NXFLAT tools to create the
binary module in FLASH. To do this, you will need to download the
buildroot package and build it on your Linux or Cygwin machine. The
buildroot can be downloaded from
`Bitbucket.org <https://bitbucket.org/nuttx/buildroot/downloads>`__. You
will need version 0.1.7 or later.
Here are some general build instructions:
- You must have already configured NuttX in ``<some-dir>/nuttx``
- Download the buildroot package ``buildroot-0.x.y`` into
``<some-dir>``
- Unpack ``<some-dir>/buildroot-0.x.y.tar.gz`` using a command like ``tar zxf buildroot-0.x.y``. This will result in a new directory like ``<some-dir>/buildroot-0.x.y``
- Move this into position:
``mv <some-dir>/buildroot-0.x.y``\ <some-dir>/buildroot
- ``cd``\ <some-dir>/buildroot
- Copy a configuration file into the top buildroot directory:
``cp boards/abc-defconfig-x.y.z .config``.
- Enable building of the NXFLAT tools by ``make menuconfig``. Select to
build the NXFLAT toolchain with GCC (you can also select omit
building GCC with and only build the NXFLAT toolchain for use with
your own GCC toolchain).
- Make the toolchain: ``make``. When the make completes, the tool
binaries will be available under
``<some-dir>/buildroot/build_abc/staging_dir/bin``
mknxflat
--------
``mknxflat`` is used to build a *thunk* file. See below
for usage::
Usage: mknxflat [options] <bfd-filename>
Where options are one or more of the following. Note
that a space is always required between the option and
any following arguments.
-d Use dynamic symbol table. [symtab]
-f <cmd-filename>
Take next commands from <cmd-filename> [cmd-line]
-o <out-filename>
Output to [stdout]
-v Verbose output [no output]
-w Import weakly declared functions, i.e., weakly
declared functions are expected to be provided at
load-time [not imported]
ldnxflat
--------
``ldnxflat`` is use to link your object files along with the *thunk*
file generated by ``mknxflat`` to produce the NXFLAT
binary module. See below for usage::
Usage: ldnxflat [options] <bfd-filename>
Where options are one or more of the following. Note
that a space is always required between the option and
any following arguments.
-d Use dynamic symbol table [Default: symtab]
-e <entry-point>
Entry point to module [Default: _start]
-o <out-filename>
Output to <out-filename> [Default: <bfd-filename>.nxf]
-s <stack-size>
Set stack size to <stack-size> [Default: 4096]
-v Verbose output. If -v is applied twice, additional
debug output is enabled [Default: no verbose output].
mksymtab
--------
There is a small helper program available in ``nuttx/tools`` call
``mksymtab``. ``mksymtab`` can be sued to generate symbol tables for the
NuttX base code that would be usable by the typical NXFLAT application.
``mksymtab`` builds symbol tables from common-separated value (CSV)
files. In particular, the CSV files:
#. ``nuttx/syscall/syscall.csv`` that describes the NuttX RTOS
interface, and
#. ``nuttx/libc/libc.csv`` that describes the NuttX C library interface.
#. ``nuttx/libc/math.cvs`` that descirbes any math library.
::
USAGE: ./mksymtab <cvs-file> <symtab-file>
Where:
<cvs-file> : The path to the input CSV file
<symtab-file>: The path to the output symbol table file
-d : Enable debug output
For example,
::
cd nuttx/tools
cat ../syscall/syscall.csv ../libc/libc.csv | sort >tmp.csv
./mksymtab.exe tmp.csv tmp.c
Making an NXFLAT module
-----------------------
Below is a snippet from an NXFLAT make file (simplified from NuttX
`Hello,
World! <https://github.com/apache/incubator-nuttx-apps/blob/master/examples/nxflat/tests/hello/Makefile>`__
example).
* Target 1:
.. code-block:: makefile
hello.r1: hello.o
abc-nuttx-elf-ld -r -d -warn-common -o $@ $^
* Target 2:
.. code-block:: makefile
hello-thunk.S: hello.r1
mknxflat -o $@ $^
* Target 3:
.. code-block:: makefile
hello.r2: hello-thunk.S
abc-nuttx-elf-ld -r -d -warn-common -T binfmt/libnxflat/gnu-nxflat-gotoff.ld -no-check-sections -o $@ hello.o hello-thunk.o
* Target 4:
.. code-block:: makefile
hello: hello.r2
ldnxflat -e main -s 2048 -o $@ $^
**Target 1**. This target links all of the module's object files
together into one relocatable object. Two relocatable objects will be
generated; this is the first one (hence, the suffic ``.r1``). In this
"Hello, World!" case, there is only a single object file, ``hello.o``,
that is linked to produce the ``hello.r1`` object.
When the module's object files are compiled, some special compiler
CFLAGS must be provided. First, the option ``-fpic`` is required to tell
the compiler to generate position independent code (other GCC options,
like ``-fno-jump-tables`` might also be desirable). For ARM compilers,
two additional compilation options are required: ``-msingle-pic-base``
and ``-mpic-register=r10``.
**Target 2**. Given the ``hello.r1`` relocatable object, this target
will invoke ```mknxflat`` <#mknxflat>`__ to make the *thunk* file,
``hello-thunk.S``. This *thunk* file contains all of the information
needed to create the imported function list.
**Target 3** This target is similar to **Target 1**. In this case, it
will link together the module's object files (only ``hello.o`` here)
along with the assembled *thunk* file, ``hello-thunk.o`` to create the
second relocatable object, ``hello.r2``. The linker script,
``gnu-nxflat-gotoff.ld`` is required at this point to correctly position
the sections. This linker script produces two segments: An *I-Space*
(Instruction Space) segment containing mostly ``.text`` and a *D-Space*
(Data Space) segment containing ``.got``, ``.data``, and ``.bss``
sections. The I-Space section must be origined at address 0 (so that the
segment's addresses are really offsets into the I-Space segment) and the
D-Space section must also be origined at address 0 (so that segment's
addresses are really offsets into the I-Space segment). The option
``-no-check-sections`` is required to prevent the linker from failing
because these segments overlap.
**NOTE:** There are two linker scripts located at ``binfmt/libnxflat/``.
#. ``binfmt/libnxflat/gnu-nxflat-gotoff.ld``. Older versions of GCC
(at least up to GCC 4.3.3), use GOT-relative addressing to access RO
data. In that case, read-only data (.rodata) must reside in D-Space
and this linker script should be used.
#. ``binfmt/libnxflat/gnu-nxflat-pcrel.ld``. Newer versions of GCC
(at least as of GCC 4.6.3), use PC-relative addressing to access RO
data. In that case, read-only data (.rodata) must reside in I-Space
and this linker script should be used.
**Target 4**. Finally, this target will use the ``hello.r2`` relocatable
object to create the final, NXFLAT module ``hello`` by executing
``ldnxflat``.
**binfmt Registration** NXFLAT calls :c:func:`register_binfmt` to
incorporate itself into the system.
Appendix A: No GOT Operation
============================
When GCC generate position independent code, new code sections will
appear in your programs. One of these is the GOT (Global Offset Table)
and, in ELF environments, another is the PLT (Procedure Lookup Table.
For example, if your C code generated (ARM) assembly language like this
without PIC:
.. code-block:: asm
ldr r1, .L0 /* Fetch the offset to 'x' */
ldr r0, [r10, r1] /* Load the value of 'x' with PIC offset */
/* ... */
.L0: .word x /* Offset to 'x' */
Then when PIC is enabled (say with the -fpic compiler option), it will
generate code like this:
.. code-block:: asm
ldr r1, .L0 /* Fetch the offset to the GOT entry */
ldr r1, [r10, r1] /* Fetch the (relocated) address of 'x' from the GOT */
ldr r0, [r1, #0] /* Fetch the value of 'x' */
/* ... */
.L1 .word x(GOT) /* Offset to entry in the GOT */
See
`reference <http://xflat.sourceforge.net/NoMMUSharedLibs.html#shlibsgot>`__
Notice that the generates an extra level of indirection through the GOT.
This indirection is not needed by NXFLAT and only adds more RAM usage
and execution time.
NXFLAT (like `XFLAT <http://xflat.sourceforge.net/>`__) can work even
better without the GOT. Patches against older version of GCC exist to
eliminate the GOT indirections. Several are available
`here <http://xflat.cvs.sourceforge.net/viewvc/xflat/xflat/gcc/>`__ if
you are inspired to port them to a new GCC version.
Appendix B: PIC Text Workaround
===============================
There is a problem with the memory model in GCC that prevents it from
being used as you need to use it in the NXFLAT context. The problem is
that GCC PIC model assumes that the executable lies in a flat,
contiguous (virtual) address space like::
Virtual
.text
.got
.data
.bss
It assumes that the PIC base register (usually r10 for ARM) points to
the base of ``.text`` so that any address in ``.text``, ``.got``,
``.data``, ``.bss`` can be found with an offset from the same base
address. But that is not the memory arrangement that we need in the XIP
embedded environment. We need two memory regions, one in FLASH
containing shared code and on per task in RAM containing task-specific
data::
Flash RAM
.text .got
.data
.bss
The PIC base register needs to point to the base of the ``.got`` and
only addresses in the ``.got``, ``.data``, and ``.bss`` sections can be
accessed as an offset from the PIC base register. See also this `XFLAT
discussion <http://xflat.cvs.sourceforge.net/viewvc/*checkout*/xflat/xflat/gcc/README?revision=1.1.1.1>`__.
Patches against older version of GCC exist to correct this GCC behavior.
Several are available
`here <http://xflat.cvs.sourceforge.net/viewvc/xflat/xflat/gcc/>`__ if
you are inspired to port them to a new GCC version.
Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

@@ -0,0 +1,647 @@
========
Appendix
========
``graphics/`` Directory Structure
=================================
The graphics capability consist both of components internal to the RTOS
and of user-callable interfaces. In the NuttX kernel mode build there
are some components of the graphics subsystem are callable in user mode
and other components that are internal to the RTOS. The directory
``nuttx/graphics`` contains only those components that are internal to
the RTOS. User callable functions must be part of a library that can be
linked against user applications. This user callable interfaces are
provided in sub-directories under ``nuttx/libnx``.
``libnx/nx``
Common callable interfaces that are, logically, part of both nxmu and
nxsu.
``graphics/nxglib`` and ``libnx/nxglib``
The NuttX tiny graphics library. The directory contains generic
utilities support operations on primitive graphics objects and logic
to rasterize directly into a framebuffer or through an LCD driver
interface. It has no concept of windows (other than the one,
framebuffer or LCD window).
``graphics/nxbe``
This is the *back-end* of a tiny windowing system. It can be used
with either of two front-ends to complete a windowing system (see
``nxmu`` and ``nxsu`` below). It contains most of the important
window management logic: clipping, window controls, window drawing,
etc.
``graphics/nxmu`` and ``libnx/nxmu``
This is the NX multi user *front end*. When combined with the generic
*back-end* (``nxbe``), it implements a multi-threaded, multi-user
windowing system. The files in this directory present the window APIs
described in ``include/nuttx/nx/nx.h``. The multi-user front end
includes a graphics server that executes on its own thread; multiple
graphics clients then communicate with the server via a POSIX message
queue to serialize window operations from many threads.
``libnx/nxfonts``
This is where the NXFONTS implementation resides. This is a
relatively low-level set of charset set/glyph management APIs. See
``include/nuttx/nx/nxfonts.h``.
``libnx/nxtk``
This is where the NXTOOLKIT implementation resides. This toolkit is
built on top of NX and works with the multi-user NX front-end. See
``include/nuttx/nx/nxtk.h``.
``apps/graphics/NxWidgets``
The :ref:`NxWidgets <nxwidgets>` code is provided as a separate
package provided in the ``apps/`` repository.
``graphics/nxterm``
The NxTerm driver is built on top of NX and works with the multi-user
NX front-end. See ``include/nuttx/nx/nxterm.h``.
NX Configuration Options
========================
General Configuration Settings
------------------------------
``CONFIG_NX``
Enables overall support for graphics library and NX
``CONFIG_NX_RAMBACKED``
Enables RAM backed window support. If this option is selected, then
windows may be optionally created with a RAM framebuffer backing up
the window content. Rending into the window will result in rending
into the backup framebuffer, then updating the physical display from
the framebuffer.
The advantage of this option is that the application that manages
window will no longer receive redraw() callbacks. Those calls
normally occur, for example, when a window "above" moves exposing a
portion of the window below. If this option is selected, then the
system will redraw the exposed portion of the window from the backup
framebuffer without intervention of the window applications. This
greatly reduces the complexity of the application and performance of
the window at the expense of increased memory usage.
An exception is the case when the window is resized to a wider and/or
taller size. In that case, the redraw callback will till occur. It is
necessary in that case to provide new graphic content for the
extended window area.
Redraw requests in other cases are also suppressed: Changes to window
position, size, etc.
NXGL Configuration Settings
---------------------------
``CONFIG_NX_NPLANES``:
Some YUV color formats requires support for multiple planes, one for
each color component. Unless you have such special hardware, this
value should be undefined or set to 1.
``CONFIG_NX_DISABLE_1BPP``, ``CONFIG_NX_DISABLE_2BPP``, ``CONFIG_NX_DISABLE_4BPP``, ``CONFIG_NX_DISABLE_8BPP`` ``CONFIG_NX_DISABLE_16BPP``, ``CONFIG_NX_DISABLE_24BPP``, and ``CONFIG_NX_DISABLE_32BPP``:
NX supports a variety of pixel depths. You can save some memory by
disabling support for unused color depths.
``CONFIG_NX_PACKEDMSFIRST``:
If a pixel depth of less than 8-bits is used, then NX needs to know
if the pixels pack from the MS to LS or from LS to MS
``CONFIG_NX_LCDDRIVER``:
By default, NX builds to use a framebuffer driver (see
``include/nuttx/video/fb.h``). If this option is defined, NX will
build to use an LCD driver (see ``include/nuttx/lcd/lcd.h``).
``CONFIG_NX_ANTIALIASING``:
Enable support for anti-aliasing when rendering lines as various
orientations. This option is only available for use with frame buffer
drivers and only with 16-, 24-, or 32-bit RGB color formats.
Configuration Settings
----------------------
``CONFIG_NX_XYINPUT``:
Build in support for an X/Y input such as a mouse or a touscreen.
``CONFIG_NX_KBD``:
Build in support of keypad/keyboard input.
``CONFIG_NX_WRITEONLY``:
Define if the underlying graphics device does not support read
operations. Automatically defined if ``CONFIG_NX_LCDDRIVER`` and
``CONFIG_LCD_NOGETRUN`` are defined.
NX Server Configuration Settings
--------------------------------
``CONFIG_NX_BLOCKING``
Open the client message queues in blocking mode. In this case,
``nx_eventhandler()`` will not return until a message is received and
processed.
``CONFIG_NX_MXSERVERMSGS`` and ``CONFIG_NX_MXCLIENTMSGS``
Specifies the maximum number of messages that can fit in the message
queues. No additional resources are allocated, but this can be set to
prevent flooding of the client or server with too many messages
(``CONFIG_PREALLOC_MQ_MSGS`` controls how many messages are
pre-allocated).
NXTK Configuration Settings
---------------------------
``CONFIG_NXTK_BORDERWIDTH``:
Specifies the width of the border (in pixels) used with framed
windows. The default is 4.
``CONFIG_NXTK_BORDERCOLOR1``, ``CONFIG_NXTK_BORDERCOLOR2``, and ``CONFIG_NXTK_BORDERCOLOR3``:
Specify the colors of the border used with framed windows.
``CONFIG_NXTK_BORDERCOLOR2``
The shadow side color and so is normally darker.
``CONFIG_NXTK_BORDERCOLOR3``
The shiny side color and so is normally brighter. The default is
medium, dark, and light grey, respectively
``CONFIG_NXTK_AUTORAISE``:
If set, a window will be raised to the top if the mouse position is
over a visible portion of the window. Default: A mouse button must be
clicked over a visible portion of the window.
NXFONTS Configuration Settings
------------------------------
``CONFIG_NXFONTS_CHARBITS``:
The number of bits in the character set. Current options are only 7
and 8. The default is 7.
``CONFIG_NXFONT_SANS17X22``:
This option enables support for a tiny, 17x22 san serif font (font
``ID FONTID_SANS17X22`` == 14).
``CONFIG_NXFONT_SANS20X26``:
This option enables support for a tiny, 20x26 san serif font (font
``ID FONTID_SANS20X26`` == 15).
``CONFIG_NXFONT_SANS23X27``:
This option enables support for a tiny, 23x27 san serif font (font
``ID FONTID_SANS23X27`` == 1).
``CONFIG_NXFONT_SANS22X29``:
This option enables support for a small, 22x29 san serif font (font
``ID FONTID_SANS22X29`` == 2).
``CONFIG_NXFONT_SANS28X37``:
This option enables support for a medium, 28x37 san serif font (font
``ID FONTID_SANS28X37`` == 3).
``CONFIG_NXFONT_SANS39X48``:
This option enables support for a large, 39x48 san serif font (font
``ID FONTID_SANS39X48`` == 4).
``CONFIG_NXFONT_SANS17X23B``:
This option enables support for a tiny, 17x23 san serif bold font
(font ``ID FONTID_SANS17X23B`` == 16).
``CONFIG_NXFONT_SANS20X27B``:
This option enables support for a tiny, 20x27 san serif bold font
(font ``ID FONTID_SANS20X27B`` == 17).
``CONFIG_NXFONT_SANS22X29B``:
This option enables support for a small, 22x29 san serif bold font
(font ID ``FONTID_SANS22X29B`` == 5).
``CONFIG_NXFONT_SANS28X37B``:
This option enables support for a medium, 28x37 san serif bold font
(font ID ``FONTID_SANS28X37B`` == 6).
``CONFIG_NXFONT_SANS40X49B``:
This option enables support for a large, 40x49 san serif bold font
(font ID ``FONTID_SANS40X49B`` == 7).
``CONFIG_NXFONT_SERIF22X29``:
This option enables support for a small, 22x29 font (with serifs)
(font ID ``FONTID_SERIF22X29`` == 8).
``CONFIG_NXFONT_SERIF29X37``:
This option enables support for a medium, 29x37 font (with serifs)
(font ID ``FONTID_SERIF29X37`` == 9).
``CONFIG_NXFONT_SERIF38X48``:
This option enables support for a large, 38x48 font (with serifs)
(font ID ``FONTID_SERIF38X48`` == 10).
``CONFIG_NXFONT_SERIF22X28B``:
This option enables support for a small, 27x38 bold font (with
serifs) (font ID ``FONTID_SERIF22X28B`` == 11).
``CONFIG_NXFONT_SERIF27X38B``:
This option enables support for a medium, 27x38 bold font (with
serifs) (font ID ``FONTID_SERIF27X38B`` == 12).
``CONFIG_NXFONT_SERIF38X49B``:
This option enables support for a large, 38x49 bold font (with
serifs) (font ID ``FONTID_SERIF38X49B`` == 13).
NxTerm Configuration Settings
-----------------------------
General NxTerm settings.
``CONFIG_NXTERM``:
Enables building of the NxTerm driver.
NxTerm output text/graphics options:
``CONFIG_NXTERM_BPP``:
Currently, NxTerm supports only a single pixel depth. This
configuration setting must be provided to support that single pixel
depth. Default: The smallest enabled pixel depth. (see
``CONFIG_NX_DISABLE_*BPP``)
``CONFIG_NXTERM_CURSORCHAR``:
The bitmap code to use as the cursor. Default '_'
``CONFIG_NXTERM_MXCHARS``:
NxTerm needs to remember every character written to the console so
that it can redraw the window. This setting determines the size of
some internal memory allocations used to hold the character data.
Default: 128.
``CONFIG_NXTERM_CACHESIZE``:
NxTerm supports caching of rendered fonts. This font caching is
required for two reasons: (1) First, it improves text performance,
but more importantly (2) it preserves the font memory. Since the NX
server runs on a separate server thread, it requires that the
rendered font memory persist until the server has a chance to render
the font. Unfortunately, the font cache would be quite large if all
fonts were saved. The ``CONFIG_NXTERM_CACHESIZE`` setting will
control the size of the font cache (in number of glyphs). Only that
number of the most recently used glyphs will be retained. Default:
16.
NOTE: There can still be a race condition between the NxTerm
driver and the NX task. If you every see character corruption
(especially when printing a lot of data or scrolling), then
increasing the value of ``CONFIG_NXTERM_CACHESIZE`` is something
that you should try. Alternatively, you can reduce the size of
``CONFIG_MQ_MAXMSGSIZE`` which will force NxTerm task to pace the
server task. ``CONFIG_NXTERM_CACHESIZE`` should be larger than
``CONFIG_MQ_MAXMSGSIZE`` in any event.
``CONFIG_NXTERM_LINESEPARATION``:
This the space (in rows) between each row of test. Default: 0
``CONFIG_NXTERM_NOWRAP``:
By default, lines will wrap when the test reaches the right hand side
of the window. This setting can be defining to change this behavior
so that the text is simply truncated until a new line is encountered.
NxTerm input options:
``CONFIG_NXTERM_NXKBDIN``:
Take input from the NX keyboard input callback. By default, keyboard
input is taken from stdin (``/dev/console``). If this option is set,
then the interface\ ``nxterm_kdbin()`` is enabled. That interface may
be driven by window callback functions so that keyboard input *only*
goes to the top window.
``CONFIG_NXTERM_KBDBUFSIZE``:
If ``CONFIG_NXTERM_NXKBDIN`` is enabled, then this value may be used
to define the size of the per-window keyboard input buffer. Default:
16
``CONFIG_NXTERM_NPOLLWAITERS``:
The number of threads that can be waiting for read data available.
Default: 4
Installing New Fonts
====================
**The BDF Font Converter**. There is a tool called *bdf-converter* in
the directory ``tools/.``. The *bdf-converter* program be used to
convert fonts in Bitmap Distribution Format (BDF) into fonts that can be
used in the NX graphics system. The BDF format most well known as a font
format traditionally used for X-11 bitmap fonts.
A Note about Font Copyrights: My understanding is that the underlying
bitmap font data for traditional fonts cannot be copyrighted (the
same is not true for scalable fonts). This is because a copyright
covers only the form of delivery of the font and not the underlying
font content and, at least for the traditional typefaces, the
underlying font designs are ancient. There could be issues, however,
if you convert from modern, trademarked images. However, remember
that I am a programmer not an attorney and that my knowledge of font
copyright issues is limited to what I glean by Googling.
**Font Installation Steps**, Below are general instructions for creating
and installing a new font in the NX graphic system. The first two steps
only apply if you are using the BDF font converter program.
#. Locate a font in BDF format. There are many good BDF bitmap fonts
bundled with X-11. See `this
link <http://www.cl.cam.ac.uk/~mgk25/ucs-fonts.html>`__, as an
example,
#. Use the *bdf-converter* program to convert the BDF font to the NuttX
font format. This will result in a C header file containing
definitions. That header file should be installed at, for example,
``graphics/nxfonts/nxfonts_myfont.h``.
The remaining steps apply however you managed to create the NuttX C font
header file. After you have your C font header file, the next thing to
do is to create a new NuttX configuration variable to select the font.
For example, suppose you define the following variable:
``CONFIG_NXFONT_MYFONT``. Then you would need to:
3. Define ``CONFIG_NXFONT_MYFONT=y`` in your NuttX configuration file.
A font ID number has to be assigned for each new font. The font IDs are
defined in the file ``include/nuttx/nx/nxfonts.h``. Those definitions
have to be extended to support your new font. Look at how the font ID
enabled by ``CONFIG_NXFONT_SANS23X27`` is defined and add an ID for
yournew font in a similar fashion:
4. ``include/nuttx/nx/nxfonts.h``. Add you new font as a possible
system default font:
.. code-block:: c
#if defined(CONFIG_NXFONT_SANS23X27)
# define NXFONT_DEFAULT FONTID_SANS23X27
#elif defined(CONFIG_NXFONT_MYFONT)
# define NXFONT_DEFAULT FONTID_MYFONT
#endif
Then define the actual font ID. Make sure that the font ID value is
unique:
.. code-block:: c
#if defined(CONFIG_NXFONT_SANS23X27)
# define NXFONT_DEFAULT FONTID_SANS23X27
#elif defined(CONFIG_NXFONT_MYFONT)
# define NXFONT_DEFAULT FONTID_MYFONT
#endif
New Add the font to the NX build system. There are several files that
you have to modify to do this. Look how the build system uses the font
CONFIG_NXFONT_SANS23X27 for examaples:
5. ``nuttx/graphics/Makefile``. This file needs logic to
auto-generate a C source file from the header file that you generated
with the *bdf-converter* program. Notice ``NXFONTS_FONTID=2``; this
must be set to the same font ID value that you defined in the
``include/nuttx/nx/nxfonts.h`` file.
.. code-block:: makefile
genfontsources:
ifeq ($(CONFIG_NXFONT_SANS23X27),y)
@$(MAKE) -C nxfonts -f Makefile.sources NXFONTS_FONTID=1 EXTRAFLAGS=$(EXTRAFLAGS)
endif
ifeq ($(CONFIG_NXFONT_MYFONT),y)
@$(MAKE) -C nxfonts -f Makefile.sources NXFONTS_FONTID=2 EXTRAFLAGS=$(EXTRAFLAGS)
endif
6. ``nuttx/graphics/nxfonts/Make.defs``. Set the make variable
``NXFSET_CSRCS``. ``NXFSET_CSRCS`` determines the name of the font C
file to build when ``NXFONTS_FONTID=2``:
.. code-block:: makefile
ifeq ($(CONFIG_NXFONT_SANS23X27),y)
NXFSET_CSRCS += nxfonts_bitmaps_sans23x27.c
endif
ifeq ($(CONFIG_NXFONT_MYFONT),y)
NXFSET_CSRCS += nxfonts_bitmaps_myfont.c
endif
7. ``nuttx/graphics/nxfonts/Makefile.sources``. This is the Makefile
used in step 5 that will actually generate the font C file. So, given
your NXFONTS_FONTID=2, it needs to determine a prefix to use for
auto-generated variable and function names and (again) the name of
the autogenerated file to create (this must be the same name that was
used in ``nuttx/graphics/nxfonts/Make.defs``):
.. code-block:: makefile
ifeq ($(NXFONTS_FONTID),1)
NXFONTS_PREFIX := g_sans23x27_
GEN_CSRC = nxfonts_bitmaps_sans23x27.c
endif
ifeq ($(NXFONTS_FONTID),2)
NXFONTS_PREFIX := g_myfont_
GEN_CSRC = nxfonts_bitmaps_myfont.c
endif
8. ``graphics/nxfonts/nxfonts_bitmaps.c``. This is the file that
contains the generic font structures. It is used as a "template&qout;
file by ``nuttx/graphics/nxfonts/Makefile.sources``\ to create your
customized font data set at build time.
.. code-block:: c
#if NXFONTS_FONTID == 1
# include "nxfonts_sans23x27.h"
#elif NXFONTS_FONTID == 2
# include "nxfonts_myfont.h"
#else
# error "No font ID specified"
#endif
Where ``nxfonts_myfont.h`` is the NuttX font file that we generated
in step 2 using the *bdf-converter* tool.
9. ``graphics/nxfonts/nxfonts_getfont.c``. Finally, we need to
extend the logic that does the run-time font lookups so that can find
our new font. The lookup function is
```NXHANDLE nxf_getfonthandle(enum nx_fontid_e fontid)`` <#nxfgetfonthandle>`__.
Note that the lookup is based on the font ID that was defined in step
4. The new font information needs to be added to data structures used
by that function:
.. code-block:: c
#ifdef CONFIG_NXFONT_SANS23X27
extern const struct nx_fontpackage_s g_sans23x27_package;
#endif
#ifdef CONFIG_NXFONT_MYFONT
extern const struct nx_fontpackage_s g_myfont_package;
#endif
static FAR const struct nx_fontpackage_s *g_fontpackages[] =
{
#ifdef CONFIG_NXFONT_SANS23X27
&g_sans23x27_package,
#endif
#ifdef CONFIG_NXFONT_MYFONT
&g_myfont_package,
#endif
NULL
};
NX Test Coverage
================
``apps/examples/nx``. The primary test tool for debugging NX resides
at ``apps/examples/nx``.
**Building** ``apps/examples/nx``. NX testing was performed using
``apps/examples/nx`` with the Linux/Cygwin-based NuttX simulator.
Configuration files for building this test can be found in
``boards/sim/sim/sim/configs/nx`` and
``boards/sim/sim/sim/configs/nx11``. There are two alternative
configurations for building the simulation:
#. The configuration using the configuration file at
``boards/sim/sim/sim/configs/nx/defconfig``. This default
configuration exercises the NX logic a 8 BPP but provides no visual
feedback. In this configuration, a very simple, simulated framebuffer
driver is used that is based upon a simple region of memory posing as
video memory. That default configuration can be built as follows::
tools/configure.sh sim:nx
make
./nuttx
#. The preferred configuration is at
``boards/sim/sim/sim/configs/nx11/defconfig``. This configuration
extends the test with a simulated framebuffer driver that uses an X
window as a framebuffer. This is a superior test configuration
because the X window appears at your desktop and you can see the NX
output. This preferred configuration can be built as follows::
tools/configure sim:nx11
make
./nuttx
*Update:* The sim target has suffered some bit-rot over the years and
so the following caveats need to be added:
- The X target builds under recent Cygwin configurations, but does
not execute. (It fails inside of ``XOpenDisplay()``.
- The X target does not build under current (9.09) Ubuntu
distributions. I needed to make the following changes:
The build will also fail to locate the X header files unless you
install an X11 development package.
- Refer to the readme file in sim configuration
`README.txt <https://github.com/apache/incubator-nuttx/blob/master/boards/sim/sim/sim/README.txt>`__
file for additional information.
**Test Coverage**. At present, ``apps/examples/nx``\ t only exercises a
subset of NX; the remainder is essentially untested. The following table
describes the testing performed on each NX API:
NXGLIB API Test Coverage
------------------------
================================ ==================================== ========
Function Special Setup/Notes Verified
================================ ==================================== ========
``nxgl_rgb2yuv()`` . NO
``nxgl_yuv2rgb()`` . NO
``nxgl_rectcopy()`` . YES
``nxgl_rectoffset()`` . YES
``nxgl_vectoradd()`` . YES
``nxgl_vectorsubtract()`` . YES
``nxgl_rectintersect()`` . YES
``nxgl_rectunion()`` . YES
``nxgl_nonintersecting()`` . YES
``nxgl_rectoverlap()`` . YES
``nxgl_rectinside()`` . YES
``nxgl_rectsize()`` . YES
``nxgl_nullrect()`` . YES
``nxgl_runoffset()`` Verified by apps/examples/nxlines. YES
``nxgl_runcopy()`` . NO
``nxgl_trapoffset()`` Verified by apps/examples/nxlines. YES
``nxgl_trapcopy()`` Verified by apps/examples/nxlines. YES
``nxgl_colorcopy`` . YES
``nxgl_splitline`` Verified using apps/examples/nxlines YES
Generally works well, but has some
accuracy/overflow problems wide
lines that are nearly horizontal.
There is a "fudge factor" that seems
to eliminate the problem, but there
could still be issues in some
configurations.
``nxgl_circlepts`` Verified by apps/examples/nxlines. YES
``nxgl_circletraps`` Verified by apps/examples/nxlines. YES
================================ ==================================== ========
NX Server Callbacks Test Coverage
---------------------------------
============== ==================== ========
Function Special Setup/Notes Verified
============== ==================== ========
``redraw()`` . YES
``position()`` . YES
``mousein()`` . YES
``kbdin()`` . YES
============== ==================== ========
NX API Test Coverage
--------------------
========================= =============================================================== ========
Function Special Setup/Notes Verified
========================= =============================================================== ========
``nx_runinstance()`` . YES
``nx_connectinstance()`` . YES
``nx_disconnect()`` . YES
``nx_eventhandler()`` . YES
``nx_eventnotify()`` This is not used in the current version of apps/examples/nx, NO
was tested in a previous version)
``nx_openwindow()`` Change to ``CONFIG_EXAMPLES_NX_RAWWINDOWS=y`` in the YES
``<NuttX-Directory>/.config file``
``nx_closewindow()`` Change to ``CONFIG_EXAMPLES_NX_RAWWINDOWS=y`` YES
in the ``<NuttX-Directory>/.config`` file
``nx_requestbkgd()`` Verified by ``apps/examples/nxtext`` and YES
``apps/examples/nxhello``.
``nx_releasebkgd()`` Verified by ``apps/examples/nxtext`` and YES
``apps/examples/nxhello``.
``nx_getposition()`` . NO
``nx_setposition()`` Change to ``CONFIG_EXAMPLES_NX_RAWWINDOWS=y`` in the YES
``<NuttX-Directory>/.config`` file
``nx_setsize()`` Change to ``CONFIG_EXAMPLES_NX_RAWWINDOWS=y`` in the YES
``<NuttX-Directory>/.config`` file
``nx_raise()`` Change to ``CONFIG_EXAMPLES_NX_RAWWINDOWS=y`` in the YES
``<NuttX-Directory>/.config`` file
``nx_lower()`` Change to ``CONFIG_EXAMPLES_NX_RAWWINDOWS=y`` in the YES
``<NuttX-Directory>/.config`` file
``nx_modal()`` . NO
``nx_setvisibility()`` Exercized using Twm4Nx YES, Informally
``nx_ishidden()`` Exercized using Twm4Nx YES, Informally
``nx_fill()`` Change to ``CONFIG_EXAMPLES_NX_RAWWINDOWS=y`` in the YES
``<NuttX-Directory>/.config`` file
``nx_getrectangle()`` . YES
``nx_filltrapezoid()`` Verified by ``apps/examples/nxlines``. YES
``nx_drawline()`` by ``apps/examples/nxlines``. YES
``nx_drawcircle()`` Verified by ``apps/examples/nxlines``. YES
``nx_fillcircle()`` Verified by ``apps/examples/nxlines``. YES
``nx_setbgcolor()`` . YES
``nx_move()`` Change to ``CONFIG_EXAMPLES_NX_RAWWINDOWS=y`` in the YES
``<NuttX-Directory>/.config`` file
``nx_bitmap()`` Change to ``CONFIG_EXAMPLES_NX_RAWWINDOWS=y`` in the YES
``<NuttX-Directory>/.config`` file.
``nx_kbdin()`` . YES
``nx_mousein()`` . YES
========================= =============================================================== ========
NXTK API Test Coverage
----------------------
============================ ========================= ========
Function Special Setup/Notes Verified
============================ ========================= ========
``nxtk_openwindow()`` . YES
``nxtk_closewindow()`` . YES
``nxtk_getposition()`` . NO
``nxtk_setposition()`` . YES
``nxtk_setsize()`` . YES
``nxtk_raise()`` . YES
``nxtk_lower()`` . YES
``nxtk_modal()`` . NO
``nxtk_setvisibility()`` Exercized using Twm4Nx YES, informally
``nxtk_ishidden()`` Exercized using Twm4Nx YES, informally
``nxtk_fillwindow()`` . YES
``nxtk_getwindow()`` . NO
``nxtk_filltrapwindow()`` . NO
``nxtk_drawlinewindow()`` . YES
``nxtk_drawcirclewindow()`` . YES
``nxtk_fillcirclewindow()`` . YES
``nxtk_movewindow()`` . NO
``nxtk_bitmapwindow()`` . YES
``nxtk_opentoolbar()`` . YES
``nxtk_closetoolbar()`` . YES
``nxtk_filltoolbar()`` . YES
``nxtk_gettoolbar()`` . NO
``nxtk_filltraptoolbar()`` . NO
``nxtk_drawlinetoolbar()`` . NO
``nxtk_drawcircletoolbar()`` . NO
``nxtk_fillcircletoolbar()`` . NO
``nxtk_movetoolbar()`` . NO
``nxtk_bitmaptoolbar()`` . NO
============================ ========================= ========
NXFONTS API Test Coverage
-------------------------
======================== ============================= ========
Function Special Setup/Notes Verified
======================== ============================= ========
``nxf_getfonthandle()`` . YES
``nxf_getfontset()`` . YES
``nxf_getbitmap()`` . YES
``nxf_convert_2bpp()`` . NO
``nxf_convert_4bpp()`` . NO
``nxf_convert_8bpp()`` Use defconfig when building. YES
``nxf_convert_16bpp()`` . YES
``nxf_convert_24bpp()`` . NO
``nxf_convert_32bpp()`` . YES
======================== ============================= ========
@@ -0,0 +1,176 @@
.. _nxgraphics:
=====================
NX Graphics Subsystem
=====================
This document describes the tiny graphics support included in NuttX. It
includes an overview description of that graphics support, detailed
descriptions of the NuttX graphics APIs, and discussion of code
organization, and OS configuration options.
.. figure:: NuttXScreenShot.jpg
:align: center
**Figure 1**. This screnshot shows the final frame for the NuttX example
at ``apps/examples/nx`` running on the simulated, Linux x86 platform with
simulated framebuffer output to an X window. This picture shows to framed window
with (blank) toolbars. Each window has displayed text as received from the
NX keyboard interface The second window has just been raised to the top of the display.
Objectives
==========
The objective of this development was to provide a tiny windowing system
in the spirit of X, but greatly scaled down and appropriate for most
resource-limited embedded environments. The current NX implementation
supports the general following, high-level features:
- **Virtual Vertical Graphics Space**. Windows that reside in a
virtual, *vertical* space so that it makes sense to talk about one
window being on top of another and obscuring the window below it.
- **Client/Server Model**. A standard client server/model was adopted.
NX may be considered a server and other logic that presents the
windows are NX clients.
- **Multi-User Support**. NX includes *front-end* logic to support a
separate NX server thread that can serve multiple NX client threads.
The NX is a server thread/daemon the serializes graphics operations
from multiple clients.
- **Minimal Graphics Toolset**. The actual implementation of the
graphics operations is performed by common, *back-end* logic. This
back-end supports only a primitive set of graphic and rendering
operations.
- **Device Interface**. NX supports any graphics device either of two
device interfaces:
- Any device with random access video memory using the NuttX
framebuffer driver interface (see ``include/nuttx/video/fb.h``).
- Any LCD-like device than can accept raster line *runs* through a
parallel or serial interface (see ``include/nuttx/lcd/lcd.h``). By
default, NX is configured to use the frame buffer driver unless
``CONFIG_NX_LCDDRIVER`` is defined =y in your NuttX configuration
file.
- **Transparent to NX Client**. The window client on "sees" the
sub-window that is operates in and does not need to be concerned with
the virtual, vertical space (other that to respond to *redraw*
requests from NX when needed).
- **Framed Windows and Toolbars**. NX also adds the capability to
support windows with frames and toolbars on top of the basic
windowing support. These are windows such as those shown in the
`screenshot <#screenshot>`__ above. These framed windows sub-divide
one one window into three relatively independent subwindows: A frame,
the contained window and an (optional) toolbar window.
- **Mouse Support**. NX provides support for a mouse or other X/Y
pointing devices. APIs are provided to allow external devices to give
X/Y position information and mouse button presses to NX. NX will then
provide the mouse input to the relevant window clients via callbacks.
Client windows only receive the mouse input callback if the mouse is
positioned over a visible portion of the client window; X/Y position
is provided to the client in the relative coordinate system of the
client window.
- **Keyboard input**. NX also supports keyboard/keypad devices. APIs
are provided to allow external devices to give keypad information to
NX. NX will then provide the mouse input to the top window on the
display (the window that has the *focus*) via a callback function.
Organization
============
NX is organized into 6 (and perhaps someday 7 or 8) logical modules.
These logical modules also correspond to the directory organization.
That NuttX directory organization is discussed in `Appendix
B <#grapicsdirs>`__ of this document. The logic modules are discussed in
the following sub-paragraphs.
.. figure:: NXOrganization.gif
:align: center
NX Graphics Library (``NXGL``)
------------------------------
NXGLIB is a standalone library that contains low-level graphics
utilities and direct framebuffer or LCD rendering logic. NX is built on
top NXGLIB.
NX (``NXSU`` and ``NXMU``)
--------------------------
NX is the tiny NuttX windowing system for raw windows (i.e., simple
regions of graphics memory). NX includes a small-footprint, multi-user
implementation (NXMU as described below). NX can be used without
NxWidgets and without NXTOOLKIT for raw window displays.
:sup:`1`\ NXMU and NXSU are interchangeable other than (1) certain
start-up and initialization APIs (as described below), and (2) timing.
With NXSU, NX APIs execute immediately; with NXMU, NX APIs defer and
serialize the operations and, hence, introduce different timing and
potential race conditions that you would not experience with NXSU.
**NXNULL?** At one time, I also envisioned a *NULL* front-end that did
not support windowing at all but, rather, simply provided the entire
framebuffer or LCD memory as one dumb window. This has the advantage
that the same NX APIs can be used on the one dumb window as for the
other NX windows. This would be in the NuttX spirit of scalability.
However, the same end result can be obtained by using the
```nx_requestbkgd()`` <#nxrequestbkgd>`__ API. It still may be possible
to reduce the footprint in this usage case by developing and even
thinner NXNULL front-end. That is a possible future development.
NX Tool Kit (``NXTK``)
----------------------
NXTK is a s set of C graphics tools that provide higher-level window
drawing operations. This is the module where the framed windows and
toolbar logic is implemented. NXTK is built on top of NX and does not
depend on NxWidgets.
NX Fonts Support (``NXFONTS``)
------------------------------
A set of C graphics tools for present (bitmap) font images. The font
implementation is at a very low level or graphics operation, comparable
to the logic in NXGLIB. NXFONTS does not depend on any NX module other
than some utilities and types from NXGLIB.
NX Widgets (``NxWidgets``)
--------------------------
:ref:`NxWidgets <nxwidgets>` is a higher level, C++, object-oriented
library for object-oriented access to graphical "widgets." NxWidgets is
provided as a separate library in the ``apps/`` repository NxWidgets is
built on top of the core NuttX graphics subsystem, but is part of the
application space rather than part of the core OS graphics subsystems.
Terminal Driver (``NxTerm``)
----------------------------
NxTerm is a write-only character device (not shown) that is built on top
of an NX window. This character device can be used to provide ``stdout``
and ``stderr`` and, hence, can provide the output side of NuttX console.
).
NX Header Files
===============
``include/nuttx/nx/nxglib.h``
Describes the NXGLIB C interfaces
``include/nuttx/nx/nx.h``
Describes the NX C interfaces
``include/nutt/nxtk.h``
Describe the NXTOOLKIT C interfaces
``include/nutt/nxfont.h``
Describe sthe NXFONT C interfaces
.. toctree::
:Caption: User APIs
nxgl.rst
nx.rst
nxtk.rst
nxfonts.rst
nxcursor.rst
sample.rst
appendix.rst
@@ -0,0 +1,719 @@
==
NX
==
Pre-Processor Definitions
=========================
The default server message queue name used by the :c:macro:`nx_run` macro:
.. code-block:: c
#define NX_DEFAULT_SERVER_MQNAME "/dev/nxs"
Mouse button bits:
.. code-block:: c
#define NX_MOUSE_NOBUTTONS 0x00
#define NX_MOUSE_LEFTBUTTON 0x01
#define NX_MOUSE_CENTERBUTTON 0x02
#define NX_MOUSE_RIGHTBUTTON 0x04
NX Types
========
The interface to the NX server is managed using a opaque handle:
.. c:type:: FAR void *NXHANDLE
The interface to a specific window is managed using an opaque handle:
.. c:type:: FAR void *NXWINDOW
These define callbacks that must be provided to :c:func:`nx_openwindow`.
These callbacks will be invoked as part of the processing performed by
:c:func:`nx_eventhandler`.
.. c:struct:: nx_callback_s
.. code-block:: c
struct nx_callback_s
{
void (*redraw)(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect,
bool more, FAR void *arg);
void (*position)(NXWINDOW hwnd, FAR const struct nxgl_size_s *size,
FAR const struct nxgl_point_s *pos,
FAR const struct nxgl_rect_s *bounds,
FAR void *arg);
#ifdef CONFIG_NX_XYINPUT
void (*mousein)(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos,
uint8_t buttons, FAR void *arg);
#endif
#ifdef CONFIG_NX_KBD
void (*kbdin)(NXWINDOW hwnd, uint8_t nch, FAR const uint8_t *ch, FAR void *arg);
#endif
};
Starting the NX Server
======================
The *NX Server* is a kernel daemon that receives and serializes graphic
commands. Before you can use the NX graphics system, you must first
start this daemon. There are two ways that this can be done:
#. The NX server may be started in your board startup logic by simply
calling the function ``nxmu_start()``. The board startup logic
usually resides the the ``boards/arch/chip/board/src`` directory. The
board startup logic can run automatically during the early system if
``CONFIG_BOARD_LATE_INITIALIZE`` is defined in the configuration. Or,
the board startup logic can execute under control of the application
by calling :c:func:`boardctl` as:
.. code-block:: c
boardctl(BOARDIOC_INIT, arg)
The board initialization logic will run in either case and the simple
call to ``nxmu_start()`` will start the NX server.
#. The NX server may also be started later by the application via
:c:func:`boardctl` as:
.. code-block:: c
boardctl(BOARDIOC_NX_START, arg)
.. c:function:: int nxmu_start(int display, int plane);
Provides a wrapper function to
simplify and standardize the starting of the NX server.
:param display: The display number to be served by this new NXMU instance.
:param plane: The plane number to use to get information about the display geometry and color format.
:return: Zero (``OK``) is returned on success. This indicates
that the NX server has been successfully started, is running, and
waiting to accept connections from NX clients.
A negated ``errno`` value is returned on failure. The ``errno`` value
indicates the nature of the failure.
NX Server Callbacks
===================
.. c:function:: void redraw(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, bool more, FAR void *arg);
NX requests that the client re-draw the portion of the
window within with rectangle.
:param hwnd:
The handle created by :c:func:`nx_openwindow` or :c:func:`nx_requestbkgd`
:param rect:
The rectangle that needs to be re-drawn (in window relative
coordinates)
:param more:
true: More re-draw requests will follow
:param arg:
User provided argument (see :c:func:`nx_openwindow`)
.. c:function:: void position(NXWINDOW hwnd, FAR const struct nxgl_size_s *size, \
FAR const struct nxgl_point_s *pos, \
FAR const struct nxgl_rect_s *bounds, \
FAR void *arg);
The size or position of the window has changed (or the
window was just created with zero size.
:param hwnd:
The handle created by :c:func:`nx_openwindow` or :c:func:`nx_requestbkgd`
:param size:
The size of the window
:param pos:
The position of the upper left hand corner of the window on the
overall display
:param bounds:
The bounding rectangle that the describes the entire display
:param arg:
User provided argument (see :c:func:`nx_openwindow`)
.. c:function:: void mousein(NXWINDOW hwnd, FAR const struct nxgl_point_s *pos, \
uint8_t buttons, FAR void *arg);
New mouse data is available for the window
:param hwnd:
The handle created by :c:func:`nx_openwindow` or :c:func:`nx_requestbkgd`
:param pos:
The (x,y) position of the mouse
:param buttons:
See ``NX_MOUSE_*`` definitions
:param arg:
User provided argument (see :c:func:`nx_openwindow`)
.. c:var:: void (*kbdin)(NXWINDOW hwnd, uint8_t nch, FAR const uint8_t *ch, FAR void *arg);
New keyboard/keypad data is available for the window.
:param hwnd:
The handle created by :c:func:`nx_openwindow` or :c:func:`nx_requestbkgd`
:param nch:
The number of characters that are available in ch[]
:param ch:
The array of characters
:param arg:
User provided argument (see :c:func:`nx_openwindow`)
.. c:var:: void (*event)(NXWINDOW hwnd, enum nx_event_e event, FAR void *arg1, FAR void *arg2);
This callback is used to communicate server events to the window listener.
- ``NXEVENT_BLOCKED``: Window messages are blocked.
This callback is the response from :c:func:`nx_block`,
:c:func:`nxtk_block`. Those blocking interfaces are used
to assure that no further messages are directed to the window.
Receipt of the blocked callback signifies that (1) there are no
further pending callbacks and (2) that the window is now *defunct*
and will receive no further callbacks. This callback supports
coordinated destruction of a window. In the multi-user mode, the
client window logic must stay intact until all of the queued
callbacks are processed. Then the window may be safely closed.
Closing the window prior with pending callbacks can lead to bad
behavior when the callback is executed.
- ``NXEVENT_SYNCHED``: Synchronization handshake
This completes the handshake started by
:c:func:`nx_synch`, or :c:func:`nxtk_synch`.
Those interfaces send a synchronization messages to the NX server
which responds with this event. The sleeping client is awakened and
continues graphics processing, completing the handshake. Due to the
highly asynchronous nature of client-server communications,
synchronization is sometimes necessary to assure that the client and
server are working together properly.
:param hwnd:
TWindow handle of window receiving the event
:param event:
The server event
:param arg1:
User provided argument (see :c:func:`nx_openwindow`,
:c:func:`nx_requestbkgd`, or :c:func:`nxtk_opentoolbar`)
:param arg2:
TUser provided argument (see :c:func:`nx_block`, :c:func:`nxtk_block`,
:c:func:`nx_synch`, or :c:func:`nxtk_synch`)
.. c:macro:: nx_run(fb)
.. code-block:: c
#define nx_run(fb) nx_runinstance(NX_DEFAULT_SERVER_MQNAME, dev)
.. c:function:: int nx_runinstance(FAR const char *mqname, FAR struct fb_vtable_s *fb)
This is the server entry point. It does not return; the
calling thread is dedicated to supporting NX server.
NOTE that multiple instances of the NX server may run at the same time,
with different callback and message queue names. ``nx_run()`` is simply
a macro that can be used when only one server instance is required. In
that case, a default server name is used.
:param mqname: The name for the server incoming message queue
:param dev: Framebuffer or LCD driver "object" to be used
:return: This function usually does not return. If it does
return, it will return ``ERROR`` and ``errno`` will be set
appropriately.
.. c:macro:: nx_connect(cb)
.. code-block:: c
#define nx_connect(cb) nx_connectinstance(NX_DEFAULT_SERVER_MQNAME)
.. c:function:: NXHANDLE nx_connectinstance(FAR const char *svrmqname);
Open a connection from a client to the NX server. One
one client connection is normally needed per thread as each connection
can host multiple windows.
NOTES:
- This function returns before the connection is fully instantiated. it
is necessary to wait for the connection event before using the
returned handle.
- Multiple instances of the NX server may run at the same time, each
with different message queue names.
- ``nx_connect()`` is simply a macro that can be used when only one
server instance is required. In that case, a default server name is
used.
:param svrmqname: The name for the server incoming message queue
:return: Success: A non-NULL handle used with subsequent NX accesses
Failure: NULL is returned and errno is set appropriately.
.. c:function:: void nx_disconnect(NXHANDLE handle)
Disconnect a client from the NX server and/or free
resources reserved by :c:func:`nx_connect`/c:func:`nx_connectinstance`.
:param handle: The handle returned by :c:func:`nx_connectinstance`.
.. c:function:: int nx_eventhandler(NXHANDLE handle);
The client code must call this function periodically to
process incoming messages from the server. If ``CONFIG_NX_BLOCKING`` is
defined, then this function not return until a server message is
received.
When ``CONFIG_NX_BLOCKING`` is not defined, the client must exercise
caution in the looping to assure that it does not eat up all of the CPU
bandwidth calling nx_eventhandler repeatedly.
```nx_eventnotify()`` <#nxeventnotify>`__ may be called to get a signal
event whenever a new incoming server event is available.
:param handle: The handle returned by ```nx_connect()`` <#nxconnectinstance>`__.
:return:
- ``OK``: No errors occurred. If ``CONFIG_NX_BLOCKING`` is defined,
then one or more server messages were processed.
- ``ERROR``: An error occurred and ``errno`` has been set
appropriately. Of particular interest, it will return
``errno == EHOSTDOWN`` when the server is disconnected. After that
event, the handle can no longer be used.
.. c:function:: int nx_eventnotify(NXHANDLE handle, int signo);
Rather than calling :c:func:`nx_eventhandler` periodically, the client may
register to receive a signal when a server event is available. The
client can then call :c:func:nx_eventhandler` only
when incoming events are available.
The underlying implementation used ``mq_notifiy()`` and, as a result,
the client must observe the rules for using ``mq_notifiy()``:
- Only one event is signalled. Upon receipt of the signal, if the
client wishes further notifications, it must call
``nx_eventnotify()`` again.
- The signal will only be issued when the message queue transitions
from empty to not empty.
:param handle: The handle returned by ```nx_connect()`` <#nxconnectinstance>`__.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_block(NXWINDOW hwnd, FAR void *arg);
The response to this function call is two things: (1)
any queued callback messages to the window are 'blocked' and then (2)
also subsequent window messaging is blocked.
The ``event`` callback with the ``NXEVENT_BLOCKED`` event is the
response from ``nx_block()``. This blocking interface is used to assure
that no further messages are are directed to the window. Receipt of the
``NXEVENT_BLOCKED`` event signifies that (1) there are no further
pending callbacks and (2) that the window is now *defunct* and will
receive no further callbacks.
This callback supports coordinated destruction of a window. The client
window logic must stay intact until all of the queued callbacks are
processed. Then the window may be safely closed. Closing the window
prior with pending callbacks can lead to bad behavior when the callback
is executed.
:param wnd: The window to be blocked
:param arg: An argument that will accompany the block messages (This is ``arg2`` in
the event callback).
:return: OK on success; ERROR on failure with errno set
appropriately.
.. c:function:: int nx_synch(NXWINDOW hwnd, FAR void *arg);
This interface can be used to synchronize the window
client with the NX server. It really just implements an *echo*: A synch
message is sent from the window client to the server which then responds
immediately by sending the ``NXEVENT_SYNCHED`` back to the windows
client.
Due to the highly asynchronous nature of client-server communications,
``nx_synch()`` is sometimes necessary to assure that the client and
server are fully synchronized in time.
Usage by the window client might be something like this:
.. code-block:: c
extern bool g_synched;
extern sem_t g_synch_sem;
g_synched = false;
ret = nx_synch(hwnd, handle);
if (ret < 0)
{
-- Handle the error --
}
while (!g_synched)
{
ret = sem_wait(&g_sync_sem);
if (ret < 0)
{
-- Handle the error --
}
}
When the window listener thread receives the ``NXEVENT_SYNCHED`` event,
it would set ``g_synched`` to ``true`` and post ``g_synch_sem``, waking
up the above loop.
:param wnd: The window to be synched
:param arg: An argument that will accompany the synch messages (This is ``arg2`` in the event callback).
:return: OK on success; ERROR on failure with errno set
appropriately
.. c:function:: NXWINDOW nx_openwindow(NXHANDLE handle, uint8_t flags, \
FAR const struct nx_callback_s *cb, \
FAR void *arg);
Create a new window.
:param handle: The handle returned by ```nx_connect()`` <#nxconnectinstance>`__.
:param flags: Optional flags. These include:
- ``NXBE_WINDOW_RAMBACKED``: Creates a RAM backed window. This option is only valid if ``CONFIG_NX_RAMBACKED`` is enabled.
- ``NXBE_WINDOW_HIDDEN``: The window is create in the HIDDEN state and can be made visible later with ``nx_setvisibility()``.
:param cb: Callbacks used to process window events
:param arg: User provided value that will be returned with NX callbacks.
:return: Success: A non-NULL handle used with subsequent NX accesses
Failure: NULL is returned and errno is set appropriately.
.. c:function:: int nx_closewindow(NXWINDOW hwnd)
Destroy a window created by :c:func:`nx_openwindow` window.
:param hwnd: The handle returned by ```nx_openwindow()`` <#nxopenwindow>`__ that
identifies the window to be destroyed. This handle must not have been
one returned by ```nx_requestbkgd()`` <#nxrequestbkgd>`__.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_requestbkgd(NXHANDLE handle, \
FAR const struct nx_callback_s *cb, \
FAR void *arg);
NX normally controls a separate window called the
background window. It repaints the window as necessary using only a
solid color fill. The background window always represents the entire
screen and is always below other windows. It is useful for an
application to control the background window in the following
conditions:
- If you want to implement a windowless solution. The single screen can
be used to create a truly simple graphic environment.
- When you want more on the background than a solid color. For example,
if you want an image in the background, or animations in the
background, or live video, etc.
This API only requests the handle of the background window. That handle
will be returned asynchronously in a subsequent position and redraw
callbacks.
Cautions:
- The following should never be called using the background window.
They are guaranteed to cause severe crashes: :c:func:`nx_setposition`,
:c:func:`nx_setsize`, :c:func:`nx_raise`, or :c:func:`nx_lower`,
:c:func:`nx_modal`, :c:func:`nx_setvisibility`.
- Neither :c:func:`nx_requestbkgd` nor :c:func:`nx_releasebkgd`
should be called more than once. Multiple instances of the
background window are not supported.
:param handle: The handle returned by ```nx_connect()`` <#nxconnectinstance>`__.
:param cb: Callbacks to use for processing background window events
:param arg: User provided argument (see ```nx_openwindow()`` <#nxopenwindow>`__)
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_releasebkgd(NXWINDOW hwnd)
Release the background window previously acquired using
:c:func:`nx_requestbkgd` and return control of the background to NX.
:param handle: The handle returned indirectly by :c:func:`nx_requestbkgd`.
This handle must not have been one created by :c:func:`nx_openwindow`.
:return: ``OK`` on success; ``ERROR`` on failure with ``errno`` set appropriately
.. c:function:: int nx_getposition(NXWINDOW hwnd)
Request the position and size information for the
selected window. The values will be return asynchronously through the
client callback function pointer.
:param hwnd: The handle returned by :c:func:`nx_openwindow` or
:c:func:`nx_requestbkgd`.
:return: ``OK`` on success; ``ERROR`` on failure with ``errno`` set appropriately
.. c:function:: int nx_setposition(NXWINDOW hwnd, FAR struct nxgl_point_s *pos)
Set the position and size for the selected window.
:param hwnd: The handle returned by :c:func:`nx_openwindow`. This
handle must not have been created by :c:func:`nx_requestbkgd`.
:param pos: The new position of the window
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_setsize(NXWINDOW hwnd, FAR struct nxgl_size_s *size)
Set the size of the selected window.
:param hwnd: The handle returned by :c:func:`nx_openwindow`. This
handle must not have been created by :c:func:`nx_requestbkgd`.
:param size: The new size of the window (in pixels).
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_raise(NXWINDOW hwnd)
Bring the specified window to the top of the display.
:param hwnd: The handle returned by :c:func:`nx_openwindow`. This
handle must not have been created by :c:func:`nx_requestbkgd`.
:return: ``OK`` on success; ``ERROR`` on failure with ``errno`` set appropriately
.. c:function:: int nx_lower(NXWINDOW hwnd);
Lower the specified window to the bottom of the display.
:param hwnd: The handle returned by :c:func:`nx_openwindow`. This
handle must not have been created by :c:func:`nx_requestbkgd`.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_modal(NXWINDOW hwnd, bool modal)
May be used to either (1) raise a window to the top of
the display and select modal behavior, or (2) disable modal behavior.
:param hwnd: The handle returned by :c:func:`nx_openwindow`. This
handle must not have been created by :c:func:`nx_requestbkgd`.
:param modal: True: enter modal state; False: leave modal state
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_setvisibility(NXWINDOW hwnd, bool hide);
Select if the window is visible or hidden. A hidden
window is still present and will update normally, but will not be
visible on the display until it is unhidden.
:param hwnd: The handle returned by :c:func:`nx_openwindow`. This
handle must not have been created by :c:func:`nx_requestbkgd`.
:param hide: True: Window will be hidden; false: Window will be visible
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: bool nx_ishidden(NXWINDOW hwnd);
Return true if the window is hidden.
**NOTE**: There will be a delay between the time that the visibility of
the window is changed via :c:func:`nx_setvisibily`
before that new setting is reported by :c:func:`nx_ishidden`. ``nx_synch()``
may be used if temporal synchronization is required.
:param hwnd: The handle returned by :c:func:`nx_openwindow` that
identifies the window to be queried.
:return: *True*: the window is hidden, *false*: the window is
visible
.. c:function:: int nx_fill(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, \
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Fill the specified rectangle in the window with the
specified color.
:param hwnd: The handle returned by ```nx_openwindow()`` <#nxopenwindow>`__ or
```nx_requestbkgd()`` <#nxrequestbkgd>`__
:param rect: The location to be filled
:param color: The color to use in the fill
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: void nx_getrectangle(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, \
unsigned int plane, FAR uint8_t *dest, \
unsigned int deststride);
Get the raw contents of graphic memory within a
rectangular region. NOTE: Since raw graphic memory is returned, the
returned memory content may be the memory of windows above this one and
may not necessarily belong to this window unless you assure that this is
the top window.
:param hwnd: The handle returned by :c:func:`nx_openwindow` or
:c:func:`nx_requestbkgd`
:param rect: The location to be copied
:param plane: Specifies the color plane to get from
:param dest: The location to copy the memory region
:param deststride: The width, in bytes, of the dest memory
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_filltrapezoid(NXWINDOW hwnd, FAR const struct nxgl_rect_s *clip, \
FAR const struct nxgl_trapezoid_s *trap, \
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Fill the specified trapezoidal region in the window
with the specified color.
:param hwnd: The handle returned by :c:func:`nx_openwindow` or
:c:func:`nx_requestbkgd`
:param clip: Clipping rectangle relative to window (may be null)
:param trap: The trapezoidal region to be filled
:param color: The color to use in the fill
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_drawline(NXWINDOW hwnd, FAR struct nxgl_vector_s *vector, \
nxgl_coord_t width, nxgl_mxpixel_t color[CONFIG_NX_NPLANES], \
uint8_t caps);
Fill the specified trapezoidal region in the window
with the specified color. Fill the specified line in the window with the
specified color. This is simply a wrapper that uses :c:func:`nxgl_splitline`
to break the line into trapezoids and then calls :c:func:`nx_filltrapezoid`
to render the line.
:param hwnd: The handle returned by :c:func:`nx_openwindow` or
:c:func:`nx_requestbkgd`
:param vector: Describes the line to be drawn.
:param width: The width of the line
:param color: The color to use to fill the line
:param caps: Draw a circular cap on the ends of the line to support better line
joins. One of::
/* Line caps */
#define NX_LINECAP_NONE 0x00, /* No line caps */
#define NX_LINECAP_PT1 0x01 /* Line cap on pt1 on of the vector only */
#define NX_LINECAP_PT2 0x02 /* Line cap on pt2 on of the vector only */
#define NX_LINECAP_BOTH 0x03 /* Line cap on both ends of the vector only */
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_drawcircle(NXWINDOW hwnd, FAR const struct nxgl_point_s *center, \
nxgl_coord_t radius, nxgl_coord_t width, \
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Draw a circular outline using the specified line
thickness and color.
:param hwnd: The handle returned by :c:func:`nx_openwindow` or
:c:func:`nx_requestbkgd`
:param center: A pointer to the point that is the center of the circle.
:param radius: The radius of the circle in pixels.
:param width: The width of the line
:param color: The color to use to fill the line
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_fillcircle(NXWINDOW hwnd, FAR const struct nxgl_point_s *center, \
nxgl_coord_t radius, nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Fill a circular region using the specified color.
:param hwnd: The handle returned by :c:func:`nx_openwindow` or
:c:func:`nx_requestbkgd`
:param center: A pointer to the point that is the center of the circle.
:param radius: The width of the line
:param color: The color to use to fill the circle
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_setbgcolor(NXHANDLE handle, \
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Set the color of the background.
:param handle: The handle created by :c:func:`nx_openwindow` or
:c:func:`nx_requestbkgd`
:param color: The color to use in the background
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_move(NXWINDOW hwnd, FAR const struct nxgl_rect_s *rect, \
FAR const struct nxgl_point_s *offset);
Move a rectangular region within the window.
:param hwnd: The handle returned by :c:func:`nx_openwindow` or
:c:func:`nx_requestbkgd` that specifies the window within which the move is to be done
:param rect: Describes the (source) rectangular region to move
:param offset: The offset to move the region
:return: ``OK`` on success; ``ERROR`` on failure with ``errno`` set appropriately
.. c:function:: int nx_bitmap(NXWINDOW hwnd, FAR const struct nxgl_rect_s *dest, \
FAR const void *src[CONFIG_NX_NPLANES], \
FAR const struct nxgl_point_s *origin, \
unsigned int stride);
Copy a rectangular region of a larger image into the
rectangle in the specified window.
:param hwnd: The handle returned by :c:func:`nx_openwindow` or
:c:func:`nx_requestbkgd` that specifies the window that will receive the bitmap image.
:param dest: Describes the rectangular on the display that will receive the bit map.
:param src: The start of the source image. This is an array source images of size ``CONFIG_NX_NPLANES`` (probably 1).
:param origin: The origin of the upper, left-most corner of the full bitmap. Both
dest and origin are in window coordinates, however, the origin may
lie outside of the display.
:param stride: The width of the full source image in bytes.
:return: ``OK`` on success; ``ERROR`` on failure with ``errno`` set appropriately
.. c:function:: int nx_kbdchin(NXHANDLE handle, uint8_t ch);
.. c:function:: int nx_kbdin(NXHANDLE handle, uint8_t nch, FAR const uint8_t *ch);
Used by a thread or interrupt handler that manages some
kind of keypad hardware to report text information to the NX server.
That text data will be routed by the NX server to the appropriate window
client.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nx_mousein(NXHANDLE handle, nxgl_coord_t x, nxgl_coord_t y, uint8_t buttons)
Used by a thread or interrupt handler that manages some
kind of pointing hardware to report new positional data to the NX
server. That positional data will be routed by the NX server to the
appropriate window client.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. _nx-tool-kit-nxtk-1:
@@ -0,0 +1,50 @@
================================
NX Cursor Support (``NXCURSOR``)
================================
.. c:function:: int nxcursor_enable(NXHANDLE hnd, bool enable)
Enable/disable presentation of the cursor. The disabled
cursor still exits and still may be controlled, but is not visible on
the display.
:param hnd:
The server handle returned by :c:func:`nx_connect`.
:param enable: The new cursor position
:return: OK on success; ERROR on failure with errno set appropriately.
.. c:function:: int nxcursor_setimage(NXHANDLE hnd, FAR const struct nx_cursorimage_s *image)
Set the cursor image.
The image is provided a a 2-bits-per-pixel image. The two bit incoding
is as following:
- 00: The transparent background.
- 01: Color1: The main color of the cursor.
- 10: Color2: The color of any border.
- 11: Color3: A blend color for better imaging (fake anti-aliasing).
**NOTE:** The NX logic will reference the user image buffer repeatedly.
That image buffer must persist for as long as the NX server connection
persists.
:param hnd: The server handle returned by :c:func:`nx_connect`
:param image:
An instance of ``struct struct nx_cursorimage_s`` that describes the
cursor image. See ``<nuttx/nx/nxcursor.h>`` for the full description
of this structure.
:return: OK on success; ERROR on failure with errno set appropriately.
.. c:function:: int nxcursor_setposition(NXHANDLE hnd, FAR const struct nxgl_point_s *pos)
Move the cursor to the specified position.
:param hnd: The server handle returned by :c:func:`nx_connect`
:param pos: The new cursor position
:return: OK on success; ERROR on failure with errno set appropriately.
@@ -0,0 +1,127 @@
==============================
NX Fonts Support (``NXFONTS``)
==============================
NXFONTS types
=============
.. c:struct:: nx_fontmetric_s
This structures provides the metrics for one glyph:
.. code-block:: c
struct nx_fontmetric_s
{
uint32_t stride : 2; /* Width of one font row in bytes */
uint32_t width : 6; /* Width of the font in bits */
uint32_t height : 6; /* Height of the font in rows */
uint32_t xoffset : 6; /* Top, left-hand corner X-offset in pixels */
uint32_t yoffset : 6; /* Top, left-hand corner y-offset in pixels */
uint32_t unused : 6;
};
.. c:struct:: nx_fontbitmap_s
This structure binds the glyph metrics to the glyph bitmap:
.. code-block:: c
struct nx_fontbitmap_s
{
struct nx_fontmetric_s metric; /* Character metrics */
FAR const uint8_t *bitmap; /* Pointer to the character bitmap */
};
.. c:struct:: nx_fontset_s
This structure describes one contiguous grouping of glyphs that can be
described by an array starting with encoding ``first`` and extending
through (``first`` + ``nchars`` - 1).
.. code-block:: c
struct nx_fontset_s
{
uint8_t first; /* First bitmap character code */
uint8_t nchars; /* Number of bitmap character codes */
FAR const struct nx_fontbitmap_s *bitmap;
};
.. c:struct:: nx_font_s
This structure describes the overall fontset.
.. code-block:: c
struct nx_font_s
{
uint8_t mxheight; /* Max height of one glyph in rows */
uint8_t mxwidth; /* Max width of any glyph in pixels */
uint8_t mxbits; /* Max number of bits per character code */
uint8_t spwidth; /* The width of a space in pixels */
};
.. c:function:: NXHANDLE nxf_getfonthandle(enum nx_fontid_e fontid);
Given a numeric font ID, return a handle that may be
subsequently be used to access the font data sets.
:param fontid: Identifies the font set to use
:return: A handle that may be subsequently be used to access the font data sets.
.. c:function:: FAR const struct nx_font_s *nxf_getfontset(NXHANDLE handle);
Return information about the current font set.
:param handle: A font handle previously returned by :c:func:`nxf_getfonthandle`.
:return: An instance of ``struct nx_font_s`` describing the font set.
.. c:function:: FAR const struct nx_fontbitmap_s *nxf_getbitmap(NXHANDLE handle, uint16_t ch)
Return font bitmap information for the selected
character encoding.
:param ch: The char code for the requested bitmap.
:param handle: A font handle previously returned by :c:func:`nxf_getfonthandle`.
:return: An instance of :c:struct:`nx_fontbitmap_s` describing the glyph.
.. c:function:: int nxf_convert_2bpp(FAR uint8_t *dest, uint16_t height, \
uint16_t width, uint16_t stride, \
FAR const struct nx_fontbitmap_s *bm, \
nxgl_mxpixel_t color);
.. c:function:: int nxf_convert_4bpp(FAR uint8_t *dest, uint16_t height, \
uint16_t width, uint16_t stride, \
FAR const struct nx_fontbitmap_s *bm, \
nxgl_mxpixel_t color);
.. c:function:: int nxf_convert_8bpp(FAR uint8_t *dest, uint16_t height, \
uint16_t width, uint16_t stride, \
FAR const struct nx_fontbitmap_s *bm, \
nxgl_mxpixel_t color);
.. c:function:: int nxf_convert_16bpp(FAR uint16_t *dest, uint16_t height, \
uint16_t width, uint16_t stride, \
FAR const struct nx_fontbitmap_s *bm, \
nxgl_mxpixel_t color);
.. c:function:: int nxf_convert_24bpp(FAR uint32_t *dest, uint16_t height, \
uint16_t width, uint16_t stride, \
FAR const struct nx_fontbitmap_s *bm, \
nxgl_mxpixel_t color);
.. c:function:: int nxf_convert_32bpp(FAR uint32_t *dest, uint16_t height, \
uint16_t width, uint16_t stride, \
FAR const struct nx_fontbitmap_s *bm, \
nxgl_mxpixel_t color);
Convert the 1BPP font to a new pixel depth.
:param dest: The destination buffer provided by the caller.
:param height: The max height of the returned char in rows.
:param width: The max width of the returned char in pixels.
:param stride: The width of the destination buffer in bytes.
:param bm: Describes the character glyph to convert
:param color: The color to use for '1' bits in the font bitmap (0 bits are transparent).
:return: ``OK`` on success; ``ERROR`` on failure with ``errno`` set appropriately.
@@ -0,0 +1,259 @@
.. _nx-graphics-library-nxgl-1:
==============================
NX Graphics Library (``NXGL``)
==============================
NXGL provides many APIs, some available for use internally by NX and
others for use by applications as well. Only those APIs intended for
application usage are documented here See ``include/nuttx/nx/nxglib.h``
for the full set of APIs; those APIs might be of interest if you are
rendering directly into framebuffer or LCD memory.
NXGL Types
----------
.. c:type:: nxgl_mxpixel_t
Holds one device pixel. NXGLIB will select the
smallest size for the ``nxgl_mxpixel_t`` that just contains the pixel:
``byte`` if 16, 24, and 32 resolution support is disabled, ``uint16_t``
if 24, and 32 resolution support is disabled, or ``uint32_t``.
.. c:type:: nxgl_coord_t
A given coordinate is limited to the screen height an
width. If either of those values exceed 32,767 pixels, then the
following will have to need to change:
.. c:struct:: nxgl_point_s
Describes a point on the display:
.. code-block:: c
struct nxgl_point_s
{
nxgl_coord_t x; /* X position, range: 0 to screen width - 1 */
nxgl_coord_t y; /* Y position, range: 0 to screen height - 1 */
};
.. c:struct:: nxgl_size_s
Describes the size of a rectangular region.
.. code-block:: c
struct nxgl_size_s
{
nxgl_coord_t w; /* Width in pixels */
nxgl_coord_t h; /* Height in rows */
};
.. c:struct:: nxgl_rect_s
Describes a positioned rectangle on the display.
.. code-block:: c
struct nxgl_rect_s
{
struct nxgl_point_s pt1; /* Upper, left-hand corner */
struct nxgl_point_s pt2; /* Lower, right-hand corner */
};
.. c:struct:: nxgl_run_s
Describes a run, i.e., a horizontal line. Note
that the start/end positions have fractional precision. This is
necessary for good joining of trapezoids when a more complex shape is
decomposed into trapezoids.
.. code-block:: c
struct nxgl_run_s
{
b16_t x1; /* Left X position, range: 0 to x2 */
b16_t x2; /* Right X position, range: x1 to screen width - 1 */
nxgl_coord_t y; /* Top Y position, range: 0 to screen height - 1 */
};
.. c:struct:: nxgl_trapezoid_s
Describes a horizontal trapezoid on the
display in terms the run at the top of the trapezoid and the run at the
bottom.
.. code-block:: c
struct nxgl_trapezoid_s
{
struct nxgl_run_s top; /* Top run */
struct nxgl_run_s bot; /* bottom run */
};
.. c:function:: void nxgl_rgb2yuv(uint8_t r, uint8_t g, uint8_t b, uint8_t *y, uint8_t *u, uint8_t *v)
Convert 8-bit RGB triplet to 8-bit YUV triplet.
.. c:function:: void nxgl_yuv2rgb(uint8_t y, uint8_t u, uint8_t v, uint8_t *r, uint8_t *g, uint8_t *b);
Convert 8-bit YUV triplet to 8-bit RGB triplet.
.. c:function:: void nxgl_rectcopy(FAR struct nxgl_rect_s *dest, FAR const struct nxgl_rect_s *src)
This is essentially ``memcpy()``\ for rectangles. We
don't do structure assignments because some compilers are not good at
that.
.. c:function:: void nxgl_rectoffset(FAR struct nxgl_rect_s *dest, \
FAR const struct nxgl_rect_s *src, \
nxgl_coord_t dx, nxgl_coord_t dy);
Offset the rectangle position by the specified dx, dy
values.
.. c:function:: void nxgl_vectoradd(FAR struct nxgl_point_s *dest, \
FAR const struct nxgl_point_s *v1, \
FAR const struct nxgl_point_s *v2);
Add two 2x1 vectors and save the result to a third.
.. c:function:: void nxgl_vectsubtract(FAR struct nxgl_point_s *dest, \
FAR const struct nxgl_point_s *v1, \
FAR const struct nxgl_point_s *v2);
Add subtract vector ``v2`` from vector ``v1`` and
return the result in vector dest.
.. c:function:: void nxgl_rectintersect(FAR struct nxgl_rect_s *dest, \
FAR const struct nxgl_rect_s *src1, \
FAR const struct nxgl_rect_s *src2);
Return the rectangle representing the intersection of
the two rectangles.
.. c:function:: void nxgl_rectunion(FAR struct nxgl_rect_s *dest, \
FAR const struct nxgl_rect_s *src1, \
FAR const struct nxgl_rect_s *src2);
Given two rectangles, ``src1`` and ``src2``, return the
larger rectangle that contains both, ``dest``.
.. c:function:: void nxgl_nonintersecting(FAR struct nxgl_rect_s result[4], \
FAR const struct nxgl_rect_s *rect1, \
FAR const struct nxgl_rect_s *rect2);
Return the regions of rectangle ``rect1`` that do not
intersect with ``rect2``. This will four rectangles, some of which may
be degenerate (and can be picked off with :c:func:`nxgl_nullrect`).
.. c:function:: bool nxgl_rectoverlap(FAR struct nxgl_rect_s *rect1, \
FAR struct nxgl_rect_s *rect2);
Return true if the two rectangles overlap.
.. c:function:: bool nxgl_rectinside(FAR const struct nxgl_rect_s *rect, \
FAR const struct nxgl_point_s *pt);
Return true if the point ``pt`` lies within ``rect``.
.. c:function:: void nxgl_rectsize(FAR struct nxgl_size_s *size, \
FAR const struct nxgl_rect_s *rect);
Return the size of the specified rectangle.
.. c:function:: bool nxgl_nullrect(FAR const struct nxgl_rect_s *rect);
Return true if the area of the retangle is <= 0.
.. c:function:: void nxgl_runoffset(FAR struct nxgl_run_s *dest, \
FAR const struct nxgl_run_s *src, \
nxgl_coord_t dx, nxgl_coord_t dy);
Offset the run position by the specified ``dx``, ``dy``
values.
.. c:function:: void nxgl_runcopy(FAR struct nxgl_run_s *dest, \
FAR const struct nxgl_run_s *src);
This is essentially ``memcpy()``\ for runs. We don't do
structure assignments because some compilers are not good at that.
.. c:function:: void nxgl_trapoffset(FAR struct nxgl_trapezoid_s *dest, \
FAR const struct nxgl_trapezoid_s *src, \
nxgl_coord_t dx, nxgl_coord_t dy);
Offset the trapezoid position by the specified ``dx``,
``dy`` values.
.. c:function:: void nxgl_trapcopy(FAR struct nxgl_trapezoid_s *dest, \
FAR const struct nxgl_trapezoid_s *src);
This is essentially ``memcpy()``\ for trapezoids. We
don't do structure assignments because some compilers are not good at
that.
.. c:function:: void nxgl_colorcopy(nxgl_mxpixel_t dest[CONFIG_NX_NPLANES], \
const nxgl_mxpixel_t src[CONFIG_NX_NPLANES]);
This is essentially ``memcpy()``\ for colors. This does
very little for us other than hide all of the conditional compilation
for planar colors in one place.
.. c:function:: int nxgl_splitline(FAR struct nxgl_vector_s *vector, FAR struct nxgl_trapezoid_s *traps, \
FAR struct nxgl_rect_s *rect, nxgl_coord_t linewidth);
In the general case, a line with width can be
represented as a parallelogram with a triangle at the top and bottom.
Triangles and parallelograms are both degenerate versions of a
trapezoid. This function breaks a wide line into triangles and
trapezoids. This function also detects other degenerate cases:
#. If ``y1 == y2`` then the line is horizontal and is better represented
as a rectangle.
#. If ``x1 == x2`` then the line is vertical and also better represented
as a rectangle.
#. If the width of the line is 1, then there are no triangles at the top
and bottom (this may also be the case if the width is narrow and the
line is near vertical).
#. If the line is oriented is certain angles, it may consist only of the
upper and lower triangles with no trapezoid in between. In this case,
3 trapezoids will be returned, but traps[1] will be degenerate.
:param vector: A pointer to the vector described the line to be drawn.
:param traps: A pointer to a array of trapezoids (size 3).
:param rect: A pointer to a rectangle.
:return:
- 0: Line successfully broken up into three trapezoids. Values in traps[0], traps[1], and traps[2] are valid.
- 1: Line successfully represented by one trapezoid. Value in traps[1] is valid.
- 2: Line successfully represented by one rectangle. Value in rect is valid
- <0: On errors, a negated errno value is returned.
.. c:function:: void nxgl_circlepts(FAR const struct nxgl_point_s *center, nxgl_coord_t radius, \
FAR struct nxgl_point_s *circle);
Given a description of a circle, return a set of 16
points on the circumference of the circle. These points may then be used
by :c:func:`nx_drawcircle` or related APIs to draw a
circle outline.
:param center: A pointer to the point that is the center of the circle.
:param radius: The radius of the circle in pixels.
:param circle: A pointer the first entry in an array of 16 points where the circle points will be returned.
.. c:function:: void nxgl_circletraps(FAR const struct nxgl_point_s *center, nxgl_coord_t radius, \
FAR struct nxgl_trapezoid_s *circle);
Given a description of a a circle, return 8 trapezoids
that can be used to fill the circle by
:c:func:`nx_fillcircle` and other interfaces.
:param center: A pointer to the point that is the center of the circle.
:param radius: The radius of the circle in pixels.
:param circle: A pointer the first entry in an array of 8 trapezoids where the
circle description will be returned.
@@ -0,0 +1,653 @@
======================
NX Tool Kit (``NXTK``)
======================
NXTK implements where the *framed window*. NX framed windows consist of
three components within one NX window:
#. The window *border*,
#. The main *client window* area, and
#. A *toolbar* area
Each sub-window represents a region within one window. `Figure
1 <#screenshot>`__ shows some simple NX framed windows. NXTK allows
these sub-windows to be managed more-or-less independently:
- Each component has its own callbacks for redraw and position events
as well as mouse and keyboard inputs. The client sub-window callbacks
are registered when the framed window is created with a call to
:c:func:`nxtk_openwindow`; Separate toolbar
sub-window callbacks are reigistered when the toolbar is added using
:c:func:`nxtk_opentoolbar`. (NOTES: (1) only the
client sub-window receives keyboard input and, (2) border callbacks
are not currently accessible by the user).
- All position informational provided within the callback is relative
to the specific sub-window. That is, the origin (0,0) of the
coordinate system for each sub-window begins at the top left
corner of the subwindow. This means that toolbar logic need not
be concerned about client window geometry (and vice versa) and,
for example, common toolbar logic can be used with different windows.
.. c:type:: FAR void *NXTKWINDOW
This is the handle that can be used to access the window data region.
.. c:function:: int nxtk_block(NXWINDOW hwnd, FAR void *arg)
The response to this function call is two things: (1)
any queued callback messages to the window are 'blocked' and then (2)
also subsequent window messaging is blocked.
The ``event`` callback with the ``NXEVENT_BLOCKED`` event is the
response from ``nxtk_block()``. This blocking interface is used to
assure that no further messages are are directed to the window. Receipt
of the ``NXEVENT_BLOCKED`` event signifies that (1) there are no further
pending callbacks and (2) that the window is now *defunct* and will
receive no further callbacks.
This callback supports coordinated destruction of a window. The client
window logic must stay intact until all of the queued callbacks are
processed. Then the window may be safely closed. Closing the window
prior with pending callbacks can lead to bad behavior when the callback
is executed.
:param wnd: The window to be blocked
:param arg: An argument that will accompany the block messages (This is ``arg2`` in
the event callback).
:return: OK on success; ERROR on failure with errno set
appropriately.
.. c:function:: int nxtk_synch(NXWINDOW hwnd, FAR void *arg);
This interface can be used to synchronize the window
client with the NX server. It really just implements an *echo*: A synch
message is sent from the window client to the server which then responds
immediately by sending the ``NXEVENT_SYNCHED`` back to the windows
client.
Due to the highly asynchronous nature of client-server communications,
``nx_synch()`` is sometimes necessary to assure that the client and
server are fully synchronized in time.
Usage by the window client might be something like this:
.. code-block:: c
extern bool g_synched;
extern sem_t g_synch_sem;
g_synched = false;
ret = nxtk_synch(hfwnd, handle);
if (ret < 0)
{
-- Handle the error --
}
while (!g_synched)
{
ret = sem_wait(&g_sync_sem);
if (ret < 0)
{
-- Handle the error --
}
}
When the window listener thread receives the ``NXEVENT_SYNCHED`` event,
it would set ``g_synched`` to ``true`` and post ``g_synch_sem``, waking
up the above loop.
:param wnd:
The window to be synched
:param arg:
An argument that will accompany the synch messages (This is ``arg2``
in the event callback).
:return: OK on success; ERROR on failure with errno set
appropriately
.. c:function:: NXTKWINDOW nxtk_openwindow(NXHANDLE handle, uint8_t flags, \
FAR const struct nx_callback_s *cb, \
FAR void *arg);
Create a new, framed window.
:param handle:
The handle returned by ```nx_connect()`` <#nxconnectinstance>`__.
:param flags:
Optional flags. These include:
- ``NXBE_WINDOW_RAMBACKED``: Creates a RAM backed window. This
option is only valid if ``CONFIG_NX_RAMBACKED`` is enabled.
- ``NXBE_WINDOW_HIDDEN``: The window is create in the HIDDEN state
and can be made visible later with ``nxtk_setvisibility()``.
:param cb:
Callbacks used to process window events
:param arg:
User provided argument (see ```nx_openwindow()`` <#nxopenwindow>`__)
:return: Success: A non-NULL handle used with subsequent NXTK window accesses
Failure: NULL is returned and errno is set appropriately.
.. c:function:: int nxtk_closewindow(NXTKWINDOW hfwnd);
Close the window opened by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_getposition(NXTKWINDOW hfwnd);
Request the position and size information for the
selected framed window. The size/position for the client window and
toolbar will be return asynchronously through the client callback
function pointer.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_setposition(NXTKWINDOW hfwnd, FAR struct nxgl_point_s *pos);
Set the position for the selected client window. This
position does not include the offsets for the borders nor for any
toolbar. Those offsets will be added in to set the full window position.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param pos:
The new position of the client sub-window
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_setsize(NXTKWINDOW hfwnd, FAR struct nxgl_size_s *size);
Set the size for the selected client window. This size
does not include the sizes of the borders nor for any toolbar. Those
sizes will be added in to set the full window size.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param size:
The new size of the client sub-window.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_raise(NXTKWINDOW hfwnd);
Bring the window containing the specified client
sub-window to the top of the display.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__ specifying the window to
be raised.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_lower(NXTKWINDOW hfwnd);
Lower the window containing the specified client
sub-window to the bottom of the display.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__ specifying the window to
be lowered.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_modal(NXWINDOW hwnd, bool modal);
May be used to either (1) raise a window to the top of
the display and select modal behavior, or (2) disable modal behavior.
:param hwnd:
The handle returned by ```nxtk_openwindow()`` <#nxtkopenwindow>`__
specifying the window to be modified.
:param modal:
True: enter modal state; False: leave modal state
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_setvisibility(NXWINDOW hwnd, bool hide);
Select if the window is visible or hidden. A hidden
window is still present and will update normally, but will not be
visible on the display until it is unhidden.
:param hwnd:
The handle returned by ```nxtk_openwindow()`` <#nxtkopenwindow>`__
specifying the window to be modified.
:param hide:
True: Window will be hidden; false: Window will be visible
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: bool nxtk_ishidden(NXTKWINDOW hfwnd);
Return true if the window is hidden.
**NOTE**: There will be a delay between the time that the visibility of
the window is changed via
```nxtk_setvisibily()`` <#nxtksetvisibility>`__ before that new setting
is reported by ``nxtk_ishidden()``. ``nxtk_synch()`` may be used if
temporal synchronization is required.
:param hfwnd:
The handle returned by ```nxtk_openwindow()`` <#nxtkopenwindow>`__
that identifies the window to be queried.
:return: *True*: the window is hidden, *false*: the window is
visible
.. c:function:: int nxtk_fillwindow(NXTKWINDOW hfwnd, FAR const struct nxgl_rect_s *rect, \
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Fill the specified rectangle in the client window with
the specified color.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param rect:
The location within the client window to be filled
:param color:
The color to use in the fill
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: void nxtk_getwindow(NXTKWINDOW hfwnd, FAR const struct nxgl_rect_s *rect, \
unsigned int plane, FAR uint8_t *dest, \
unsigned int deststride);
Get the raw contents of graphic memory within a
rectangular region. NOTE: Since raw graphic memory is returned, the
returned memory content may be the memory of windows above this one and
may not necessarily belong to this window unless you assure that this is
the top window.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param rect:
The location within the client window to be retrieved.
:param plane:
Specifies the color plane to get from.
:param dest:
The location to copy the memory region
:param deststride:
The width, in bytes, of the dest memory
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_filltrapwindow(NXTKWINDOW hfwnd, \
FAR const struct nxgl_trapezoid_s *trap, \
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Fill the specified trapezoid in the client window with
the specified color
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param trap:
The trapezoidal region to be filled.
:param color:
The color to use in the fill.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_drawlinewindow(NXTKWINDOW hfwnd, FAR struct nxgl_vector_s *vector, \
nxgl_coord_t width, nxgl_mxpixel_t color[CONFIG_NX_NPLANES], \
uint8_t caps);
Fill the specified trapezoidal region in the window
with the specified color. Fill the specified line in the window with the
specified color. This is simply a wrapper that uses ``nxgl_splitline()``
to break the line into trapezoids and then calls
``nxtk_filltrapwindow()`` to render the line.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param vector:
Describes the line to be drawn.
:param width:
The width of the line
:param color:
The color to use to fill the line
:param caps:
Draw a circular cap on the ends of the line to support better line
joins. One of:
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_drawcirclewindow(NXTKWINDOW hfwnd, FAR const struct nxgl_point_s *center, \
nxgl_coord_t radius, nxgl_coord_t width, \
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Draw a circular outline using the specified line
thickness and color.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param center:
A pointer to the point that is the center of the circle.
:param radius:
The radius of the circle in pixels.
:param width:
The width of the line
:param color:
The color to use to fill the line
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_fillcirclewindow(NXWINDOW hfwnd, FAR const struct nxgl_point_s *center, \
nxgl_coord_t radius, nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Fill a circular region using the specified color.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param center:
A pointer to the point that is the center of the circle.
:param radius:
The width of the line
:param color:
The color to use to fill the circle
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_movewindow(NXTKWINDOW hfwnd, FAR const struct nxgl_rect_s *rect, \
FAR const struct nxgl_point_s *offset);
Move a rectangular region within the client sub-window
of a framed window.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__ specifying the client
sub-window within which the move is to be done.
:param rect:
Describes the rectangular region relative to the client sub-window to
move.
:param offset:
The offset to move the region
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_bitmapwindow(NXTKWINDOW hfwnd, \
FAR const struct nxgl_rect_s *dest, \
FAR const void *src[CONFIG_NX_NPLANES], \
FAR const struct nxgl_point_s *origin, \
unsigned int stride);
Copy a rectangular region of a larger image into the
rectangle in the specified client sub-window.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__ specifying the client
sub-window that will receive the bitmap.
:param dest:
Describes the rectangular region on in the client sub-window will
receive the bit map.
:param src:
The start of the source image(s). This is an array source images of
size ``CONFIG_NX_NPLANES`` (probably 1).
:param origin:
The origin of the upper, left-most corner of the full bitmap. Both
dest and origin are in sub-window coordinates, however, the origin
may lie outside of the sub-window display.
:param stride:
The width of the full source image in pixels.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_opentoolbar(NXTKWINDOW hfwnd, nxgl_coord_t height, \
FAR const struct nx_callback_s *cb, \
FAR void *arg);
Create a tool bar at the top of the specified framed
window.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param height:
The requested height of the toolbar in pixels.
:param cb:
Callbacks used to process toolbar events.
:param arg:
User provided value that will be returned with toolbar callbacks.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_closetoolbar(NXTKWINDOW hfwnd);
Remove the tool bar at the top of the specified framed
window.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_filltoolbar(NXTKWINDOW hfwnd, FAR const struct nxgl_rect_s *rect, \
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Fill the specified rectangle in the toolbar sub-window
with the specified color.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param rect:
The location within the toolbar window to be filled.
:param color:
The color to use in the fill.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_gettoolbar(NXTKWINDOW hfwnd, FAR const struct nxgl_rect_s *rect, \
unsigned int plane, FAR uint8_t *dest, \
unsigned int deststride);
Get the raw contents of graphic memory within a
rectangular region. NOTE: Since raw graphic memory is returned, the
returned memory content may be the memory of windows above this one and
may not necessarily belong to this window unless you assure that this is
the top window.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param rect:
The location within the toolbar window to be retrieved.
:param plane:
TSpecifies the color plane to get from.
:param dest:
TThe location to copy the memory region.
:param deststride:
The width, in bytes, of the dest memory.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_filltraptoolbar(NXTKWINDOW hfwnd, FAR const struct nxgl_trapezoid_s *trap, \
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Fill the specified trapezoid in the toolbar sub-window
with the specified color.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param trap:
The trapezoidal region to be filled
:param color:
The color to use in the fill
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_drawlinetoolbar(NXTKWINDOW hfwnd, FAR struct nxgl_vector_s *vector, \
nxgl_coord_t width, nxgl_mxpixel_t color[CONFIG_NX_NPLANES], \
uint8_t caps);
Fill the specified line in the toolbar sub-window with
the specified color. This is simply a wrapper that uses
``nxgl_splitline()`` to break the line into trapezoids and then calls
``nxtk_filltraptoolbar()`` to render the line.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param vector:
Describes the line to be drawn.
:param width:
The width of the line
:param color:
The color to use to fill the line
:param caps:
Draw a circular cap on the ends of the line to support better line
joins. One of:
.. code-block:: c
/* Line caps */
#define NX_LINECAP_NONE 0x00, /* No line caps */
#define NX_LINECAP_PT1 0x01 /* Line cap on pt1 on of the vector only */
#define NX_LINECAP_PT2 0x02 /* Line cap on pt2 on of the vector only */
#define NX_LINECAP_BOTH 0x03 /* Line cap on both ends of the vector only */
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_drawcircletoolbar(NXTKWINDOW hfwnd, FAR const struct nxgl_point_s *center, \
nxgl_coord_t radius, nxgl_coord_t width, \
nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Draw a circular outline using the specified line
thickness and color.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param center:
A pointer to the point that is the center of the circle.
:param radius:
The radius of the circle in pixels.
:param width:
The width of the line
:param color:
The color to use to fill the line
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_fillcircletoolbar(NXWINDOW hfwnd, FAR const struct nxgl_point_s *center, \
nxgl_coord_t radius, nxgl_mxpixel_t color[CONFIG_NX_NPLANES]);
Fill a circular region using the specified color.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param center:
A pointer to the point that is the center of the circle.
:param radius:
The width of the line
:param color:
The color to use to fill the circle
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_movetoolbar(NXTKWINDOW hfwnd, FAR const struct nxgl_rect_s *rect, \
FAR const struct nxgl_point_s *offset);
Move a rectangular region within the toolbar sub-window
of a framed window.
:param hfwnd:
A handle identifying sub-window containing the toolbar within which
the move is to be done. This handle must have previously been
returned by ```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param rect:
Describes the rectangular region relative to the toolbar sub-window
to move.
:param offset:
The offset to move the region
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. c:function:: int nxtk_bitmaptoolbar(NXTKWINDOW hfwnd, \
FAR const struct nxgl_rect_s *dest, \
FAR const void *src[CONFIG_NX_NPLANES], \
FAR const struct nxgl_point_s *origin, \
unsigned int stride);
Copy a rectangular region of a larger image into the
rectangle in the specified toolbar sub-window.
:param hfwnd:
A handle previously returned by
```nxtk_openwindow()`` <#nxtkopenwindow>`__.
:param dest:
Describes the rectangular region on in the toolbar sub-window will
receive the bit map.
:param src:
The start of the source image.
:param origin:
The origin of the upper, left-most corner of the full bitmap. Both
dest and origin are in sub-window coordinates, however, the origin
may lie outside of the sub-window display.
:param stride:
The width of the full source image in bytes.
:return: ``OK`` on success; ``ERROR`` on failure with
``errno`` set appropriately
.. _nx-fonts-support-nxfonts-1:
@@ -0,0 +1,30 @@
===========
Sample Code
===========
``apps/examples/nx*``. No sample code is provided in this document.
However, examples can be found in the NuttX source tree at the follow
locations: That example code is intended to test NX. Since it is test
code, it is designed to exercise functionality and does not necessarily
represent best NX coding practices.
- ``apps/examples/nx``. This is a test of windows, optionally with
toolbars. Two windows are created, re-sized, moved, raise lowered.
Simulated mouse and keyboard input is provided.
- ``apps/examples/nxhello``. This is intended to be simplest NX test:
It simply displays the words "Hello, World!" centered on the display.
- ``apps/examples/nxtext``. This illustrates how fonts may be managed
to provide scrolling text windows. Pop-up windows are included to
verify the clipping and re-drawing of the text display.
In its current form, the NX graphics system provides a low level of
graphics and window support. Most of the complexity of manage redrawing
and handling mouse and keyboard events must be implemented by the NX
client code.
**Building** ``apps/examples/nx``. Testing was performed using the
Linux/Cygwin-based NuttX simulator. Instructions are provided for
building that simulation are provided in `Appendix C <#testcoverage>`__
of this document.
@@ -0,0 +1,55 @@
.. _nxwidgets:
=========
NxWidgets
=========
In order to better support NuttX based platforms, a special graphical
userinterface has been created called NXWidgets. NXWidgets is written in
C++ and integrates seamlessly with the NuttX :ref:`NX graphics
subsystem <nxgraphics>` in order to provide graphic
objects, or "widgets," in the NX Graphics Subsystem
Some of the features of NXWidgets include:
- **Conservative C++**. NXWidgets is written entirely in C++ but using
only selected "embedded friendly" C++ constructs that are fully
supported under NuttX. No additional C++ support libraries are
required.
- **NX Integration**. NXWidgets integrate seamlessly with the
:ref:`NX graphics subsystem <nxgraphics>`. Think of the X
server under Linux … the NX graphics system is like a tiny X server
that provides windowing under NuttX. By adding NXWidgets, you can
support graphics objects like buttons and text boxes in the NX
windows and toolbars.
- **Small Footprint**. NXWidgets is tailored for use MCUs in embedded
applications. It is ideally suited for mid- and upper-range of most
MCU families. A complete NXWidgets is possible in as little as 40K of
FLASH and maybe 4K of SRAM.
- **Output Devices**. NXWidgets will work on the high-end frame buffer
devices as well as on LCDs connected via serial or parallel ports to
a small MCU.
- **Input Devices**. NXWidgets will accept position and selection
inputs from a mouse or a touchscreen. It will also support character
input from a keyboard such as a USB keyboard. NXWidgets supports on
very special widget called CKeypad that will provide keyboard input
via an on-screen keypad that can be operated via mouse or touchscreen
inputs.
- **Many Graphic Objects**. Some of the graphic objects supported by
NXWidgets include labels, buttons, text boxes, button arrays, check
boxes, cycle buttons, images, sliders, scrollable list boxes,
progress bars, and more.
- **DOxygen Documentation** DOxygen documentation is available.
Note: Many of the fundamental classed in NxWidgets derive from the
Antony Dzeryn's "Woopsi" project which also has a
BSD style license. See the COPYING file for details.
NXWidgets Doxygen Documentation
===============================
.. todo::
NXWidgets supports building HTML documentation via Doxygen. We should
integrate this into the Sphinx documentation build.
Thanks go to Jose Pablo Carballo for contributing this!
@@ -0,0 +1,409 @@
.. _ondemandpaging:
================
On-Demand Paging
================
Introduction
============
Overview
--------
This document summarizes the design of NuttX on-demand paging. This
feature permits embedded MCUs with some limited RAM space to execute
large programs from some non-random access media.
What kind of platforms can support NuttX on-demang paging?
#. The MCU should have some large, probably low-cost non-volatile
storage such as serial FLASH or an SD card. This storage probably
does not support non-random access (otherwise, why not just execute
the program directly on the storage media). SD and serial FLASH are
inexpensive and do not require very many pins and SPI support is
prevalent in just about all MCUs. This large serial FLASH would
contain a big program. Perhaps a program of several megabytes in
size.
#. The MCU must have a (relatively) small block of fast SRAM from which
it can execute code. A size of, say 256K (or 192K as in the NXP
LPC3131) would be sufficient for many applications.
#. The MCU has an MMU (again like the NXP LPC3131).
If the platform meets these requirement, then NuttX can provide
on-demand paging: It can copy .text from the large program in
non-volatile media into RAM as needed to execute a huge program from the
small RAM.
Terminology
-----------
``g_waitingforfill``:
An OS list that is used to hold the TCBs of tasks that are waiting
for a page fill.
``g_pftcb``:
A variable that holds a reference to the TCB of the thread that is
currently be re-filled.
``g_pgworker``:
The *process* ID of the thread that will perform the page fills.
``pg_callback()``:
The callback function that is invoked from a driver when the fill is
complete.
``pg_miss()``:
The function that is called from architecture-specific code to handle
a page fault.
``TCB``:
Task Control Block
NuttX Common Logic Design Description
=====================================
Initialization
--------------
The following declarations will be added.
- ``g_waitingforfill``. A doubly linked list that will be used to
implement a prioritized list of the TCBs of tasks that are waiting
for a page fill.
- ``g_pgworker``. The *process* ID of the thread that will perform
the page fills
During OS initialization in ``sched/init/nx_start.c``, the following
steps will be performed:
- The ``g_waitingforfill`` queue will be initialized.
- The special, page fill worker thread, will be started. The ``pid`` of
the page will worker thread will be saved in ``g_pgworker``. Note
that we need a special worker thread to perform fills; we cannot use
the "generic" worker thread facility because we cannot be assured
that all actions called by that worker thread will always be resident
in memory.
Declarations for ``g_waitingforfill``, ``g_pgworker``, and other
internal, private definitions will be provided in
``sched/paging/paging.h``. All public definitions that should be used by
the architecture-specific code will be available in
``include/nuttx/page.h``. Most architecture-specific functions are
declared in ``include/nuttx/arch.h``, but for the case of this paging
logic, those architecture specific functions are instead declared in
``include/nuttx/page.h``.
Page Faults
-----------
**Page fault exception handling**. Page fault handling is performed by
the function ``pg_miss()``. This function is called from
architecture-specific memory segmentation fault handling logic. This
function will perform the following operations:
#. **Sanity checking**. This function will ASSERT if the currently
executing task is the page fill worker thread. The page fill worker
thread is how the page fault is resolved and all logic associated
with the page fill worker must be "`locked <#MemoryOrg>`__" and
always present in memory.
#. **Block the currently executing task**. This function will call
``up_block_task()`` to block the task at the head of the ready-to-run
list. This should cause an interrupt level context switch to the next
highest priority task. The blocked task will be marked with state
``TSTATE_WAIT_PAGEFILL`` and will be retained in the
``g_waitingforfill`` prioritized task list.
#. **Boost the page fill worker thread priority**. Check the priority of
the task at the head of the ``g_waitingforfill`` list. If the
priority of that task is higher than the current priority of the page
fill worker thread, then boost the priority of the page fill worker
thread to that priority. Thus, the page fill worker thread will
always run at the priority of the highest priority task that is
waiting for a fill.
#. **Signal the page fill worker thread**. Is there a page already being
filled? If not then signal the page fill worker thread to start
working on the queued page fill requests.
When signaled from ``pg_miss()``, the page fill worker thread will be
awakenend and will initiate the fill operation.
**Input Parameters.** None -- The head of the ready-to-run list is
assumed to be that task that caused the exception. The current task
context should already be saved in the TCB of that task. No additional
inputs are required.
**Assumptions**.
- It is assumed that this function is called from the level of an
exception handler and that all interrupts are disabled.
- The ``pg_miss()`` must be "`locked <#MemoryOrg>`__" in memory.
Calling ``pg_miss()`` cannot cause a nested page fault.
- It is assumed that currently executing task (the one at the head of
the ready-to-run list) is the one that cause the fault. This will
always be true unless the page fault occurred in an interrupt
handler. Interrupt handling logic must always be available and
"`locked <#MemoryOrg>`__" into memory so that page faults never come
from interrupt handling.
- The architecture-specific page fault exception handling has already
verified that the exception did not occur from interrupt/exception
handling logic.
- As mentioned above, the task causing the page fault must not be the
page fill worker thread because that is the only way to complete the
page fill.
Fill Initiation
---------------
The page fill worker thread will be awakened on one of three conditions:
- When signaled by ``pg_miss()``, the page fill worker thread will be
awakenend (see above),
- From ``pg_callback()`` after completing last fill (when
``CONFIG_PAGING_BLOCKINGFILL`` is defined... see below), or
- A configurable timeout expires with no activity. This timeout can be
used to detect failure conditions such things as fills that never
complete.
The page fill worker thread will maintain a static variable called
``struct tcb_s *g_pftcb``. If no fill is in progress, ``g_pftcb`` will
be NULL. Otherwise, it will point to the TCB of the task which is
receiving the fill that is in progress.
When awakened from ``pg_miss()``, no fill will be in progress and
``g_pftcb`` will be NULL. In this case, the page fill worker thread will
call ``pg_startfill()``. That function will perform the following
operations:
- Call the architecture-specific function ``up_checkmapping()`` to see
if the page fill still needs to be performed. In certain conditions,
the page fault may occur on several threads and be queued multiple
times. In this corner case, the blocked task will simply be restarted
(see the logic below for the case of normal completion of the fill
operation).
- Call ``up_allocpage(tcb, &vpage)``. This architecture-specific
function will set aside page in memory and map to virtual address
(vpage). If all available pages are in-use (the typical case), this
function will select a page in-use, un-map it, and make it available.
- Call the architecture-specific function ``up_fillpage()``. Two
versions of the up_fillpage function are supported -- a blocking and
a non-blocking version based upon the configuration setting
``CONFIG_PAGING_BLOCKINGFILL``.
- If ``CONFIG_PAGING_BLOCKINGFILL`` is defined, then up_fillpage is
blocking call. In this case, ``up_fillpage()`` will accept only
(1) a reference to the TCB that requires the fill.
Architecture-specific context information within the TCB will be
sufficient to perform the fill. And (2) the (virtual) address of
the allocated page to be filled. The resulting status of the fill
will be provided by return value from ``up_fillpage()``.
- If ``CONFIG_PAGING_BLOCKINGFILL`` is defined, then up_fillpage is
non-blocking call. In this case ``up_fillpage()`` will accept an
additional argument: The page fill worker thread will provide a
callback function, ``pg_callback``. This function is non-blocking,
it will start an asynchronous page fill. After calling the
non-blocking ``up_fillpage()``, the page fill worker thread will
wait to be signaled for the next event -- the fill completion
event. The callback function will be called when the page fill is
finished (or an error occurs). The resulting status of the fill
will be providing as an argument to the callback functions. This
callback will probably occur from interrupt level.
In any case, while the fill is in progress, other tasks may execute. If
another page fault occurs during this time, the faulting task will be
blocked, its TCB will be added (in priority order) to
``g_waitingforfill``, and the priority of the page worker task may be
boosted. But no action will be taken until the current page fill
completes. NOTE: The IDLE task must also be fully
`locked <#MemoryOrg>`__ in memory. The IDLE task cannot be blocked. It
the case where all tasks are blocked waiting for a page fill, the IDLE
task must still be available to run.
The architecture-specific functions, ``up_checkmapping()``,
``up_allocpage(tcb, &vpage)`` and ``up_fillpage(page, pg_callback)``
will be prototyped in ``include/nuttx/arch.h``
Fill Complete
-------------
For the blocking ``up_fillpage()``, the result of the fill will be
returned directly from the call to ``up_fillpage``.
For the non-blocking ``up_fillpage()``, the architecture-specific driver
call the ``pg_callback()`` that was provided to ``up_fillpage()`` when
the fill completes. In this case, the ``pg_callback()`` will probably be
called from driver interrupt-level logic. The driver will provide the
result of the fill as an argument to the callback function. NOTE:
``pg_callback()`` must also be `locked <#MemoryOrg>`__ in memory.
In this non-blocking case, the callback ``pg_callback()`` will perform
the following operations when it is notified that the fill has
completed:
- Verify that ``g_pftcb`` is non-NULL.
- Find the higher priority between the task waiting for the fill to
complete in ``g_pftcb`` and the task waiting at the head of the
``g_waitingforfill`` list. That will be the priority of he highest
priority task waiting for a fill.
- If this higher priority is higher than current page fill worker
thread, then boost worker thread's priority to that level. Thus, the
page fill worker thread will always run at the priority of the
highest priority task that is waiting for a fill.
- Save the result of the fill operation.
- Signal the page fill worker thread.
Task Resumption
---------------
For the non-blocking ``up_fillpage()``, the page fill worker thread will
detect that the page fill is complete when it is awakened with
``g_pftcb`` non-NULL and fill completion status from ``pg_callback``. In
the non-blocking case, the page fill worker thread will know that the
page fill is complete when ``up_fillpage()`` returns.
In this either, the page fill worker thread will:
- Verify consistency of state information and ``g_pftcb``.
- Verify that the page fill completed successfully, and if so,
- Call ``up_unblocktask(g_pftcb)`` to make the task that just received
the fill ready-to-run.
- Check if the ``g_waitingforfill`` list is empty. If not:
- Remove the highest priority task waiting for a page fill from
``g_waitingforfill``,
- Save the task's TCB in ``g_pftcb``,
- If the priority of the thread in ``g_pftcb``, is higher in
priority than the default priority of the page fill worker thread,
then set the priority of the page fill worker thread to that
priority.
- Call ``pg_startfill()`` which will start the next fill (as
described above).
- Otherwise,
- Set ``g_pftcb`` to NULL.
- Restore the default priority of the page fill worker thread.
- Wait for the next fill related event (a new page fault).
Architecture-Specific Support Requirements
==========================================
Memory Organization
-------------------
**Memory Regions**. Chip specific logic will map the virtual and
physical address spaces into three general regions:
#. A .text region containing "`locked-in-memory <#MemoryOrg>`__" code
that is always available and will never cause a page fault. This
locked memory is loaded at boot time and remains resident for all
time. This memory regions must include:
- All logic for all interrupt paths. All interrupt logic must be
locked in memory because the design present here will not support
page faults from interrupt handlers. This includes the page fault
handling logic and ```pg_miss()`` <#PageFaults>`__ that is called
from the page fault handler. It also includes the
```pg_callback()`` <#FillComplete>`__ function that wakes up the
page fill worker thread and whatever architecture-specific logic
that calls ``pg_callback()``.
- All logic for the IDLE thread. The IDLE thread must always be
ready to run and cannot be blocked for any reason.
- All of the page fill worker thread must be locked in memory. This
thread must execute in order to unblock any thread waiting for a
fill. It this thread were to block, there would be no way to
complete the fills!
#. A .text region containing pages that can be assigned allocated,
mapped to various virtual addresses, and filled from some mass
storage medium.
#. And a fixed RAM space for .bss, .text, and .heap.
This memory organization is illustrated in the following table. Notice
that:
- There is a one-to-one relationship between pages in the virtual
address space and between pages of .text in the non-volatile mass
storage device.
- There are, however, far fewer physical pages available than virtual
pages. Only a subset of physical pages will be mapped to virtual
pages at any given time. This mapping will be performed on-demand as
needed for program execution.
============================= ============================ ====================
SRAM Virtual Address Space Non-Volatile Storage
============================= ============================ ====================
. DATA .
. Virtual Page *n* (*n* > *m*) Stored Page *n*
. Virtual Page *n-1* Stored Page *n-1*
DATA ... ...
Physical Page *m* (*m* < *n*) ... ...
Physical Page *m-1* ... ...
... ... ...
Physical Page *1* Virtual Page *1* Stored Page *1*
Locked Memory Locked Memory Memory Resident
============================= ============================ ====================
**Example**. As an example, suppose that the size of the SRAM is 192K
(as in the NXP LPC3131). And suppose further that:
- The size of the locked, memory resident .text area is 32K, and
- The size of the DATA area is 64K.
- The size of one, managed page is 1K.
- The size of the whole .text image on the non-volatile, mass storage
device is 1024K.
Then, the size of the locked, memory resident code is 32K (*m*\ =32
pages). The size of the physical page region is 96K (96 pages), and the
size of the data region is 64 pages. And the size of the virtual paged
region must then be greater than or equal to (1024-32) or 992 pages
(*n*).
**Building the Locked, In-Memory Image**. One way to accomplish this
would be a two phase link:
- In the first phase, create a partially linked objected containing all
interrupt/exception handling logic, the page fill worker thread plus
all parts of the IDLE thread (which must always be available for
execution).
- All of the ``.text`` and ``.rodata`` sections of this partial link
should be collected into a single section.
- The second link would link the partially linked object along with the
remaining object to produce the final binary. The linker script
should position the "special" section so that it lies in a reserved,
"non-swappable" region.
Architecture-Specific Functions
-------------------------------
Most standard, architecture-specific functions are declared in
``include/nuttx/arch.h``. However, for the case of this paging logic,
the architecture specific functions are declared in
``include/nuttx/page.h``. Standard, architecture-specific functions that
should already be provided in the architecture port are :c:func:`up_block_task`
and :c:func:`up_unblock_task`. New, additional functions that must be
implemented just for on-demand paging support are:
.. c:function:: int up_checkmapping(FAR struct tcb_s *tcb)
The function ``up_checkmapping()`` returns an indication if the page
fill still needs to performed or not. In certain conditions, the page
fault may occur on several threads and be queued multiple times. This
function will prevent the same page from be filled multiple times.
.. c:function:: int up_allocpage(FAR struct tcb_s *tcb, FAR void *vpage)
This architecture-specific function will set aside page in memory and
map to its correct virtual address. Architecture-specific context
information saved within the TCB will provide the function with the
information needed to identify the virtual miss address. This function
will return the allocated physical page address in ``vpage``. The size
of the underlying physical page is determined by the configuration
setting ``CONFIG_PAGING_PAGESIZE``. NOTE: This function must *always*
return a page allocation. If all available pages are in-use (the typical
case), then this function will select a page in-use, un-map it, and make
it available.
.. c:function:: int up_fillpage(FAR struct tcb_s *tcb, FAR const void *vpage, void (*pg_callback)(FAR struct tcb_s *tcb, int result))
The actual filling of the page with data from the non-volatile, must be
performed by a separate call to the architecture-specific function,
``up_fillpage()``. This will start asynchronous page fill. The common
paging logic will provide a callback function, ``pg_callback``, that
will be called when the page fill is finished (or an error occurs). This
callback is assumed to occur from an interrupt level when the device
driver completes the fill operation.
Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

@@ -0,0 +1,245 @@
================
Power Management
================
.. todo::
This needs to be updated to account for the different governors
besides the activity-based one.
NuttX supports a simple power management (PM) sub-system which:
- Monitors activity from drivers (and from other parts of the
system), and
- Provides hooks to place drivers (and the whole system) into
reduce power modes of operation.
|figure|
The PM sub-system integrates the MCU idle loop with a collection
of device drivers to support:
- Reports of relevant driver or other system activity.
- Registration and callback mechanism to interface with
individual device drivers.
- IDLE time polling of overall driver activity.
- Coordinated, global, system-wide transitions to lower power
usage states.
**Low Power Consumption States**. Various "sleep" and low power
consumption states have various names and are sometimes used in
conflicting ways. In the NuttX PM logic, we will use the following
terminology:
``NORMAL``
The normal, full power operating mode.
``IDLE``
This is still basically normal operational mode, the system is,
however, ``IDLE`` and some simple simple steps to reduce power
consumption provided that they do not interfere with normal
Operation. Simply dimming the a backlight might be an example
some that that would be done when the system is idle.
``STANDBY``
Standby is a lower power consumption mode that may involve more
extensive power management steps such has disabling clocking or
setting the processor into reduced power consumption modes. In
this state, the system should still be able to resume normal
activity almost immediately.
``SLEEP``
The lowest power consumption mode. The most drastic power
reduction measures possible should be taken in this state. It
may require some time to get back to normal operation from
``SLEEP`` (some MCUs may even require going through reset).
.. c:enum:: pm_state_e
These various states are represented with type :c:enum:`pm_state_e`
in ``include/nuttx/power/pm.h``.
**Power Management Domains**. Each PM interfaces includes a
integer *domain* number. By default, only a single power domain is
supported (``CONFIG_PM_NDOMAINS=1``). But that is configurable;
any number of PM domains can be supported. Multiple PM domains
might be useful, for example, if you would want to control power
states associated with a network separately from power states
associated with a user interface.
Interfaces
==========
All PM interfaces are declared in the file ``include/nuttx/power/pm.h``.
.. c:function:: void pm_initialize(void)
Called by MCU-specific one-time logic
at power-on-reset in order to initialize the power management
capabilities. This function must be called *very* early in the
initialization sequence *before* any other device drivers are
initialized (since they may attempt to register with the power
management subsystem).
.. c:function:: int pm_register(FAR struct pm_callback_s *callbacks)
Called by a device driver in
order to register to receive power management event callbacks.
Refer to the :ref:`components/power:Callbacks` section for more
details.
:param callbacks:
An instance of :c:struct:`pm_callback_s`
providing the driver callback functions.
:return:
Zero (``OK``) on success; otherwise a negated
``errno`` value is returned.
.. c:function:: int pm_unregister(FAR struct pm_callback_s *callbacks)
Called by a device driver in
order to unregister previously registered power management event
callbacks. Refer to the :ref:`components/power:Callbacks` section for
more details.
**Input Parameters:**
:param callbacks:
An instance of :c:struct:`pm_callback_s`
providing the driver callback functions.
:return:
Zero (``OK``) on success; otherwise a negated
``errno`` value is returned.
.. c:function:: void pm_activity(int domain, int priority)
Called by a device driver to
indicate that it is performing meaningful activities (non-idle).
This increment an activity count and/or will restart a idle timer
and prevent entering reduced power states.
:param domain: Identifies the domain of the new PM activity
:param priority:
Activity priority, range 0-9. Larger values correspond to
higher priorities. Higher priority activity can prevent the
system from entering reduced power states for a longer period
of time. As an example, a button press might be higher priority
activity because it means that the user is actively interacting
with the device.
**Assumptions:** This function may be called from an interrupt
handler (this is the ONLY PM function that may be called from an
interrupt handler!).
.. c:function:: enum pm_state_e pm_checkstate(int domain)
Called from the MCU-specific
IDLE loop to monitor the power management conditions. This
function returns the "recommended" power management state based on
the PM configuration and activity reported in the last sampling
periods. The power management state is not automatically changed,
however. The IDLE loop must call :c:func:`pm_changestate` in order to
make the state change.
These two steps are separated because the platform-specific IDLE
loop may have additional situational information that is not
available to the PM sub-system. For example, the IDLE loop may
know that the battery charge level is very low and may force lower
power states even if there is activity.
NOTE: That these two steps are separated in time and, hence, the
IDLE loop could be suspended for a long period of time between
calling :c:func:`pm_checkstate` and :c:func:`pm_changestate`. The IDLE
loop may need to make these calls atomic by either disabling
interrupts until the state change is completed.
:param domain: Identifies the PM domain to check
:return: The recommended power management state.
.. c:function:: int pm_changestate(int domain, enum pm_state_e newstate)
This function is used by platform-specific power
management logic. It will announce the power management power
management state change to all drivers that have registered for
power management event callbacks.
:param domain: Identifies the domain of the new PM state
:param newstate: Identifies the new PM state
:return:
0 (``OK``) means that the callback function
for all registered drivers returned ``OK`` (meaning that they
accept the state change). Non-zero means that one of the drivers
refused the state change. In this case, the system will revert to
the preceding state.
**Assumptions:** It is assumed that interrupts are disabled when
this function is called. This function is probably called from the
IDLE loop... the lowest priority task in the system. Changing
driver power management states may result in renewed system
activity and, as a result, can suspend the IDLE thread before it
completes the entire state change unless interrupts are disabled
throughout the state change.
Callbacks
=========
.. c:struct:: pm_callback_s
This struct includes the pointers to the driver
callback functions. This structure is defined
``include/nuttx/power/pm.h``. These callback functions can be used
to provide power management information to the driver.
.. c:var:: int (*prepare)(FAR struct pm_callback_s *cb, int domain, enum pm_state_e pmstate)
Request the driver to prepare for a new power
state. This is a warning that the system is about to enter into a
new power state. The driver should begin whatever operations that
may be required to enter power state. The driver may abort the
state change mode by returning a non-zero value from the callback
function.
:param cb:
Returned to the driver. The driver version of the callback
structure may include additional, driver-specific state data at
the end of the structure.
:param domain:
Identifies the activity domain of the state change
:param pmstate:
Identifies the new PM state
:return:
Zero (``OK``) means the event was successfully
processed and that the driver is prepared for the PM state change.
Non-zero means that the driver is not prepared to perform the
tasks needed achieve this power setting and will cause the state
change to be aborted. NOTE: The ``prepare()`` method will also be
called when reverting from lower back to higher power consumption
modes (say because another driver refused a lower power state
change). Drivers are not permitted to return non-zero values when
reverting back to higher power consumption modes!
.. c:var:: void (*notify)(FAR struct pm_callback_s *cb, int domain, enum pm_state_e pmstate)
Notify the driver of new power state. This
callback is called after all drivers have had the opportunity to
prepare for the new power state.
:param cb:
Returned to the driver. The driver version of the callback
structure may include additional, driver-specific state data at
the end of the structure.
:param domain:
Identifies the activity domain of the state change
:param pmstate:
Identifies the new PM state
The driver already agreed to transition
to the low power consumption state when when it returned ``OK`` to
the :c:var:`prepare` call.
.. |figure| image:: pm.png
@@ -0,0 +1,121 @@
##############################################################################
# Documentation/conf.py
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
##############################################################################
# Configuration file for the Sphinx documentation builder.
#
# This file only contains a selection of the most common options. For a full
# list see the documentation:
# https://www.sphinx-doc.org/en/master/usage/configuration.html
# -- Path setup --------------------------------------------------------------
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#
# import os
# import sys
# sys.path.insert(0, os.path.abspath('.'))
# -- Project information -----------------------------------------------------
project = "NuttX"
copyright = "2020, The Apache Software Foundation"
author = "NuttX community"
version = release = "latest"
# -- General configuration ---------------------------------------------------
# Add any Sphinx extension module names here, as strings. They can be
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
# ones.
extensions = [
"sphinx_rtd_theme",
"m2r2",
"sphinx.ext.autosectionlabel",
"sphinx.ext.todo",
"sphinx_tabs.tabs",
]
source_suffix = [".rst", ".md"]
todo_include_todos = True
autosectionlabel_prefix_document = True
# do not set Python as primary domain for code blocks
highlight_language = "none"
primary_domain = None
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
# List of patterns, relative to source directory, that match files and
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"]
# list of documentation versions to offer (besides latest). this will be
# overriden by command line option but we can provide a sane default
# this way
html_context = dict()
html_context["nuttx_versions"] = "latest"
# TODO: append other options using releases detected from git (or maybe just
# a few hand-selected ones, or maybe just a "stable" option)
# -- Options for HTML output -------------------------------------------------
# The theme to use for HTML and HTML Help pages. See the documentation for
# a list of builtin themes.
#
html_theme = "sphinx_rtd_theme"
html_show_sphinx = False
html_theme_options = {"navigation_depth": 5}
# Add any paths that contain custom static files (such as style sheets) here,
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ["_static"]
html_css_files = ["custom.css"]
html_show_license = True
html_logo = "_static/NuttX.png"
html_favicon = "_static/favicon.ico"
today_fmt = "%d %B %y at %H:%M"
c_id_attributes = ["FAR", "CODE", "noreturn_function"]
# This is required to allow running linkcheck with sphinx-tabs
sphinx_tabs_valid_builders = ["linkcheck"]
# There are some sites where the linkchecker cannot handle anchors
linkcheck_ignore = [
"https://github.com/pyenv/pyenv#installation",
"http://openocd.zylin.com/#/c/4103/",
]
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,195 @@
=============
Documentation
=============
The Apache NuttX Documentation is built using the
`Sphinx documentation system <https://www.sphinx-doc.org/en/master/>`_. Documentation
is written in `ReStructured Text <https://docutils.sourceforge.io/rst.html>`_ (RST),
with Sphinx-specific directives. RST is the format used for
`Python documentation <https://docs.python.org/3/>`_ and is also used in many other projects.
Using Sphinx, the RST files are rendered into HTML files that can be read in your browser.
Building
========
To render the Documentation locally, you should clone the NuttX main repository, and
go into ``Documentation`` directory. Then,
1. Install Sphinx and other dependencies using pipenv.
You may also find it helpful on platforms such as Windows and MacOS to use *pyenv*
to manage your python installation. You can read about installing that on the
project `site <https://github.com/pyenv/pyenv#installation>`_.
.. code-block:: console
$ pip3 install pipenv
$ pipenv install
$ # activate the virtual environent
$ pipenv shell
2. Build documentation:
.. code-block:: console
$ make html
The resulting HTMLs will end up under ``_build/html``. You can open your browser at the root with:
.. code-block:: console
$ xdg-open _build/html/index.html
Live Rebuild
------------
For more comfortable editing and previewing of changes (as ``make html`` will perform a slower full rebuild),
you can install ``sphinx-autobuild`` which will monitor file changes and rebuild only affected files. To
install it (within the virtual environment):
.. code-block:: console
$ pip3 install sphinx-autobuild
To run:
.. code-block:: console
$ make autobuild
Which will perform an initial clean build and monitor changes from then on.
Contributing
============
Contributions to documentation are appreciated. These can be as simple as fixing a typo or formatting issues to more involved
changes such as documenting parts of NuttX which are not yet covered or even writing guides for other users.
The contribution workflow is the same as for the code, so check the :doc:`/contributing/workflow` to understand
how your changes should be upstreamed.
Writing ReStructure Text with Sphinx
====================================
The following links can be used to learn about RST syntax and about Sphinx specific directives. Note that
sometimes Sphinx's approach is used over standard RST since it is more powerful (e.g. standard linking vs Sphinx
``:ref:`` which can be used across files, ``code-block`` directive vs ``::`` which allows specifying highlight language, etc.):
* `Sphinx documentation system <https://www.sphinx-doc.org/en/master/>`__
* `ReStructured Text documentation <https://docutils.sourceforge.io/rst.html>`__
* `Sphinx Guide to ReStructured Text <http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html>`__
* `Restructured Text cheat sheet <https://thomas-cokelaer.info/tutorials/sphinx/rest_syntax.html>`__
Documentation Conventions
=========================
While RST/Sphinx provide many ways to do things, it is best to follow a given convention to mantain consistency and avoid
pitfalls. For this reason, documentation changes should follow the following set of conventions.
Indentation
-----------
Child blocks should be indented two-spaces. This includes itemizations/enumerations.
Headings
--------
Three levels of headings should be used in general. The style used to mark sections is based around ``=`` and ``-``.
Sections should look like this:
.. code-block:: RST
=================
Top Level Heading
=================
Subsection
==========
Subsubsection
-------------
Code
----
Code should be documented using the `C domain <https://www.sphinx-doc.org/en/master/usage/restructuredtext/domains.html#the-c-domain>`_.
This means for example that a function should be documented as:
.. code-block:: RST
.. c:function:: bool myfunction(int arg1, int arg2)
Here the function should be described
:param arg1: Description of arg1
:param arg2: Description of arg2
:return: Description of return value
To document a piece of code, use a ``code-block`` `directive <https://www.sphinx-doc.org/en/master/usage/restructuredtext/directives.html#directive-code-block>`_, specifying the highlight language. If the block is not of code but some verbatim piece of text,
it is acceptable to use RST standard `::`. This is specially useful and compact when used in the following mode:
.. code-block:: RST
The text file should have the following content::
Line1
Line2
Line3
Linking
-------
To generate internal links, Sphinx's `roles <https://www.sphinx-doc.org/en/master/usage/restructuredtext/roles.html#ref-role>`_ should
be used. So, use ``:ref:`` instead of standard RST syntax like ```link <target>`_`` for internal links.
If the target is in a different file, you can refer it with: ``:ref:`link text </pathtorst:Section Name>```.
Linking to a specific document can be done with ``:doc:`/path/to/document``` (without ``.rst`` extension).
Notes and TODOS
---------------
Use RST `admonitions <https://docutils.sourceforge.io/docs/ref/rst/directives.html#admonitions>`_ to highlight things from the text,
such as a note that should be prominently displayed.
In case you need to leave a TODO note in the documentation to point that something needs to be improved, use a ``todo`` admonition,
which is available via the ``sphinx.ext.todo`` extension. This will let the reader of the documentation also know that the documentation
is not yet finished somewhere and may further motivate a contribution.
User Indications
----------------
To indicate a keypress, menu action or GUI button selection, use the following:
.. code-block:: RST
Go into menu :menuselection:`File --> Save As`, click :guilabel:`&OK` or press :kbd:`Enter`.
which would render as:
Go into menu :menuselection:`File --> Save As`, click :guilabel:`&OK` or press :kbd:`Enter`.
Tabbed examples
---------------
To indicate different instructions/examples for different scenarios (for example, different Operating
Systems) use the `tabs <https://github.com/executablebooks/sphinx-tabs>`_ extension (see link for examples).
Tips
====
Spacing
-------
If you are getting formatting errors, be sure to provide the appropiate spacing between a directive and its content.
Generally, you should follow this format:
.. code-block:: RST
.. directive::
child content
non-child content which appears after previous directive
Note the line between directive and content and the indentation.
@@ -0,0 +1,14 @@
Contributing
============
In the following sections you will find important information on how to contribute to NuttX codebase (from small bugfixes to large new features)
and documentation (the one you are reading now):
.. toctree::
:maxdepth: 2
workflow.rst
making-changes.rst
coding_style.rst
documentation.rst
@@ -0,0 +1,222 @@
.. include:: /substitutions.rst
.. _making-changes:
Making Changes Using Git
========================
The Apache NuttX project uses the `Git version control system <https://git-scm.com/book/en/v2/Getting-Started-About-Version-Control>`_
to track changes, and the source code is hosted on `GitHub <https://www.github.com>`_.
If you want to make changes to NuttX, for your own personal use, or to submit them back to project to improve NuttX,
that's easy. For the purposes of this guide, you'll need a `GitHub <https://www.github.com>`_ account, since
the Apache NuttX team uses GitHub. (You could also use git locally, or save your changes to other sites like
`GitLab <https://about.gitlab.com/>`_ or `BitBucket <https://bitbucket.org>`_, but that's beyond the scope of this
guide).
Here's how to do it:
#. Set your git user name and email
.. code-block:: bash
$ cd nuttx/
$ git config --global user.name "Your Name"
$ git config --global user.email "yourname@somedomaincom"
#. Sign in to GitHub
If you don't have a `GitHub <https://www.github.com>`_ account, it's free to
sign up.
#. Fork the Projects
Visit both these links and hit the Fork button in the upper right of the page:
* `NuttX <https://github.com/apache/incubator-nuttx/>`_
* `NuttX Apps <https://github.com/apache/incubator-nuttx-apps/>`_
#. Clone the Repositories
On the GitHub web page for your forked ``incubator-nuttx`` project, copy the clone url get it by hitting the
green ``Clone or Download`` button in the upper right. Then do this:
.. code-block:: bash
$ git clone <your forked incubator-nuttx project clone url>
$ git remote add upstream https://github.com/apache/incubator-nuttx.git
Do the same for your forked ``incubator-nuttx-apps`` project:
.. code-block:: bash
$ cd ../apps
$ git clone <your forked incubator-nuttx-apps project clone url>
$ git remote add upstream https://github.com/apache/incubator-nuttx-apps.git
#. Create a Local Git Branch
Now you can create local git branches and push them to GitHub:
.. code-block:: bash
$ git checkout -b test/my-new-branch
$ git push
Git Workflow With an Upstream Repository
----------------------------------------
The main NuttX git repository is called an "upstream" repository - this is because it's the main source of truth, and
its changes flow downstream to people who've forked that repository, like us.
Working with an upstream repo is a bit more complex, but it's worth it since you can submit fixes and features
to the main NuttX repos. One of the things you need to do regularly is keep your local repo in sync
with the upstream. I work with a local branch, make changes, pull new software from the upstream and merge it in,
maybe doing that several times. Then when everything works, I get my branch ready to do a Pull Request. Here's how:
#. Fetch upstream changes and merge into my local master:
.. code-block:: bash
$ git checkout master
$ git fetch upstream
$ git merge upstream/master
$ git push
#. Merge my local master with my local branch:
.. code-block:: bash
$ git checkout my-local-branch
$ git merge master
$ git push
#. Make changes and push them to my fork
.. code-block:: bash
$ vim my-file.c
$ git add my-file.c
$ git commit my-file.c
$ git push
#. Repeat 1-3 as necessary
#. Run the ``tools/checkpatch.sh`` script on your files
When your code runs, then you're almost ready to submit it. But first you need to check the code to ensure
that it conforms to the NuttX :ref:`contributing/coding_style:C Coding Standard`.
The ``tools/checkpatch.sh`` script will do that. Here's the usage info:
.. code-block:: bash
$ ./tools/checkpatch.sh -h
USAGE: ./tools/checkpatch.sh [options] [list|-]
Options:
-h
-c spell check with codespell(install with: pip install codespell
-r range check only (used with -p and -g)
-p <patch list> (default)
-g <commit list>
-f <file list>
- read standard input mainly used by git pre-commit hook as below:
git diff --cached | ./tools/checkpatch.sh -
Run it against your files and correct all the errors in the code you added, so that
``tools/checkpatch.sh`` reports no errors. Then commit the result.
For example:
.. code-block:: bash
$ ./tools/checkpatch.sh -f my-file.c
arch/arm/src/sama5/hardware/my-file.c:876:82: warning: Long line found
$ # fix errors
$ vim my-file.c
$ # run again
$ ./tools/checkpatch.sh -f my-file.c
If you have made a lot of changes, you can also use this bash commandline to see the errors for all the changed C
files in your branch (assumes you are currently on the branch that has the changed files):
.. code-block:: bash
$ git diff --name-only master | egrep "\.c|\.h" | xargs echo | xargs ./tools/checkpatch.sh -f | less
Note that there are some bugs in the ``nxstyle`` program that ``checkpatch.sh`` uses, so
it may report a few errors that are not actually errors. The committers will help you
find these. (Or view the
`nxstyle Issues <https://github.com/apache/incubator-nuttx/issues?q=is%3Aissue+is%3Aopen+nxstyle>`_.)
|br|
|br|
#. Commit the fixed files
.. code-block:: bash
$ git add my-file.c
$ git commit my-file.c
$ git push
Submitting Your Changes to NuttX
--------------------------------
Pull requests let you tell others about changes you've pushed to a branch in a repository on GitHub. Once a pull
request is opened, you can discuss and review the potential changes with collaborators and add follow-up commits
before your changes are merged into the base branch.
(from GitHub's `About pull requests <https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests>`_ page)
Before you do a Pull Request, the NuttX team will usually want all the changes you made in your branch "squashed" into
a single commit, so that when they review your changes, there's a clean view of the history. If there are changes
after Pull Request review feedback, they can be separate commits. Here's the easiest way I found to do that initial
squash before submitting the Pull Request:
#. Check out my branch
.. code-block:: bash
$ git checkout my-branch
#. Fetch the upstream code
.. code-block:: bash
$ git fetch upstream
#. Rebase onto the upstream code
.. code-block:: bash
$ git rebase upstream/master
#. Push to your remote
This needs to a force push with ``-f``.
.. code-block:: bash
$ git push -u my-branch -f
#. Create a GitHub Pull Request
A Pull Request is how you ask your upstream to review and merge your changes.
Here's `GitHub's instructions for creating a Pull Request <https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request>`_.
#. Get Pull Request feedback and implement changes
Get suggestions for improvements from reviewers, make changes, and push them to the branch. Once the reviewers are
happy, they may suggest squashing and merging again to make a single commit. In this case you would repeat steps
1 through 6.
Git Resources
-------------
* `Git Cheat Sheet (by GitHub) <https://github.github.com/training-kit/downloads/github-git-cheat-sheet.pdf>`_
* `Git Book (online) <https://git-scm.com/book/en/v2>`_
* `NuttX Code Contribution Workflow (draft) <https://cwiki.apache.org/confluence/display/NUTTX/Code+Contribution+Workflow>`_
All the details are here if you need them!
@@ -0,0 +1,42 @@
.. todo:: update when workflow is settled
Development Workflow
====================
NuttX development workflow is based around contributions submitted in the form of GitHub Pull Requests (PR). This is true both for external contributors and NuttX maintainers, as direct pushes to the repository are not allowed as a general rule. Once submitted, your PR
will be reviewed and checked using Continuous Integration (CI) practices.
You should be aware of the following:
- All contributions must adhere to the :doc:`Coding Standard <coding_style>`. You can check your files using ``nxstyle``
or complete patchsets using ``checkpatch`` script (both found in ``tools`` subdirectory of NuttX repository). This check will also run
automatically during CI to ensure conformance.
Note that not all existing files in the repository are already adapted to conform to the standard as this is an ongoing effort. Thus,
if you're submitting a patch to an existing file you may have to make the file conform to the standard, even if you are not reponsible
for those standard violations.
It is also appreciated that you separate any styling fixes in a separate commit from the functional changes so that these are more
easily readable during review.
- Before starting work on any given non trivial contribution, do subscribe to the mailing list and ask about your idea to avoid
wasted effort by going the wrong-route.
- If you are submitting an original contribution (you wrote the code yourself from scratch) it will have to be submitted under
the terms of the Apache 2.0 License using the corresponding :ref:`header <contributing/coding_style:Appendix>`.
Note that if you are working as an employee in a company, usually copyright belongs to the company and thus this means the company
will have to authorize this and submit the appropriate license agreements.
- If you are submitting third-party code:
- Code from actively developed projects is not accepted to be included in NuttX (i.e.: creating a fork). It is expected that
changes required in third-party code for NuttX support are to be implemented in these projects. As an intermediate solution,
it is acceptable to include a patch to be applied to this third-party code, which will be pulled during built.
- If this is from an inactive project, it may be considered for inclusion in NuttX, provided that licensing terms allow to do so
and it is deemed of sufficient value to be included, considering that this code will have to be maintained in NuttX afterwards.
Note that it is undesireable to included non Apache 2.0 Licensed code inside the repository, even if the license itself allows it
(for example BSD License).
@@ -0,0 +1,368 @@
========
Glossary
========
.. glossary::
6LoWPAN
IPv6 over Low power Wireless Personal Area Networks
ACM
Abstract Control Model (USB)
ADC
Analog to Digital Conversion
AIC
Advanced Interrupt Controller (Atmel SAM)
ARP
Address Resolution Protocol (networking)
BCH
Block to Character
BINFMT
Binary Format (Dynamic Loader)
BLE
Bluetooth4 Low Energy
BPP
Bits Per Pixel
CAN
Controller Area Network
CDC
Communication Device Class (USB)
CP15
Coprocessor 15 (ARM)
CPU
Central Processing Unit
DEVIF
Device Interface (networking)
DAC
Digital to Analog Conversion
DCD
Device Controller Driver (USB)
DCMI
Digital Camera Interface
DEV
Device
DHCP
Dynamic Host Configuration Protocol
DHCPC
DHCP Client
DHCPD
DHCP Daemon (server)
DMA
Direct Memory Access (hardware)
DMAC
DMA Controller (hardware)
DNS
Domain Name Service (or System or Server) (networking)
DRAM
Dynamic RAM
EABI
Embedded-Application Binary Interface
EEPROM
Electrically Erasable Programmable Read-Only Memory
EMAC
Ethernet Media Access Controller (networking)
EPROM
Erasable Programmable Read-Only Memory
FAT
File Allocation Table (file systems)
FB
Frame Buffer (video interface)
FSMC
Flexible Static Memory Controller (STM32)
FTL
FLASH Translation Layer (MTD)
GPIO
General Purpose Input/Output
GMAC
Gigabit Media Access Controller (networking)
HCD
Host Controller Driver (USB)
HSMCI
High Speed Memory Card Interface (Atmel)
I/O Input/Output
IOCTL
Input/Output Control
IoT
Internet of Things (marketing BS)
IP
Internet Protocol (version 4?) (networking)
IPv4
Internet Protocol Version 4 (networking)
IPv6
Internet Protocol Version 6 (networking)
IRQ
Interrupt Request (hardware)
I2C
Inter-Integrated Circuit (serial interface)
I2S
Inter IC Sound (serial interface)
ICMP
Internet Control Message Protocol (networking)
ICMPv6
Internet Control Message Protocol for IPv6 (networking)
IGMP
Internet Group Multicast Protocol (networking)
IOB
I/O Buffer (networking)
LAN
Local Area Network (networking)
LCD
Liquid Crystal Display
LIBC
The "C" Library
LIBM
The "C" Math Library
LP
Low Power
MAC
Media Access Control (networking, OSI model)
MCI
Memory Card Interface
MCU
Microcontroller Unit
MM
Memory Management/Manager
MMAP
Memory Map
MMC
Multi-Media Card
MMCSD
See MMC and SD
MMU
Memory Management Unit
MPU
Memory Protection Unit
MTD
Memory Technology Device
NFS
Network File System
NETDB
Network Data Base (networking)
NETDEV
Network Device (networking)
NSH
NuttShell
NVM
Non-Volatile Memory
NTP
Network Time Protocol (networking)
NX
NuttX, the NuttX Graphics server (graphics)
NXFFS
NuttX Flash File System
NXWM
The NuttX Window Manager (graphics)
PID
Process ID (operating systems)
Peripheral
ID (Atmel SAM)
PROM
Programmable Read-Only Memory
OS
Operating System
OTG
On-The-Go (USB)
OTP
One-Time Programmable
POR
Power-On Reset
PWM
Pulse Width Modulation
PKT
"Raw" Packet socket (networking)
PRNG
Pseudo-Random Number Generator
QSPI
Quad SPI
RAM
Random Access Memory
RNG
Random Number Generator
ROM
Read-Only Memory
RNDIS
Remote Network Driver Interface Specification (USB, networking)
RTC
Real Time Clock
RTCC
Real Time Clock/Calendar
RTOS
Real Time Operating System
SAIC
Secure Advanced Interrupt Controller (Atmel SAM)
SCI
Serial Communications Interface
SD
Secure Digital (flash memory)
SDHC
Secure Digital High Capacity (flash memory),
Secure
Digital Host Controller (hardware)
SDIO
Secure Digital I/O
SDRAM
Synchronous Dynamic Random Access Memory
SLCD
Segment Liquid Crystal Display
SMC
Static Memory Controller (hardware)
SPI
Serial Peripheral Interface
SPRNG
Scalable Parallel Random Number Generator
SRAM
Static RAM
SYSLOG
System Log
TCP
Transmission Control Protocol (networking)
TRNG
True Random Number Generator
TSC
Touchscreen Controller
TUN
network TUNnel
TWI
Two-Wire Interface (serial interface)
UDP
User Datagram Protocol (networking)
UART
Universal Asynchronous Receiver/Transmitter
USB
Universal Serial Bus (serial interface)
USART
Universal Synchronous/Asynchronous Receiver/Transmitter
VNC
Virtual Network Computing (graphics, remote desktop)
WAN
Wide Area Network (networking)
WLAN
Wireless Local Area Network (networking)
WPAN
Wireless Personal Area Network (networking)
WDT
Watchdog Timer (hardware)
XIP
eXecute In Place
XDMAC
Extended DMA Controller (Atmel)
@@ -0,0 +1,284 @@
.. include:: /substitutions.rst
.. _cpp_cmake:
C++ Example using CMake
=======================
In some situations, developers intend to implement software using the NuttX platform in
a previously set hardware and configuration where it is not possible or allowed to make
changes. In such situations, less contact with the operating source tree is better, where
it is only used for the application.
Some approaches are possible to do that today:
* https://cwiki.apache.org/confluence/display/NUTTX/Building+NuttX+with+Applications+Outside+of+the+Source+Tree
* https://www.programmersought.com/article/61604062421/
We have been seen the increase of the use of C++ language in embedded systems application. And
CMake (https://www.cmake.org) is the preferred build system used to build C++ projects. NuttX
support C++ based projects.
Using the 'build as a library' procedure of NuttX, it is possible to build NuttX
applications using C++ language and also the cmake build tool.
This document will show how to reimplement the hellocpp project using this cmake.
Preparation
-----------
#. Base NuttX compilation changes
For this example, load the configuration 'stm32f4discovery:testlibcxx' for building
.. code-block:: console
$ cd nuttx
$ ./tools/configure.sh stm32f4discovery:testlibcxx
In menuconfig, the main points to be changed on a typical NuttX configuration are the following:
* Set RTOS Features -> Tasks and Scheduling -> Application entry point to 'hellocpp_main'
* Build NuttX and generate the export
.. code-block:: console
$ make export
Creating the project
--------------------
#. Create your project file structure
The project structure is organized as follow:
.. code-block:: console
hellocpp/
hellocpp/CMakeLists.txt
hellocpp/cmake/stm32f4discovery.cmake
hellocpp/nuttx-export-10.0.1/
hellocpp/src/CMakeLists.txt
hellocpp/src/main.cpp
hellocpp/src/HelloWorld.h
hellocpp/src/HelloWorld.cpp
The directory 'nuttx-export-10.0.1' is the unzipped content from the file created during
make export procedure done before.
#. File contents
* hellocpp/CMakeLists.txt
.. code-block:: cmake
cmake_minimum_required(VERSION 3.2...3.15)
project(HelloCpp
VERSION 1.0
DESCRIPTION "Hello world C++ Nuttx"
)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_C_STANDARD 99)
set(NUTTX_PATH "${CMAKE_SOURCE_DIR}/nuttx-export-10.0.1")
include(cmake/stm32f4discovery.cmake)
set(AC_COMMON_FLAGS "${AC_COMMON_FLAGS} -fno-builtin -Wall -Wshadow -Wundef -fno-strict-aliasing -fno-strength-reduce -fomit-frame-pointer -Os")
set(AC_COMMON_FLAGS "${AC_COMMON_FLAGS} -D_DEBUG -D_LIBCPP_BUILD_STATIC -D_LIBCPP_NO_EXCEPTIONS ")
set(AC_COMMON_FLAGS "${AC_COMMON_FLAGS} -fno-exceptions -fcheck-new -fno-rtti -pedantic ")
set(AC_COMMON_FLAGS "${AC_COMMON_FLAGS} -nostdinc++")
set(AC_DEFINES "${AC_DEFINES} -DCONFIG_WCHAR_BUILTIN")
include_directories(
src
${NUTTX_PATH}/include
${NUTTX_PATH}/include/libcxx
${NUTTX_PATH}/arch/chip
)
set(EXE_NAME hellocpp)
set(CMAKE_CXX_FLAGS "${AC_HW_FLAGS} ${AC_DEFINES} ${AC_COMMON_FLAGS} ${AC_CXX_EXTRA_FLAGS}")
if (PARAM_DEBUG)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
endif()
set(CMAKE_SKIP_RPATH ON)
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_LINKER} ${AC_LINKER_FLAGS} -o ${EXE_NAME}.elf <OBJECTS> <LINK_LIBRARIES>")
set(BUILD_SHARED_LIBS OFF)
add_subdirectory(src)
* hellocpp/cmake/stm32f4discovery.cmake
.. code-block:: cmake
set(CMAKE_SYSTEM_NAME Generic)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(MCU_LINKER_SCRIPT "${NUTTX_PATH}/scripts/ld.script")
set(COMPILER_PREFIX arm-none-eabi-)
# cmake-format: off
set(CMAKE_C_COMPILER ${COMPILER_PREFIX}gcc)
set(CMAKE_CXX_COMPILER ${COMPILER_PREFIX}g++)
set(CMAKE_AR ${COMPILER_PREFIX}ar)
set(CMAKE_RANLIB ${COMPILER_PREFIX}ranlib)
set(CMAKE_LINKER ${COMPILER_PREFIX}ld)
set(CMAKE_ASM_COMPILER ${COMPILER_PREFIX}gcc)
set(CMAKE_OBJCOPY ${COMPILER_PREFIX}objcopy)
set(CMAKE_OBJDUMP ${COMPILER_PREFIX}objdump)
set(CMAKE_SIZE ${COMPILER_PREFIX}size)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
set(AC_HW_FLAGS "-mcpu=cortex-m4 -mthumb -mfloat-abi=soft ")
set(AC_HW_FLAGS "${AC_HW_FLAGS} -isystem ${NUTTX_PATH}/include")
set(AC_HW_FLAGS "${AC_HW_FLAGS} -pipe -D__NuttX__")
set(AC_LINKER_FLAGS "--entry=__start -nostartfiles -nodefaultlibs -T${MCU_LINKER_SCRIPT}")
* hellocpp/src/CMakeLists.txt
.. code-block:: cmake
set(HEADER_FILES
HelloWorld.h
)
set(SOURCE_FILES
HelloWorld.cpp
)
link_directories(${EXE_NAME} ${NUTTX_PATH}/libs)
add_executable(${EXE_NAME} ${SOURCE_FILES} main.cpp ${HEADER_FILES})
add_custom_command(
TARGET ${EXE_NAME}
POST_BUILD
COMMAND ${CMAKE_OBJCOPY} ARGS -S -O binary ${CMAKE_BINARY_DIR}/${EXE_NAME}.elf ${CMAKE_BINARY_DIR}/${EXE_NAME}.bin
)
target_link_libraries(${EXE_NAME} --start-group)
target_link_libraries(${EXE_NAME} sched)
target_link_libraries(${EXE_NAME} drivers)
target_link_libraries(${EXE_NAME} boards)
target_link_libraries(${EXE_NAME} c)
target_link_libraries(${EXE_NAME} mm)
target_link_libraries(${EXE_NAME} arch)
target_link_libraries(${EXE_NAME} xx)
target_link_libraries(${EXE_NAME} apps)
target_link_libraries(${EXE_NAME} fs)
target_link_libraries(${EXE_NAME} binfmt)
target_link_libraries(${EXE_NAME} board)
target_link_libraries(${EXE_NAME} gcc)
target_link_libraries(${EXE_NAME} supc++)
target_link_libraries(${EXE_NAME} --end-group)
* hellocpp/src/main.cpp
.. code-block:: c++
#include "HelloWorld.h"
#include <nuttx/config.h>
extern "C"
{
int hellocpp_main(void)
{
CHelloWorld *pHelloWorld = new CHelloWorld();
pHelloWorld->HelloWorld();
CHelloWorld helloWorld;
helloWorld.HelloWorld();
delete pHelloWorld;
return 0;
}
}
* hellocpp/src/HelloWorld.h
.. code-block:: c++
#ifndef HELLOWORLD_H_
#define HELLOWORLD_H_
#include "nuttx/config.h"
class CHelloWorld
{
public:
CHelloWorld();
~CHelloWorld();
bool HelloWorld(void);
private:
int mSecret;
};
#endif
* hellocpp/src/HelloWorld.cpp
.. code-block:: c++
#include <cstdio>
#include <string>
#include "HelloWorld.h"
CHelloWorld::CHelloWorld() {
mSecret = 42;
std::printf("Constructor: mSecret=%d\n",mSecret);
}
CHelloWorld::~CHelloWorld() {
}
bool CHelloWorld::HelloWorld(void) {
std::printf("HelloWorld: mSecret=%d\n",mSecret);
std::string sentence = "Hello";
std::printf("TEST=%s\n",sentence.c_str());
if (mSecret == 42) {
std::printf("CHelloWorld: HelloWorld: Hello, world!\n");
return true;
}
else {
std::printf("CHelloWorld: HelloWorld: CONSTRUCTION FAILED!\n");
return false;
}
}
Building
--------
To launch build, you use the cmake procedure:
.. code-block:: console
$ mkdir build
$ cd build
$ cmake ..
$ make
And finally a bin file will be created to be loaded on the board.
@@ -0,0 +1,206 @@
.. include:: /substitutions.rst
.. _drivers:
Drivers
=======
Some NuttX boards don't have full support for all the on-chip peripherals. If you need support for this hardware,
you will either need to port a driver from another chip, or write one yourself. This section discusses how to do that.
.. _drivers-porting:
Porting a Driver
----------------
Often support for on-chip peripherals exists in a closely related chip, or even a different family or from a different
manufacturer. Many chips are made up of different Intellectual Property (IP) blocks that are licensed from vendors like
Cadence, Synopsys, and others. The IP blocks may be similar enough to use another chip's driver with little
modification.
* Find a similar driver in NuttX source code:
* Look at register names listed in the datasheet for the peripheral.
* Search the NuttX codebase for the register names (try several different ones).
* Note that you'll have to compare the datasheet to the header and code files to see if there are differences; there
will usually be some differences between architectures, and they can be significant.
* Find a similar driver in U-Boot, Zephyr or BSD Unix (OpenBSD, FreeBSD, NetBSD) source code:
* Only for inspiration, you can't copy code because of license incompatibility and Apache Foundation restrictions.
(Apache License 2.0 and BSD code can come in with a software grant agreement from the original authors; this can
sometimes be hard to get. Ask on the mailing list if you're unsure.)
* But you can debug to see how the driver works.
* `U-Boot <https://www.denx.de/wiki/U-Boot>`_ drivers are often easier to understand than BSD Unix drivers because
U-Boot is simpler.
* Understanding how the driver works
Here are a couple of techniques that helped me.
* printf debugging
* Sprinkle ``custinfo()`` logging statements through your code to see execution paths and look at variables
while the code is running. The reason to use ``custinfo()`` as opposed to the other logging shortcuts
(``mcinfo()``, etc.) is that you can turn on and off other other logging and still see your custom debug
logging. Sometimes it's useful to quiet the flood of logging that comes from a particular debug logging
shortcut.
* Note that printing info to the console will affect timing.
* Keep a file with just your debug settings in it, like this (``debugsettings``):
.. code-block:: c
CONFIG_DEBUG_CUSTOM_INFO=y
(etc..)
* Add the settings to the end of your ``.config`` file after running ``make menuconfig`` (that will reorder
the file, making it harder to see and change the debug settings if you need to).
.. code-block:: bash
$ cat .config debugsettings > .config1 ; mv .config1 .config
* If you are using interrupts and threads (many things in NuttX run in different threads as a response to interrupts),
you can use printf debugging to see overlapping execution.
* Interrupts - here's how to inspect the C stack frame to see what execution environment is currently running:
.. code-block:: c
uint32_t frame = 0; /* MUST be the very first thing in the function */
uint32_t p_frame;
frame++; /* make sure that frame doesn't get optimized out */
p_frame = (uint32_t)(&frame);
custinfo("p_frame: %08x\n", p_frame);
* Threads - here's how to get the thread identifier to see which thread is currently executing:
.. code-block:: c
pthread_t thread_id = pthread_self();
custinfo("pthread_id: %08x\n", thread_id);
* stack frame printf
* thread printf
* `GDB — the GNU Debugger <https://www.gnu.org/software/gdb/>`_
GDB is a great tool. In this guide we've already used it to load our program and run it. But it can do a lot
more. You can single-step through code, examine variables and memory, set breakpoints, and more. I generally use
it from the commandline, but have also used it from an IDE like JetBrains' Clion, where it's easier to see the
code context.
One add-on that I found to be essential is the ability to examine blocks of memory, like buffers that NuttX uses
for reading and writing to storage media or network adapters. This `Stack Overflow question on using GDB to
examine memory <https://stackoverflow.com/a/54784260/431222>`_ includes a GDB command that is very handy. Add
this to your ``.gdbinit`` file, and then use the ``xxd`` command to dump memory in an easy-to-read format:
.. code-block::
define xxd
if $argc < 2
set $size = sizeof(*$arg0)
else
set $size = $arg1
end
dump binary memory dump.bin $arg0 ((void *)$arg0)+$size
eval "shell xxd -o %d dump.bin; rm dump.bin", ((void *)$arg0)
end
document xxd
Dump memory with xxd command (keep the address as offset)
xxd addr [size]
addr -- expression resolvable as an address
size -- size (in byte) of memory to dump
sizeof(*addr) is used by default end
Here's a short GDB session that shows what this looks like in practice. Note that the memory location being
examined (``0x200aa9eo`` here) is a buffer being passed to ``mmcsd_readsingle``:
.. code-block::
Program received signal SIGTRAP, Trace/breakpoint trap.
0x200166e8 in up_idle () at common/arm_idle.c:78
78 }
(gdb) b mmcsd_readsingle
Breakpoint 1 at 0x2006ea70: file mmcsd/mmcsd_sdio.c, line 1371.
(gdb) c
Continuing.
Breakpoint 1, mmcsd_readsingle (priv=0x200aa8c0, buffer=0x200aa9e0 "WRTEST TXT \030", startblock=2432) at mmcsd/mmcsd_sdio.c:1371
1371 finfo("startblock=%d\n", startblock);
(gdb) xxd 0x200aa9e0 200
200aa9e0: 5752 5445 5354 2020 5458 5420 1800 0000 WRTEST TXT ....
200aa9f0: 0000 0000 0000 0000 0000 5500 1100 0000 ..........U.....
200aaa00: 5752 5445 5354 3520 5458 5420 1800 0000 WRTEST5 TXT ....
200aaa10: 0000 0000 0000 0000 0000 5800 1500 0000 ..........X.....
200aaa20: e552 5445 5854 3620 5458 5420 1800 0000 .RTEXT6 TXT ....
200aaa30: 0000 0000 0000 0000 0000 5600 1200 0000 ..........V.....
200aaa40: 5752 5445 5354 3620 5458 5420 1800 0000 WRTEST6 TXT ....
200aaa50: 0000 0000 0000 0000 0000 5600 1200 0000 ..........V.....
200aaa60: 0000 0000 0000 0000 0000 0000 0000 0000 ................
200aaa70: 0000 0000 0000 0000 0000 0000 0000 0000 ................
200aaa80: 0000 0000 0000 0000 0000 0000 0000 0000 ................
200aaa90: 0000 0000 0000 0000 0000 0000 0000 0000 ................
200aaaa0: 0000 0000 0000 0000 ........
NuttX Drivers as a Reference
----------------------------
If you're not porting a NuttX driver from another architecture, it still helps to look at other similar NuttX
drivers, if there are any. For instance, when implementing an Ethernet driver, look at other NuttX Ethernet drivers;
for an SD Card driver, look at other NuttX Ethernet drivers. Even if the chip-specific code won't be the same, the
structure to interface with NuttX can be used.
Using Chip Datasheets
---------------------
To port or write a driver, you'll have to be familiar with the information in the chip datasheet. Definitely find
the datasheet for your chip, and read the sections relevant to the peripheral you're working with. Doing so ahead
of time will save a lot of time later.
Another thing that's often helpful is to refer to sample code provided by the manufacturer, or driver code from
another operating system (like U-Boot, Zephyr, or FreeBSD) while referring to the datasheet — seeing how working
code implements the necessary algorithms often helps one understand how the driver needs to work.
* How to use a datasheet
Key pieces of information in System-on-a-Chip (SoC) datasheets are usually:
* Chip Architecture Diagram — shows how the subsections of the chip (CPU, system bus, peripherals, I/O, etc.) connect
to each other.
* Memory Map — showing the location of peripheral registers in memory. This info usually goes into a header file.
* DMA Engine — if Direct Memory Access (DMA) is used, this may have info on how to use it.
* Peripheral — the datasheet usually has a section on how the peripheral works. Key parts of this include:
* Registers List — name and offset from the base memory address of the peripheral. This needs to go into a header
file.
* Register Map — what is the size of each register, and what do the bits mean? You will need to create ``#defines``
in a header file that your code will use to operate on the registers. Refer to other driver header files for
examples.
Logic Analyzers
---------------
For drivers that involve input and output (I/O), especially that involve complex protocols like SD Cards, SPI, I2C,
etc., actually seeing the waveform that goes in and out the chip's pins is extremely helpful. `Logic Analyzers <https://en.wikipedia.org/wiki/Logic_analyzer>`_
can capture that information and display it graphically, allowing you to see if the driver is doing the right thing
on the wire.
DMA Debugging
-------------
* Dump registers before, during, and after transfer. Some NuttX drivers (``sam_sdmmc.c`` or ``imxrt_sdmmc.c`` for
example) have built-in code for debugging register states, and can sample registers before, during, and
immediately after a DMA transfer, as well as code that can dump the peripheral registers in a nicely-formatted
way onto the console device (which can be a serial console, a network console, or memory). Consider using something
like this to see what's happening inside the chip if you're trying to debug DMA transfer code.
* Compare register settings to expected settings determined from the datasheet or from dumping registers from working
code in another operating system (U-Boot, Zephyr, FreeBSD, etc.).
* Use the ``xxd`` GDB tool mentioned above to dump NuttX memory buffers before, during, and after a transfer to see if
data is being transferred correctly, if there are over- or under-runs, or to diagnose data being stored in incorrect
locations.
* printf debugging register states can also help here.
* Remember that logging can change the timing of any algorithms you might be using, so things may start or stop
working when logging is added or removed. Definitely test with logging disabled.
Binary file not shown.

After

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 517 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

@@ -0,0 +1,13 @@
.. todo::
Create "tutorial" type documentation for specific subjects not to be covered in more general terms.
Guides
======
.. toctree::
nfs.rst
usbtrace.rst
simulator.rst
drivers.rst
tasktrace.rst
cpp_cmake.rst
@@ -0,0 +1,284 @@
=================
NFS Client How-To
=================
Adding NFS to the NuttX Configuration
=====================================
The NFS client is easily added to your configuration: You simply need to
add ``CONFIG_NFS`` to your ``nuttx/.config`` file. There are, however, a
few dependencies on other system settings:
First, there are things that you must configure in order to be able to
use any file system:
- ``CONFIG_DISABLE_MOUNTPOINT=n``. You must include support for mount
points in the pseudo-file system.
And there are several dependencies on the networking configuration. At a
minimum, you need to have the following selections:
- ``CONFIG_NET=y``. General networking support.
- ``CONFIG_NET_UDP=y``. Support for UDP.
Mount Interface
===============
A low-level, C-callable interface is provided to mount a file system.
That interface is called ``mount()`` and is mentioned in the
porting guide and is prototyped in the header file ``include/sys/mount.h``:
.. c:function:: int mount(const char *source, const char *target, const char *filesystemtype, unsigned long mountflags, const void *data)
``mount()`` attaches the filesystem specified by the
``source`` block device name into the root file system at the path
specified by ``target``.
:param source: A null-terminated string providing the fill path to a
block driver in the NuttX pseudo-file system.
:param target: The location in the NuttX pseudo-file system where the
volume will be mounted.
:param filesystemtype: A string identifying the type of file system to
use.
:param mountflags: Various flags that can be used to qualify how the
file system is mounted.
:param data: Opaque data that is passed to the file system with the
mount occurs.
:return: Zero is returned on success; -1 is returned on an
error and ``errno`` is set appropriately:
- ``EACCES``. A component of a path was not searchable or mounting a
read-only filesystem was attempted without giving the ``MS_RDONLY``
flag.
- ``EBUSY``. ``source`` is already mounted.
- ``EFAULT``. One of the pointer arguments points outside the user
address space.
- ``EINVAL``. ``source`` had an invalid superblock.
- ``ENODEV``. ``filesystemtype`` not configured
- ``ENOENT``. A pathname was empty or had a nonexistent component.
- ``ENOMEM``. Could not allocate a memory to copy filenames or data
into.
- ``ENOTBLK``. ``source`` is not a block device
This same interface can be used to mount a remote, NFS file system using
some special parameters. The NFS mount differs from the *normal* file
system mount in that: (1) there is no block driver for the NFS file
system, and (2) special parameters must be passed as ``data`` to
describe the remote NFS server. Thus the following code snippet might
represent how an NFS file system is mounted:
.. code-block:: c
#include <sys/mount.h>
#include <nuttx/fs/nfs.h>
struct nfs_args data;
char *mountpoint;
ret = mount(NULL, mountpoint, string "nfs", 0, (FAR void *)&data);
NOTE that: (1) the block driver parameter is ``NULL``. The ``mount()``
is smart enough to know that no block driver is needed with the NFS file
system. (2) The NFS file system is identified with the simple string
"nfs" (3) A reference to ``struct nfs_args`` is passed as an
NFS-specific argument.
The NFS-specific interface is described in the file
``include/nuttx/fs/nfs.h``. There you can see that ``struct nfs_args``
is defined as:
.. code-block:: c
struct nfs_args
{
uint8_t addrlen; /* Length of address */
uint8_t sotype; /* Socket type */
uint8_t flags; /* Flags, determines if following are valid: */
uint8_t timeo; /* Time value in deciseconds (with NFSMNT_TIMEO) */
uint8_t retrans; /* Times to retry send (with NFSMNT_RETRANS) */
uint16_t wsize; /* Write size in bytes (with NFSMNT_WSIZE) */
uint16_t rsize; /* Read size in bytes (with NFSMNT_RSIZE) */
uint16_t readdirsize; /* readdir size in bytes (with NFSMNT_READDIRSIZE) */
char *path; /* Server's path of the directory being mount */
struct sockaddr_storage addr; /* File server address (requires 32-bit alignment) */
};
NFS Mount Command
=================
The :ref:`NuttShell (NSH) <nsh>` also supports a command called
``nfsmount`` that can be used to mount a remote file system via the NSH
command line.
**Command Syntax:**
.. code-block::
fsmount <server-address> <mount-point> <remote-path>
**Synopsis**. The ``nfsmount`` command mounts a network file system in
the NuttX pseudo filesystem. The ``nfsmount`` will use NFSv3 UDP
protocol to mount the remote file system.
**Command Line Arguments**. The ``nfsmount`` takes three arguments:
#. The ``<server-address>`` is the IP address of the server exporting
the file system you wish to mount. This implementation of NFS for the
NuttX RTOS is only for a local area network, so the server and client
must be in the same network.
#. The ``<mount-point >`` is the location in the NuttX pseudo filesystem
where the mounted volume will appear. This mount point can only
reside in the NuttX pseudo filesystem. By convention, this mount
point is a subdirectory under ``/mnt``. The mount command will create
whatever pseudo directories that may be needed to complete the full
path (but the full path must not already exist).
#. The ``<remote-path>`` is the file system ``/`` directory being
exported from server. This ``/`` directory must have been configured
for exportation on the server before when the NFS server was set up.
After the volume has been mounted in the NuttX pseudo filesystem, it may
be access in the same way as other objects in the file system.
**Example**. Suppose that the NFS server has been configured to export
the directory ``/export/shared``. The the following command would mount
that file system (assuming that the target also has privileges to mount
the file system).
.. code-block:: fish
NuttShell (NSH)
nsh> ls /mnt
/mnt:
nsh: ls: no such directory: /mnt
nsh> nfsmount 10.0.0.1 /mnt/nfs /export/shared
nsh> ls -l /mnt/nfs
/mnt/nfs:
drwxrwxrwx 4096 ..
drwxrwxrwx 4096 testdir/
-rw-rw-rw- 6 ctest.txt
-rw-r--r-- 15 btest.txt
drwxrwxrwx 4096 .
nsh> echo "This is a test" >/mnt/nfs/testdir/testfile.txt
nsh> ls -l /mnt/nfs/testdir
/mnt/nfs/testdir:
-rw-rw-rw- 21 another.txt
drwxrwxrwx 4096 ..
drwxrwxrwx 4096 .
-rw-rw-rw- 16 testfile.txt
nsh> cat /mnt/nfs/testdir/testfile.txt
This is a test
Configuring the NFS server (Ubuntu)
===================================
Setting up the server will be done in two steps: First, setting up the
configuration file for NFS, and then starting the NFS services. But
first, you need to install the nfs server on Ubuntu with these two
commands:
.. code-block:: console
# sudo apt-get install nfs-common
# sudo apt-get install nfs-kernel-server
After that, we need to make or choose the directory we want to export
from the NFS server. In our case, we are going to make a new directory
called ``/export``.
.. code-block:: console
# sudo mkdir /export
It is important that ``/export`` directory allow access to everyone (777
permissions) as we will be accessing the NFS share from the client with
no authentication.
.. code-block:: console
# sudo chmod 777 /export
When all this is done, we will need to edit the configuration file to
set up an NFS server: ``/etc/exports``. This file contains a list of
entries; each entry indicates a volume that is shared and how it is
shared. For more information for a complete description of all the setup
options for this file you can check in the man pages (``man export``).
An entry in ``/etc/exports`` will typically look like this:
.. code-block::
directory machine1(option11,option12)
So for our example we export ``/export`` to the client 10.0.0.2 add the
entry:
.. code-block::
/export 10.0.0.2(rw)
In our case we are using all the default options except for the ``ro``
that we replaced with ``rw`` so that our client will have read and write
access to the directory that we are exporting.
After we do all the require configurations, we are ready to start the
server with the next command:
.. code-block:: console
# sudo /etc/init.d/nfs-kernel-server start
Note: If you later decide to add more NFS exports to the /etc/exports
file, you will need to either restart NFS daemon or run command
exportfs.
.. code-block:: console
# sudo /etc/init.d/nfs-kernel-server start
Or
.. code-block:: console
# exportfs -ra
Now we can check if the export directory and our mount point is properly
set up.
.. code-block:: console
# sudo showmount -e
# sudo showmount -a
And also we can verify if NFS is running in the system with:
.. code-block:: console
# rpcinfo p
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100011 1 udp 749 rquotad
100011 2 udp 749 rquotad
100005 1 udp 759 mountd
100005 1 tcp 761 mountd
100005 2 udp 764 mountd
100005 2 tcp 766 mountd
100005 3 udp 769 mountd
100005 3 tcp 771 mountd
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
300019 1 tcp 830 amd
300019 1 udp 831 amd
100024 1 udp 944 status
100024 1 tcp 946 status
100021 1 udp 1042 nlockmgr
100021 3 udp 1042 nlockmgr
100021 4 udp 1042 nlockmgr
100021 1 tcp 1629 nlockmgr
100021 3 tcp 1629 nlockmgr
100021 4 tcp 1629 nlockmgr
Now your NFS sever is sharing ``/export`` directory to be accessed.
@@ -0,0 +1,189 @@
.. include:: /substitutions.rst
.. _simulator:
Simulator
=========
Apache NuttX has a simulator that can run as a regular program on Linux, Mac, and Windows computers.
It's useful for debugging operating system features that aren't associated with particular
device drivers— for instance the TCP/IP stack itself, a web interface or API for your
application, or other communication protocols. It's also handy for trying out Apache NuttX without
having a piece of embedded hardware.
This guide assumes you're on Linux. It works on Windows and Mac too— if you know how,
submit a PR to improve this guide!
.. todo:: Add Mac and Windows instructions
Compiling
---------
#. Configure the Simulator
There are a lot of simulator configurations available that set you up to test various
operating system features.
Here we'll use the ``sim:nsh`` basic NuttX Shell configuration.
.. code-block:: console
$ cd nuttx
$ ./tools/configure.sh sim:nsh
#. Compile
.. code-block:: console
$ make
#. Run the simulator:
.. code-block:: console
$ ./nuttx
login: admin
password: Administrator
User Logged-in!
NuttShell (NSH) NuttX-9.1.0
MOTD: username=admin password=Administrator
nsh> help
help usage: help [-v] [<cmd>]
[ cp exit losetup mv rmdir true
? cmp false ls mw set uname
basename dirname free mb poweroff sh unset
break dd help mkdir ps sleep usleep
cat echo hexdump mkfatfs pwd test xd
cd exec kill mh rm time
Builtin Apps:
hello nsh
nsh>
#. Stop the simulator:
.. code-block:: console
nsh> poweroff
$
$ # we're back at the Linux prompt.
Accessing the Network
---------------------
#. Here we'll use the ``sim:tcpblaster`` configuration because it comes with networking
that is ready to use.
.. code-block:: console
$ make distclean
$ ./tools/configure.sh sim:tcpblaster
$ make
#. Give the Simulator Privileges
On recent Linux distributions, you need to give the ``nuttx`` program the capabilities
(similar to permissions) to access the network:
.. code-block:: console
$ sudo setcap cap_net_admin+ep ./nuttx
#. Run the simulator:
.. code-block:: console
$ ./nuttx
#. Bring Up the Network Interfaces
On Apache NuttX:
.. code-block:: console
nsh> ifup eth0
On Linux, first you need to find your main network interface— this will usually either
be an ethernet or wireless network adapter. Do this:
.. code-block:: console
$ ifconfig
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 5846 bytes 614351 (614.3 KB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 5846 bytes 614351 (614.3 KB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
wlp0s20f3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.1.209 netmask 255.255.255.0 broadcast 192.168.1.255
inet6 fe80::1161:c26b:af05:d784 prefixlen 64 scopeid 0x20<link>
ether 24:41:8c:a8:30:d1 txqueuelen 1000 (Ethernet)
RX packets 219369 bytes 176416490 (176.4 MB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 108399 bytes 27213617 (27.2 MB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
``lo0`` is the Loopback Interface, so ``wlp0s20f3`` is the wireless interface. Note
that it has an IP address on the local net. There may be other interfaces listed, you'll
need to pick the one that's right for your system.
Then, on Linux do this to set up the tap network interface and route that will let
the Apache NuttX simulator access the network:
.. code-block:: console
$ sudo ./tools/simhostroute.sh wlp0s20f3 on
$ ping -c 1 10.0.1.2 # nuttx system
PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data.
64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=7.52 ms
--- 10.0.1.2 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 7.529/7.529/7.529/0.000 m
#. Test that Apache NuttX can access the Internet
First let's ping the network interface of our Linux host to prove we can see the
gateway to the Internet:
.. code-block:: console
nsh> ping -c 1 10.0.1.1
nsh> ping -c 1 10.0.1.1
PING 10.0.1.1 56 bytes of data
56 bytes from 10.0.1.1: icmp_seq=0 time=0 ms
1 packets transmitted, 1 received, 0% packet loss, time 1010 ms
Now let's ping one of Google's DNS servers to prove we can access the rest of the
Internet:
.. code-block:: console
nsh> ping -c 1 8.8.8.8
PING 8.8.8.8 56 bytes of data
56 bytes from 8.8.8.8: icmp_seq=0 time=10 ms
1 packets transmitted, 1 received, 0% packet loss, time 1010 ms
Success!
Stopping
--------
If you don't have an nsh prompt, the only effective way to stop the simulator is kill it from another terminal:
.. code-block:: console
$ pkill nuttx
Debugging
---------
You can debug the simulator like any regular Linux program.
@@ -0,0 +1,20 @@
==========
Task Trace
==========
Task Trace is the tool to collect the various events in the NuttX kernel and display the result graphically.
It can collect the following events.
- Task execution, termination, switching
- System call enter/leave
- Interrupt handler enter/leave
.. toctree::
:maxdepth: 1
:caption: Contents:
tasktraceuser.rst
tasktraceinternal.rst
.. image:: image/task-trace-overview.png
@@ -0,0 +1,96 @@
====================
Task Trace Internals
====================
Overview
========
.. image:: image/task-trace-internal.png
The Task Trace is constructed by the following functions.
NuttX kernel events collection
------------------------------
The kernel events are collected by ``sched_note_*()`` API calls embedded in NuttX kernel.
- For task switch events
- ``sched_note_start()``
- ``sched_note_stop()``
- ``sched_note_suspend()``
- ``sched_note_resume()``
- For system call events
- ``sched_note_syscall_enter()``
- ``sched_note_syscall_leave()``
- For interrupt event
- ``sched_note_irqhandler()``
Filter logic (``nuttx/sched/sched_note.c``)
-------------------------------------------
- The ``sched_note_*()`` APIs are implemented here.
- Filter the notes and pass them to noteram driver by ``sched_note_add()`` API.
Noteram device driver (``nuttx/drivers/note/noteram_driver.c``)
---------------------------------------------------------------
- Accumurate incoming note records into the buffer.
- Read the note records from the buffer by user requests.
- The notes are recorded in the binary format of ``struct note_*_s``.
- The detail function is described in :doc:`../components/drivers/character/note`.
Notectl device driver (``nuttx/drivers/note/notectl_driver.c``)
---------------------------------------------------------------
- ``/dev/notectl`` device driver.
- Control the filter logic in ``sched_note.c`` by calling note filter APIs.
- The detail function is described in :doc:`../components/drivers/character/note`.
"``trace``" Built-In Application (``apps/system/trace/trace.c``)
----------------------------------------------------------------
- ``trace`` Built-In Application to control the trace function interactively.
- Read binary note records from ``/dev/note`` and convert into the ftrace text format which is acceptable by `"Trace Compass" <https://www.eclipse.org/tracecompass/>`_.
- The command syntax is described in :doc:`tasktraceuser`.
Getting the system call events
==============================
To get the system call events, two different methods are used for FLAT build and PROTECTED/KERNEL build.
FLAT build
----------
In FLAT build, a system call is just a function call into the NuttX kernel.
.. image:: image/syscall-flat-before.png
To get the system call events, `wrapper function option <https://sourceware.org/binutils/docs/ld/Options.html#index-_002d_002dwrap_003dsymbol>`_ of the GNU Linker is used.
The mksyscall tool is fixed to generate the system call wrapper which call system call enter/leave hook.
The wrapper supersedes the system call function call of the NuttX binary by passing ``--wrap`` linker option to the build system.
The wrapper calls the system call hooks before and after calling the real system call function.
.. image:: image/syscall-flat-after.png
PROTECTED/KERNEL build
----------------------
Different to FLAT build, in PROTECTED and KERNEL build, a system call is issued by an user space is handled as the following steps.
#. System call issued by an application code is handled by the system call proxy (automatically generated by mksyscall).
#. System call proxy issues the supervisor call instruction to enter into the kernel space.
#. System call handler in the kernel space calls the system call stub (automatically generated by mksyscall).
#. System call stub calls the API implementation in the NuttX kernel.
.. image:: image/syscall-protected-before.png
To get the system call events, the mksyscall tool is fixed to generate the system call wrapper which supersedes the system call function call in the system call stub.
.. image:: image/syscall-protected-after.png
@@ -0,0 +1,366 @@
=====================
Task Trace User Guide
=====================
Installation
============
Install Trace Compass
---------------------
Task Trace uses the external tool `"Trace Compass" <https://www.eclipse.org/tracecompass/>`_ to display the trace result.
Download it from https://www.eclipse.org/tracecompass/ and install into the host environment.
After the installation, execute it and choose ``Tools`` -> ``add-ons`` menu, then select ``Install Extensions`` to install the extension named "Trace Compass ftrace (Incubation)".
NuttX kernel configuration
--------------------------
To enable the task trace function, the NuttX kernel configuration needs to be modified.
The following configurations must be enabled.
- ``CONFIG_SCHED_INSTRUMENTATION`` : Enables the feature of scheduler notes.
- ``CONFIG_SCHED_INSTRUMENTATION_FILTER`` : Enables the filter logic of the notes.
- ``CONFIG_SCHED_INSTRUMENTATION_SYSCALL`` : Enable system call instrumentation.
- ``CONFIG_SCHED_INSTRUMENTATION_IRQHANDLER`` : Enables IRQ instrumentation.
- ``CONFIG_DRIVER_NOTE`` : Enables note driver support.
- ``CONFIG_DRIVER_NOTERAM`` : Enables ``/dev/note`` in-memory buffering driver.
- ``CONFIG_DRIVER_NOTECTL`` : Enables ``/dev/notectl`` filter control driver.
- ``CONFIG_SYSTEM_TRACE`` : Enables "``trace``" command
- ``CONFIG_SYSTEM_SYSTEM`` : Enables "``system``" command (required by :ref:`trace_cmd`)
The following configurations are configurable parameters for trace.
- ``CONFIG_SCHED_INSTRUMENTATION_FILTER_DEFAULT_MODE``
- Specify the default filter mode.
If the following bits are set, the corresponding instrumentations are enabled on boot.
- Bit 0 = Enable instrumentation
- Bit 1 = Enable syscall instrumentation
- Bit 2 = Enable IRQ instrumentation
- Bit 3 = Enable collecting syscall arguments
- ``CONFIG_SCHED_INSTRUMENTATION_HIRES``
- If enabled, use higher resolution system timer for instrumentation.
- ``CONFIG_DRIVER_NOTERAM_BUFSIZE``
- Specify the note buffer size in bytes.
Higher value can hold more note records, but consumes more kernel memory.
- ``CONFIG_DRIVER_NOTERAM_TASKNAME_BUFSIZE``
- Specify the task name buffer size in bytes.
The buffer is used to hold the name of the task during instrumentation.
Trace dump can find and show a task name corresponding to given pid in the instrumentation data by using this buffer.
If 0 is specified, this feature is disabled and trace dump shows only the name of the newly created task.
- ``CONFIG_DRIVER_NOTERAM_DEFAULT_NOOVERWRITE``
- If enabled, stop overwriting old notes in the circular buffer when the buffer is full by default.
This is useful to keep instrumentation data of the beginning of a system boot.
After the configuration, rebuild the NuttX kernel and application.
If the trace function is enabled, "``trace``" :doc:`../applications/nsh/builtin` will be available.
How to get trace data
=====================
The trace function can be controlled by "``trace``" command.
Quick Guide
-----------
Getting the trace
^^^^^^^^^^^^^^^^^
Trace is started by the following command.
.. code-block::
nsh> trace start
Trace is stopped by the following command.
.. code-block::
nsh> trace stop
If you want to get the trace while executing some command, the following command can be used.
.. code-block::
nsh> trace cmd <command> [<args>...]
Displaying the trace result
^^^^^^^^^^^^^^^^^^^^^^^^^^^
The trace result is accumulated in the memory.
After getting the trace, the following command displays the accumulated trace data to the console.
.. code-block::
nsh> trace dump
This will be get the trace results like the followings:
.. code-block::
<noname>-1 [0] 7.640000000: sys_close()
<noname>-1 [0] 7.640000000: sys_close -> 0
<noname>-1 [0] 7.640000000: sys_sched_lock()
<noname>-1 [0] 7.640000000: sys_sched_lock -> 0
<noname>-1 [0] 7.640000000: sys_nxsched_get_stackinfo()
<noname>-1 [0] 7.640000000: sys_nxsched_get_stackinfo -> 0
<noname>-1 [0] 7.640000000: sys_sched_unlock()
<noname>-1 [0] 7.640000000: sys_sched_unlock -> 0
<noname>-1 [0] 7.640000000: sys_clock_nanosleep()
<noname>-1 [0] 7.640000000: sched_switch: prev_comm=<noname> prev_pid=1 prev_state=S ==> next_comm=<noname> next_pid=0
<noname>-0 [0] 7.640000000: irq_handler_entry: irq=11
<noname>-0 [0] 7.640000000: irq_handler_exit: irq=11
<noname>-0 [0] 7.640000000: irq_handler_entry: irq=15
<noname>-0 [0] 7.650000000: irq_handler_exit: irq=15
<noname>-0 [0] 7.650000000: irq_handler_entry: irq=15
:
By using the logging function of your terminal software, the trace result can be saved into the host environment and it can be used as the input for `"Trace Compass" <https://www.eclipse.org/tracecompass/>`_.
If the target has a storage, the trace result can be stored into the file by using the following command.
It also can be used as the input for "Trace Compass" by transferring the file in the target device to the host.
.. code-block::
nsh> trace dump <file name>
To display the trace result by `"Trace Compass" <https://www.eclipse.org/tracecompass/>`_, choose ``File`` -> ``Open Trace`` menu to specify the trace data file name.
.. image:: image/trace-compass-screenshot.png
Trace command description
=========================
.. _trace_start:
trace start
-----------
Start task tracing
**Command Syntax:**
.. code-block::
trace start [-c][<duration>]
- ``-c`` : Continue the previous trace.
The trace data is not cleared before starting new trace.
- ``<duration>`` : Specify the duration of the trace by seconds.
Task tracing is stopped after the specified period.
If not specified, the tracing continues until stopped by the command.
.. _trace_stop:
trace stop
----------
Stop task tracing
**Command Syntax:**
.. code-block::
trace stop
.. _trace_cmd:
trace cmd
---------
Get the trace while running the specified command.
After the termination of the command, task tracing is stopped.
To use this command, ``CONFIG_SYSTEM_SYSTEM`` needs to be enabled.
**Command Syntax:**
.. code-block::
trace cmd [-c] <command> [<args>...]
- ``-c`` : Continue the previous trace.
The trace data is not cleared before starting new trace.
- ``<command>`` : Specify the command to get the task trace.
- ``<args>`` : Arguments for the command.
**Example:**
.. code-block::
nsh> trace cmd sleep 1
.. _trace_dump:
trace dump
----------
Output the trace result.
If the task trace is running, it is stopped before the output.
**Command Syntax:**
.. code-block::
trace dump [-c][<filename>]
- ``-c`` : Not stop tracing before the output.
Because dumping trace itself is a task activity and new trace data is added while output, the dump will never stop.
- ``<filename>`` : Specify the filename to save the trace result.
If not specified, the trace result is displayed to console.
.. _trace_mode:
trace mode
----------
Set the task trace mode options.
The default value is given by the kernel configuration ``CONFIG_SCHED_INSTRUMENTATION_FILTER_DEFAULT_MODE``.
**Command Syntax:**
.. code-block::
trace mode [{+|-}{o|s|a|i}...]
- ``+o`` : Enable overwrite mode.
The trace buffer is a ring buffer and it can overwrite old data if no free space is available in the buffer.
Enables this behavior.
- ``-o`` : Disable overwrite mode.
The new trace data will be disposed when the buffer is full.
This is useful to keep the data of the beginning of the trace.
- ``+s`` : Enable system call trace.
It records the event of enter/leave system call which is issued by the application.
All system calls are recorded by default. ``trace syscall`` command can filter the system calls to be recorded.
- ``-s`` : Disable system call trace.
- ``+a`` : Enable recording the system call arguments.
It records the arguments passed to the issued system call to the trace data.
- ``-a`` : Disable recording the system call arguments.
- ``+i`` : Enable interrupt trace.
It records the event of enter/leave interrupt handler which is occured while the tracing.
All IRQs are recorded by default. ``trace irq`` command can filter the IRQs to be recorded.
- ``-i`` : Disable interrupt trace.
If no command parameters are specified, display the current mode as the follows.
**Example:**
.. code-block::
nsh> trace mode
Task trace mode:
Trace : enabled
Overwrite : on (+o)
Syscall trace : on (+s)
Filtered Syscalls : 16
Syscall trace with args : on (+a)
IRQ trace : on (+i)
Filtered IRQs : 2
.. _trace_syscall:
trace syscall
-------------
Configure the filter of the system call trace.
**Command Syntax:**
.. code-block::
trace syscall [{+|-}<syscallname>...]
- ``+<syscallname>`` : Add the specified system call name to the filter.
The execution of the filtered system call is not recorded into the trace data.
- ``-<syscallname>`` : Remove the specified system call name from the filter.
Wildcard "``*``" can be used to specify the system call name.
For example, "``trace syscall +sem_*``" filters the system calls begin with "``sem_``", such as ``sem_post()``, ``sem_wait()``,...
If no command parameters are specified, display the current filter settings as the follows.
**Example:**
.. code-block:: console
nsh> trace syscall
Filtered Syscalls: 16
getpid
sem_destroy
sem_post
sem_timedwait
sem_trywait
sem_wait
mq_close
mq_getattr
mq_notify
mq_open
mq_receive
mq_send
mq_setattr
mq_timedreceive
mq_timedsend
mq_unlink
.. _trace_irq:
trace irq
---------
Configure the filter of the interrupt trace.
**Command Syntax:**
.. code-block::
trace irq [{+|-}<irqnum>...]
- ``+<irqnum>`` : Add the specified IRQ number to the filter.
The execution of the filtered IRQ handler is not recorded into the trace data.
- ``-<irqnum>`` : Remove the specified IRQ number from the filter.
Wildcard "``*``" can be used to specify all IRQs.
If no command parameters are specified, display the current filter settings as the follows.
**Example:**
.. code-block:: console
nsh> trace irq
Filtered IRQs: 2
11
15
@@ -0,0 +1,216 @@
.. _usbtrace:
================
USB Device Trace
================
**USB Device Tracing Controls**. The NuttX USB device subsystem supports
a fairly sophisticated tracing facility. The basic trace cabability is
controlled by these NuttX configuration settings:
- ``CONFIG_USBDEV_TRACE``: Enables USB tracing
- ``CONFIG_USBDEV_TRACE_NRECORDS``: Number of trace entries to remember
**Trace IDs**. The trace facility works like this: When enabled, USB
events that occur in either the USB device driver or in the USB class
driver are logged. These events are described in
``include/nuttx/usb/usbdev_trace.h``. The logged events are identified
by a set of event IDs:
========================= ==================================
``TRACE_INIT_ID`` Initialization events
``TRACE_EP_ID`` Endpoint API calls
``TRACE_DEV_ID`` USB device API calls
``TRACE_CLASS_ID`` USB class driver API calls
``TRACE_CLASSAPI_ID`` Other class driver system API calls
``TRACE_CLASSSTATE_ID`` Track class driver state changes
``TRACE_INTENTRY_ID`` Interrupt handler entry
``TRACE_INTDECODE_ID`` Decoded interrupt event
``TRACE_INTEXIT_ID`` Interrupt handler exit
``TRACE_OUTREQQUEUED_ID`` Request queued for OUT endpoint
``TRACE_INREQQUEUED_ID`` Request queued for IN endpoint
``TRACE_READ_ID`` Read (OUT) action
``TRACE_WRITE_ID`` Write (IN) action
``TRACE_COMPLETE_ID`` Request completed
``TRACE_DEVERROR_ID`` USB controller driver error event
``TRACE_CLSERROR_ID`` USB class driver error event
========================= ==================================
**Logged Events**. Each logged event is 32-bits in size and includes
#. 8-bits of the trace ID (values associated with the above)
#. 8-bits of additional trace ID data, and
#. 16-bits of additional data.
**8-bit Trace Data** The 8-bit trace data depends on the specific event
ID. As examples,
- For the USB serial and mass storage class, the 8-bit event data is
provided in ``include/nuttx/usb/usbdev_trace.h``.
- For the USB device driver, that 8-bit event data is provided within
the USB device driver itself. So, for example, the 8-bit event data
for the LPC1768 USB device driver is found in
``arch/arm/src/lpc17xx_40xx/lpc17_40_usbdev.c``.
**16-bit Trace Data**. The 16-bit trace data provided additional context
data relevant to the specific logged event.
**Trace Control Interfaces**. Logging of each of these kinds events can
be enabled or disabled using the interfaces described in
``include/nuttx/usb/usbdev_trace.h``.
**Enabling USB Device Tracing**. USB device tracing will be configured
if ``CONFIG_USBDEV`` and either of the following are set in the NuttX
configuration file:
- ``CONFIG_USBDEV_TRACE``, or
- ``CONFIG_DEBUG_FEATURES and CONFIG_DEBUG_USB``
**Log Data Sink**. The logged data itself may go to either (1) an
internal circular buffer, or (2) may be provided on the console. If
``CONFIG_USBDEV_TRACE`` is defined, then the trace data will go to the
circular buffer. The size of the circular buffer is determined by
``CONFIG_USBDEV_TRACE_NRECORDS``. Otherwise, the trace data goes to
console.
**Example**. Here is an example of USB trace output using
``apps/examples/usbserial`` for an LPC1768 platform with the following
NuttX configuration settings:
- ``CONFIG_DEBUG_FEATURES``, ``CONFIG_DEBUG_INFO``, ``CONFIG_USB``
- ``CONFIG_EXAMPLES_USBSERIAL_TRACEINIT``,
``CONFIG_EXAMPLES_USBSERIAL_TRACECLASS``,
``CONFIG_EXAMPLES_USBSERIAL_TRACETRANSFERS``,
``CONFIG_EXAMPLES_USBSERIAL_TRACECONTROLLER``,
``CONFIG_EXAMPLES_USBSERIAL_TRACEINTERRUPTS``
Console Output::
ABDE
usbserial_main: Registering USB serial driver
uart_register: Registering /dev/ttyUSB0
usbserial_main: Successfully registered the serial driver
1 Class API call 1: 0000
2 Class error: 19:0000
usbserial_main: ERROR: Failed to open /dev/ttyUSB0 for reading: 107
usbserial_main: Not connected. Wait and try again.
3 Interrupt 1 entry: 0039
4 Interrupt decode 7: 0019
5 Interrupt decode 32: 0019
6 Interrupt decode 6: 0019
7 Class disconnect(): 0000
8 Device pullup(): 0001
9 Interrupt 1 exit: 0000
The numbered items are USB USB trace output. You can look in the file
``drivers/usbdev/usbdev_trprintf.c`` to see examctly how each output
line is formatted. Here is how each line should be interpreted:
== ==================== ================ ================================== =================
N. USB EVENT ID 8-bit EVENT DATA MEANING 16-bit EVENT DATA
1 TRACE_CLASSAPI_ID1 1 USBSER_TRACECLASSAPI_SETUP1 0000
2 TRACE_CLSERROR_ID1 19 USBSER_TRACEERR_SETUPNOTCONNECTED1 0000
3 TRACE_INTENTRY_ID1 1 LPC17_40_TRACEINTID_USB2 0039
4 TRACE_INTDECODE_ID2 7 LPC17_40_TRACEINTID_DEVSTAT2 0019
5 TRACE_INTDECODE_ID2 32 LPC17_40_TRACEINTID_SUSPENDCHG2 0019
6 TRACE_INTDECODE_ID2 6 LPC17_40_TRACEINTID_DEVRESET2 0019
7 TRACE_CLASS_ID1 3 (See TRACE_CLASSDISCONNECT1) 0000
8 TRACE_DEV_ID1 6 (See TRACE_DEVPULLUP1) 0001
9 TRACE_INTEXIT_ID1 1 LPC17_40_TRACEINTID_USB2 0000
== ==================== ================ ================================== =================
NOTES:
1. See include/nuttx/usb/usbdev_trace.h
2. See arch/arm/src/lpc17xx_40xx/lpc17_40_usbdev.c
In the above example you can see that:
- **1**. The serial class USB setup method was called for the USB
serial class. This is the corresponds to the following logic in
``drivers/usbdev/pl2303.c``:
.. code-block:: c
static int pl2303_setup(FAR struct uart_dev_s *dev)
{
...
usbtrace(PL2303_CLASSAPI_SETUP, 0);
...
- **2**. An error occurred while processing the setup command because
no configuration has yet been selected by the host. This corresponds
to the following logic in ``drivers/usbdev/pl2303.c``:
.. code-block:: c
static int pl2303_setup(FAR struct uart_dev_s *dev)
{
...
/* Check if we have been configured */
if (priv->config == PL2303_CONFIGIDNONE)
{
usbtrace(TRACE_CLSERROR(USBSER_TRACEERR_SETUPNOTCONNECTED), 0);
return -ENOTCONN;
}
...
- **3-6**. Here is a USB interrupt that suspends and resets the device.
- **7-8**. During the interrupt processing the serial class is
disconnected
- **9**. And the interrupt returns
**USB Monitor**. The *USB monitor* is an application in the
``apps/system/usbmonitor`` that provides a convenient way to get debug
trace output. If tracing is enabled, the USB device will save encoded
trace output in in-memory buffer; if the USB monitor is also enabled,
that trace buffer will be periodically emptied and dumped to the system
logging device (the serial console in most configurations). The
following are some of the relevant configuration options:
=========================================== ===================================================
Device Drivers -> USB Device Driver Support .
``CONFIG_USBDEV_TRACE=y`` Enable USB trace feature
``CONFIG_USBDEV_TRACE_NRECORDS=nnnn`` Buffer nnnn records in memory. If you lose trace data,
. then you will need to increase the size of this buffer
. (or increase the rate at which the trace buffer is emptied).
``CONFIG_USBDEV_TRACE_STRINGS=y`` Optionally, convert trace ID numbers to strings.
. This feature may not be supported by all drivers.
=========================================== ===================================================
=========================================== ===================================================
Application Configuration -> NSH LIbrary .
``CONFIG_NSH_USBDEV_TRACE=n`` Make sure that any built-in tracing from NSH is disabled.
``CONFIG_NSH_ARCHINIT=y`` Enable this option only if your board-specific logic
. has logic to automatically start the USB monitor.
. Otherwise the USB monitor can be started or stopped
. with the usbmon_start and usbmon_stop commands from the NSH console.
=========================================== ===================================================
=============================================== ============================================
Application Configuration -> System NSH Add-Ons .
``CONFIG_USBMONITOR=y`` Enable the USB monitor daemon
``CONFIG_USBMONITOR_STACKSIZE=nnnn`` Sets the USB monitor daemon stack size to nnnn. The default is 2KiB.
``CONFIG_USBMONITOR_PRIORITY=50`` Sets the USB monitor daemon priority to nnnn.
. This priority should be low so that it does not
. interfere with other operations, but not so low that
. you cannot dump the buffered USB data sufficiently
. rapidly. The default is 50.
``CONFIG_USBMONITOR_INTERVAL=nnnn`` Dump the buffered USB data every nnnn seconds.
. If you lose buffered USB trace data, then dropping
. this value will help by increasing the rate at which
. the USB trace buffer is emptied.
``CONFIG_USBMONITOR_TRACEINIT=y`` Selects which USB event(s) that you want to be traced.
``CONFIG_USBMONITOR_TRACECLASS=y`` .
``CONFIG_USBMONITOR_TRACETRANSFERS=y`` .
``CONFIG_USBMONITOR_TRACECONTROLLER=y`` .
``CONFIG_USBMONITOR_TRACEINTERRUPTS=y`` .
=============================================== ============================================
NOTE: If USB debug output is also enabled, both outputs will appear on
the serial console. However, the debug output will be asynchronous with
the trace output and, hence, difficult to interpret.
@@ -0,0 +1,34 @@
.. note::
The present documentation is a recent addition to NuttX and was migrated from previous
documentation content. For this reason, it is possible you may find broken links or
formatting errors. You can help contribute fixes or improvements to this documentation
by following these :doc:`instructions <contributing/documentation>`.
.. tip::
You can find the old documentation `here <https://cwiki.apache.org/confluence/display/NUTTX/Documentation>`_.
===================
NuttX Documentation
===================
NuttX is a real-time operating system (RTOS) with an emphasis on standards compliance and small footprint. Scalable from 8-bit to 64-bit microcontroller environments, the primary governing standards in NuttX are POSIX and ANSI standards. Additional standard APIs from Unix and other common RTOSs (such as VxWorks) are adopted for functionality not available under these standards, or for functionality that is not appropriate for deeply-embedded environments (such as fork()).
Last Updated: |today|
.. toctree::
:caption: Table of Contents
:maxdepth: 2
Home <self>
introduction/index.rst
quickstart/index.rst
introduction/inviolables.rst
platforms/index.rst
components/index.rst
applications/index.rst
reference/index.rst
guides/index.rst
contributing/index.rst
glossary.rst
.. include:: substitutions.rst
@@ -0,0 +1,281 @@
==================
About Apache NuttX
==================
NuttX is a real time embedded operating system (RTOS). Its goals are:
* **Small Footprint**
Usable in all but the tightest micro-controller environments, the focus is on the
tiny-to-small, deeply embedded environment.
* **Rich Feature OS Set**
The goal is to provide implementations of most standard POSIX OS interfaces to support a
rich, multi-threaded development environment for deeply embedded processors.
NON-GOALS: It is not a goal to provide the level of OS features like those provided by Linux. In order to work with
smaller MCUs, small footprint must be more important than an extensive feature set. But standard compliance is more
important than small footprint. Surely a smaller RTOS could be produced by ignoring standards. Think of NuttX is a
tiny Linux work-alike with a much reduced feature set.
* **Highly Scalable**
Fully scalable from tiny (8-bit) to moderate embedded (64-bit). Scalability with rich feature set
is accomplished with: Many tiny source files, link from static libraries, highly configurable,
use of weak symbols when available.
* **Standards Compliance**
NuttX strives to achieve a high degree of standards compliance. The primary governing standards
are POSIX and ANSI standards. Additional standard APIs from Unix and other common RTOS's are
adopted for functionality not available under these standards or for functionality that is not
appropriate for the deeply-embedded RTOS (such as ``fork()``).
Because of this standards conformance, software developed under other standard OSs (such as
Linux) should port easily to NuttX.
* **Real-Time**
Fully pre-emptible; fixed priority, round-robin, and "sporadic" scheduling.
* **Totally Open**
Non-restrictive Apache license.
* **GNU Toolchains**
Compatible GNU toolchains based on `buildroot <http://buildroot.uclibc.org/>`__ available for `download <https://bitbucket.org/nuttx/buildroot/downloads/>`__
to provide a complete development environment for many architectures.
Feature Set
===========
Key features of NuttX include:
* **Standards Compliant Core Task Management**
* Fully pre-emptible.
* Naturally scalable.
* Highly configurable.
* Easily extensible to new processor architectures, SoC architecture, or board architectures. :doc:`/reference/os/index` is available.
* FIFO and round-robin scheduling.
* Realtime, deterministic, with support for priority inheritance
* Tickless Operation
* POSIX/ANSI-like task controls, named message queues, counting semaphores, clocks/timers,
signals, pthreads, robust mutexes, cancellation points, environment variables, filesystem.
* Standard default signal actions (optional).
* VxWorks-like task management and watchdog timers.
* BSD socket interface.
* Extensions to manage pre-emption.
* Optional tasks with address environments (*Processes*).
* Loadable kernel modules; lightweight, embedded shared libraries.
* Memory Configurations: (1) Flat embedded build, (2) Protected build with MPU, and (3) Kernel build with MMU.
* Memory Allocators: (1) standard heap memory allocation, (2) granule allocator, (3) shared memory, and
(4) dynamically sized, per-process heaps.
* Inheritable "controlling terminals" and I/O re-direction.
* Pseudo-terminals
* On-demand paging.
* System logging.
* May be built either as an open, flat embedded RTOS or as a separately built, secure, monolithic kernel with a
system call interface.
* Built-in, per-thread CPU load measurements.
* Well documented in the NuttX User Guide.
* **File system**
* Tiny, in-memory, root pseudo-file-system.
* Virtual file system (VFS) supports drivers and mountpoints.
* Mount-able volumes. Bind mountpoint, filesystem, and block device driver.
* Generic system logging (SYSLOG) support.
* FAT12/16/32 filesystem support with optional FAT long file name support1.
* NFS Client. Client side support for a Network File System (NFS, version 3, UDP).
* NXFFS. The tiny NuttX wear-leveling FLASH file system.
* SMART. FLASH file system from Ken Pettit.
* SPIFFS. FLASH file system, originally by Peter Anderson.
* LittleFS. FLASH file system from ARM mbed..
* ROMFS filesystem support (XIP capable).
* CROMFS (Compressed ROMFS) filesystem support.
* TMPFS RAM filesystem support.
* BINFS pseudo-filesystem support.
* HOSTFS filesystem support (simulation only).
* Union filesystem - Supports combining and overlaying file systems.
* UserFS - User application file system.
* ``procfs/`` pseudo-filesystem support.
* :doc:`/components/binfmt` with support for the following formats:
- Separately linked ELF modules.
- Separately linked :doc:`/components/nxflat` modules. NXFLAT is a binary format that can be XIP from a
file system.
- "Built-In" applications.
* PATH variable support.
* File transfers via TFTP and FTP (``get`` and ``put``), HTML (``wget``), and Zmodem (``sz``
and ``rz``). Intel HEX file conversions.
* FAT long file name support may be subject to certain Microsoft patent restrictions if enabled.
See the top-level ``NOTICE`` file for details.
* **Device Drivers**
* Supports character and block drivers as well as specialized driver interfaces.
* Full VFS integration. Asynchronous I/O (AIO)
* Network, USB (host), USB (device), serial, I2C, I2S, NAND, CAN, ADC, DAC, PWM, Quadrature Encoder, I/O Expander, Wireless,
generic timer, and watchdog timer driver architectures.
* RAMDISK, pipes, FIFO, ``/dev/null``, ``/dev/zero``, ``/dev/random``, and loop drivers.
* Generic driver for SPI-based or SDIO-based MMC/SD/SDH cards.
* Graphics: framebuffer drivers, graphic- and segment-LCD drivers. VNC server.
* Audio subsystem: CODECs, audio input and output drivers. Command line and graphic media player applications.
* Cryptographic subsystem.
* :doc:`/components/power` sub-system.
* ModBus support provided by built-in `FreeModBus <https://www.embedded-experts.at/en/freemodbus/>`__ version 1.5.0.
* **C/C++ Libraries**
* Standard C Library Fully integrated into the OS.
* Includes floating point support via a Standard Math Library.
* Add-on `uClibc++ <http://cxx.uclibc.org/>`__ module provides Standard C++ Library (LGPL).
* **Networking**
* Multiple network interface support; multiple network link layer support.
* IPv4, IPv6, TCP/IP, UDP, ICMP, ICMPv6, IGMPv2 and MLDv1/v2 (client) stacks.
* IP Forwarding (routing) support.
* User space stacks.
* Stream and datagram sockets.
* Address Families: IPv4/IPv6 (``AF_INET``/``AF_INET6``), Raw socket (``AF_PACKET``), raw IEEE
802.15.4 (``AF_IEEE802154``), raw Bluetooth (``AF_BLUETOOTH``), and local, Unix domain socket support (``AF_LOCAL``).
* Special ``INET`` protocol sockets: Raw ICMP and ICMPv6 protocol ping sockets (``IPPROTO_ICMP``/``IPPROTO_ICMP6``).
* Custom user sockets.
* IP Forwarding.
* DNS name resolution / NetDB
* IEEE 802.11 FullMac
* Radio Network Drivers: IEEE 802.15.4 MAC, Generic Packet Radio, Bluetooth LE
* 6LoWPAN for radio network drivers (IEEE 802.15.4 MAC and generic packet radios)
* SLIP, TUN/PPP, Local loopback devices
* A port cJSON
* Small footprint.
* BSD compatible socket layer.
* Networking utilities (DHCP server and client, SMTP client, Telnet server and client, FTP server and
client, TFTP client, HTTP server and client, PPPD, NTP client). Inheritable TELNET server sessions (as "controlling
terminal"). VNC server.
* ICMPv6 autonomous auto-configuration
* NFS Client. Client side support for a Network File System (NFS, version 3, UDP).
* A NuttX port of Jeff Poskanzer's `THTTPD <http://acme.com/software/thttpd>`__
HTTP server integrated with the NuttX :doc:`/components/binfmt` to provide true, embedded CGI.
* PHY Link Status Management.
* UDP Network Discovery (Contributed by Richard Cochran).
* XML RPC Server (Contributed by Richard Cochran).
* Support for networking modules (e.g., ESP8266).
* **FLASH Support**
* *MTD*\ -inspired interface for *M*\ emory *T*\ echnology *D*\ evices.
* NAND support.
* *FTL*. Simple *F*\ lash *T*\ ranslation *L*\ ayer support file systems on FLASH.
* Wear-Leveling FLASH File Systems: NXFFS, SmartFS, SPIFFS.
* Support for SPI-based FLASH and FRAM devices.
* **USB Host Support**
* USB host architecture for USB host controller drivers and device-dependent USB class drivers.
* USB host controller drivers available for the Atmel SAMA5Dx, NXP LPC17xx, LPC31xx, and STmicro STM32
* Device-dependent USB class drivers available for USB mass storage, CDC/ACM serial, HID keyboard, and HID mouse.
* Seam-less support for USB hubs.
* **USB Device Support**
* *Gadget*-like architecture for USB device controller drivers and device-dependent USB class drivers.
* USB device controller drivers available for the most MCU architectures includeing PIC32,
Atmel AVR, SAM3, SAM4, SAMv7, and SAMA5Dx, NXP/Freescale LPC17xx, LPC214x, LPC313x, LPC43xx, and
Kinetis, Silicon Laboraties EFM32, STMicro STM32 F1, F2, F3, F4, and F7, TI DM320, and others.
* Device-dependent USB class drivers available for USB serial (CDC/ACM and a PL2303 emulation),
for USB mass storage, for USB networking (RNDIS and CDC/ECM), DFU, and for a dynamically
configurable, composite USB devices.
* Built-in :doc:`/guides/usbtrace` and USB host trace functionality for non-invasive USB debug.
* **Graphics Support**
* Framebuffer drivers.
* Graphic LCD drivers for both parallel and SPI LCDs and OLEDs.
* Segment LCD drivers.
* VNC Server.
* ``mmap``-able, framebuffer character driver.
* NX: A graphics library, tiny windowing system and tiny font support that works with either
framebuffer or LCD drivers. Documented in the :doc:`/components/nxgraphics/index` manual.
* Font management sub-system.
* :doc:`/components/nxwidgets`: NXWidgets is library of graphic objects, or "widgets," (labels,
buttons, text boxes, images, sliders, progress bars, etc.). NXWidgets is written in C++ and
integrates seamlessly with the NuttX NX graphics and font management subsystems.
* NxWM is the tiny NuttX window manager based on NX and NxWidgets.
* **Input Devices**
* Touchscreen, USB keyboard, GPIO-based buttons and keypads.
* **Analog Devices**
* Support for Analog-to-Digital conversion (ADC), Digital-to-Analog conversion (DAC), multiplexers, and
amplifiers.
* **Motor Control**
* Pulse width modulation (PWM) / Pulse count modulation.
* **NuttX Add-Ons**.
The following packages are available to extend the basic NuttX feature set:
* **NuttShell (NSH)**
A small, scalable, bash-like shell for NuttX with rich feature set and small footprint. See the :doc:`/applications/nsh/index`.
* **BAS 2.4**
Seamless integration of Michael Haardt's BAS 2.4: "Bas is an interpreter for the classic dialect of the programming language BASIC. It is pretty compatible to typical BASIC interpreters of the 1980s, unlike some other UNIX BASIC interpreters, that implement a different syntax, breaking compatibility to existing programs. Bas offers many ANSI BASIC statements for structured programming, such as procedures, local variables and various loop types. Further there are matrix operations, automatic LIST indentation and many statements and functions found in specific classic dialects. Line numbers are not required."
Look at all those files and features... How can it be a tiny OS?
================================================================
The NuttX feature list (above) is fairly long and if you
look at the NuttX source tree, you will see that there are hundreds of source files comprising NuttX. How can NuttX be a tiny
OS with all of that?
* **Lots of Features -- More can be smaller!**
The philosophy behind that NuttX is that lots of features are great... *BUT* also that if you
don't use those features, then you should not have to pay a penalty for the unused features.
And, with NuttX, you don't! If you don't use a feature, it will not be included in the final
executable binary. You only have to pay the penalty of increased footprint for the features that
you actually use.
Using a variety of technologies, NuttX can scale from the very tiny to the moderate-size system.
I have executed NuttX with some simple applications in as little as 32K *total* memory (code and
data). On the other hand, typical, richly featured NuttX builds require more like 64K (and
if all of the features are used, this can push 100K).
* **Many, many files -- More really is smaller!**
One may be intimidated by the size NuttX source tree. There are hundreds of source files! How can
that be a tiny OS? Actually, the large number of files is one of the tricks to keep NuttX small
and as scalable as possible. Most files contain only a single function. Sometimes just one tiny
function with only a few lines of code. Why?
- **Static Libraries**.
Because in the NuttX build processed, objects are compiled and saved into *static libraries*
(*archives*). Then, when the file executable is linked, only the object files that are
needed are extracted from the archive and added to the final executable. By having many,
many tiny source files, you can assure that no code that you do not execute is ever
included in the link. And by having many, tiny source files you have better granularity --
if you don't use that tiny function of even just a few lines of code, it will not be
included in the binary.
* **Other Tricks**
As mentioned above, the use of many, tiny source files and linking from static libraries
keeps the size of NuttX down. Other tricks used in NuttX include:
- **Configuration Files**.
Before you build NuttX, you must provide a configuration file that specifies what features you plan to use and
which features you do not. This configuration file contains a long list of settings that control what is
built into NuttX and what is not. There are hundreds of such settings (see the
`Configuration Variable Documentation <https://cwiki.apache.org/confluence/display/NUTTX/Configuration+Variables?src=contextnavpagetreemode>`__
for a partial list that excludes platform specific settings). These many, many configuration options allow
NuttX to be highly tuned to meet size requirements. The downside to all of these configuration options is that
it greatly complicates the maintenance of NuttX -- but that is my problem, not yours. -
- **Weak Symbols**
The GNU toolchain supports *weak* symbols and these also help to keep the size of NuttX down.
Weak symbols prevent object files from being drawn into the link even if they are accessed from source code.
Careful use of weak symbols is another trick for keep unused code out of the final binary.
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,155 @@
.. todo:: revise and update links
========================
Development Environments
========================
Linux + GNU ``make`` + GCC/binutils for Linux
=============================================
The is the most natural development environment for NuttX. Any version
of the GCC/binutils toolchain may be used. There is a highly modified
`buildroot <http://buildroot.uclibc.org/>`__ available for download from
the `NuttX
Bitbucket.org <https://bitbucket.org/nuttx/buildroot/downloads/>`__
page. This download may be used to build a NuttX-compatible ELF
toolchain under Linux or Cygwin. That toolchain will support ARM, m68k,
m68hc11, m68hc12, and SuperH ports. The buildroot GIT may be accessed in
the NuttX `buildroot GIT <https://bitbucket.org/nuttx/buildroot>`__.
Linux + GNU ``make`` + SDCC for Linux
=====================================
Also very usable is the Linux environment using the
`SDCC <http://sdcc.sourceforge.net/>`__ compiler. The SDCC compiler
provides support for the 8051/2, z80, hc08, and other microcontrollers.
The SDCC-based logic is less well exercised and you will likely find
some compilation issues if you use parts of NuttX with SDCC that have
not been well-tested.
Windows with Cygwin + GNU ``make`` + GCC/binutils (custom built under Cygwin)
=============================================================================
This combination works well too. It works just as well as the native
Linux environment except that compilation and build times are a little
longer. The custom NuttX
`buildroot <https://bitbucket.org/nuttx/buildroot/downloads/>`__
referenced above may be build in the Cygwin environment as well.
Windows with Cygwin + GNU ``make`` + SDCC (custom built under Cygwin)
=====================================================================
I have never tried this combination, but it would probably work just
fine.
Windows with Cygwin + GNU ``make`` + Windows Native Toolchain
=============================================================
This is a tougher environment. In this case, the Windows native
toolchain is unaware of the Cygwin *sandbox* and, instead, operates in
the native Windows environment. The primary difficulties with this are:
- **Paths**. Full paths for the native toolchain must follow Windows
standards. For example, the path ``/home/my\ name/nuttx/include`` my
have to be converted to something like
``'C:\cygwin\home\my name\nuttx\include'`` to be usable by the
toolchain.
- **Symbolic Links** NuttX depends on symbolic links to install
platform-specific directories in the build system. On Linux, true
symbolic links are used. On Cygwin, emulated symbolic links are used.
Unfortunately, for native Windows applications that operate outside
of the Cygwin *sandbox*, these symbolic links cannot be used.
- **Dependencies** NuttX uses the GCC compiler's ``-M`` option to
generate make dependencies. These dependencies are retained in files
called ``Make.deps`` throughout the system. For compilers other than
GCC, there is no support for making dependencies in this way.
**Supported Windows Native Toolchains**. At present, the following
Windows native toolchains are in use:
#. GCC built for Windows (such as CodeSourcery, Atollic, devkitARM,
etc.),
#. SDCC built for Windows,
#. the ZiLOG XDS-II toolchain for Z16F, z8Encore, and eZ80Acclaim parts.
Windows Native (``CMD.exe``) + GNUWin32 (including GNU ``make``) + MinGW Host GCC compiler + Windows Native Toolchain
=====================================================================================================================
Build support has been added to support building natively in a Windows
console rather than in a POSIX-like environment.
This build:
#. Uses all Windows style paths
#. Uses primarily Windows batch commands from cmd.exe, with
#. A few extensions from GNUWin32
This capability first appeared in NuttX-6.24 and should still be
considered a work in progress because: (1) it has not been verfied on
all targets and tools, and (2) still lacks some of the creature-comforts
of the more mature environments. The windows native build logic
initiated if ``CONFIG_WINDOWS_NATIVE=y`` is defined in the NuttX
configuration file:
At present, this build environment also requires:
**Windows Console**. The build must be performed in a Windows console
window. This may be using the standard ``CMD.exe`` terminal that comes
with Windows. I prefer the ConEmu terminal which can be downloaded from:
http://code.google.com/p/conemu-maximus5/
**GNUWin32**. The build still relies on some Unix-like commands. I
usethe GNUWin32 tools that can be downloaded from
http://gnuwin32.sourceforge.net/. See the top-level ``nuttx/README.txt``
file for some download, build, and installation notes.
**MinGW-GCC**. MinGW-GCC is used to compiler the C tools in the
``nuttx/tools`` directory that are needed by the build. MinGW-GCC can be
downloaded from http://www.mingw.org/. If you are using GNUWin32, then
it is recommended that you not install the optional MSYS components as
there may be conflicts.
Wine + GNU ``make`` + Windows Native Toolchain
==============================================
I've never tried this one, but I off the following reported by an ez80
user using the ZiLOG ZDS-II Windows-native toolchain:
"I've installed ZDS-II 5.1.1 (IDE for ez80-based boards) on wine
(windows emulator for UNIX) and to my surprise, not many changes were
needed to make GIT snapshot of NuttX buildable... I've tried nsh
profile and build process completed successfully. One remark is
necessary: NuttX makefiles for ez80 are referencing ``cygpath``
utility. Wine provides similar thing called ``winepath`` which is
compatible and offers compatible syntax. To use that, ``winepath``
(which itself is a shell script) has to be copied as ``cygpath``
somewhere in ``$PATH``, and edited as in following patch:
"Better solution would be replacing all ``cygpath`` references in
``Makefiles`` with ``$(CONVPATH)`` (or ``${CONVPATH}`` in shell
scripts) and setting ``CONVPATH`` to ``cygpath`` or ``winepath``
regarding to currently used environment.
Other Environments
==================
**Environment Dependencies**. The primary environmental dependency of
NuttX are (1) GNU make, (2) bash scripting, and (3) Linux utilities
(such as cat, sed, etc.). If you have other platforms that support GNU
make or make utilities that are compatible with GNU make, then it is
very likely that NuttX would work in that environment as well (with some
porting effort). If GNU make is not supported, then some significant
modification of the Make system would be required.
**MSYS**. I have not used MSYS but what I gather from talking with NuttX
users is that MSYS can be used as an alternative to Cygwin in any of the
above Cygwin environments. This is not surprising since MSYS is based on
an older version of Cygwin (cygwin-1.3). MSYS has been modified,
however, to interoperate in the Windows environment better than Cygwin
and that may be of value to some users.
MSYS, however, cannot be used with the native Windows NuttX build
because it will invoke the MSYS bash shell instead of the ``CMD.exe``
shell. Use GNUWin32 in the native Windows build environment.
@@ -0,0 +1,17 @@
Introduction
============
In the following sections you will find basic information introducing main NuttX features.
.. toctree::
:maxdepth: 1
about.rst
supported_platforms.rst
detailed_support.rst
development_environments.rst
licensing.rst
trademarks.rst
resources.rst
@@ -0,0 +1 @@
.. mdinclude:: ../../INVIOLABLES.md
@@ -0,0 +1,11 @@
=========
Licensing
=========
NuttX is available under the Apache 2.0 License. You can find more information about the terms `here <https://www.apache.org/foundation/license-faq.html>`_.
License terms
=============
.. include:: ../../LICENSE
:literal:
@@ -0,0 +1,22 @@
=========
Resources
=========
.. note:: this should be revised
Here's a list of Apache NuttX resources that you might find helpful:
* Apache NuttX
* `Apache NuttX website <https://nuttx.apache.org>`_
* `Apache NuttX online documentation <https://cwiki.apache.org/confluence/display/NUTTX/Nuttx>`_
* `Apache NuttX mailing list <https://nuttx.apache.org/community/>`_ a very active mailing list, the place to get help with your application or any questions you have about NuttX.
* `Apache NuttX YouTube channel <https://www.youtube.com/channel/UC0QciIlcUnjJkL5yJJBmluw/videos>`_  Alan Carvalho de Assis's YouTube channel on NuttX. It's a source of a lot of great practical information.
* `Apache NuttX Coding Standard <https://cwiki.apache.org/confluence/display/NUTTX/Coding+Standard>`_ — How code should look when you submit new files or modify existing ones.
* `Apache NuttX Code Contribution Guidlines <https://cwiki.apache.org/confluence/display/NUTTX/Code+Contribution+Workflow>`_ — The full workflow to follow for submitting code with all the details.
* Git
* `Git Cheat Sheet (by GitHub) <https://github.github.com/training-kit/downloads/github-git-cheat-sheet.pdf>`_
* `Git Book (online) <https://git-scm.com/book/en/v2>`_
@@ -0,0 +1,285 @@
.. include:: /substitutions.rst
===================
Supported Platforms
===================
**Supported Platforms by CPU core**. The number of ports to this
CPU follow in parentheses. The state of the various ports vary
from board-to-board. Follow the links for the details:
.. list-table::
:class: valign-top
* -
- :ref:`introduction/detailed_support:Linux User Mode Simulation` (1)
- ARM
- :ref:`introduction/detailed_support:ARM7TDMI` (4)
- :ref:`introduction/detailed_support:ARM920T` (1)
- :ref:`introduction/detailed_support:ARM926EJS` (4)
- :ref:`introduction/detailed_support:Other ARMv4` (1)
- :ref:`introduction/detailed_support:ARM1176JZ` (1)
- :ref:`introduction/detailed_support:ARM Cortex-A5` (3)
- :ref:`introduction/detailed_support:ARM Cortex-A8` (2)
- :ref:`introduction/detailed_support:ARM Cortex-A9` (1)
- :ref:`introduction/detailed_support:ARM Cortex-R4` (2)
- :ref:`introduction/detailed_support:ARM Cortex-M0/M0+` (13)
- :ref:`introduction/detailed_support:ARM Cortex-M3` (39)
- :ref:`introduction/detailed_support:ARM Cortex-M4` (59)
- :ref:`introduction/detailed_support:ARM Cortex-M7` (15)
- Atmel AVR
- :ref:`introduction/detailed_support:Microchip AVR` (8-bit) (5)
- :ref:`introduction/detailed_support:Microchip AVR32` (1)
- Freescale
- :ref:`introduction/detailed_support:Freescale M68HCS12` (2)
-
- Intel
- :ref:`introduction/detailed_support:Intel 80x86` (2)
- Microchip
- :ref:`introduction/detailed_support:Microchip PIC32MX` (MIPS M4K) (4)
- :ref:`introduction/detailed_support:Microchip PIC32MZEF` (MIPS M5150) (1)
- Misoc
- :ref:`introduction/detailed_support:Misoc` (1)
- OpenRISC
- :ref:`introduction/detailed_support:OpenRISC mor1kx` (1)
- Renesas/Hitachi:
- :ref:`introduction/detailed_support:Renesas/Hitachi SuperH` (1/2)
- :ref:`introduction/detailed_support:Renesas M16C/26` (1/2)
- :ref:`introduction/detailed_support:Renesas RX65N` (2)
-
- :ref:`introduction/detailed_support:RISC-V` (2)
- :ref:`introduction/detailed_support:LiteX on Arty A7` (1)
- Xtensa LX6:
- :ref:`introduction/detailed_support:ESP32 (Dual Xtensa LX6)` (1)
- ZiLOG
- :ref:`introduction/detailed_support:ZiLOG ZNEO Z16F` (2)
- :ref:`introduction/detailed_support:ZiLOG eZ80 Acclaim!` (4)
- :ref:`introduction/detailed_support:ZiLOG Z8Encore!` (2)
- :ref:`introduction/detailed_support:ZiLOG Z180` (1)
- :ref:`introduction/detailed_support:ZiLOG Z80` (2)
**Supported Platforms by Manufacturer/MCU Family**. CPU core type
follows in parentheses. The state of the various ports vary from MCU to
MCU. Follow the links for the details:
.. list-table::
:class: valign-top
* -
- :ref:`introduction/detailed_support:Linux User Mode Simulation` (1)
- Allwinner
- :ref:`introduction/detailed_support:Allwinner A10` (Cortex-A8)
- Broadcom
- :ref:`introduction/detailed_support:Broadcom BCM2708` (ARM1176JZ)
- Espressif
- :ref:`introduction/detailed_support:Xtensa LX6 ESP32` (Dual Xtensa LX6)
- Host PC based simulations
- :ref:`introduction/detailed_support:Linux User Mode Simulation`
- Infineon
- :ref:`introduction/detailed_support:Infineon XMC45xx`
- Intel
- :ref:`introduction/detailed_support:Intel 80x86`
- Maxim Integrated
- :ref:`introduction/detailed_support:Maxim Integrated MAX32660` (ARM Cortex-M3)
- Microchip
- :ref:`introduction/detailed_support:Microchip PIC32MX2xx` (MIPS32 M4K)
- :ref:`introduction/detailed_support:Microchip PIC32MX4xx` (MIPS32 M4K)
- :ref:`introduction/detailed_support:Microchip PIC32MX7xx` (MIPS32 M4K)
- :ref:`introduction/detailed_support:Microchip PIC32MZEC` (MIPS32 microAptiv)
- :ref:`introduction/detailed_support:Microchip PIC32MZEF` (MIPS32 M5150)
- Microchip (Formerly Atmel)
- :ref:`introduction/detailed_support:AVR ATMega128` (8-bit AVR)
- :ref:`introduction/detailed_support:AVR ATMega1284p` (8-bit AVR)
- :ref:`introduction/detailed_support:AVR ATMega2560` (8-bit AVR)
- :ref:`introduction/detailed_support:AVR AT90USB64x and AT90USB6128x` (8-bit AVR)
- :ref:`introduction/detailed_support:Microchip AVR32` (AT32UC3BXXX, 32-bit AVR32)
- :ref:`introduction/detailed_support:Microchip SAMD20` (ARM Cortex-M0+)
- :ref:`introduction/detailed_support:Microchip SAMD21` (ARM Cortex-M0+)
- :ref:`introduction/detailed_support:Microchip SAML21` (ARM Cortex-M0+)
- :ref:`introduction/detailed_support:Microchip SAM3U` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:Microchip SAM3X` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:Microchip SAM4CM` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:Microchip SAM4E` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:Microchip SAM4L` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:Microchip SAM4S` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:Microchip SAMD5x/E5x` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:Microchip SAME70` (ARM Cortex-M7)
- :ref:`introduction/detailed_support:Microchip SAMV71` (ARM Cortex-M7)
- :ref:`introduction/detailed_support:Microchip SAMA5D2` (ARM Cortex-A5)
- :ref:`introduction/detailed_support:Microchip SAMA5D3` (ARM Cortex-A5)
- :ref:`introduction/detailed_support:Microchip SAMA5D4` (ARM Cortex-A5)
- Moxa
- :ref:`introduction/detailed_support:Moxa NP51x0` (ARMv4)
- nuvoTon
- :ref:`introduction/detailed_support:nuvoTon NUC120` (ARM Cortex-M0)
- Nordic Semiconductor
- :ref:`introduction/detailed_support:Nordic Semiconductor NRF52xxx` (ARM Cortex-M4)
- NXP/Freescale
- :ref:`introduction/detailed_support:Freescale M68HCS12`
- :ref:`introduction/detailed_support:NXP/Freescale i.MX1` (ARM920-T)
- :ref:`introduction/detailed_support:NXP/Freescale i.MX6` (ARM Cortex-A9)
- :ref:`introduction/detailed_support:NXP/Freescale i.MX RT` (ARM Cortex-M7)
- :ref:`introduction/detailed_support:NXP/FreeScale KL25Z` (ARM Cortex-M0+)
- :ref:`introduction/detailed_support:NXP/FreeScale KL26Z` (ARM Cortex-M0+)
- :ref:`introduction/detailed_support:NXP/FreeScale Kinetis K20` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:NXP/FreeScale Kinetis K28F` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:NXP/FreeScale Kinetis K40` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:NXP/FreeScale Kinetis K60` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:NXP/FreeScale Kinetis K64` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:NXP/FreeScale Kinetis K66` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:NXP LPC11xx` (Cortex-M0)
- :ref:`introduction/detailed_support:NXP LPC214x` (ARM7TDMI)
- :ref:`introduction/detailed_support:NXP LPC2378` (ARM7TDMI)
- :ref:`introduction/detailed_support:NXP LPC3131` (ARM9E6JS)
- :ref:`introduction/detailed_support:NXP LPC315x` (ARM9E6JS)
- :ref:`introduction/detailed_support:NXP LPC176x` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:NXP LPC178x` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:NXP LPC40xx` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:NXP LPC43xx` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:NXP LPC54xx` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:NXP S32K11x` (Cortex-M0+)
- :ref:`introduction/detailed_support:NXP S32K14x` (Cortex-M4F)
-
- ON Semiconductor:
- :ref:`introduction/detailed_support:On Semiconductor LC823450` (Dual core ARM Cortex-M3)
- Renesas/Hitachi:
- :ref:`introduction/detailed_support:Renesas/Hitachi SuperH`
- :ref:`introduction/detailed_support:Renesas M16C/26`
- :ref:`introduction/detailed_support:Renesas RX65N`
- Silicon Laboratories, Inc.
- :ref:`introduction/detailed_support:SiLabs EFM32 Gecko` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:SiLabs EFM32 Giant Gecko` (ARM Cortex-M3)
- Sony.
- :ref:`introduction/detailed_support:Sony CXD56xx` (6 x ARM Cortex-M4)
- STMicroelectronics
- :ref:`introduction/detailed_support:STMicro STR71x` (ARM7TDMI)
- :ref:`introduction/detailed_support:STMicro STM32 F0xx` (STM32 F0, ARM Cortex-M0)
- :ref:`introduction/detailed_support:STMicro STM32 L0xx` (STM32 L0, ARM Cortex-M0)
- :ref:`introduction/detailed_support:STMicro STM32 G0xx` (STM32 G0, ARM Cortex-M0+)
- :ref:`introduction/detailed_support:STMicro STM32 L152` (STM32 L1 "EnergyLite" Line, ARM Cortex-M3)
- :ref:`introduction/detailed_support:STMicro STM32 L15x/16x` (STM32 L1 "EnergyLite" Medium+ Density, ARM Cortex-M3)
- :ref:`introduction/detailed_support:STMicro STM32 F100x` (STM32 F1 "Value Line" Family, ARM Cortex-M3)
- :ref:`introduction/detailed_support:STMicro STM32 F102x` (STM32 F1 family, ARM Cortex-M3)
- :ref:`introduction/detailed_support:STMicro STM32 F103C4/C8` (STM32 F1 "Low- and Medium-Density Line" Family, ARM Cortex-M3)
- :ref:`introduction/detailed_support:STMicro STM32 F103x` (STM32 F1 family, ARM Cortex-M3)
- :ref:`introduction/detailed_support:STMicro STM32 F105x` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:STMicro STM32 F107x` (STM32 F1 family, "Connectivity Line" ARM Cortex-M3)
- :ref:`introduction/detailed_support:STMicro STM32 F205x` (STM32 F2 family, ARM Cortex-M3)
- :ref:`introduction/detailed_support:STMicro STM32 F207x` (STM32 F2 family, ARM Cortex-M3)
- :ref:`introduction/detailed_support:STMicro STM32 F302x` (STM32 F3 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F303x` (STM32 F3 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F334` (STM32 F3 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F372/F373` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F4x1` (STM32 F4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F405x/407x` (STM32 F4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F427/F437` (STM32 F4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F429` (STM32 FB family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F433` (STM32 F4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F446` (STM32 F4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F46xx` (STM32 F4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 G474x` (STM32 G4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 G431x` (STM32 G4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 L4x2` (STM32 L4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 L475` (STM32 L4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 L476` (STM32 L4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 L496` (STM32 L4 family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 L4Rx` (STM32 LB family, ARM Cortex-M4)
- :ref:`introduction/detailed_support:STMicro STM32 F72x/F73x` (STM32 F7 family, ARM Cortex-M7)
- :ref:`introduction/detailed_support:STMicro STM32 F745/F746` (STM32 F7 family, ARM Cortex-M7)
- :ref:`introduction/detailed_support:STMicro STM32 F756` (STM32 F7 family, ARM Cortex-M7)
- :ref:`introduction/detailed_support:STMicro STM32 F76xx/F77xx` (STM32 F7 family, ARM Cortex-M7)
- :ref:`introduction/detailed_support:STMicro STM32 H7x3` (STM32 H7 family, ARM Cortex-M7)
-
- Texas Instruments (some formerly Luminary)
- :ref:`introduction/detailed_support:TI TMS320-C5471` (ARM7TDMI)
- :ref:`introduction/detailed_support:TI TMS320-DM320` (ARM9E6JS)
- :ref:`introduction/detailed_support:TI/Stellaris LM3S6432` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:TI/Stellaris LM3S6432S2E` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:TI/Stellaris LM3S6918` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:TI/Stellaris LM3S6965` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:TI/Stellaris LM3S8962` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:TI/Stellaris LM3S9B92` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:TI/Stellaris LM3S9B96` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:TI/SimpleLink CC13x0` (ARM Cortex-M3)
- :ref:`introduction/detailed_support:TI/Stellaris LM4F120x` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:TI/Tiva TM4C123G` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:TI/Tiva TM4C1294` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:TI/Tiva TM4C129X` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:TI/SimpleLink CC13x2` (ARM Cortex-M4)
- :ref:`introduction/detailed_support:TI/Hercules TMS570LS04xx` (ARM Cortex-R4)
- :ref:`introduction/detailed_support:TI/Hercules TMS570LS31xx` (ARM Cortex-R4)
- :ref:`introduction/detailed_support:TI/Sitara AM335x` (Cortex-A8)
- ZiLOG
- :ref:`introduction/detailed_support:ZiLOG ZNEO Z16F`
- :ref:`introduction/detailed_support:ZiLOG eZ80 Acclaim!`
- :ref:`introduction/detailed_support:ZiLOG Z8Encore!`
- :ref:`introduction/detailed_support:ZiLOG Z180`
- :ref:`introduction/detailed_support:ZiLOG Z80`
@@ -0,0 +1,30 @@
==========
Trademarks
==========
- NuttX is a registered trademark of Gregory Nutt.
- ARM, ARM7 ARM7TDMI, ARM9, ARM920T, ARM926EJS, Cortex-M3 are
trademarks of Advanced RISC Machines, Limited.
- Beaglebone is a trademark of GHI.
- BSD is a trademark of the University of California, Berkeley, USA.
- Cygwin is a trademark of Red Hat, Incorporated.
- Linux is a registered trademark of Linus Torvalds.
- Eagle-100 is a trademark of `Micromint USA,
LLC <http://www.micromint.com/>`__.
- EnergyLite is a trademark of STMicroelectronics.
- EFM32 is a trademark of Silicon Laboratories, Inc.
- LPC2148 is a trademark of NXP Semiconductors.
- POSIX is a trademark of the Institute of Electrical and Electronic
Engineers, Inc.
- RISC-V is a registration pending trade mark of the RISC-V Foundation.
- Sitara is a trademark of Texas Instruments Incorporated.
- TI is a tradename of Texas Instruments Incorporated.
- Tiva is a trademark of Texas Instruments Incorporated.
- UNIX is a registered trademark of The Open Group.
- VxWorks is a registered trademark of Wind River Systems,
Incorporated.
- ZDS, ZNEO, Z16F, Z80, and Zilog are a registered trademark of Zilog,
Inc.
NOTE: NuttX is *not* licensed to use the POSIX trademark. NuttX uses the
POSIX standard as a development guideline only.
@@ -0,0 +1,35 @@
@ECHO OFF
pushd %~dp0
REM Command file for Sphinx documentation
if "%SPHINXBUILD%" == "" (
set SPHINXBUILD=sphinx-build
)
set SOURCEDIR=.
set BUILDDIR=_build
if "%1" == "" goto help
%SPHINXBUILD% >NUL 2>NUL
if errorlevel 9009 (
echo.
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
echo.installed, then set the SPHINXBUILD environment variable to point
echo.to the full path of the 'sphinx-build' executable. Alternatively you
echo.may add the Sphinx directory to PATH.
echo.
echo.If you don't have Sphinx installed, grab it from
echo.http://sphinx-doc.org/
exit /b 1
)
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
goto end
:help
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
:end
popd
@@ -0,0 +1,11 @@
===
ARM
===
The following ARM SoC are supported:
.. toctree::
:maxdepth: 1
:glob:
*/*
@@ -0,0 +1,61 @@
=======================
MakerDiary nRF52832-MDK
=======================
The `nRF52832-MDK <https://wiki.makerdiary.co/nrf52832-mdk>`_ is a development board for
the nRF52832 SoC from Nordic. It features 24 I/Os an on-board RGB led and a chip antenna.
It also includes an embedded DAPlink debugger which allows to flash/debug and monitor UART
from the USB port.
.. figure:: pinout.webp
:align: center
Pinout diagram
Features
========
- nRF52832 MCU, 512K FLASH, 64K SRAM
- 32768 Hz crystal
- Embedded DAPlink debugger (debug/flash and monitor serial)
- Reset button
- Programming mode RGB LED indicator (CDC, MSD or DAP)
- Power indicator LED
- User RGB LED
- Inductor + capacitor for DC/DC mode
Pin Mapping
===========
===== ========== ==========
Pin Signal Notes
===== ========== ==========
P0.24 Blue LED Active LOW
P0.23 Red LED Active LOW
P0.22 Green LED Active LOW
P0.20 UART TX
P0.19 UART RX
===== ========== ==========
Configurations
==============
nsh
---
Basic NuttShell configuration (console enabled in UART0, exposed via USB connection, at 115200 bps).
sdc
---
Enables Nordic's SoftDevice controller and uses nimBLE for the host-layer.
The ``nimble`` test application can be used to enable a simple GATT server.
Flash & Debug
=============
Both flashing and debugging are done using the embedded DAPlink debugger. OpenOCD can be invoked
in the following way to flash::
openocd -f interface/cmsis-dap.cfg -f target/nrf52.cfg -c "program nuttx/nuttx.bin 0x0000000 verify reset; shutdown"

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