├── .devcontainer └── devcontainer.json ├── .gitignore ├── LICENCE_SLIDES ├── LICENSE ├── README.md ├── app ├── CMakeLists.txt ├── Kconfig ├── prj.conf ├── sample.yaml └── src │ ├── common │ ├── CMakeLists.txt │ ├── message_channel.c │ └── message_channel.h │ ├── main.c │ └── modules │ ├── button │ ├── CMakeLists.txt │ ├── Kconfig.button │ └── button.c │ └── led │ ├── CMakeLists.txt │ ├── Kconfig.led │ └── led.c ├── samples ├── 01_hello_world │ ├── CMakeLists.txt │ ├── README.rst │ ├── prj.conf │ ├── sample.yaml │ └── src │ │ └── main.c ├── 02_logging │ ├── CMakeLists.txt │ ├── README.rst │ ├── prj.conf │ ├── sample.yaml │ └── src │ │ └── main.c ├── 03_workqueues │ ├── CMakeLists.txt │ ├── README.rst │ ├── prj.conf │ ├── sample.yaml │ └── src │ │ └── main.c ├── 04_shell │ ├── CMakeLists.txt │ ├── Kconfig │ ├── overlay-usb.conf │ ├── prj.conf │ ├── prj_getopt.conf │ ├── prj_login.conf │ ├── prj_minimal.conf │ ├── prj_minimal_rtt.conf │ ├── sample.yaml │ ├── src │ │ ├── dynamic_cmd.c │ │ ├── login_cmd.c │ │ ├── main.c │ │ ├── test_module.c │ │ └── uart_reinit.c │ └── usb.overlay ├── 05_sensor │ ├── CMakeLists.txt │ ├── README.rst │ ├── boards │ │ └── nucleo_l496zg.overlay │ ├── prj.conf │ ├── sample.yaml │ └── src │ │ └── main.c ├── 06_ble │ ├── CMakeLists.txt │ ├── Kconfig │ ├── README.rst │ ├── prj.conf │ ├── sample.yaml │ └── src │ │ ├── hts.c │ │ ├── hts.h │ │ └── main.c └── 07_display_cfb │ ├── CMakeLists.txt │ ├── README.rst │ ├── boards │ └── reel_board.conf │ ├── prj.conf │ ├── sample.yaml │ └── src │ └── main.c ├── slides ├── Makefile ├── images │ ├── Zephyr_getting_started.png │ ├── ai_requirements.txt │ ├── application_topologies.svg │ ├── application_topologies_1.svg │ ├── application_topologies_2.svg │ ├── application_topologies_3.svg │ ├── application_topologies_4.svg │ ├── boards.jpg │ ├── codespaces_how_to_start.png │ ├── codespaces_open.png │ ├── codespaces_setting_up.png │ ├── codespaces_setting_up_class.png │ ├── devicetree-logo.svg │ ├── jrov2201.jpg │ ├── jrov2201_housing.jpg │ ├── lf-stacked-color.svg │ ├── nrf_connect_ble_connected.png │ ├── nrf_connect_scan.png │ ├── reel_board.jpg │ ├── reel_board_descr_back.jpg │ ├── reel_board_hdc1010.jpg │ ├── reel_board_passive_display.jpg │ ├── system-architecture.png │ ├── zbus_application.svg │ ├── zbus_zephyr.svg │ ├── zephyr_blinky.png │ └── zephyr_logo.png └── workshop_slides.tex ├── test ├── button │ ├── CMakeLists.txt │ ├── Kconfig │ ├── prj.conf │ ├── sample.yaml │ └── src │ │ └── main.c └── led │ ├── CMakeLists.txt │ ├── Kconfig │ ├── prj.conf │ ├── sample.yaml │ └── src │ └── main.c ├── util ├── flash_boards.sh ├── run_twister_integration.sh └── stm32f4.resc └── west.yml /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "image": "ubuntu:24.04", 3 | "workspaceMount": "source=${localWorkspaceFolder},target=/zephyrproject/zephyr-workshop,type=bind", 4 | "workspaceFolder": "/zephyrproject", 5 | "onCreateCommand": "apt-get update 6 | echo 'tzdata tzdata/Areas select Europe' | debconf-set-selections 7 | echo 'tzdata tzdata/Zones/Europe select Berlin' | debconf-set-selections 8 | DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends git cmake ninja-build gperf ccache dfu-util device-tree-compiler wget python3-dev python3-pip python3-setuptools python3-tk python3-wheel xz-utils file make gcc gcc-multilib g++-multilib libsdl2-dev libmagic1 vim htop 9 | pip3 install west --break-system-packages 10 | west init -l zephyr-workshop 11 | west update 12 | west zephyr-export 13 | pip install -r zephyr/scripts/requirements.txt --break-system-packages 14 | west sdk install --toolchains arm-zephyr-eabi x86_64-zephyr-elf 15 | mkdir renode_portable 16 | wget https://builds.renode.io/renode-latest.linux-portable.tar.gz 17 | tar xf renode-latest.linux-portable.tar.gz -C renode_portable --strip-components=1 18 | echo \"export PATH='/zephyrproject/renode_portable:$PATH'\" >> ~/.bashrc 19 | rm renode-latest.linux-portable.tar.gz 20 | cd zephyr-workshop 21 | ", 22 | "remoteEnv": { "LC_ALL": "C" }, 23 | "customizations": { 24 | "vscode": { 25 | "settings": { 26 | "cmake.configureOnOpen": false, 27 | "cmake.showOptionsMovedNotification": false, 28 | "git.autofetch": false 29 | }, 30 | "extensions": [ 31 | "ms-vscode.cpptools-extension-pack", 32 | "plorefice.devicetree" 33 | ] 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.pdf 2 | build/ 3 | .cache/ 4 | twister-out*/ 5 | 6 | 7 | # latex build artifacts 8 | _minted 9 | svg-inkscape/ 10 | *.aux 11 | *.bbl 12 | *.log 13 | *.out 14 | *.nav 15 | *.snm 16 | *.toc 17 | *.vrb 18 | -------------------------------------------------------------------------------- /LICENCE_SLIDES: -------------------------------------------------------------------------------- 1 | Attribution-ShareAlike 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution-ShareAlike 4.0 International Public 58 | License 59 | 60 | By exercising the Licensed Rights (defined below), You accept and agree 61 | to be bound by the terms and conditions of this Creative Commons 62 | Attribution-ShareAlike 4.0 International Public License ("Public 63 | License"). To the extent this Public License may be interpreted as a 64 | contract, You are granted the Licensed Rights in consideration of Your 65 | acceptance of these terms and conditions, and the Licensor grants You 66 | such rights in consideration of benefits the Licensor receives from 67 | making the Licensed Material available under these terms and 68 | conditions. 69 | 70 | 71 | Section 1 -- Definitions. 72 | 73 | a. Adapted Material means material subject to Copyright and Similar 74 | Rights that is derived from or based upon the Licensed Material 75 | and in which the Licensed Material is translated, altered, 76 | arranged, transformed, or otherwise modified in a manner requiring 77 | permission under the Copyright and Similar Rights held by the 78 | Licensor. For purposes of this Public License, where the Licensed 79 | Material is a musical work, performance, or sound recording, 80 | Adapted Material is always produced where the Licensed Material is 81 | synched in timed relation with a moving image. 82 | 83 | b. Adapter's License means the license You apply to Your Copyright 84 | and Similar Rights in Your contributions to Adapted Material in 85 | accordance with the terms and conditions of this Public License. 86 | 87 | c. BY-SA Compatible License means a license listed at 88 | creativecommons.org/compatiblelicenses, approved by Creative 89 | Commons as essentially the equivalent of this Public License. 90 | 91 | d. Copyright and Similar Rights means copyright and/or similar rights 92 | closely related to copyright including, without limitation, 93 | performance, broadcast, sound recording, and Sui Generis Database 94 | Rights, without regard to how the rights are labeled or 95 | categorized. For purposes of this Public License, the rights 96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 97 | Rights. 98 | 99 | e. Effective Technological Measures means those measures that, in the 100 | absence of proper authority, may not be circumvented under laws 101 | fulfilling obligations under Article 11 of the WIPO Copyright 102 | Treaty adopted on December 20, 1996, and/or similar international 103 | agreements. 104 | 105 | f. Exceptions and Limitations means fair use, fair dealing, and/or 106 | any other exception or limitation to Copyright and Similar Rights 107 | that applies to Your use of the Licensed Material. 108 | 109 | g. License Elements means the license attributes listed in the name 110 | of a Creative Commons Public License. The License Elements of this 111 | Public License are Attribution and ShareAlike. 112 | 113 | h. Licensed Material means the artistic or literary work, database, 114 | or other material to which the Licensor applied this Public 115 | License. 116 | 117 | i. Licensed Rights means the rights granted to You subject to the 118 | terms and conditions of this Public License, which are limited to 119 | all Copyright and Similar Rights that apply to Your use of the 120 | Licensed Material and that the Licensor has authority to license. 121 | 122 | j. Licensor means the individual(s) or entity(ies) granting rights 123 | under this Public License. 124 | 125 | k. Share means to provide material to the public by any means or 126 | process that requires permission under the Licensed Rights, such 127 | as reproduction, public display, public performance, distribution, 128 | dissemination, communication, or importation, and to make material 129 | available to the public including in ways that members of the 130 | public may access the material from a place and at a time 131 | individually chosen by them. 132 | 133 | l. Sui Generis Database Rights means rights other than copyright 134 | resulting from Directive 96/9/EC of the European Parliament and of 135 | the Council of 11 March 1996 on the legal protection of databases, 136 | as amended and/or succeeded, as well as other essentially 137 | equivalent rights anywhere in the world. 138 | 139 | m. You means the individual or entity exercising the Licensed Rights 140 | under this Public License. Your has a corresponding meaning. 141 | 142 | 143 | Section 2 -- Scope. 144 | 145 | a. License grant. 146 | 147 | 1. Subject to the terms and conditions of this Public License, 148 | the Licensor hereby grants You a worldwide, royalty-free, 149 | non-sublicensable, non-exclusive, irrevocable license to 150 | exercise the Licensed Rights in the Licensed Material to: 151 | 152 | a. reproduce and Share the Licensed Material, in whole or 153 | in part; and 154 | 155 | b. produce, reproduce, and Share Adapted Material. 156 | 157 | 2. Exceptions and Limitations. For the avoidance of doubt, where 158 | Exceptions and Limitations apply to Your use, this Public 159 | License does not apply, and You do not need to comply with 160 | its terms and conditions. 161 | 162 | 3. Term. The term of this Public License is specified in Section 163 | 6(a). 164 | 165 | 4. Media and formats; technical modifications allowed. The 166 | Licensor authorizes You to exercise the Licensed Rights in 167 | all media and formats whether now known or hereafter created, 168 | and to make technical modifications necessary to do so. The 169 | Licensor waives and/or agrees not to assert any right or 170 | authority to forbid You from making technical modifications 171 | necessary to exercise the Licensed Rights, including 172 | technical modifications necessary to circumvent Effective 173 | Technological Measures. For purposes of this Public License, 174 | simply making modifications authorized by this Section 2(a) 175 | (4) never produces Adapted Material. 176 | 177 | 5. Downstream recipients. 178 | 179 | a. Offer from the Licensor -- Licensed Material. Every 180 | recipient of the Licensed Material automatically 181 | receives an offer from the Licensor to exercise the 182 | Licensed Rights under the terms and conditions of this 183 | Public License. 184 | 185 | b. Additional offer from the Licensor -- Adapted Material. 186 | Every recipient of Adapted Material from You 187 | automatically receives an offer from the Licensor to 188 | exercise the Licensed Rights in the Adapted Material 189 | under the conditions of the Adapter's License You apply. 190 | 191 | c. No downstream restrictions. You may not offer or impose 192 | any additional or different terms or conditions on, or 193 | apply any Effective Technological Measures to, the 194 | Licensed Material if doing so restricts exercise of the 195 | Licensed Rights by any recipient of the Licensed 196 | Material. 197 | 198 | 6. No endorsement. Nothing in this Public License constitutes or 199 | may be construed as permission to assert or imply that You 200 | are, or that Your use of the Licensed Material is, connected 201 | with, or sponsored, endorsed, or granted official status by, 202 | the Licensor or others designated to receive attribution as 203 | provided in Section 3(a)(1)(A)(i). 204 | 205 | b. Other rights. 206 | 207 | 1. Moral rights, such as the right of integrity, are not 208 | licensed under this Public License, nor are publicity, 209 | privacy, and/or other similar personality rights; however, to 210 | the extent possible, the Licensor waives and/or agrees not to 211 | assert any such rights held by the Licensor to the limited 212 | extent necessary to allow You to exercise the Licensed 213 | Rights, but not otherwise. 214 | 215 | 2. Patent and trademark rights are not licensed under this 216 | Public License. 217 | 218 | 3. To the extent possible, the Licensor waives any right to 219 | collect royalties from You for the exercise of the Licensed 220 | Rights, whether directly or through a collecting society 221 | under any voluntary or waivable statutory or compulsory 222 | licensing scheme. In all other cases the Licensor expressly 223 | reserves any right to collect such royalties. 224 | 225 | 226 | Section 3 -- License Conditions. 227 | 228 | Your exercise of the Licensed Rights is expressly made subject to the 229 | following conditions. 230 | 231 | a. Attribution. 232 | 233 | 1. If You Share the Licensed Material (including in modified 234 | form), You must: 235 | 236 | a. retain the following if it is supplied by the Licensor 237 | with the Licensed Material: 238 | 239 | i. identification of the creator(s) of the Licensed 240 | Material and any others designated to receive 241 | attribution, in any reasonable manner requested by 242 | the Licensor (including by pseudonym if 243 | designated); 244 | 245 | ii. a copyright notice; 246 | 247 | iii. a notice that refers to this Public License; 248 | 249 | iv. a notice that refers to the disclaimer of 250 | warranties; 251 | 252 | v. a URI or hyperlink to the Licensed Material to the 253 | extent reasonably practicable; 254 | 255 | b. indicate if You modified the Licensed Material and 256 | retain an indication of any previous modifications; and 257 | 258 | c. indicate the Licensed Material is licensed under this 259 | Public License, and include the text of, or the URI or 260 | hyperlink to, this Public License. 261 | 262 | 2. You may satisfy the conditions in Section 3(a)(1) in any 263 | reasonable manner based on the medium, means, and context in 264 | which You Share the Licensed Material. For example, it may be 265 | reasonable to satisfy the conditions by providing a URI or 266 | hyperlink to a resource that includes the required 267 | information. 268 | 269 | 3. If requested by the Licensor, You must remove any of the 270 | information required by Section 3(a)(1)(A) to the extent 271 | reasonably practicable. 272 | 273 | b. ShareAlike. 274 | 275 | In addition to the conditions in Section 3(a), if You Share 276 | Adapted Material You produce, the following conditions also apply. 277 | 278 | 1. The Adapter's License You apply must be a Creative Commons 279 | license with the same License Elements, this version or 280 | later, or a BY-SA Compatible License. 281 | 282 | 2. You must include the text of, or the URI or hyperlink to, the 283 | Adapter's License You apply. You may satisfy this condition 284 | in any reasonable manner based on the medium, means, and 285 | context in which You Share Adapted Material. 286 | 287 | 3. You may not offer or impose any additional or different terms 288 | or conditions on, or apply any Effective Technological 289 | Measures to, Adapted Material that restrict exercise of the 290 | rights granted under the Adapter's License You apply. 291 | 292 | 293 | Section 4 -- Sui Generis Database Rights. 294 | 295 | Where the Licensed Rights include Sui Generis Database Rights that 296 | apply to Your use of the Licensed Material: 297 | 298 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 299 | to extract, reuse, reproduce, and Share all or a substantial 300 | portion of the contents of the database; 301 | 302 | b. if You include all or a substantial portion of the database 303 | contents in a database in which You have Sui Generis Database 304 | Rights, then the database in which You have Sui Generis Database 305 | Rights (but not its individual contents) is Adapted Material, 306 | including for purposes of Section 3(b); and 307 | 308 | c. You must comply with the conditions in Section 3(a) if You Share 309 | all or a substantial portion of the contents of the database. 310 | 311 | For the avoidance of doubt, this Section 4 supplements and does not 312 | replace Your obligations under this Public License where the Licensed 313 | Rights include other Copyright and Similar Rights. 314 | 315 | 316 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 317 | 318 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 319 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 320 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 321 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 322 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 323 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 324 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 325 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 326 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 327 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 328 | 329 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 330 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 331 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 332 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 333 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 334 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 335 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 336 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 337 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 338 | 339 | c. The disclaimer of warranties and limitation of liability provided 340 | above shall be interpreted in a manner that, to the extent 341 | possible, most closely approximates an absolute disclaimer and 342 | waiver of all liability. 343 | 344 | 345 | Section 6 -- Term and Termination. 346 | 347 | a. This Public License applies for the term of the Copyright and 348 | Similar Rights licensed here. However, if You fail to comply with 349 | this Public License, then Your rights under this Public License 350 | terminate automatically. 351 | 352 | b. Where Your right to use the Licensed Material has terminated under 353 | Section 6(a), it reinstates: 354 | 355 | 1. automatically as of the date the violation is cured, provided 356 | it is cured within 30 days of Your discovery of the 357 | violation; or 358 | 359 | 2. upon express reinstatement by the Licensor. 360 | 361 | For the avoidance of doubt, this Section 6(b) does not affect any 362 | right the Licensor may have to seek remedies for Your violations 363 | of this Public License. 364 | 365 | c. For the avoidance of doubt, the Licensor may also offer the 366 | Licensed Material under separate terms or conditions or stop 367 | distributing the Licensed Material at any time; however, doing so 368 | will not terminate this Public License. 369 | 370 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 371 | License. 372 | 373 | 374 | Section 7 -- Other Terms and Conditions. 375 | 376 | a. The Licensor shall not be bound by any additional or different 377 | terms or conditions communicated by You unless expressly agreed. 378 | 379 | b. Any arrangements, understandings, or agreements regarding the 380 | Licensed Material not stated herein are separate from and 381 | independent of the terms and conditions of this Public License. 382 | 383 | 384 | Section 8 -- Interpretation. 385 | 386 | a. For the avoidance of doubt, this Public License does not, and 387 | shall not be interpreted to, reduce, limit, restrict, or impose 388 | conditions on any use of the Licensed Material that could lawfully 389 | be made without permission under this Public License. 390 | 391 | b. To the extent possible, if any provision of this Public License is 392 | deemed unenforceable, it shall be automatically reformed to the 393 | minimum extent necessary to make it enforceable. If the provision 394 | cannot be reformed, it shall be severed from this Public License 395 | without affecting the enforceability of the remaining terms and 396 | conditions. 397 | 398 | c. No term or condition of this Public License will be waived and no 399 | failure to comply consented to unless expressly agreed to by the 400 | Licensor. 401 | 402 | d. Nothing in this Public License constitutes or may be interpreted 403 | as a limitation upon, or waiver of, any privileges and immunities 404 | that apply to the Licensor or You, including from the legal 405 | processes of any jurisdiction or authority. 406 | 407 | 408 | ======================================================================= 409 | 410 | Creative Commons is not a party to its public 411 | licenses. Notwithstanding, Creative Commons may elect to apply one of 412 | its public licenses to material it publishes and in those instances 413 | will be considered the “Licensor.” The text of the Creative Commons 414 | public licenses is dedicated to the public domain under the CC0 Public 415 | Domain Dedication. Except for the limited purpose of indicating that 416 | material is shared under a Creative Commons public license or as 417 | otherwise permitted by the Creative Commons policies published at 418 | creativecommons.org/policies, Creative Commons does not authorize the 419 | use of the trademark "Creative Commons" or any other trademark or logo 420 | of Creative Commons without its prior written consent including, 421 | without limitation, in connection with any unauthorized modifications 422 | to any of its public licenses or any other arrangements, 423 | understandings, or agreements concerning use of licensed material. For 424 | the avoidance of doubt, this paragraph does not form part of the 425 | public licenses. 426 | 427 | Creative Commons may be contacted at creativecommons.org. 428 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Zephyr Workshop 2 | 3 | Welcome to this Zephyr Workshop! This workshop is designed for everyone who is 4 | new to Zephyr. This repository includes slides firmware samples and a modular 5 | application. It links to existing references on how to get started and explains 6 | basic RTOS concepts with examples. 7 | 8 | The slides will guide you through the content and the hands-on parts of the 9 | workshop. Please check out the pdf version of the slides at the [releases 10 | section](https://github.com/jonas-rem/zephyr-workshop/releases) 11 | 12 | Resources to quickly get started with Zephyr: 13 | 14 | - [Zephyr Documentation](https://docs.zephyrproject.org/latest/) 15 | - [Supported Boards](https://docs.zephyrproject.org/latest/boards/) 16 | - [Samples and Demos](https://docs.zephyrproject.org/latest/samples/) 17 | - [Zephyr GitHub Repository](https://github.com/zephyrproject-rtos/zephyr) 18 | 19 | ## Slides 📊 20 | 21 | The slides can be downloaded as pdf file under the releases. They explain 22 | Zephyr fundamentals and how to get started with the hands-on part of the 23 | workshop. 24 | 25 | The presentation slides are written with Latex Beamer and the 26 | [mtheme](https://github.com/matze/mtheme/tree/master). To build the 27 | presentation and generate a PDF file, execute `make`. 28 | 29 | ### Presentation License 30 | 31 | The content in the `/slides` directory is licensed under the Creative Commons 32 | Attribution-ShareAlike 4.0 International License (CC BY-SA 4.0). A full copy of 33 | the license text is available in the `LICENSE_PRESENTATION` file at the root of 34 | this repository. 35 | 36 | ## Firmware 🛠 37 | 38 | ### Samples 39 | 40 | There are several samples in the folder `samples`. These samples are mostly 41 | adapted from the [Zephyr GitHub 42 | Repository](https://github.com/zephyrproject-rtos/zephyr) and referenced here 43 | for a better overview. All samples can be built as Zephyr workspace examples. 44 | 45 | ### Modular Application 46 | The modular application is a simple example of a modular application that 47 | consists of multiple modules. Different modules communicate with each oter via 48 | Zephyr's Zbus. The application is located at ´app´, related tests are in the 49 | ´tests´ folder. 50 | 51 | The application should run on most supported boards as it only uses a button 52 | and an led. However, if you do not have a hardware available, you can run the 53 | application with Renode. The Renode configuration is located in the `utils` 54 | folder. For running the application in Renode, you have to build for the 55 | `stm32f4_disco` board. 56 | 57 | You can build the application as follows: 58 | ```shell 59 | west build -b stm32f4_disco app -p 60 | ``` 61 | 62 | And run in Renode: 63 | ```shell 64 | renode util/stm32f4.resc --disable-gui --console 65 | ``` 66 | 67 | To run and explore integration tests with twister, you can build the tests and 68 | application for mulitple boards: 69 | ```shell 70 | west twister -T app/ -T test/ --integration 71 | ``` 72 | 73 | ## Github Codespaces Environment 74 | Just click on the button `<> Code` above to create a Github Codespaces 75 | environment for the workshop. For further instructions, please refer to the 76 | slides. 77 | 78 | ## Local Environment 79 | 80 | ### Setup the with existing Zephyr Project Workspace 81 | 82 | After completing the Zephyr Getting Started guide, you should already have a 83 | project folder setup. In this case, you can just clone this repository into the 84 | existing `zephyrproject` folder: 85 | 86 | ```shell 87 | # clone this repository in the existing zephyrproject folder 88 | cd zephyrproject 89 | git clone https://github.com/jonas-rem/zephyr-workshop 90 | # Change west config manifest file location to the zephyr-workshop repository 91 | west config manifest.path zephyr-workshop 92 | cd zephyr-workshop 93 | # update Zephyr modules 94 | west update 95 | ``` 96 | 97 | ### Setup from Scratch 98 | 99 | To set up a new Zephyr workspace directly from this repository, west can be 100 | used with the following options: 101 | 102 | ```shell 103 | # Initialize a workspace named zephyrproject from this repository. 104 | west init -m https://github.com/jonas-rem/zephyr-workshop --mr main zephyrproject 105 | # update Zephyr modules 106 | cd zephyrproject/zephyr-workshop 107 | west update 108 | ``` 109 | 110 | ### Building and running of the Firmware Samples 111 | 112 | ```shell 113 | # e.g. for reel_board 114 | west build -b reel_board samples/01_hello_world -p 115 | 116 | # Or for a simulation that can run on the host system 117 | west build -b qemu_cortex_m0 samples/01_hello_world -p 118 | ``` 119 | 120 | Once the sample is build, run the following command to flash/run it: 121 | 122 | ```shell 123 | # on a board 124 | west flash 125 | 126 | # qemu simulation 127 | west build -t run 128 | ``` 129 | -------------------------------------------------------------------------------- /app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20.0) 2 | 3 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 4 | project(application) 5 | 6 | target_sources(app PRIVATE src/main.c) 7 | add_subdirectory(src/common common) 8 | add_subdirectory(src/modules/led led) 9 | add_subdirectory(src/modules/button button) 10 | -------------------------------------------------------------------------------- /app/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Application" 2 | 3 | rsource "src/modules/led/Kconfig.led" 4 | rsource "src/modules/button/Kconfig.button" 5 | 6 | endmenu 7 | 8 | menu "Zephyr Kernel" 9 | source "Kconfig.zephyr" 10 | endmenu 11 | -------------------------------------------------------------------------------- /app/prj.conf: -------------------------------------------------------------------------------- 1 | # Logging 2 | CONFIG_LOG=y 3 | #Make Logging more responsive for better visualization 4 | CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=1 5 | CONFIG_LED_MODULE_LOG_LEVEL_DBG=y 6 | CONFIG_BUTTON_MODULE_LOG_LEVEL_DBG=y 7 | 8 | # ZBus 9 | CONFIG_ZBUS=y 10 | 11 | # Shell Testing 12 | CONFIG_SHELL=y 13 | -------------------------------------------------------------------------------- /app/sample.yaml: -------------------------------------------------------------------------------- 1 | sample: 2 | description: Application 3 | name: app 4 | common: 5 | tags: introduction 6 | integration_platforms: 7 | - reel_board 8 | - frdm_k64f 9 | - nucleo_wb55rg 10 | - nucleo_l496zg 11 | - mimxrt1010_evk 12 | - nucleo_l452re 13 | - nrf5340dk/nrf5340/cpuapp 14 | - stm32f4_disco 15 | # The following platforms are not supported in twister currently 16 | #- nrf52833dk_nrf52833 17 | #- atsamr21_xpro 18 | tests: 19 | sample.basic.app: 20 | tags: introduction 21 | -------------------------------------------------------------------------------- /app/src/common/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Include message_channel.h 2 | target_include_directories(app PRIVATE .) 3 | 4 | target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/message_channel.c) 5 | -------------------------------------------------------------------------------- /app/src/common/message_channel.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "message_channel.h" 5 | 6 | 7 | ZBUS_CHAN_DEFINE(button_ch, /* Name */ 8 | enum sys_events, /* Message type */ 9 | NULL, /* Validator */ 10 | NULL, /* User data */ 11 | , /* Observers */ 12 | ZBUS_MSG_INIT(0) /* Initial value {0} */ 13 | ); 14 | 15 | ZBUS_CHAN_DEFINE(led_ch, /* Name */ 16 | enum sys_states, /* Message type */ 17 | NULL, /* Validator */ 18 | NULL, /* User data */ 19 | , /* Observers */ 20 | ZBUS_MSG_INIT(0) /* Initial value {0} */ 21 | ); 22 | -------------------------------------------------------------------------------- /app/src/common/message_channel.h: -------------------------------------------------------------------------------- 1 | #ifndef _MESSAGE_CHANNEL_H_ 2 | #define _MESSAGE_CHANNEL_H_ 3 | 4 | #include 5 | 6 | #define DEFAULT_OBS_PRIO 1 7 | 8 | /** 9 | * @brief System State. 10 | */ 11 | enum sys_states { 12 | /** 13 | * @brief System was active and is transitioning to sleep now. 14 | */ 15 | SYS_SLEEP, 16 | 17 | /** 18 | * @brief System is in standby. 19 | */ 20 | SYS_STANDBY, 21 | 22 | /* Add your code here */ 23 | 24 | /* */ 25 | }; 26 | 27 | /** 28 | * @brief System Events. 29 | */ 30 | enum sys_events { 31 | /** 32 | * @brief Button Pressed event 33 | */ 34 | SYS_BUTTON_PRESSED, 35 | }; 36 | 37 | ZBUS_CHAN_DECLARE(button_ch); 38 | ZBUS_CHAN_DECLARE(led_ch); 39 | 40 | #endif /* _MESSAGE_CHANNEL_H_ */ 41 | -------------------------------------------------------------------------------- /app/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "message_channel.h" 5 | 6 | #include 7 | LOG_MODULE_REGISTER(app, CONFIG_LED_MODULE_LOG_LEVEL); 8 | 9 | /* Boot to State Standby */ 10 | static enum sys_states sys_state = SYS_STANDBY; 11 | 12 | 13 | static void led_msg(enum sys_states msg) 14 | { 15 | int err; 16 | 17 | err = zbus_chan_pub(&led_ch, &msg, K_SECONDS(1)); 18 | if (err) { 19 | LOG_ERR("zbus_chan_pub, error: %d", err); 20 | } 21 | } 22 | 23 | static void button_msg_cb(const struct zbus_channel *chan) 24 | { 25 | const enum sys_events *msg_type; 26 | 27 | /* Get message from channel. */ 28 | msg_type = zbus_chan_const_msg(chan); 29 | 30 | if (*msg_type != SYS_BUTTON_PRESSED) { 31 | /* Ignore other messages */ 32 | return; 33 | } 34 | 35 | /* Assign new system state */ 36 | switch (sys_state) { 37 | case SYS_SLEEP: 38 | sys_state = SYS_STANDBY; 39 | LOG_INF("System state standby"); 40 | break; 41 | case SYS_STANDBY: 42 | sys_state = SYS_SLEEP; 43 | LOG_INF("System state sleep"); 44 | break; 45 | /* Add your code here */ 46 | 47 | /* */ 48 | default: 49 | return; 50 | break; 51 | } 52 | 53 | led_msg(sys_state); 54 | } 55 | 56 | static int cmd_button(const struct shell *sh, size_t argc, char **argv, 57 | void *data) 58 | { 59 | int err; 60 | enum sys_events msg; 61 | 62 | msg = SYS_BUTTON_PRESSED; 63 | 64 | err = zbus_chan_pub(&button_ch, &msg, K_SECONDS(1)); 65 | if (err) { 66 | LOG_ERR("zbus_chan_pub, error: %d", err); 67 | } 68 | 69 | return 0; 70 | } 71 | 72 | SHELL_SUBCMD_DICT_SET_CREATE(sub_button_cmds, cmd_button, 73 | (button_press, 1, "Trigger Button Press") 74 | ); 75 | 76 | SHELL_STATIC_SUBCMD_SET_CREATE(my_app_cmds, 77 | SHELL_CMD(button, &sub_button_cmds, "Button test commands", NULL), 78 | SHELL_SUBCMD_SET_END /* Array terminated. */ 79 | ); 80 | SHELL_CMD_REGISTER(my_app, &my_app_cmds, "my App test", NULL); 81 | 82 | int main(void) 83 | { 84 | /* Notify the LED module about the initial system state */ 85 | led_msg(sys_state); 86 | 87 | return 0; 88 | } 89 | 90 | ZBUS_LISTENER_DEFINE(button_test, button_msg_cb); 91 | ZBUS_CHAN_ADD_OBS(button_ch, button_test, DEFAULT_OBS_PRIO); 92 | -------------------------------------------------------------------------------- /app/src/modules/button/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/button.c) 2 | target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../) 3 | -------------------------------------------------------------------------------- /app/src/modules/button/Kconfig.button: -------------------------------------------------------------------------------- 1 | module = BUTTON_MODULE 2 | module-str = BUTTON 3 | source "subsys/logging/Kconfig.template.log_config" 4 | -------------------------------------------------------------------------------- /app/src/modules/button/button.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "message_channel.h" 9 | 10 | LOG_MODULE_REGISTER(button_module, CONFIG_BUTTON_MODULE_LOG_LEVEL); 11 | 12 | #define DEBOUNCE_DELAY_MS 10 13 | #define SW0_NODE DT_ALIAS(sw0) 14 | #if !DT_NODE_HAS_STATUS(SW0_NODE, okay) 15 | #error "Unsupported board: sw0 devicetree alias is not defined" 16 | #endif 17 | static const struct gpio_dt_spec button = GPIO_DT_SPEC_GET_OR(SW0_NODE, gpios, 18 | {0}); 19 | static struct gpio_callback button_cb_data; 20 | 21 | static struct k_work_delayable send_event_work; 22 | 23 | /* System workqueue context */ 24 | static void send_event_work_handler(struct k_work *work) 25 | { 26 | int err; 27 | enum sys_events msg; 28 | 29 | /* Due to button bouncing, check if button was pressed or released */ 30 | if (gpio_pin_get(button.port, button.pin) == 0) { 31 | return; 32 | } 33 | 34 | msg = SYS_BUTTON_PRESSED; 35 | LOG_INF("Button pressed, sent zbus event"); 36 | err = zbus_chan_pub(&button_ch, &msg, K_SECONDS(1)); 37 | if (err) { 38 | LOG_ERR("zbus_chan_pub, error: %d", err); 39 | } 40 | } 41 | 42 | /* Interrupt context */ 43 | static void button_pressed(const struct device *dev, struct gpio_callback *cb, 44 | uint32_t pins) 45 | { 46 | static int64_t last_press_time; 47 | int64_t now = k_uptime_get(); 48 | 49 | if (now - last_press_time > DEBOUNCE_DELAY_MS) { 50 | last_press_time = now; 51 | k_work_schedule(&send_event_work, K_MSEC(DEBOUNCE_DELAY_MS/2)); 52 | } 53 | } 54 | 55 | 56 | static int init(void) 57 | { 58 | int ret; 59 | 60 | if (!gpio_is_ready_dt(&button)) { 61 | LOG_ERR("Error: button device %s is not ready", 62 | button.port->name); 63 | return 0; 64 | } 65 | 66 | ret = gpio_pin_configure_dt(&button, GPIO_INPUT); 67 | if (ret != 0) { 68 | LOG_ERR("Error %d: failed to configure %s pin %d", 69 | ret, button.port->name, button.pin); 70 | return 0; 71 | } 72 | 73 | ret = gpio_pin_interrupt_configure_dt(&button, GPIO_INT_EDGE_TO_ACTIVE); 74 | if (ret != 0) { 75 | LOG_ERR("Error %d: failed to configure interrupt on %s pin %d", 76 | ret, button.port->name, button.pin); 77 | return 0; 78 | } 79 | 80 | gpio_init_callback(&button_cb_data, button_pressed, BIT(button.pin)); 81 | gpio_add_callback(button.port, &button_cb_data); 82 | LOG_INF("Set up button at %s pin %d", button.port->name, button.pin); 83 | 84 | k_work_init_delayable(&send_event_work, send_event_work_handler); 85 | 86 | return 0; 87 | } 88 | 89 | SYS_INIT(init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); 90 | -------------------------------------------------------------------------------- /app/src/modules/led/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/led.c) 2 | target_include_directories(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../../) 3 | -------------------------------------------------------------------------------- /app/src/modules/led/Kconfig.led: -------------------------------------------------------------------------------- 1 | config LED_MODULE_THREAD_STACK_SIZE 2 | int "Thread stack size" 3 | default 1024 4 | 5 | config LED_MODULE_THREAD_STACK_PRIO 6 | int "Thread stack priority" 7 | default 1 8 | 9 | module = LED_MODULE 10 | module-str = LED 11 | source "subsys/logging/Kconfig.template.log_config" 12 | -------------------------------------------------------------------------------- /app/src/modules/led/led.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "message_channel.h" 9 | 10 | LOG_MODULE_REGISTER(led_module, CONFIG_LED_MODULE_LOG_LEVEL); 11 | 12 | /* The devicetree node identifier for the "led0" alias. */ 13 | #define LED0_NODE DT_ALIAS(led0) 14 | 15 | /* 16 | * A build error on this line means your board is unsupported. 17 | * See the sample documentation for information on how to fix this. 18 | */ 19 | static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios); 20 | 21 | ZBUS_SUBSCRIBER_DEFINE(led_subscriber, 4); 22 | ZBUS_CHAN_ADD_OBS(led_ch, led_subscriber, DEFAULT_OBS_PRIO); 23 | 24 | static enum sys_states read_sys_msg(void) 25 | { 26 | int ret; 27 | enum sys_states msg; 28 | 29 | ret = zbus_chan_read(&led_ch, &msg, K_NO_WAIT); 30 | if (ret != 0) { 31 | LOG_ERR("zbus_chan_read, error: %d", ret); 32 | return false; 33 | } 34 | 35 | return msg; 36 | } 37 | 38 | /* LED Task Function */ 39 | static void led_fn(void) 40 | { 41 | const struct zbus_channel *chan; 42 | enum sys_states sys_state; 43 | int ret; 44 | 45 | if (!gpio_is_ready_dt(&led)) { 46 | LOG_ERR("LED device not ready"); 47 | return; 48 | } 49 | ret = gpio_pin_configure_dt(&led, GPIO_OUTPUT_ACTIVE); 50 | if (ret < 0) { 51 | LOG_ERR("LED configure error"); 52 | return; 53 | } 54 | 55 | /* Boot to State Sleep */ 56 | sys_state = SYS_SLEEP; 57 | 58 | LOG_INF("LED module started\n"); 59 | while (1) { 60 | switch (sys_state) { 61 | case SYS_SLEEP: 62 | gpio_pin_set_dt(&led, 0); 63 | printk("LED off\n"); 64 | /* Nothing to do, blocking wait to save energy */ 65 | ret = zbus_sub_wait(&led_subscriber, &chan, K_FOREVER); 66 | break; 67 | case SYS_STANDBY: 68 | gpio_pin_set_dt(&led, 1); 69 | printk("LED on\n"); 70 | k_sleep(K_MSEC(50)); 71 | gpio_pin_set_dt(&led, 0); 72 | printk("LED off\n"); 73 | k_sleep(K_MSEC(500)); 74 | /* Blinking led, blocking wait not possible */ 75 | ret = zbus_sub_wait(&led_subscriber, &chan, K_NO_WAIT); 76 | break; 77 | /* Add your code here */ 78 | 79 | /* */ 80 | default: 81 | break; 82 | } 83 | if (ret == 0) { 84 | /* Wait a short moment for the system to wake up from 85 | * sleep. 86 | */ 87 | k_sleep(K_MSEC(1)); 88 | sys_state = read_sys_msg(); 89 | } 90 | } 91 | } 92 | 93 | K_THREAD_DEFINE(led_task, CONFIG_LED_MODULE_THREAD_STACK_SIZE, led_fn, NULL, 94 | NULL, NULL, CONFIG_LED_MODULE_THREAD_STACK_PRIO, 0, 0); 95 | -------------------------------------------------------------------------------- /samples/01_hello_world/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 6 | project(hello_world) 7 | 8 | target_sources(app PRIVATE src/main.c) 9 | -------------------------------------------------------------------------------- /samples/01_hello_world/README.rst: -------------------------------------------------------------------------------- 1 | .. _hello_world: 2 | 3 | Hello World 4 | ########### 5 | 6 | Overview 7 | ******** 8 | 9 | A simple sample that can be used with any :ref:`supported board ` and 10 | prints "Hello World" to the console. 11 | 12 | Building and Running 13 | ******************** 14 | 15 | This application can be built and executed on QEMU as follows: 16 | 17 | .. zephyr-app-commands:: 18 | :zephyr-app: samples/hello_world 19 | :host-os: unix 20 | :board: qemu_x86 21 | :goals: run 22 | :compact: 23 | 24 | To build for another board, change "qemu_x86" above to that board's name. 25 | 26 | Sample Output 27 | ============= 28 | 29 | .. code-block:: console 30 | 31 | Hello World! x86 32 | 33 | Exit QEMU by pressing :kbd:`CTRL+A` :kbd:`x`. 34 | -------------------------------------------------------------------------------- /samples/01_hello_world/prj.conf: -------------------------------------------------------------------------------- 1 | # nothing here 2 | -------------------------------------------------------------------------------- /samples/01_hello_world/sample.yaml: -------------------------------------------------------------------------------- 1 | sample: 2 | description: Hello World sample, the simplest Zephyr 3 | application 4 | name: hello world 5 | common: 6 | tags: introduction 7 | integration_platforms: 8 | - native_posix 9 | - reel_board 10 | harness: console 11 | harness_config: 12 | type: one_line 13 | regex: 14 | - "Hello World! (.*)" 15 | tests: 16 | sample.basic.helloworld: 17 | tags: introduction 18 | -------------------------------------------------------------------------------- /samples/01_hello_world/src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2014 Wind River Systems, Inc. 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | 9 | int main(void) 10 | { 11 | printf("Hello World! %s\n", CONFIG_BOARD_TARGET); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /samples/02_logging/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 6 | project(hello_world) 7 | 8 | target_sources(app PRIVATE src/main.c) 9 | -------------------------------------------------------------------------------- /samples/02_logging/README.rst: -------------------------------------------------------------------------------- 1 | Logging Sample 2 | ############## 3 | 4 | This sample shows how to use the logging module. It prints different types of 5 | logging messages to the console. 6 | 7 | Small details can be observed, e.g. that logging messages of the type 'DBG' 8 | also print the function name from which they are emitted. 9 | -------------------------------------------------------------------------------- /samples/02_logging/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_LOG=y 2 | CONFIG_LOG_PRINTK=y 3 | CONFIG_LOG_BUFFER_SIZE=2048 4 | -------------------------------------------------------------------------------- /samples/02_logging/sample.yaml: -------------------------------------------------------------------------------- 1 | sample: 2 | name: logging test 3 | common: 4 | integration_platforms: 5 | - native_posix 6 | tests: 7 | sample.basic.logging: 8 | build_only: true 9 | -------------------------------------------------------------------------------- /samples/02_logging/src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012-2014 Wind River Systems, Inc. 3 | * Copyright (c) 2021 Intel Corporation 4 | * 5 | * SPDX-License-Identifier: Apache-2.0 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | LOG_MODULE_REGISTER(hello_world, LOG_LEVEL_DBG); 15 | 16 | static const char *hexdump_msg = "HEXDUMP! #@"; 17 | 18 | int main(void) 19 | { 20 | int8_t i8 = 1; 21 | uint8_t u8 = 2; 22 | int16_t i16 = 16; 23 | uint16_t u16 = 17; 24 | int32_t i32 = 32; 25 | uint32_t u32 = 33; 26 | int64_t i64 = 64; 27 | uint64_t u64 = 65; 28 | char c = '!'; 29 | char *s = "static str"; 30 | char *s1 = "c str"; 31 | char vs0[32]; 32 | char vs1[32]; 33 | void *p = s; 34 | 35 | printk("Hello World! %s\n", CONFIG_BOARD); 36 | 37 | LOG_ERR("error string"); 38 | LOG_DBG("debug string"); 39 | LOG_INF("info string"); 40 | 41 | LOG_DBG("int8_t %" PRId8 ", uint8_t %" PRIu8, i8, u8); 42 | LOG_DBG("int16_t %" PRId16 ", uint16_t %" PRIu16, i16, u16); 43 | LOG_DBG("int32_t %" PRId32 ", uint32_t %" PRIu32, i32, u32); 44 | LOG_DBG("int64_t %" PRId64 ", uint64_t %" PRIu64, i64, u64); 45 | 46 | memset(vs0, 0, sizeof(vs0)); 47 | snprintk(&vs0[0], sizeof(vs0), "%s", "dynamic str"); 48 | 49 | LOG_DBG("char %c", c); 50 | LOG_DBG("s str %s %s", s, s1); 51 | LOG_DBG("d str %s", vs0); 52 | LOG_DBG("mixed str %s %s %s %s %s %s %s", vs0, "---", vs0, "---", vs1, "---", vs1); 53 | LOG_DBG("mixed c/s %c %s %s %s %c", c, s, vs0, s, c); 54 | 55 | LOG_DBG("pointer %p", p); 56 | 57 | LOG_HEXDUMP_DBG(hexdump_msg, strlen(hexdump_msg), "HeXdUmP!"); 58 | 59 | return 0; 60 | } 61 | -------------------------------------------------------------------------------- /samples/03_workqueues/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 6 | project(hello_world) 7 | 8 | target_sources(app PRIVATE src/main.c) 9 | -------------------------------------------------------------------------------- /samples/03_workqueues/README.rst: -------------------------------------------------------------------------------- 1 | Workqueues 2 | ########## 3 | 4 | A sample application that demonstrates how to use workqueues. The application 5 | executes different work items in different workqueues. The work item 6 | (my_work_handler) prints the runtime context in which it is running (e.g. 7 | sysworkq) and the priority of the underlaying thread. 8 | 9 | Negative priorities represent cooperative priorities that can not be 10 | interrupted. Positive priorities represent preemptible threads, so threads that 11 | can be interrupted. The lower the thread priority the higher the assigned 12 | number. In this scheme, the idle thread has the lowest priority and therefore 13 | the highest assigned numer. 14 | 15 | Resources: 16 | - https://docs.zephyrproject.org/latest/kernel/services/threads/index.html#thread-priorities 17 | -------------------------------------------------------------------------------- /samples/03_workqueues/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_THREAD_NAME=y 2 | -------------------------------------------------------------------------------- /samples/03_workqueues/sample.yaml: -------------------------------------------------------------------------------- 1 | sample: 2 | name: workqueue test 3 | common: 4 | integration_platforms: 5 | - native_posix 6 | tests: 7 | sample.basic.workqueue: 8 | build_only: true 9 | -------------------------------------------------------------------------------- /samples/03_workqueues/src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2023 Phytec Messtechnik GmbH. 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | 10 | #define MY_STACK_SIZE 512 11 | #define MY_PRIORITY 5 12 | 13 | K_THREAD_STACK_DEFINE(my_stack_area, MY_STACK_SIZE); 14 | 15 | struct k_work_q my_work_q; 16 | 17 | /* 18 | * This work item gets executed in the context a workqueue. The workqueue itself 19 | * can run in different thread contexts. 20 | */ 21 | static void my_work_handler(struct k_work *work) { 22 | struct k_thread *thread; 23 | const char *thread_name; 24 | 25 | thread = k_current_get(); 26 | thread_name = k_thread_name_get(thread); 27 | printf("Work Item Executed - runtime context:\n"); 28 | if (k_is_in_isr()) { 29 | printk(" ISR Context!\n\n"); 30 | return; 31 | } 32 | printf(" Thread Name: %s \n", thread_name); 33 | printf(" Thread Priority: %d \n", thread->base.prio); 34 | printf("\n"); 35 | } 36 | 37 | K_WORK_DEFINE(my_work, my_work_handler); 38 | 39 | void my_timer_handler(struct k_timer *dummy) 40 | { 41 | printf("Timer Expired!!\n"); 42 | 43 | /* Executing work directly */ 44 | my_work_handler(NULL); 45 | 46 | /* Executing work via work queue */ 47 | k_work_submit(&my_work); 48 | } 49 | 50 | K_TIMER_DEFINE(my_timer, my_timer_handler, NULL); 51 | 52 | int main(void) 53 | { 54 | /* Directly run work item */ 55 | my_work_handler(NULL); 56 | 57 | /* Submitting a work item to the system workqueue */ 58 | k_work_submit(&my_work); 59 | 60 | /* Initializing a custom workqueue */ 61 | k_work_queue_init(&my_work_q); 62 | k_work_queue_start(&my_work_q, my_stack_area, 63 | K_THREAD_STACK_SIZEOF(my_stack_area), MY_PRIORITY, 64 | NULL); 65 | k_thread_name_set(&(my_work_q.thread), "my_work_q_thread"); 66 | 67 | /* Submitting a work item to a custom workqueue */ 68 | k_work_submit_to_queue(&my_work_q, &my_work); 69 | 70 | /* Starting a single shot timer */ 71 | k_timer_start(&my_timer, K_MSEC(1000), K_NO_WAIT); 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /samples/04_shell/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 5 | project(shell_module) 6 | 7 | target_sources(app PRIVATE src/main.c src/test_module.c) 8 | target_sources_ifdef(CONFIG_SHELL_DYNAMIC_CMDS app PRIVATE src/dynamic_cmd.c) 9 | target_sources_ifdef(CONFIG_SHELL_BACKEND_SERIAL app PRIVATE src/uart_reinit.c) 10 | target_sources_ifdef(CONFIG_SHELL_START_OBSCURED app PRIVATE src/login_cmd.c) 11 | -------------------------------------------------------------------------------- /samples/04_shell/Kconfig: -------------------------------------------------------------------------------- 1 | # Config options for logger sample app 2 | 3 | # Copyright (c) 2018 Nordic Semiconductor ASA 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | mainmenu "Shell module sample application" 7 | 8 | menu "Application configuration" 9 | 10 | config SHELL_FOREGROUND_CMDS 11 | bool "Shell foreground commands example" 12 | default y 13 | 14 | config SHELL_DYNAMIC_CMDS 15 | bool "Shell dynamic commands example" 16 | default y 17 | 18 | endmenu 19 | 20 | source "Kconfig.zephyr" 21 | -------------------------------------------------------------------------------- /samples/04_shell/overlay-usb.conf: -------------------------------------------------------------------------------- 1 | CONFIG_USB_DEVICE_STACK=y 2 | CONFIG_USB_DEVICE_PRODUCT="Zephyr USB shell sample" 3 | CONFIG_SHELL_BACKEND_SERIAL_CHECK_DTR=y 4 | CONFIG_UART_LINE_CTRL=y 5 | CONFIG_SHELL_BACKEND_SERIAL_INIT_PRIORITY=51 6 | CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n 7 | -------------------------------------------------------------------------------- /samples/04_shell/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_PRINTK=y 2 | CONFIG_SHELL=y 3 | CONFIG_LOG=y 4 | CONFIG_LOG_CMDS=y 5 | CONFIG_INIT_STACKS=y 6 | CONFIG_THREAD_STACK_INFO=y 7 | CONFIG_KERNEL_SHELL=y 8 | CONFIG_THREAD_MONITOR=y 9 | CONFIG_BOOT_BANNER=n 10 | CONFIG_THREAD_NAME=y 11 | CONFIG_DEVICE_SHELL=y 12 | CONFIG_POSIX_API=y 13 | CONFIG_POSIX_TIMERS=y 14 | CONFIG_DATE_SHELL=y 15 | CONFIG_THREAD_RUNTIME_STATS=y 16 | CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS=y 17 | CONFIG_STATS=y 18 | CONFIG_STATS_SHELL=y 19 | CONFIG_SENSOR=y 20 | CONFIG_SENSOR_SHELL=y 21 | CONFIG_SENSOR_INFO=y 22 | CONFIG_I2C_SHELL=y 23 | -------------------------------------------------------------------------------- /samples/04_shell/prj_getopt.conf: -------------------------------------------------------------------------------- 1 | CONFIG_PRINTK=y 2 | CONFIG_SHELL=y 3 | CONFIG_SHELL_GETOPT=y 4 | CONFIG_LOG=y 5 | CONFIG_INIT_STACKS=y 6 | CONFIG_THREAD_STACK_INFO=y 7 | CONFIG_KERNEL_SHELL=y 8 | CONFIG_THREAD_MONITOR=y 9 | CONFIG_BOOT_BANNER=n 10 | CONFIG_THREAD_NAME=y 11 | CONFIG_DEVICE_SHELL=y 12 | CONFIG_POSIX_CLOCK=y 13 | CONFIG_DATE_SHELL=y 14 | CONFIG_THREAD_RUNTIME_STATS=y 15 | -------------------------------------------------------------------------------- /samples/04_shell/prj_login.conf: -------------------------------------------------------------------------------- 1 | CONFIG_PRINTK=y 2 | CONFIG_SHELL=y 3 | CONFIG_LOG=y 4 | CONFIG_INIT_STACKS=y 5 | CONFIG_THREAD_STACK_INFO=y 6 | CONFIG_KERNEL_SHELL=y 7 | CONFIG_THREAD_MONITOR=y 8 | CONFIG_BOOT_BANNER=n 9 | CONFIG_THREAD_NAME=y 10 | CONFIG_DEVICE_SHELL=y 11 | CONFIG_POSIX_API=y 12 | CONFIG_POSIX_TIMERS=y 13 | CONFIG_DATE_SHELL=y 14 | CONFIG_THREAD_RUNTIME_STATS=y 15 | 16 | CONFIG_SHELL_CMDS_SELECT=y 17 | CONFIG_SHELL_START_OBSCURED=y 18 | CONFIG_SHELL_PROMPT_UART="login: " 19 | CONFIG_SHELL_CMD_ROOT="login" 20 | -------------------------------------------------------------------------------- /samples/04_shell/prj_minimal.conf: -------------------------------------------------------------------------------- 1 | CONFIG_PRINTK=y 2 | CONFIG_SHELL=y 3 | CONFIG_SHELL_MINIMAL=y 4 | CONFIG_SHELL_STACK_SIZE=1024 5 | CONFIG_SHELL_BACKEND_SERIAL=y 6 | 7 | CONFIG_THREAD_MONITOR=y 8 | CONFIG_INIT_STACKS=y 9 | CONFIG_BOOT_BANNER=n 10 | CONFIG_THREAD_NAME=y 11 | CONFIG_LOG=n 12 | CONFIG_CBPRINTF_NANO=y 13 | -------------------------------------------------------------------------------- /samples/04_shell/prj_minimal_rtt.conf: -------------------------------------------------------------------------------- 1 | CONFIG_PRINTK=y 2 | CONFIG_SHELL=y 3 | CONFIG_SHELL_MINIMAL=y 4 | CONFIG_SHELL_STACK_SIZE=1024 5 | CONFIG_SHELL_BACKEND_SERIAL=n 6 | 7 | CONFIG_THREAD_MONITOR=y 8 | CONFIG_INIT_STACKS=y 9 | CONFIG_BOOT_BANNER=n 10 | CONFIG_THREAD_NAME=y 11 | CONFIG_LOG=n 12 | CONFIG_CONSOLE=y 13 | CONFIG_CBPRINTF_NANO=y 14 | 15 | #enable RTT shell 16 | CONFIG_USE_SEGGER_RTT=y 17 | CONFIG_SHELL_BACKEND_RTT=y 18 | -------------------------------------------------------------------------------- /samples/04_shell/sample.yaml: -------------------------------------------------------------------------------- 1 | sample: 2 | name: console build test 3 | common: 4 | integration_platforms: 5 | - native_posix 6 | tests: 7 | sample.basic.console: 8 | build_only: true 9 | -------------------------------------------------------------------------------- /samples/04_shell/src/dynamic_cmd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #define MAX_CMD_CNT (20u) 13 | #define MAX_CMD_LEN (33u) 14 | 15 | /* buffer holding dynamically created user commands */ 16 | static char dynamic_cmd_buffer[MAX_CMD_CNT][MAX_CMD_LEN]; 17 | /* commands counter */ 18 | static uint8_t dynamic_cmd_cnt; 19 | 20 | typedef int cmp_t(const void *, const void *); 21 | extern void qsort(void *a, size_t n, size_t es, cmp_t *cmp); 22 | 23 | /* function required by qsort */ 24 | static int string_cmp(const void *p_a, const void *p_b) 25 | { 26 | return strcmp((const char *)p_a, (const char *)p_b); 27 | } 28 | 29 | static int cmd_dynamic_add(const struct shell *sh, 30 | size_t argc, char **argv) 31 | { 32 | uint16_t cmd_len; 33 | uint8_t idx; 34 | 35 | ARG_UNUSED(argc); 36 | 37 | if (dynamic_cmd_cnt >= MAX_CMD_CNT) { 38 | shell_error(sh, "command limit reached"); 39 | return -ENOEXEC; 40 | } 41 | 42 | cmd_len = strlen(argv[1]); 43 | 44 | if (cmd_len >= MAX_CMD_LEN) { 45 | shell_error(sh, "too long command"); 46 | return -ENOEXEC; 47 | } 48 | 49 | for (idx = 0U; idx < cmd_len; idx++) { 50 | if (isalnum((int)(argv[1][idx])) == 0) { 51 | shell_error(sh, 52 | "bad command name - please use only" 53 | " alphanumerical characters"); 54 | return -ENOEXEC; 55 | } 56 | } 57 | 58 | for (idx = 0U; idx < MAX_CMD_CNT; idx++) { 59 | if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) { 60 | shell_error(sh, "duplicated command"); 61 | return -ENOEXEC; 62 | } 63 | } 64 | 65 | sprintf(dynamic_cmd_buffer[dynamic_cmd_cnt++], "%s", argv[1]); 66 | 67 | qsort(dynamic_cmd_buffer, dynamic_cmd_cnt, 68 | sizeof(dynamic_cmd_buffer[0]), string_cmp); 69 | 70 | shell_print(sh, "command added successfully"); 71 | 72 | return 0; 73 | } 74 | 75 | static int cmd_dynamic_execute(const struct shell *sh, 76 | size_t argc, char **argv) 77 | { 78 | ARG_UNUSED(argc); 79 | ARG_UNUSED(argv); 80 | 81 | for (uint8_t idx = 0; idx < dynamic_cmd_cnt; idx++) { 82 | if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) { 83 | shell_print(sh, "dynamic command: %s", argv[1]); 84 | return 0; 85 | } 86 | } 87 | 88 | shell_error(sh, "%s: unknown parameter: %s", argv[0], argv[1]); 89 | 90 | return -ENOEXEC; 91 | } 92 | 93 | static int cmd_dynamic_remove(const struct shell *sh, size_t argc, 94 | char **argv) 95 | { 96 | ARG_UNUSED(argc); 97 | ARG_UNUSED(argv); 98 | 99 | for (uint8_t idx = 0; idx < dynamic_cmd_cnt; idx++) { 100 | if (!strcmp(dynamic_cmd_buffer[idx], argv[1])) { 101 | if (idx == MAX_CMD_CNT - 1) { 102 | dynamic_cmd_buffer[idx][0] = '\0'; 103 | } else { 104 | memmove(dynamic_cmd_buffer[idx], 105 | dynamic_cmd_buffer[idx + 1], 106 | sizeof(dynamic_cmd_buffer[idx]) * 107 | (dynamic_cmd_cnt - idx)); 108 | } 109 | 110 | --dynamic_cmd_cnt; 111 | shell_print(sh, "command removed successfully"); 112 | return 0; 113 | } 114 | } 115 | shell_error(sh, "did not find command: %s", argv[1]); 116 | 117 | return -ENOEXEC; 118 | } 119 | 120 | static int cmd_dynamic_show(const struct shell *sh, 121 | size_t argc, char **argv) 122 | { 123 | ARG_UNUSED(argc); 124 | ARG_UNUSED(argv); 125 | 126 | if (dynamic_cmd_cnt == 0U) { 127 | shell_warn(sh, "Please add some commands first."); 128 | return -ENOEXEC; 129 | } 130 | 131 | shell_print(sh, "Dynamic command list:"); 132 | 133 | for (uint8_t i = 0; i < dynamic_cmd_cnt; i++) { 134 | shell_print(sh, "[%3d] %s", i, dynamic_cmd_buffer[i]); 135 | } 136 | 137 | return 0; 138 | } 139 | 140 | /* dynamic command creation */ 141 | static void dynamic_cmd_get(size_t idx, struct shell_static_entry *entry) 142 | { 143 | if (idx < dynamic_cmd_cnt) { 144 | /* m_dynamic_cmd_buffer must be sorted alphabetically to ensure 145 | * correct CLI completion 146 | */ 147 | entry->syntax = dynamic_cmd_buffer[idx]; 148 | entry->handler = NULL; 149 | entry->subcmd = NULL; 150 | entry->help = "Show dynamic command name."; 151 | } else { 152 | /* if there are no more dynamic commands available syntax 153 | * must be set to NULL. 154 | */ 155 | entry->syntax = NULL; 156 | } 157 | } 158 | 159 | SHELL_DYNAMIC_CMD_CREATE(m_sub_dynamic_set, dynamic_cmd_get); 160 | SHELL_STATIC_SUBCMD_SET_CREATE(m_sub_dynamic, 161 | SHELL_CMD_ARG(add, NULL, 162 | "Add a new dynamic command.\nExample usage: [ dynamic add test " 163 | "] will add a dynamic command 'test'.\nIn this example, command" 164 | " name length is limited to 32 chars. You can add up to 20" 165 | " commands. Commands are automatically sorted to ensure correct" 166 | " shell completion.", 167 | cmd_dynamic_add, 2, 0), 168 | SHELL_CMD_ARG(execute, &m_sub_dynamic_set, 169 | "Execute a command.", cmd_dynamic_execute, 2, 0), 170 | SHELL_CMD_ARG(remove, &m_sub_dynamic_set, 171 | "Remove a command.", cmd_dynamic_remove, 2, 0), 172 | SHELL_CMD_ARG(show, NULL, 173 | "Show all added dynamic commands.", cmd_dynamic_show, 1, 0), 174 | SHELL_SUBCMD_SET_END 175 | ); 176 | 177 | SHELL_CMD_REGISTER(dynamic, &m_sub_dynamic, 178 | "Demonstrate dynamic command usage.", NULL); 179 | -------------------------------------------------------------------------------- /samples/04_shell/src/login_cmd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Intel Corporation 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | #define DEFAULT_PASSWORD "zephyr" 12 | 13 | static int login_init(void) 14 | { 15 | printk("Shell Login Demo\nHint: password = %s\n", DEFAULT_PASSWORD); 16 | if (!CONFIG_SHELL_CMD_ROOT[0]) { 17 | shell_set_root_cmd("login"); 18 | } 19 | return 0; 20 | } 21 | 22 | static int check_passwd(char *passwd) 23 | { 24 | /* example only -- not recommended for production use */ 25 | return strcmp(passwd, DEFAULT_PASSWORD); 26 | } 27 | 28 | static int cmd_login(const struct shell *sh, size_t argc, char **argv) 29 | { 30 | static uint32_t attempts; 31 | 32 | if (check_passwd(argv[1]) != 0) { 33 | shell_error(sh, "Incorrect password!"); 34 | attempts++; 35 | if (attempts > 3) { 36 | k_sleep(K_SECONDS(attempts)); 37 | } 38 | return -EINVAL; 39 | } 40 | 41 | /* clear history so password not visible there */ 42 | z_shell_history_purge(sh->history); 43 | shell_obscure_set(sh, false); 44 | shell_set_root_cmd(NULL); 45 | shell_prompt_change(sh, "uart:~$ "); 46 | shell_print(sh, "Shell Login Demo\n"); 47 | shell_print(sh, "Hit tab for help.\n"); 48 | attempts = 0; 49 | return 0; 50 | } 51 | 52 | static int cmd_logout(const struct shell *sh, size_t argc, char **argv) 53 | { 54 | shell_set_root_cmd("login"); 55 | shell_obscure_set(sh, true); 56 | shell_prompt_change(sh, "login: "); 57 | shell_print(sh, "\n"); 58 | return 0; 59 | } 60 | 61 | SHELL_CMD_ARG_REGISTER(login, NULL, "", cmd_login, 2, 0); 62 | 63 | SHELL_CMD_REGISTER(logout, NULL, "Log out.", cmd_logout); 64 | 65 | SYS_INIT(login_init, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY); 66 | -------------------------------------------------------------------------------- /samples/04_shell/src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Intel Corporation 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | #ifdef CONFIG_ARCH_POSIX 17 | #include 18 | #else 19 | #include 20 | #endif 21 | 22 | LOG_MODULE_REGISTER(app); 23 | 24 | extern void foo(void); 25 | 26 | void timer_expired_handler(struct k_timer *timer) 27 | { 28 | LOG_INF("Timer expired."); 29 | 30 | /* Call another module to present logging from multiple sources. */ 31 | foo(); 32 | } 33 | 34 | K_TIMER_DEFINE(log_timer, timer_expired_handler, NULL); 35 | 36 | static int cmd_log_test_start(const struct shell *sh, size_t argc, 37 | char **argv, uint32_t period) 38 | { 39 | ARG_UNUSED(argv); 40 | 41 | k_timer_start(&log_timer, K_MSEC(period), K_MSEC(period)); 42 | shell_print(sh, "Log test started\n"); 43 | 44 | return 0; 45 | } 46 | 47 | static int cmd_log_test_start_demo(const struct shell *sh, size_t argc, 48 | char **argv) 49 | { 50 | return cmd_log_test_start(sh, argc, argv, 200); 51 | } 52 | 53 | static int cmd_log_test_start_flood(const struct shell *sh, size_t argc, 54 | char **argv) 55 | { 56 | return cmd_log_test_start(sh, argc, argv, 10); 57 | } 58 | 59 | static int cmd_log_test_stop(const struct shell *sh, size_t argc, 60 | char **argv) 61 | { 62 | ARG_UNUSED(argc); 63 | ARG_UNUSED(argv); 64 | 65 | k_timer_stop(&log_timer); 66 | shell_print(sh, "Log test stopped"); 67 | 68 | return 0; 69 | } 70 | 71 | SHELL_STATIC_SUBCMD_SET_CREATE(sub_log_test_start, 72 | SHELL_CMD_ARG(demo, NULL, 73 | "Start log timer which generates log message every 200ms.", 74 | cmd_log_test_start_demo, 1, 0), 75 | SHELL_CMD_ARG(flood, NULL, 76 | "Start log timer which generates log message every 10ms.", 77 | cmd_log_test_start_flood, 1, 0), 78 | SHELL_SUBCMD_SET_END /* Array terminated. */ 79 | ); 80 | SHELL_STATIC_SUBCMD_SET_CREATE(sub_log_test, 81 | SHELL_CMD_ARG(start, &sub_log_test_start, "Start log test", NULL, 2, 0), 82 | SHELL_CMD_ARG(stop, NULL, "Stop log test.", cmd_log_test_stop, 1, 0), 83 | SHELL_SUBCMD_SET_END /* Array terminated. */ 84 | ); 85 | 86 | SHELL_CMD_REGISTER(log_test, &sub_log_test, "Log test", NULL); 87 | 88 | static int cmd_demo_ping(const struct shell *sh, size_t argc, char **argv) 89 | { 90 | ARG_UNUSED(argc); 91 | ARG_UNUSED(argv); 92 | 93 | shell_print(sh, "pong"); 94 | 95 | return 0; 96 | } 97 | 98 | static int cmd_demo_board(const struct shell *sh, size_t argc, char **argv) 99 | { 100 | ARG_UNUSED(argc); 101 | ARG_UNUSED(argv); 102 | 103 | shell_print(sh, CONFIG_BOARD); 104 | 105 | return 0; 106 | } 107 | 108 | #if defined CONFIG_SHELL_GETOPT 109 | /* Thread save usage */ 110 | static int cmd_demo_getopt_ts(const struct shell *sh, size_t argc, 111 | char **argv) 112 | { 113 | struct getopt_state *state; 114 | char *cvalue = NULL; 115 | int aflag = 0; 116 | int bflag = 0; 117 | int c; 118 | 119 | while ((c = getopt(argc, argv, "abhc:")) != -1) { 120 | state = getopt_state_get(); 121 | switch (c) { 122 | case 'a': 123 | aflag = 1; 124 | break; 125 | case 'b': 126 | bflag = 1; 127 | break; 128 | case 'c': 129 | cvalue = state->optarg; 130 | break; 131 | case 'h': 132 | /* When getopt is active shell is not parsing 133 | * command handler to print help message. It must 134 | * be done explicitly. 135 | */ 136 | shell_help(sh); 137 | return SHELL_CMD_HELP_PRINTED; 138 | case '?': 139 | if (state->optopt == 'c') { 140 | shell_print(sh, 141 | "Option -%c requires an argument.", 142 | state->optopt); 143 | } else if (isprint(state->optopt) != 0) { 144 | shell_print(sh, 145 | "Unknown option `-%c'.", 146 | state->optopt); 147 | } else { 148 | shell_print(sh, 149 | "Unknown option character `\\x%x'.", 150 | state->optopt); 151 | } 152 | return 1; 153 | default: 154 | break; 155 | } 156 | } 157 | 158 | shell_print(sh, "aflag = %d, bflag = %d", aflag, bflag); 159 | return 0; 160 | } 161 | 162 | static int cmd_demo_getopt(const struct shell *sh, size_t argc, 163 | char **argv) 164 | { 165 | char *cvalue = NULL; 166 | int aflag = 0; 167 | int bflag = 0; 168 | int c; 169 | 170 | while ((c = getopt(argc, argv, "abhc:")) != -1) { 171 | switch (c) { 172 | case 'a': 173 | aflag = 1; 174 | break; 175 | case 'b': 176 | bflag = 1; 177 | break; 178 | case 'c': 179 | cvalue = optarg; 180 | break; 181 | case 'h': 182 | /* When getopt is active shell is not parsing 183 | * command handler to print help message. It must 184 | * be done explicitly. 185 | */ 186 | shell_help(sh); 187 | return SHELL_CMD_HELP_PRINTED; 188 | case '?': 189 | if (optopt == 'c') { 190 | shell_print(sh, 191 | "Option -%c requires an argument.", 192 | optopt); 193 | } else if (isprint(optopt) != 0) { 194 | shell_print(sh, "Unknown option `-%c'.", 195 | optopt); 196 | } else { 197 | shell_print(sh, 198 | "Unknown option character `\\x%x'.", 199 | optopt); 200 | } 201 | return 1; 202 | default: 203 | break; 204 | } 205 | } 206 | 207 | shell_print(sh, "aflag = %d, bflag = %d", aflag, bflag); 208 | return 0; 209 | } 210 | #endif 211 | 212 | static int cmd_demo_params(const struct shell *sh, size_t argc, char **argv) 213 | { 214 | shell_print(sh, "argc = %zd", argc); 215 | for (size_t cnt = 0; cnt < argc; cnt++) { 216 | shell_print(sh, " argv[%zd] = %s", cnt, argv[cnt]); 217 | } 218 | 219 | return 0; 220 | } 221 | 222 | static int cmd_demo_hexdump(const struct shell *sh, size_t argc, char **argv) 223 | { 224 | shell_print(sh, "argc = %zd", argc); 225 | for (size_t cnt = 0; cnt < argc; cnt++) { 226 | shell_print(sh, "argv[%zd]", cnt); 227 | shell_hexdump(sh, argv[cnt], strlen(argv[cnt])); 228 | } 229 | 230 | return 0; 231 | } 232 | 233 | static int cmd_version(const struct shell *sh, size_t argc, char **argv) 234 | { 235 | ARG_UNUSED(argc); 236 | ARG_UNUSED(argv); 237 | 238 | shell_print(sh, "Zephyr version %s", KERNEL_VERSION_STRING); 239 | 240 | return 0; 241 | } 242 | 243 | static int set_bypass(const struct shell *sh, shell_bypass_cb_t bypass) 244 | { 245 | static bool in_use; 246 | 247 | if (bypass && in_use) { 248 | shell_error(sh, "Sample supports setting bypass on single instance."); 249 | 250 | return -EBUSY; 251 | } 252 | 253 | in_use = !in_use; 254 | if (in_use) { 255 | shell_print(sh, "Bypass started, press ctrl-x ctrl-q to escape"); 256 | in_use = true; 257 | } 258 | 259 | shell_set_bypass(sh, bypass); 260 | 261 | return 0; 262 | } 263 | 264 | #define CHAR_1 0x18 265 | #define CHAR_2 0x11 266 | 267 | static void bypass_cb(const struct shell *sh, uint8_t *data, size_t len) 268 | { 269 | static uint8_t tail; 270 | bool escape = false; 271 | 272 | /* Check if escape criteria is met. */ 273 | if (tail == CHAR_1 && data[0] == CHAR_2) { 274 | escape = true; 275 | } else { 276 | for (int i = 0; i < (len - 1); i++) { 277 | if (data[i] == CHAR_1 && data[i + 1] == CHAR_2) { 278 | escape = true; 279 | break; 280 | } 281 | } 282 | } 283 | 284 | if (escape) { 285 | shell_print(sh, "Exit bypass"); 286 | set_bypass(sh, NULL); 287 | tail = 0; 288 | return; 289 | } 290 | 291 | /* Store last byte for escape sequence detection */ 292 | tail = data[len - 1]; 293 | 294 | /* Do the data processing. */ 295 | for (int i = 0; i < len; i++) { 296 | shell_fprintf(sh, SHELL_INFO, "%02x ", data[i]); 297 | } 298 | shell_fprintf(sh, SHELL_INFO, "| "); 299 | 300 | for (int i = 0; i < len; i++) { 301 | shell_fprintf(sh, SHELL_INFO, "%c", data[i]); 302 | } 303 | shell_fprintf(sh, SHELL_INFO, "\n"); 304 | 305 | } 306 | 307 | static int cmd_bypass(const struct shell *sh, size_t argc, char **argv) 308 | { 309 | return set_bypass(sh, bypass_cb); 310 | } 311 | 312 | static int cmd_dict(const struct shell *sh, size_t argc, char **argv, 313 | void *data) 314 | { 315 | int val = (intptr_t)data; 316 | 317 | shell_print(sh, "(syntax, value) : (%s, %d)", argv[0], val); 318 | 319 | return 0; 320 | } 321 | 322 | SHELL_SUBCMD_DICT_SET_CREATE(sub_dict_cmds, cmd_dict, 323 | (value_0, 0, "value 0"), (value_1, 1, "value 1"), 324 | (value_2, 2, "value 2"), (value_3, 3, "value 3") 325 | ); 326 | 327 | SHELL_STATIC_SUBCMD_SET_CREATE(sub_demo, 328 | SHELL_CMD(dictionary, &sub_dict_cmds, "Dictionary commands", NULL), 329 | SHELL_CMD(hexdump, NULL, "Hexdump params command.", cmd_demo_hexdump), 330 | SHELL_CMD(params, NULL, "Print params command.", cmd_demo_params), 331 | SHELL_CMD(ping, NULL, "Ping command.", cmd_demo_ping), 332 | SHELL_CMD(board, NULL, "Show board name command.", cmd_demo_board), 333 | #if defined CONFIG_SHELL_GETOPT 334 | SHELL_CMD(getopt_thread_safe, NULL, 335 | "Cammand using getopt in thread safe way" 336 | " looking for: \"abhc:\".", 337 | cmd_demo_getopt_ts), 338 | SHELL_CMD(getopt, NULL, "Cammand using getopt in non thread safe way" 339 | " looking for: \"abhc:\".\n", cmd_demo_getopt), 340 | #endif 341 | SHELL_SUBCMD_SET_END /* Array terminated. */ 342 | ); 343 | SHELL_CMD_REGISTER(demo, &sub_demo, "Demo commands", NULL); 344 | 345 | SHELL_CMD_ARG_REGISTER(version, NULL, "Show kernel version", cmd_version, 1, 0); 346 | 347 | SHELL_CMD_ARG_REGISTER(bypass, NULL, "Bypass shell", cmd_bypass, 1, 0); 348 | 349 | /* Create a set of commands. Commands to this set are added using @ref SHELL_SUBCMD_ADD 350 | * and @ref SHELL_SUBCMD_COND_ADD. 351 | */ 352 | SHELL_SUBCMD_SET_CREATE(sub_section_cmd, (section_cmd)); 353 | 354 | static int cmd1_handler(const struct shell *sh, size_t argc, char **argv) 355 | { 356 | ARG_UNUSED(sh); 357 | ARG_UNUSED(argc); 358 | ARG_UNUSED(argv); 359 | 360 | shell_print(sh, "cmd1 executed"); 361 | 362 | return 0; 363 | } 364 | 365 | /* Create a set of subcommands for "section_cmd cm1". */ 366 | SHELL_SUBCMD_SET_CREATE(sub_section_cmd1, (section_cmd, cmd1)); 367 | 368 | /* Add command to the set. Subcommand set is identify by parent shell command. */ 369 | SHELL_SUBCMD_ADD((section_cmd), cmd1, &sub_section_cmd1, "help for cmd1", cmd1_handler, 1, 0); 370 | 371 | SHELL_CMD_REGISTER(section_cmd, &sub_section_cmd, 372 | "Demo command using section for subcommand registration", NULL); 373 | 374 | int main(void) 375 | { 376 | #if DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_shell_uart), zephyr_cdc_acm_uart) 377 | const struct device *dev; 378 | uint32_t dtr = 0; 379 | 380 | dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart)); 381 | if (!device_is_ready(dev) || usb_enable(NULL)) { 382 | return 0; 383 | } 384 | 385 | while (!dtr) { 386 | uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr); 387 | k_sleep(K_MSEC(100)); 388 | } 389 | #endif 390 | return 0; 391 | } 392 | -------------------------------------------------------------------------------- /samples/04_shell/src/test_module.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | LOG_MODULE_REGISTER(app_test); 10 | 11 | void foo(void) 12 | { 13 | LOG_INF("info message"); 14 | LOG_WRN("warning message"); 15 | LOG_ERR("err message"); 16 | } 17 | 18 | /* Commands below are added using memory section approach which allows to build 19 | * a set of subcommands from multiple files. 20 | */ 21 | static int cmd2_handler(const struct shell *sh, size_t argc, char **argv) 22 | { 23 | ARG_UNUSED(sh); 24 | ARG_UNUSED(argc); 25 | ARG_UNUSED(argv); 26 | 27 | shell_print(sh, "cmd2 executed"); 28 | 29 | return 0; 30 | } 31 | 32 | SHELL_SUBCMD_ADD((section_cmd), cmd2, NULL, "help for cmd2", cmd2_handler, 1, 0); 33 | 34 | static int sub_cmd1_handler(const struct shell *sh, size_t argc, char **argv) 35 | { 36 | ARG_UNUSED(sh); 37 | ARG_UNUSED(argc); 38 | ARG_UNUSED(argv); 39 | 40 | shell_print(sh, "sub cmd1 executed"); 41 | 42 | return 0; 43 | } 44 | 45 | SHELL_SUBCMD_COND_ADD(1, (section_cmd, cmd1), sub_cmd1, NULL, "help for sub_cmd1", 46 | sub_cmd1_handler, 1, 0); 47 | -------------------------------------------------------------------------------- /samples/04_shell/src/uart_reinit.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | void shell_init_from_work(struct k_work *work) 12 | { 13 | const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart)); 14 | bool log_backend = CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL > 0; 15 | uint32_t level = 16 | (CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL > LOG_LEVEL_DBG) ? 17 | CONFIG_LOG_MAX_LEVEL : CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL; 18 | 19 | shell_init(shell_backend_uart_get_ptr(), dev, 20 | shell_backend_uart_get_ptr()->ctx->cfg.flags, 21 | log_backend, level); 22 | } 23 | 24 | static void shell_reinit_trigger(void) 25 | { 26 | static struct k_work shell_init_work; 27 | 28 | k_work_init(&shell_init_work, shell_init_from_work); 29 | int err = k_work_submit(&shell_init_work); 30 | 31 | (void)err; 32 | __ASSERT_NO_MSG(err >= 0); 33 | } 34 | 35 | static void direct_uart_callback(const struct device *dev, void *user_data) 36 | { 37 | static uint8_t buf[1]; 38 | static bool tx_busy; 39 | 40 | uart_irq_update(dev); 41 | 42 | 43 | if (uart_irq_rx_ready(dev)) { 44 | while (uart_fifo_read(dev, buf, sizeof(buf))) { 45 | if (!tx_busy) { 46 | uart_irq_tx_enable(dev); 47 | } 48 | } 49 | } 50 | 51 | if (uart_irq_tx_ready(dev)) { 52 | if (!tx_busy) { 53 | (void)uart_fifo_fill(dev, buf, sizeof(buf)); 54 | tx_busy = true; 55 | } else { 56 | tx_busy = false; 57 | uart_irq_tx_disable(dev); 58 | if (buf[0] == 'x') { 59 | uart_irq_rx_disable(dev); 60 | shell_reinit_trigger(); 61 | } 62 | } 63 | } 64 | } 65 | 66 | static void uart_poll_timer_stopped(struct k_timer *timer) 67 | { 68 | shell_reinit_trigger(); 69 | } 70 | 71 | static void uart_poll_timeout(struct k_timer *timer) 72 | { 73 | char c; 74 | const struct device *dev = k_timer_user_data_get(timer); 75 | 76 | while (uart_poll_in(dev, &c) == 0) { 77 | if (c != 'x') { 78 | uart_poll_out(dev, c); 79 | } else { 80 | k_timer_stop(timer); 81 | } 82 | } 83 | } 84 | 85 | K_TIMER_DEFINE(uart_poll_timer, uart_poll_timeout, uart_poll_timer_stopped); 86 | 87 | static void shell_uninit_cb(const struct shell *sh, int res) 88 | { 89 | __ASSERT_NO_MSG(res >= 0); 90 | const struct device *const dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart)); 91 | 92 | if (IS_ENABLED(CONFIG_SHELL_BACKEND_SERIAL_INTERRUPT_DRIVEN)) { 93 | /* connect uart to my handler */ 94 | uart_irq_callback_user_data_set(dev, direct_uart_callback, NULL); 95 | uart_irq_rx_enable(dev); 96 | } else { 97 | k_timer_user_data_set(&uart_poll_timer, (void *)dev); 98 | k_timer_start(&uart_poll_timer, K_MSEC(10), K_MSEC(10)); 99 | } 100 | } 101 | 102 | static int cmd_uart_release(const struct shell *sh, size_t argc, char **argv) 103 | { 104 | ARG_UNUSED(argc); 105 | ARG_UNUSED(argv); 106 | 107 | if (sh != shell_backend_uart_get_ptr()) { 108 | shell_error(sh, "Command dedicated for shell over uart"); 109 | return -EINVAL; 110 | } 111 | 112 | shell_print(sh, "Uninitializing shell, use 'x' to reinitialize"); 113 | shell_uninit(sh, shell_uninit_cb); 114 | 115 | return 0; 116 | } 117 | 118 | SHELL_CMD_REGISTER(shell_uart_release, NULL, 119 | "Uninitialize shell instance and release uart, start loopback " 120 | "on uart. Shell instance is reinitialized when 'x' is pressed", 121 | cmd_uart_release); 122 | -------------------------------------------------------------------------------- /samples/04_shell/usb.overlay: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Nordic Semiconductor ASA 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | / { 8 | chosen { 9 | zephyr,shell-uart = &cdc_acm_uart0; 10 | }; 11 | }; 12 | 13 | &zephyr_udc0 { 14 | cdc_acm_uart0: cdc_acm_uart0 { 15 | compatible = "zephyr,cdc-acm-uart"; 16 | }; 17 | }; 18 | -------------------------------------------------------------------------------- /samples/05_sensor/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 6 | project(ti_hdc) 7 | 8 | FILE(GLOB app_sources src/*.c) 9 | target_sources(app PRIVATE ${app_sources}) 10 | -------------------------------------------------------------------------------- /samples/05_sensor/README.rst: -------------------------------------------------------------------------------- 1 | .. _ti_hdc_sample: 2 | 3 | TI_HDC Sample 4 | ############## 5 | 6 | Description 7 | *********** 8 | 9 | This sample application periodically takes Temperature and Humidity 10 | using the ti_hdc sensor driver. The result is written to the console. 11 | 12 | Requirements 13 | ************ 14 | 15 | This sample needs a compatible sensor like HDC1010 or HDC1080 16 | connected to the target board's I2C connector. 17 | 18 | Example Breakout Boards: 19 | 20 | * Pmod HYGRO: Humidity and Temperature Sensor Breakout board 21 | 22 | 23 | Wiring 24 | ****** 25 | 26 | This sample is tested with the STM32L496ZG nucleo and the Pmod HYGRO 27 | Temp/RH breakout board. 28 | 29 | The sensor operates at 3.3V and uses I2C to communicate with the board. 30 | 31 | External Wires: 32 | 33 | * Breakout **GND** pin <--> Nucleo **GND** pin 34 | * Breakout **VCC** pin <--> Nucleo **3V3** pin 35 | * Breakout **SDA** pin <--> Nucleo **CN7-D14** pin 36 | * Breakout **SCL** pin <--> Nucleo **CN7-D15** pin 37 | 38 | Building and Running 39 | ******************** 40 | 41 | This sample builds one application for the HDC1080 sensor. 42 | Build/Flash Steps: 43 | 44 | .. zephyr-app-commands:: 45 | :zephyr-app: samples/sensor/ti_hdc/ 46 | :board: nucleo_l496zg 47 | :goals: build flash 48 | :compact: 49 | 50 | Sample Output 51 | ************* 52 | .. code-block:: console 53 | 54 | Running on arm! 55 | Dev 0x20001160 name HDC1080 is ready! 56 | Fetching... 57 | Raw Temp = 25144, Temp = 23.305053 C, Raw RH = 32292, RH = 49.273681 % 58 | Fetching... 59 | Raw Temp = 25148, Temp = 23.315124 C, Raw RH = 32424, RH = 49.475097 % 60 | ... 61 | 62 | Build Testing 63 | ************** 64 | 65 | .. code-block:: bash 66 | 67 | $ZEPHYR_BASE/scripts/twister -T $ZEPHYR_BASE/samples/sensor/ti_hdc/ -p nucleo_l496zg --device-testing --device-serial /dev/ttyACM0 -t build 68 | 69 | Target Testing 70 | ************** 71 | 72 | .. code-block:: bash 73 | 74 | $ZEPHYR_BASE/scripts/twister -T $ZEPHYR_BASE/samples/sensor/ti_hdc/ -p nucleo_l496zg --device-testing --device-serial /dev/ttyACM0 -t target 75 | 76 | 77 | References 78 | ********** 79 | 80 | .. _Nucleo STM32L496ZG board: https://www.st.com/en/evaluation-tools/nucleo-l496zg.html 81 | .. _HDC1080 Breakout board: https://store.digilentinc.com/pmod-hygro-digital-humidity-and-temperature-sensor/ 82 | -------------------------------------------------------------------------------- /samples/05_sensor/boards/nucleo_l496zg.overlay: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019 Centaur Analytics, Inc 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | &arduino_i2c { 8 | 9 | ti_hdc: ti_hdc@40 { 10 | compatible = "ti,hdc","ti,hdc1080"; 11 | reg = <0x40>; 12 | }; 13 | 14 | }; 15 | -------------------------------------------------------------------------------- /samples/05_sensor/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_ASSERT=y # validation 2 | CONFIG_I2C=y 3 | CONFIG_GPIO=y 4 | CONFIG_SENSOR=y 5 | -------------------------------------------------------------------------------- /samples/05_sensor/sample.yaml: -------------------------------------------------------------------------------- 1 | sample: 2 | name: sensor test 3 | common: 4 | integration_platforms: 5 | - reel_board 6 | tests: 7 | sample.basic.sensor: 8 | build_only: true 9 | -------------------------------------------------------------------------------- /samples/05_sensor/src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2019 Centaur Analytics 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | int main(void) 16 | { 17 | printk("Running on %s!\n", CONFIG_ARCH); 18 | const struct device *const dev = DEVICE_DT_GET_ONE(ti_hdc); 19 | 20 | if (!device_is_ready(dev)) { 21 | printk("sensor: device not ready.\n"); 22 | return 0; 23 | } 24 | 25 | printk("Dev %p name %s is ready!\n", dev, dev->name); 26 | 27 | struct sensor_value temp, humidity; 28 | 29 | while (1) { 30 | /* take a sample */ 31 | printk("Fetching...\n"); 32 | sensor_sample_fetch(dev); 33 | sensor_channel_get(dev, SENSOR_CHAN_AMBIENT_TEMP, &temp); 34 | sensor_channel_get(dev, SENSOR_CHAN_HUMIDITY, &humidity); 35 | 36 | /* print the result */ 37 | printk("Temp = %d.%06d C, RH = %d.%06d %%\n", 38 | temp.val1, temp.val2, humidity.val1, humidity.val2); 39 | 40 | /* wait for the next sample */ 41 | k_sleep(K_SECONDS(10)); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /samples/06_ble/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 6 | project(peripheral_ht) 7 | 8 | FILE(GLOB app_sources src/*.c) 9 | target_sources(app PRIVATE 10 | ${app_sources} 11 | ) 12 | -------------------------------------------------------------------------------- /samples/06_ble/Kconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | mainmenu "Bluetooth: Peripheral HT" 5 | 6 | if HAS_HW_NRF_TEMP 7 | 8 | config SENSOR 9 | default y 10 | 11 | config TEMP_NRF5 12 | default y 13 | 14 | endif # HAS_HW_NRF_TEMP 15 | 16 | source "Kconfig.zephyr" 17 | -------------------------------------------------------------------------------- /samples/06_ble/README.rst: -------------------------------------------------------------------------------- 1 | .. _peripheral_ht: 2 | 3 | Bluetooth: Peripheral HT 4 | ######################## 5 | 6 | Overview 7 | ******** 8 | 9 | Similar to the :ref:`Peripheral ` sample, except that this 10 | application specifically exposes the HT (Health Thermometer) GATT Service. 11 | 12 | On Nordic nRF devices, this sample uses the built-in TEMP peripheral to return 13 | die temperature values. On other boards, it will generate dummy temperature 14 | values. 15 | 16 | 17 | Requirements 18 | ************ 19 | 20 | * BlueZ running on the host, or 21 | * A board with Bluetooth LE support 22 | 23 | Building and Running 24 | ******************** 25 | 26 | This sample can be found under :zephyr_file:`samples/bluetooth/peripheral_ht` in the 27 | Zephyr tree. 28 | 29 | See :ref:`bluetooth samples section ` for details. 30 | -------------------------------------------------------------------------------- /samples/06_ble/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_BT=y 2 | CONFIG_LOG=y 3 | CONFIG_BT_SMP=y 4 | CONFIG_BT_PERIPHERAL=y 5 | CONFIG_BT_DIS=y 6 | CONFIG_BT_DIS_PNP=n 7 | CONFIG_BT_BAS=y 8 | CONFIG_BT_DEVICE_NAME="Zephyr Health Thermometer" 9 | CONFIG_BT_DEVICE_APPEARANCE=768 10 | CONFIG_CBPRINTF_FP_SUPPORT=y 11 | -------------------------------------------------------------------------------- /samples/06_ble/sample.yaml: -------------------------------------------------------------------------------- 1 | sample: 2 | name: ble build test 3 | common: 4 | integration_platforms: 5 | - reel_board 6 | tests: 7 | sample.basic.ble: 8 | build_only: true 9 | -------------------------------------------------------------------------------- /samples/06_ble/src/hts.c: -------------------------------------------------------------------------------- 1 | /** @file 2 | * @brief HTS Service sample 3 | */ 4 | 5 | /* 6 | * Copyright (c) 2020 SixOctets Systems 7 | * Copyright (c) 2019 Aaron Tsui 8 | * 9 | * SPDX-License-Identifier: Apache-2.0 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #ifdef CONFIG_TEMP_NRF5 29 | static const struct device *temp_dev = DEVICE_DT_GET_ANY(nordic_nrf_temp); 30 | #else 31 | static const struct device *temp_dev; 32 | #endif 33 | 34 | static uint8_t simulate_htm; 35 | static uint8_t indicating; 36 | static struct bt_gatt_indicate_params ind_params; 37 | 38 | static void htmc_ccc_cfg_changed(const struct bt_gatt_attr *attr, 39 | uint16_t value) 40 | { 41 | simulate_htm = (value == BT_GATT_CCC_INDICATE) ? 1 : 0; 42 | } 43 | 44 | static void indicate_cb(struct bt_conn *conn, 45 | struct bt_gatt_indicate_params *params, uint8_t err) 46 | { 47 | printk("Indication %s\n", err != 0U ? "fail" : "success"); 48 | } 49 | 50 | static void indicate_destroy(struct bt_gatt_indicate_params *params) 51 | { 52 | printk("Indication complete\n"); 53 | indicating = 0U; 54 | } 55 | 56 | /* Health Thermometer Service Declaration */ 57 | BT_GATT_SERVICE_DEFINE(hts_svc, 58 | BT_GATT_PRIMARY_SERVICE(BT_UUID_HTS), 59 | BT_GATT_CHARACTERISTIC(BT_UUID_HTS_MEASUREMENT, BT_GATT_CHRC_INDICATE, 60 | BT_GATT_PERM_NONE, NULL, NULL, NULL), 61 | BT_GATT_CCC(htmc_ccc_cfg_changed, 62 | BT_GATT_PERM_READ | BT_GATT_PERM_WRITE), 63 | /* more optional Characteristics */ 64 | ); 65 | 66 | void hts_init(void) 67 | { 68 | if (temp_dev == NULL || !device_is_ready(temp_dev)) { 69 | printk("no temperature device; using simulated data\n"); 70 | temp_dev = NULL; 71 | } else { 72 | printk("temp device is %p, name is %s\n", temp_dev, 73 | temp_dev->name); 74 | } 75 | } 76 | 77 | void hts_indicate(void) 78 | { 79 | /* Temperature measurements simulation */ 80 | struct sensor_value temp_value; 81 | 82 | if (simulate_htm) { 83 | static uint8_t htm[5]; 84 | static double temperature = 20U; 85 | uint32_t mantissa; 86 | uint8_t exponent; 87 | int r; 88 | 89 | if (indicating) { 90 | return; 91 | } 92 | 93 | if (!temp_dev) { 94 | temperature++; 95 | if (temperature == 30U) { 96 | temperature = 20U; 97 | } 98 | 99 | goto gatt_indicate; 100 | } 101 | 102 | r = sensor_sample_fetch(temp_dev); 103 | if (r) { 104 | printk("sensor_sample_fetch failed return: %d\n", r); 105 | } 106 | 107 | r = sensor_channel_get(temp_dev, SENSOR_CHAN_DIE_TEMP, 108 | &temp_value); 109 | if (r) { 110 | printk("sensor_channel_get failed return: %d\n", r); 111 | } 112 | 113 | temperature = sensor_value_to_double(&temp_value); 114 | 115 | gatt_indicate: 116 | printf("temperature is %gC\n", temperature); 117 | 118 | mantissa = (uint32_t)(temperature * 100); 119 | exponent = (uint8_t)-2; 120 | 121 | htm[0] = 0; /* temperature in celsius */ 122 | sys_put_le24(mantissa, (uint8_t *)&htm[1]); 123 | htm[4] = exponent; 124 | 125 | ind_params.attr = &hts_svc.attrs[2]; 126 | ind_params.func = indicate_cb; 127 | ind_params.destroy = indicate_destroy; 128 | ind_params.data = &htm; 129 | ind_params.len = sizeof(htm); 130 | 131 | if (bt_gatt_indicate(NULL, &ind_params) == 0) { 132 | indicating = 1U; 133 | } 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /samples/06_ble/src/hts.h: -------------------------------------------------------------------------------- 1 | /** @file 2 | * @brief HTS Service sample 3 | */ 4 | 5 | /* 6 | * Copyright (c) 2019 Aaron Tsui 7 | * 8 | * SPDX-License-Identifier: Apache-2.0 9 | */ 10 | 11 | #ifdef __cplusplus 12 | extern "C" { 13 | #endif 14 | 15 | void hts_init(void); 16 | void hts_indicate(void); 17 | 18 | #ifdef __cplusplus 19 | } 20 | #endif 21 | -------------------------------------------------------------------------------- /samples/06_ble/src/main.c: -------------------------------------------------------------------------------- 1 | /* main.c - Application main entry point */ 2 | 3 | /* 4 | * Copyright (c) 2019 Aaron Tsui 5 | * 6 | * SPDX-License-Identifier: Apache-2.0 7 | */ 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | 24 | #include "hts.h" 25 | 26 | static const struct bt_data ad[] = { 27 | BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), 28 | BT_DATA_BYTES(BT_DATA_UUID16_ALL, 29 | BT_UUID_16_ENCODE(BT_UUID_HTS_VAL), 30 | BT_UUID_16_ENCODE(BT_UUID_DIS_VAL), 31 | BT_UUID_16_ENCODE(BT_UUID_BAS_VAL)), 32 | }; 33 | 34 | static const struct bt_data sd[] = { 35 | BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1), 36 | }; 37 | 38 | static void connected(struct bt_conn *conn, uint8_t err) 39 | { 40 | if (err) { 41 | printk("Connection failed, err 0x%02x %s\n", err, bt_hci_err_to_str(err)); 42 | } else { 43 | printk("Connected\n"); 44 | } 45 | } 46 | 47 | static void disconnected(struct bt_conn *conn, uint8_t reason) 48 | { 49 | printk("Disconnected, reason 0x%02x %s\n", reason, bt_hci_err_to_str(reason)); 50 | } 51 | 52 | BT_CONN_CB_DEFINE(conn_callbacks) = { 53 | .connected = connected, 54 | .disconnected = disconnected, 55 | }; 56 | 57 | static void bt_ready(void) 58 | { 59 | int err; 60 | 61 | printk("Bluetooth initialized\n"); 62 | 63 | hts_init(); 64 | 65 | err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); 66 | if (err) { 67 | printk("Advertising failed to start (err %d)\n", err); 68 | return; 69 | } 70 | 71 | printk("Advertising successfully started\n"); 72 | } 73 | 74 | static void auth_cancel(struct bt_conn *conn) 75 | { 76 | char addr[BT_ADDR_LE_STR_LEN]; 77 | 78 | bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); 79 | 80 | printk("Pairing cancelled: %s\n", addr); 81 | } 82 | 83 | static struct bt_conn_auth_cb auth_cb_display = { 84 | .cancel = auth_cancel, 85 | }; 86 | 87 | static void bas_notify(void) 88 | { 89 | uint8_t battery_level = bt_bas_get_battery_level(); 90 | 91 | battery_level--; 92 | 93 | if (!battery_level) { 94 | battery_level = 100U; 95 | } 96 | 97 | bt_bas_set_battery_level(battery_level); 98 | } 99 | 100 | int main(void) 101 | { 102 | int err; 103 | 104 | err = bt_enable(NULL); 105 | if (err) { 106 | printk("Bluetooth init failed (err %d)\n", err); 107 | return 0; 108 | } 109 | 110 | bt_ready(); 111 | 112 | bt_conn_auth_cb_register(&auth_cb_display); 113 | 114 | /* Implement indicate. At the moment there is no suitable way 115 | * of starting delayed work so we do it here 116 | */ 117 | while (1) { 118 | k_sleep(K_SECONDS(1)); 119 | 120 | /* Temperature measurements simulation */ 121 | hts_indicate(); 122 | 123 | /* Battery level simulation */ 124 | bas_notify(); 125 | } 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /samples/07_display_cfb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | cmake_minimum_required(VERSION 3.20.0) 4 | 5 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 6 | project(cfb) 7 | 8 | FILE(GLOB app_sources src/*.c) 9 | target_sources(app PRIVATE ${app_sources}) 10 | -------------------------------------------------------------------------------- /samples/07_display_cfb/README.rst: -------------------------------------------------------------------------------- 1 | .. zephyr:code-sample:: character-frame-buffer 2 | :name: Character frame buffer 3 | :relevant-api: monochrome_character_framebuffer 4 | 5 | Display character strings using the Character Frame Buffer (CFB). 6 | 7 | Overview 8 | ******** 9 | 10 | This sample displays character strings using the Character Frame Buffer 11 | (CFB) subsystem framework. 12 | 13 | Requirements 14 | ************ 15 | 16 | This sample requires a supported board and CFB-supporting 17 | display, such as the :ref:`reel_board`. 18 | 19 | Building and Running 20 | ******************** 21 | 22 | Build this sample application with the following commands: 23 | 24 | .. zephyr-app-commands:: 25 | :zephyr-app: samples/subsys/display/cfb 26 | :board: reel_board 27 | :goals: build 28 | :compact: 29 | 30 | See :ref:`reel_board` on how to flash the build. 31 | -------------------------------------------------------------------------------- /samples/07_display_cfb/boards/reel_board.conf: -------------------------------------------------------------------------------- 1 | CONFIG_SPI=y 2 | -------------------------------------------------------------------------------- /samples/07_display_cfb/prj.conf: -------------------------------------------------------------------------------- 1 | CONFIG_STDOUT_CONSOLE=y 2 | 3 | CONFIG_HEAP_MEM_POOL_SIZE=16384 4 | 5 | CONFIG_DISPLAY=y 6 | 7 | CONFIG_LOG=y 8 | 9 | CONFIG_CFB_LOG_LEVEL_DBG=y 10 | CONFIG_CHARACTER_FRAMEBUFFER=y 11 | -------------------------------------------------------------------------------- /samples/07_display_cfb/sample.yaml: -------------------------------------------------------------------------------- 1 | common: 2 | harness: display 3 | tags: display 4 | sample: 5 | description: Character framebuffer test 6 | name: cfb sample 7 | tests: 8 | sample.display.cfb.ssd1306: 9 | platform_allow: frdm_k64f 10 | extra_args: SHIELD=ssd1306_128x64 11 | tags: shield 12 | sample.display.cfb.ssd16xx: 13 | platform_allow: reel_board 14 | -------------------------------------------------------------------------------- /samples/07_display_cfb/src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 PHYTEC Messtechnik GmbH 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | int main(void) 13 | { 14 | const struct device *dev; 15 | uint16_t x_res; 16 | uint16_t y_res; 17 | uint16_t rows; 18 | uint8_t ppt; 19 | uint8_t font_width; 20 | uint8_t font_height; 21 | 22 | dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_display)); 23 | if (!device_is_ready(dev)) { 24 | printf("Device %s not ready\n", dev->name); 25 | return 0; 26 | } 27 | 28 | if (display_set_pixel_format(dev, PIXEL_FORMAT_MONO10) != 0) { 29 | if (display_set_pixel_format(dev, PIXEL_FORMAT_MONO01) != 0) { 30 | printf("Failed to set required pixel format"); 31 | return 0; 32 | } 33 | } 34 | 35 | printf("Initialized %s\n", dev->name); 36 | 37 | if (cfb_framebuffer_init(dev)) { 38 | printf("Framebuffer initialization failed!\n"); 39 | return 0; 40 | } 41 | 42 | cfb_framebuffer_clear(dev, true); 43 | 44 | display_blanking_off(dev); 45 | 46 | x_res = cfb_get_display_parameter(dev, CFB_DISPLAY_WIDTH); 47 | y_res = cfb_get_display_parameter(dev, CFB_DISPLAY_HEIGH); 48 | rows = cfb_get_display_parameter(dev, CFB_DISPLAY_ROWS); 49 | ppt = cfb_get_display_parameter(dev, CFB_DISPLAY_PPT); 50 | 51 | for (int idx = 0; idx < 42; idx++) { 52 | if (cfb_get_font_size(dev, idx, &font_width, &font_height)) { 53 | break; 54 | } 55 | cfb_framebuffer_set_font(dev, idx); 56 | printf("idx: %d, font width %d, font height %d\n", 57 | idx, font_width, font_height); 58 | } 59 | printf("x_res %d, y_res %d, ppt %d, rows %d, cols %d\n", 60 | x_res, 61 | y_res, 62 | ppt, 63 | rows, 64 | cfb_get_display_parameter(dev, CFB_DISPLAY_COLS)); 65 | 66 | cfb_framebuffer_set_font(dev, 1); 67 | 68 | cfb_set_kerning(dev, 3); 69 | 70 | for (int i = 0; i < MIN(x_res, y_res); i++) { 71 | cfb_framebuffer_clear(dev, false); 72 | cfb_print(dev, "Zephyr Class", 17, 5); 73 | cfb_print(dev, "EW 2025", 60, 40); 74 | cfb_print(dev, "", 5, 90); 75 | cfb_framebuffer_finalize(dev); 76 | } 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /slides/Makefile: -------------------------------------------------------------------------------- 1 | TEXFILE = workshop_slides.tex 2 | 3 | all: pdf 4 | 5 | pdf: 6 | lualatex --shell-escape $(TEXFILE) 7 | @if ( grep -q "Rerun to get" $(TEXFILE:.tex=.log) ); then \ 8 | echo "Rerunning LaTeX..."; \ 9 | lualatex --shell-escape $(TEXFILE); \ 10 | fi 11 | 12 | clean: 13 | rm -f $(TEXFILE:.tex=.aux) $(TEXFILE:.tex=.log) $(TEXFILE:.tex=.nav) $(TEXFILE:.tex=.out) $(TEXFILE:.tex=.snm) $(TEXFILE:.tex=.toc) $(TEXFILE:.tex=.vrb) 14 | 15 | cleanall: clean 16 | rm -f $(TEXFILE:.tex=.pdf) 17 | 18 | .PHONY: all pdf clean cleanall 19 | -------------------------------------------------------------------------------- /slides/images/Zephyr_getting_started.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/Zephyr_getting_started.png -------------------------------------------------------------------------------- /slides/images/ai_requirements.txt: -------------------------------------------------------------------------------- 1 | I'm preparing for a 3h Zephyr Project workshop. 2 | 3 | This is my typical template slide that I use with latex beamer. Per default you can leave the image on thee 4 | right side out for now, I will add them later. 5 | 6 | \begin{frame}[fragile]{} 7 | \begin{columns} 8 | \begin{column}{0.6\textwidth} 9 | %----------------------------------------- 10 | \begin{itemize} 11 | \item 12 | \item 13 | \item 14 | \end{itemize} 15 | %----------------------------------------- 16 | \end{column} 17 | \begin{column}{0.4\textwidth} 18 | \begin{figure} 19 | %\includegraphics[width=0.8\textwidth]{} 20 | \caption{} 21 | \end{figure} 22 | \end{column} 23 | \end{columns} 24 | \end{frame} 25 | 26 | Note the rules of a good presentation, stick to them if possible: 27 | - max 6 paragraphs 28 | - max 6 words per paragraph 29 | 30 | I'm an embedded developer, the presentation is for beginner and intermediate level developer and executives. 31 | -------------------------------------------------------------------------------- /slides/images/application_topologies_1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 228 | -------------------------------------------------------------------------------- /slides/images/application_topologies_2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 344 | -------------------------------------------------------------------------------- /slides/images/boards.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/boards.jpg -------------------------------------------------------------------------------- /slides/images/codespaces_how_to_start.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/codespaces_how_to_start.png -------------------------------------------------------------------------------- /slides/images/codespaces_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/codespaces_open.png -------------------------------------------------------------------------------- /slides/images/codespaces_setting_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/codespaces_setting_up.png -------------------------------------------------------------------------------- /slides/images/codespaces_setting_up_class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/codespaces_setting_up_class.png -------------------------------------------------------------------------------- /slides/images/devicetree-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /slides/images/jrov2201.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/jrov2201.jpg -------------------------------------------------------------------------------- /slides/images/jrov2201_housing.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/jrov2201_housing.jpg -------------------------------------------------------------------------------- /slides/images/lf-stacked-color.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 21 | 23 | 24 | 26 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 40 | 42 | 43 | 44 | 45 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /slides/images/nrf_connect_ble_connected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/nrf_connect_ble_connected.png -------------------------------------------------------------------------------- /slides/images/nrf_connect_scan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/nrf_connect_scan.png -------------------------------------------------------------------------------- /slides/images/reel_board.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/reel_board.jpg -------------------------------------------------------------------------------- /slides/images/reel_board_descr_back.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/reel_board_descr_back.jpg -------------------------------------------------------------------------------- /slides/images/reel_board_hdc1010.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/reel_board_hdc1010.jpg -------------------------------------------------------------------------------- /slides/images/reel_board_passive_display.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/reel_board_passive_display.jpg -------------------------------------------------------------------------------- /slides/images/system-architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/system-architecture.png -------------------------------------------------------------------------------- /slides/images/zephyr_blinky.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/zephyr_blinky.png -------------------------------------------------------------------------------- /slides/images/zephyr_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jonas-rem/zephyr-workshop/b33612ca640ca624abc75cc56c883d81acb638d8/slides/images/zephyr_logo.png -------------------------------------------------------------------------------- /test/button/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20.0) 2 | 3 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 4 | project(button_sample) 5 | 6 | target_sources(app PRIVATE src/main.c) 7 | add_subdirectory(../../app/src/common common) 8 | add_subdirectory(../../app/src/modules/button button) 9 | -------------------------------------------------------------------------------- /test/button/Kconfig: -------------------------------------------------------------------------------- 1 | menu "Button Test" 2 | 3 | rsource "../../app/src/modules/button/Kconfig.button" 4 | 5 | endmenu 6 | 7 | menu "Zephyr Kernel" 8 | source "Kconfig.zephyr" 9 | endmenu 10 | -------------------------------------------------------------------------------- /test/button/prj.conf: -------------------------------------------------------------------------------- 1 | # Logging 2 | CONFIG_LOG=y 3 | # Make Logging more responsive for better visualization 4 | CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=1 5 | CONFIG_BUTTON_MODULE_LOG_LEVEL_DBG=y 6 | 7 | # ZBus 8 | CONFIG_ZBUS=y 9 | -------------------------------------------------------------------------------- /test/button/sample.yaml: -------------------------------------------------------------------------------- 1 | sample: 2 | description: Button module sample 3 | name: button_module_sample 4 | common: 5 | tags: introduction 6 | integration_platforms: 7 | - reel_board 8 | - frdm_k64f 9 | - nucleo_wb55rg 10 | - nucleo_l496zg 11 | - mimxrt1010_evk 12 | - nucleo_l452re 13 | - nrf5340dk/nrf5340/cpuapp 14 | - stm32f4_disco 15 | # The following platforms are not supported in twister currently 16 | #- nrf52833dk_nrf52833 17 | #- atsamr21_xpro 18 | tests: 19 | sample.basic.button: 20 | tags: introduction 21 | -------------------------------------------------------------------------------- /test/button/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "message_channel.h" 5 | 6 | #include 7 | LOG_MODULE_REGISTER(app, CONFIG_BUTTON_MODULE_LOG_LEVEL); 8 | 9 | 10 | void button_test_msg_cb(const struct zbus_channel *chan) 11 | { 12 | const enum sys_events *msg_type; 13 | 14 | /* Get message from channel. */ 15 | msg_type = zbus_chan_const_msg(chan); 16 | 17 | switch (*msg_type) { 18 | case SYS_BUTTON_PRESSED: 19 | LOG_INF("Button pressed!"); 20 | break; 21 | default: 22 | /* Ignore nonrelevant messages */ 23 | break; 24 | } 25 | } 26 | 27 | int main(void) 28 | { 29 | LOG_INF("Button test start"); 30 | 31 | return 0; 32 | } 33 | 34 | ZBUS_LISTENER_DEFINE(button_test, button_test_msg_cb); 35 | ZBUS_CHAN_ADD_OBS(button_ch, button_test, DEFAULT_OBS_PRIO); 36 | -------------------------------------------------------------------------------- /test/led/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.20.0) 2 | 3 | find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) 4 | project(led_sample) 5 | 6 | target_sources(app PRIVATE src/main.c) 7 | add_subdirectory(./../../app/src/common common) 8 | add_subdirectory(./../../app/src/modules/led led) 9 | -------------------------------------------------------------------------------- /test/led/Kconfig: -------------------------------------------------------------------------------- 1 | menu "LED Test" 2 | 3 | rsource "../../app/src/modules/led/Kconfig.led" 4 | 5 | endmenu 6 | 7 | menu "Zephyr Kernel" 8 | source "Kconfig.zephyr" 9 | endmenu 10 | -------------------------------------------------------------------------------- /test/led/prj.conf: -------------------------------------------------------------------------------- 1 | # Logging 2 | CONFIG_LOG=y 3 | # Make Logging more responsive for better visualization 4 | CONFIG_LOG_PROCESS_TRIGGER_THRESHOLD=1 5 | CONFIG_LED_MODULE_LOG_LEVEL_DBG=y 6 | 7 | # ZBus 8 | CONFIG_ZBUS=y 9 | 10 | # Shell Testing 11 | CONFIG_SHELL=y 12 | -------------------------------------------------------------------------------- /test/led/sample.yaml: -------------------------------------------------------------------------------- 1 | sample: 2 | description: LED module sample 3 | name: led_module_sample 4 | common: 5 | tags: introduction 6 | integration_platforms: 7 | - reel_board 8 | - frdm_k64f 9 | - nucleo_wb55rg 10 | - nucleo_l496zg 11 | - mimxrt1010_evk 12 | - nucleo_l452re 13 | - nrf5340dk/nrf5340/cpuapp 14 | - stm32f4_disco 15 | # The following platforms are not supported in twister currently 16 | #- nrf52833dk_nrf52833 17 | #- atsamr21_xpro 18 | tests: 19 | sample.basic.led: 20 | tags: introduction 21 | -------------------------------------------------------------------------------- /test/led/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "message_channel.h" 5 | 6 | #include 7 | LOG_MODULE_REGISTER(app, CONFIG_LED_MODULE_LOG_LEVEL); 8 | 9 | static void led_msg(enum sys_states msg) 10 | { 11 | int err; 12 | 13 | err = zbus_chan_pub(&led_ch, &msg, K_SECONDS(1)); 14 | if (err) { 15 | LOG_ERR("zbus_chan_pub, error: %d", err); 16 | } 17 | } 18 | 19 | static int cmd_led(const struct shell *sh, size_t argc, char **argv, 20 | void *data) 21 | { 22 | int val = (intptr_t)data; 23 | 24 | switch (val) { 25 | case 0: 26 | led_msg(SYS_SLEEP); 27 | break; 28 | case 1: 29 | led_msg(SYS_STANDBY); 30 | break; 31 | /* Add your code here */ 32 | 33 | /* */ 34 | default: 35 | shell_print(sh, "Invalid argument"); 36 | break; 37 | } 38 | 39 | return 0; 40 | } 41 | 42 | SHELL_SUBCMD_DICT_SET_CREATE(sub_led_cmds, cmd_led, 43 | (sys_sleep, 0, "System is sleeping"), 44 | (sys_standby, 1, "System is in standby") 45 | /* Add your code here */ 46 | 47 | /* */ 48 | ); 49 | 50 | SHELL_STATIC_SUBCMD_SET_CREATE(my_app_cmds, 51 | SHELL_CMD(led, &sub_led_cmds, "Led module commands", NULL), 52 | SHELL_SUBCMD_SET_END /* Array terminated. */ 53 | ); 54 | SHELL_CMD_REGISTER(my_app, &my_app_cmds, "my App test", NULL); 55 | 56 | int main(void) 57 | { 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /util/flash_boards.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Check if an argument is provided 4 | if [ "$#" -ne 1 ]; then 5 | echo "Usage: $0 " 6 | exit 1 7 | fi 8 | 9 | ZEPHYR_PROJECT_DIR="/home/jonas/git/zephyrproject" 10 | ZEPHYR_SDK_DIR="/home/jonas/Downloads/zephyr-sdk-0.16.5-1" 11 | SDK_SCRIPT_DIR="$ZEPHYR_SDK_DIR/sysroots/x86_64-pokysdk-linux/usr/share/openocd/scripts" 12 | CONFIG_FILE="$BOARD_DIR/openocd.cfg" 13 | HEX_FILE="$1" 14 | 15 | echo "Select a board to flash:" 16 | echo "1) reel_board" 17 | echo "2) frdm_k64f" 18 | echo "3) nucleo_wb55rg" 19 | echo "4) nucleo_l496zg" 20 | echo "5) mimxrt1010_evk" 21 | echo "6) nucleo_l452re" 22 | echo "7) nrf5340dk/nrf5340/cpuapp" 23 | echo "8) nrf52833dk_nrf52833" 24 | echo "9) atsamr21_xpro" 25 | 26 | read -p "Enter your choice (number): " choice 27 | 28 | case $choice in 29 | 1) 30 | TOOL="pyocd" 31 | TARGET="nrf52840" 32 | ;; 33 | 2) 34 | TOOL="pyocd" 35 | TARGET="k64f" 36 | ;; 37 | 3) 38 | TOOL="pyocd" 39 | TARGET="stm32wb55rgvx" 40 | ;; 41 | 4) 42 | TOOL="openocd" 43 | BOARD_DIR="$ZEPHYR_PROJECT_DIR/zephyr/boards/st/nucleo_l496zg/support" 44 | TARGET="stm32l496zg" 45 | ;; 46 | 5) 47 | TOOL="pyocd" 48 | TARGET="mimxrt1010" 49 | ;; 50 | 6) 51 | TOOL="openocd" 52 | BOARD_DIR="$ZEPHYR_PROJECT_DIR/zephyr/boards/st/nucleo_l452re/support" 53 | TARGET="stm32l454re" 54 | ;; 55 | 7) 56 | TOOL="jlink" 57 | TARGET="NRF53" 58 | ;; 59 | 8) 60 | TOOL="pyocd" 61 | TARGET="nrf52833" 62 | ;; 63 | 9) 64 | TOOL="openocd" 65 | BOARD_DIR="$ZEPHYR_PROJECT_DIR/zephyr/boards/atmel/sam0/samr21_xpro/support" 66 | TARGET="at91samr21" 67 | ;; 68 | *) 69 | echo "Invalid selection. Exiting." 70 | exit 1 71 | ;; 72 | esac 73 | 74 | if [ "$TOOL" = "pyocd" ]; then 75 | pyocd flash -t $TARGET $HEX_FILE 76 | elif [ "$TOOL" = "openocd" ]; then 77 | openocd -s $BOARD_DIR -s $SDK_SCRIPT_DIR \ 78 | -f $CONFIG_FILE \ 79 | '-c init' '-c targets' -c 'reset init' \ 80 | -c "flash write_image erase $HEX_FILE" \ 81 | -c 'reset run' -c shutdown 82 | elif [ "$TOOL" = "jlink" ]; then 83 | nrfjprog --program $HEX_FILE --sectorerase --verify -f $TARGET --coprocessor CP_APPLICATION 84 | nrfjprog --pinreset -f NRF53 85 | fi 86 | 87 | # Check if the last command was successful 88 | if [ $? -eq 0 ]; then 89 | echo "Successfully flashed $HEX_FILE to $TARGET using $TOOL" 90 | else 91 | echo "Failed to flash $HEX_FILE to $TARGET using $TOOL." 92 | exit 1 93 | fi 94 | -------------------------------------------------------------------------------- /util/run_twister_integration.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Resolve the path to the current script and set CI_PATH to its directory 4 | CI_PATH=$(dirname "$(realpath "$0")") 5 | 6 | run_twister() { 7 | local test_directory=$1 8 | echo -n "Building configurations in \"$test_directory\": " 9 | 10 | # Run west twister with the specified arguments 11 | pushd "$CI_PATH" > /dev/null 12 | # Store in File 13 | west twister -T "../$test_directory" --integration > twister_out.txt 2> twister_err.txt 14 | #west twister -T "../$test_directory" --integration 15 | local status=$? 16 | popd > /dev/null 17 | 18 | # Check the exit status and print the relevant message 19 | if [ $status -eq 0 ]; then 20 | echo "[OK]" 21 | else 22 | echo "[FAIL]" 23 | cat $CI_PATH/twister_err.txt 24 | # Exit on first failure 25 | exit 1 26 | fi 27 | } 28 | 29 | # Run twister for the specified test directories 30 | run_twister "test" 31 | run_twister "app" 32 | run_twister "samples" 33 | -------------------------------------------------------------------------------- /util/stm32f4.resc: -------------------------------------------------------------------------------- 1 | :name: STM32F4 Discovery 2 | :description: This script runs a binary on STM32F4 Discovery. 3 | 4 | 5 | using sysbus 6 | $name?="STM32F4_Discovery" 7 | mach create $name 8 | machine LoadPlatformDescription @platforms/boards/stm32f4_discovery-kit.repl 9 | 10 | cpu PerformanceInMips 125 11 | 12 | $bin?=@build/zephyr/zephyr.elf 13 | 14 | logLevel 3 15 | 16 | showAnalyzer sysbus.usart2 17 | sysbus LoadELF $bin 18 | start 19 | 20 | uart_connect sysbus.usart2 21 | -------------------------------------------------------------------------------- /west.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | manifest: 5 | remotes: 6 | - name: zephyrproject-rtos 7 | url-base: https://github.com/zephyrproject-rtos 8 | 9 | projects: 10 | - name: zephyr 11 | remote: zephyrproject-rtos 12 | revision: main 13 | import: 14 | # By using name-allowlist we can clone only the modules that are 15 | # strictly needed by the application. 16 | name-allowlist: 17 | #- lvgl # Uncomment to include LittlevGL for the git bisect demo 18 | - cmsis # required by the ARM port 19 | - mbedtls 20 | - hal_nordic 21 | - hal_stm32 22 | - hal_nxp 23 | - hal_ti 24 | - hal_atmel 25 | - tinycrypt 26 | --------------------------------------------------------------------------------