├── .github └── workflows │ └── test.yml ├── .gitignore ├── 01-renode-basics ├── README.md ├── nrf52_adafruit_feather-zephyr-shell_module.elf ├── nrf52_adafruit_feather.repl └── nrf52_adafruit_feather.resc ├── 02-automation ├── 01-run-renode.sh ├── 02-pyrenode.py ├── 03-testing.robot ├── 04-failing_test.robot ├── README.md └── cleanup_robot_results.sh ├── 03-twister ├── .gitignore ├── README.md └── example-application │ ├── .gitignore │ ├── CMakeLists.txt │ ├── Kconfig │ ├── LICENSE │ ├── README.md │ ├── boards │ ├── arm │ │ └── stm32f7 │ │ │ ├── Kconfig.board │ │ │ ├── Kconfig.defconfig │ │ │ ├── arduino_r3_connector.dtsi │ │ │ ├── board.cmake │ │ │ ├── stm32f7.dts │ │ │ ├── stm32f7.yaml │ │ │ ├── stm32f7_defconfig │ │ │ └── support │ │ │ ├── openocd.cfg │ │ │ ├── stm32f746g_disco.repl │ │ │ └── stm32f746g_disco.resc │ └── riscv │ │ └── unleashed │ │ ├── Kconfig.board │ │ ├── Kconfig.defconfig │ │ ├── board.cmake │ │ ├── support │ │ ├── hifive_unleashed.resc │ │ ├── openocd_hifive_unleashed.cfg │ │ └── sifive-fu540.repl │ │ ├── unleashed.dts │ │ ├── unleashed.yaml │ │ └── unleashed_defconfig │ ├── hello_world │ ├── CMakeLists.txt │ ├── README.rst │ ├── prj.conf │ ├── sample.yaml │ └── src │ │ └── main.c │ ├── shell_module │ ├── CMakeLists.txt │ ├── Kconfig │ ├── boards │ │ ├── intel_socfpga_agilex5_socdk.conf │ │ ├── intel_socfpga_agilex5_socdk.overlay │ │ ├── intel_socfpga_agilex_socdk.conf │ │ └── intel_socfpga_agilex_socdk.overlay │ ├── overlay-usb.conf │ ├── prj.conf │ ├── prj_getopt.conf │ ├── prj_login.conf │ ├── prj_minimal.conf │ ├── prj_minimal_rtt.conf │ ├── sample.yaml │ ├── shell_module.robot │ ├── src │ │ ├── dynamic_cmd.c │ │ ├── main.c │ │ ├── test_module.c │ │ └── uart_reinit.c │ └── usb.overlay │ ├── west.yml │ └── zephyr │ └── module.yml ├── LICENSE └── README.md /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test Zephyr Tech Talk repo 2 | on: 3 | push: 4 | jobs: 5 | 6 | markdown-link-check: 7 | runs-on: ubuntu-latest 8 | steps: 9 | - uses: actions/checkout@master 10 | - uses: gaurav-nelson/github-action-markdown-link-check@v1 11 | 12 | test: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: actions/checkout@master 16 | - uses: actions/setup-python@v4 17 | with: 18 | python-version: '3.11' 19 | - name: Run tests 20 | uses: antmicro/renode-test-action@v3.1.0 21 | with: 22 | renode-version: 'latest' 23 | tests-to-run: '02-automation/03-testing.robot' 24 | - name: Upload artifacts 25 | if: always() 26 | uses: actions/upload-artifact@v3 27 | with: 28 | name: test-results 29 | path: | 30 | robot_output.xml 31 | log.html 32 | report.html 33 | snapshots/ 34 | logs/ 35 | 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Robot test files 2 | report.html 3 | log.html 4 | robot_output.xml 5 | results-*.xml 6 | logs/ 7 | snapshots/ 8 | -------------------------------------------------------------------------------- /01-renode-basics/README.md: -------------------------------------------------------------------------------- 1 | # 01-renode-basics 2 | 3 | To start the sample, just run ``renode nrf52_adafruit_feather.resc``. 4 | -------------------------------------------------------------------------------- /01-renode-basics/nrf52_adafruit_feather-zephyr-shell_module.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antmicro/renode-zephyr-tech-talk/308578711d9ef0efa5d24b7345249b8e412b00d6/01-renode-basics/nrf52_adafruit_feather-zephyr-shell_module.elf -------------------------------------------------------------------------------- /01-renode-basics/nrf52_adafruit_feather.repl: -------------------------------------------------------------------------------- 1 | cpu0: CPU.CortexM @ sysbus 2 | cpuType: "cortex-m4f" 3 | nvic: nvic 4 | 5 | nvic: IRQControllers.NVIC @ sysbus 0xe000e000 6 | -> cpu0@0 7 | 8 | gpio0: GPIOPort.NRF52840_GPIO @ sysbus 0x50000000 9 | 17 -> led0@0 10 | 19 -> led1@0 11 | 12 | sram0: Memory.MappedMemory @ sysbus 0x20000000 13 | size: 0x10000 14 | 15 | clock: Miscellaneous.NRF52840_CLOCK @ sysbus 0x40000000 16 | ->nvic@0 17 | 18 | ecb: Miscellaneous.NRF52840_ECB @ sysbus 0x4000e000 19 | ->nvic@14 20 | 21 | rng: Miscellaneous.NRF52840_RNG @ sysbus 0x4000d000 22 | ->nvic@13 23 | 24 | rtc0: Timers.NRF52840_RTC @ sysbus 0x4000b000 25 | numberOfEvents: 3 26 | ->nvic@11 27 | 28 | rtc1: Timers.NRF52840_RTC @ sysbus 0x40011000 29 | numberOfEvents: 4 30 | ->nvic@17 31 | 32 | rtc2: Timers.NRF52840_RTC @ sysbus 0x40024000 33 | numberOfEvents: 4 34 | ->nvic@36 35 | 36 | uart0: UART.NRF52840_UART @ sysbus 0x40002000 37 | ->nvic@2 38 | 39 | flash0: Memory.MappedMemory @ sysbus 0x0 40 | size: 0x80000 41 | 42 | dwt: Miscellaneous.DWT @ sysbus 0xE0001000 43 | frequency: 72000000 44 | 45 | led0: Miscellaneous.LED @ gpio0 0x11 46 | led1: Miscellaneous.LED @ gpio0 0x13 47 | -------------------------------------------------------------------------------- /01-renode-basics/nrf52_adafruit_feather.resc: -------------------------------------------------------------------------------- 1 | using sysbus 2 | $name?="nrf52_adafruit_feather" 3 | mach create $name 4 | 5 | machine LoadPlatformDescription $ORIGIN/nrf52_adafruit_feather.repl 6 | 7 | showAnalyzer uart0 8 | 9 | macro reset 10 | """ 11 | sysbus LoadELF $ORIGIN/nrf52_adafruit_feather-zephyr-shell_module.elf 12 | cpu0 VectorTableOffset `sysbus GetSymbolAddress "_vector_table"` 13 | """ 14 | 15 | runMacro $reset 16 | -------------------------------------------------------------------------------- /02-automation/01-run-renode.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | echo "Running Renode on :5555. Connect using 'telnet localhost 5555'" 4 | if command -v renode &> /dev/null 5 | then 6 | renode --disable-xwt -P 5555 7 | elif command -v renode-run &> /dev/null 8 | then 9 | renode-run -- --disable-xwt -P 5555 10 | else 11 | echo "Renode not found!" 12 | fi 13 | 14 | -------------------------------------------------------------------------------- /02-automation/02-pyrenode.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | from pyrenode import connect_renode, get_keywords, shutdown_renode 4 | 5 | uart = 'sysbus.usart1' 6 | 7 | connect_renode() 8 | get_keywords() 9 | 10 | ExecuteCommand('i @scripts/single-node/sam_e70.resc') 11 | CreateTerminalTester(uart) 12 | ExecuteCommand(f"showAnalyzer {uart}") 13 | 14 | StartEmulation() 15 | WaitForPromptOnUart("uart:~") 16 | WriteLineToUart("version") 17 | WaitForLineOnUart("Zephyr* version 1.14.0-rc1", timeout=60, treatAsRegex=True) 18 | 19 | print(ExecuteCommand('echo "Test passed!"')) 20 | 21 | shutdown_renode() 22 | -------------------------------------------------------------------------------- /02-automation/03-testing.robot: -------------------------------------------------------------------------------- 1 | *** Variables *** 2 | ${SCRIPT} scripts/single-node/leon3_zephyr.resc 3 | ${UART} sysbus.uart 4 | ${PROMPT} uart:~$ 5 | 6 | *** Keywords *** 7 | Prepare Machine 8 | Execute Command $bin=@https://dl.antmicro.com/projects/renode/generic_leon3-zephyr-shell_module.elf-s_973840-d4749b06d75be94be2b516ff84952566bec260a2 9 | Execute Script ${SCRIPT} 10 | 11 | Create Terminal Tester ${UART} timeout=1 12 | 13 | *** Test Cases *** 14 | Should Boot Zephyr 15 | [Documentation] Boots Zephyr on the Leon3 platform. 16 | [Tags] zephyr uart 17 | Prepare Machine 18 | 19 | Start Emulation 20 | 21 | Wait For Prompt On Uart ${PROMPT} 22 | 23 | Provides booted-zephyr 24 | 25 | Should Print Version 26 | [Documentation] Tests shell responsiveness in Zephyr on the Leon3 platform. 27 | [Tags] zephyr uart 28 | Requires booted-zephyr 29 | 30 | Write Line To Uart version 31 | Wait For Line On Uart Zephyr version 3.4.99 32 | -------------------------------------------------------------------------------- /02-automation/04-failing_test.robot: -------------------------------------------------------------------------------- 1 | *** Variables *** 2 | ${SCRIPT} scripts/single-node/leon3_zephyr.resc 3 | ${UART} sysbus.uart 4 | ${PROMPT} uart:~$ 5 | 6 | *** Keywords *** 7 | Prepare Machine 8 | Execute Script ${SCRIPT} 9 | 10 | Create Terminal Tester ${UART} timeout=1 11 | 12 | *** Test Cases *** 13 | Should Boot Zephyr 14 | [Documentation] Boots Zephyr on the Leon3 platform. 15 | [Tags] zephyr uart 16 | Prepare Machine 17 | 18 | Start Emulation 19 | 20 | Wait For Prompt On Uart ${PROMPT} 21 | 22 | Provides booted-zephyr 23 | 24 | Should Print Version 25 | [Documentation] Tests shell responsiveness in Zephyr on the Leon3 platform. 26 | [Tags] zephyr uart 27 | Requires booted-zephyr 28 | 29 | Write Line To Uart version 30 | # the next assertion is intended to fail 31 | Wait For Line On Uart Zephyr version 7.6.99 32 | -------------------------------------------------------------------------------- /02-automation/README.md: -------------------------------------------------------------------------------- 1 | # 02-automation 2 | 3 | ## Renode in headless mode 4 | 5 | Headless mode can be easily automated with ``expect`` and similar tools. 6 | 7 | Run: 8 | 9 | ``` 10 | renode --disable-xwt -P 5555 11 | ``` 12 | 13 | Then connect via Telnet: 14 | 15 | ``` 16 | telnet localhost 5555 17 | ``` 18 | 19 | And start a demo: 20 | 21 | ``` 22 | (monitor) start @scripts/single-node/hifive_unmatched.resc 23 | ``` 24 | 25 | Connect to UART: 26 | 27 | ``` 28 | (hifive-unmatched) uart_connect sysbus.uart0 29 | ``` 30 | 31 | Get back to the Monitor with ``ESC`` key. 32 | 33 | 34 | ## Python API 35 | 36 | Install the ``pyrenode`` tool: 37 | 38 | ``` 39 | pip install --user git+https://github.com/antmicro/pyrenode.git 40 | ``` 41 | 42 | Run ``./02-pyrenode.py`` to see Renode connected via the Python API. 43 | 44 | ## Robot testing 45 | 46 | The repo contains two Robot files testing Zephyr on Leon3. 47 | 48 | Run them with: 49 | 50 | ``` 51 | renode-test 03-testing.robot 52 | renode-test 04-failing_test.robot 53 | ``` 54 | 55 | See the results in ``report.html``. 56 | 57 | To investigate the cause of the test failure, start ``renode`` and run: 58 | 59 | ``` 60 | Load @snapshots/04-failing_test.Should_Print_Version.fail.save 61 | mach set 0 62 | peripherals 63 | showAnalyzer sysbus.uart 64 | start 65 | ``` 66 | 67 | You can easily clean up the working directory by running ``./cleanup_robot_results.sh``. 68 | -------------------------------------------------------------------------------- /02-automation/cleanup_robot_results.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | rm -rf logs/ snapshots/ results*xml report.html log.html robot_output.xml 3 | -------------------------------------------------------------------------------- /03-twister/.gitignore: -------------------------------------------------------------------------------- 1 | zephyr 2 | modules 3 | .west 4 | -------------------------------------------------------------------------------- /03-twister/README.md: -------------------------------------------------------------------------------- 1 | # 03-twister 2 | 3 | The ``example-application`` directory contains a custom board called ``unleashed`` (a renamed version of Zephyr's ``hifive_unleashed`` target) and two samples, ``hello_world`` and ``shell_module``, copied there for convenience. 4 | 5 | ## Running tests 6 | 7 | To build the sample, initialize Zephyr with: 8 | 9 | ``` 10 | west init -l example_application 11 | ``` 12 | 13 | Then enter the ``example_application`` directory and run tests: 14 | 15 | ``` 16 | west twister --platform unleashed -T hello_world 17 | ``` 18 | 19 | or, for a more detailed output: 20 | 21 | ``` 22 | west twister -vv --platform unleashed -T hello_world 23 | ``` 24 | 25 | The Robot-based test can be run with: 26 | 27 | ``` 28 | west twister --platform stm32f7 -T shell_module 29 | ``` 30 | 31 | To see more details on the test results, open ``twister-out/stm32f7/sample.shell.shell_module.robot/report.html`` in your browser. 32 | 33 | ## Enabling Renode support in boards 34 | 35 | To enable Renode support for the ``unleashed`` target, the entries below have been added. 36 | 37 | In ``unleashed.yaml``: 38 | 39 | ``` 40 | simulation: renode 41 | simulation_exec: renode 42 | ``` 43 | 44 | In ``board.cmake``: 45 | 46 | ``` 47 | set(SUPPORTED_EMU_PLATFORMS renode) 48 | set(RENODE_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/support/hifive_unleashed.resc) 49 | set(RENODE_UART sysbus.uart0) 50 | ``` 51 | 52 | Also, the ``support/hifive_unleashed.resc`` file was added to describe the Renode configuration for this board. 53 | 54 | An analogous process for the ``stm32f7`` target was also performed, with only minor differences. 55 | 56 | ## Enabling Robot test in samples 57 | 58 | The ``shell_module`` sample has a Robot test enabled. 59 | 60 | This required a change to the sample's ``sample.yaml`` file: 61 | 62 | ``` 63 | sample.shell.shell_module.robot: 64 | harness: robot 65 | harness_config: 66 | robot_test_path: shell_module.robot 67 | ``` 68 | 69 | The ``shell_module.robot`` file needs to include the following section: 70 | 71 | ``` 72 | *** Settings *** 73 | Resource ${KEYWORDS} 74 | ``` 75 | 76 | With the resource defined as above, you can use the ``Prepare Machine`` keyword to set up the platform based on your Twister target and load the appropriate ELF file. 77 | 78 | ## Regenerating platform description 79 | 80 | The platform description file for ``stm32f7``, ``boards/arm/stm32f7/support/stm32f746g_disco.repl``, was generated using the ``dts2repl`` tool. 81 | 82 | To rebuild the platform from a DTS file, run the following: 83 | 84 | ``` 85 | west build -p -b stm32f7 hello_world 86 | dts2repl build/zephyr/zephyr.dts --output boards/arm/stm32f7/support/stm32f746g_disco.repl 87 | ``` 88 | -------------------------------------------------------------------------------- /03-twister/example-application/.gitignore: -------------------------------------------------------------------------------- 1 | # editors 2 | .vscode 3 | *.swp 4 | *~ 5 | 6 | # python 7 | .venv 8 | 9 | # build 10 | /build* 11 | /twister-out* 12 | 13 | __pycache__/ 14 | 15 | 16 | profile 17 | -------------------------------------------------------------------------------- /03-twister/example-application/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # This CMake file is picked by the Zephyr build system because it is defined 5 | # as the module CMake entry point (see zephyr/module.yml). 6 | 7 | -------------------------------------------------------------------------------- /03-twister/example-application/Kconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | # 4 | # This Kconfig file is picked by the Zephyr build system because it is defined 5 | # as the module Kconfig entry point (see zephyr/module.yml). You can browse 6 | # module options by going to Zephyr -> Modules in Kconfig. 7 | 8 | -------------------------------------------------------------------------------- /03-twister/example-application/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 | -------------------------------------------------------------------------------- /03-twister/example-application/README.md: -------------------------------------------------------------------------------- 1 | # Zephyr Example Application 2 | 3 | This project is based on https://github.com/zephyrproject-rtos/example-application. 4 | 5 | It contains two custom boards called ``unleashed`` (a renamed version of Zephyr's ``hifive_unleashed`` target) and ``stm32f7`` (based on Zephyr's ``stm32f746g_disco``) and two samples, ``hello_world`` and ``shell_module``, copied here for convenience. 6 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/arm/stm32f7/Kconfig.board: -------------------------------------------------------------------------------- 1 | # STM32F746G Discovery board configuration 2 | 3 | # Copyright (c) 2018 Yurii Hamann 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | config BOARD_STM32F7 7 | bool "STM32F746G Discovery Development Board" 8 | depends on SOC_STM32F746XX 9 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/arm/stm32f7/Kconfig.defconfig: -------------------------------------------------------------------------------- 1 | # STM32F746G DISCOVERY board configuration 2 | 3 | # Copyright (c) 2018 Yurii Hamann 4 | # SPDX-License-Identifier: Apache-2.0 5 | 6 | if BOARD_STM32F7 7 | 8 | config BOARD 9 | default "stm32f7" 10 | 11 | if NETWORKING 12 | 13 | config NET_L2_ETHERNET 14 | default y 15 | 16 | endif # NETWORKING 17 | 18 | config INPUT 19 | default y if LVGL 20 | 21 | if DISPLAY 22 | 23 | # MEMC needs to be enabled in order to store 24 | # display buffer to external SDRAM connected to FMC 25 | config MEMC 26 | default y 27 | 28 | endif # DISPLAY 29 | 30 | if INPUT 31 | 32 | config INPUT_FT5336_INTERRUPT 33 | default y 34 | 35 | endif # INPUT 36 | 37 | config DISK_DRIVER_SDMMC 38 | default y if DISK_DRIVERS 39 | 40 | endif # BOARD_STM32F746G_DISCO 41 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/arm/stm32f7/arduino_r3_connector.dtsi: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 Marco Peter 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | / { 8 | arduino_header: connector { 9 | compatible = "arduino-header-r3"; 10 | #gpio-cells = <2>; 11 | gpio-map-mask = <0xffffffff 0xffffffc0>; 12 | gpio-map-pass-thru = <0 0x3f>; 13 | gpio-map = <0 0 &gpioa 0 0>, /* A0 */ 14 | <1 0 &gpiof 10 0>, /* A1 */ 15 | <2 0 &gpiof 9 0>, /* A2 */ 16 | <3 0 &gpiof 8 0>, /* A3 */ 17 | <4 0 &gpiof 7 0>, /* A4 */ 18 | <5 0 &gpiof 6 0>, /* A5 */ 19 | <6 0 &gpioc 7 0>, /* D0 */ 20 | <7 0 &gpioc 6 0>, /* D1 */ 21 | <8 0 &gpiog 6 0>, /* D2 */ 22 | <9 0 &gpiob 4 0>, /* D3 */ 23 | <10 0 &gpiog 7 0>, /* D4 */ 24 | <11 0 &gpioi 0 0>, /* D5 */ 25 | <12 0 &gpioh 6 0>, /* D6 */ 26 | <13 0 &gpioi 3 0>, /* D7 */ 27 | <14 0 &gpioi 2 0>, /* D8 */ 28 | <15 0 &gpioa 15 0>, /* D9 */ 29 | <16 0 &gpioa 8 0>, /* D10 */ 30 | <17 0 &gpiob 15 0>, /* D11 */ 31 | <18 0 &gpiob 14 0>, /* D12 */ 32 | <19 0 &gpioi 1 0>, /* D13 */ 33 | <20 0 &gpiob 9 0>, /* D14 */ 34 | <21 0 &gpiob 8 0>; /* D15 */ 35 | }; 36 | }; 37 | 38 | arduino_i2c: &i2c1 {}; 39 | arduino_spi: &spi2 {}; 40 | arduino_serial: &usart6 {}; 41 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/arm/stm32f7/board.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | set(SUPPORTED_EMU_PLATFORMS renode) 4 | set(RENODE_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/support/stm32f746g_disco.resc) 5 | set(RENODE_UART sysbus.usart1) 6 | 7 | board_runner_args(jlink "--device=STM32F746NG" "--speed=4000") 8 | 9 | include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) 10 | include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) 11 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/arm/stm32f7/stm32f7.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2018 Yurii Hamann 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /dts-v1/; 8 | #include 9 | #include 10 | #include "arduino_r3_connector.dtsi" 11 | #include 12 | #include 13 | #include 14 | 15 | / { 16 | model = "STMicroelectronics STM32F746G DISCOVERY board"; 17 | compatible = "st,stm32f746g-disco"; 18 | 19 | chosen { 20 | zephyr,console = &usart1; 21 | zephyr,shell-uart = &usart1; 22 | zephyr,sram = &sram0; 23 | zephyr,flash = &flash0; 24 | zephyr,dtcm = &dtcm; 25 | zephyr,flash-controller = &n25q128a1; 26 | zephyr,display = <dc; 27 | }; 28 | 29 | leds { 30 | compatible = "gpio-leds"; 31 | green_led_1: led_1 { 32 | gpios = <&gpioi 1 GPIO_ACTIVE_HIGH>; 33 | label = "User LD1"; 34 | }; 35 | }; 36 | 37 | gpio_keys { 38 | compatible = "gpio-keys"; 39 | user_button: button { 40 | label = "User"; 41 | gpios = <&gpioi 11 GPIO_ACTIVE_HIGH>; 42 | zephyr,code = ; 43 | }; 44 | }; 45 | 46 | lvgl_pointer { 47 | compatible = "zephyr,lvgl-pointer-input"; 48 | input = <&ft5336>; 49 | }; 50 | 51 | sdram1: sdram@c0000000 { 52 | compatible = "zephyr,memory-region", "mmio-sram"; 53 | device_type = "memory"; 54 | reg = <0xc0000000 DT_SIZE_M(16)>; 55 | zephyr,memory-region = "SDRAM1"; 56 | zephyr,memory-attr = <( DT_MEM_ARM(ATTR_MPU_RAM) )>; 57 | }; 58 | 59 | aliases { 60 | led0 = &green_led_1; 61 | sw0 = &user_button; 62 | spi-flash0 = &n25q128a1; 63 | }; 64 | }; 65 | 66 | &clk_lsi { 67 | status = "okay"; 68 | }; 69 | 70 | &clk_hse { 71 | clock-frequency = ; 72 | status = "okay"; 73 | }; 74 | 75 | &pll { 76 | div-m = <25>; 77 | mul-n = <432>; 78 | div-p = <2>; 79 | div-q = <9>; 80 | clocks = <&clk_hse>; 81 | status = "okay"; 82 | }; 83 | 84 | &rcc { 85 | clocks = <&pll>; 86 | clock-frequency = ; 87 | ahb-prescaler = <1>; 88 | apb1-prescaler = <4>; 89 | apb2-prescaler = <2>; 90 | }; 91 | 92 | &i2c1 { 93 | pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>; 94 | pinctrl-names = "default"; 95 | status = "okay"; 96 | clock-frequency = ; 97 | }; 98 | 99 | &i2c3 { 100 | pinctrl-0 = <&i2c3_scl_ph7 &i2c3_sda_ph8>; 101 | pinctrl-names = "default"; 102 | status = "okay"; 103 | clock-frequency = ; 104 | 105 | ft5336: ft5336@38 { 106 | compatible = "focaltech,ft5336"; 107 | reg = <0x38>; 108 | int-gpios = <&gpioi 13 0>; 109 | }; 110 | }; 111 | 112 | &spi2 { 113 | pinctrl-0 = <&spi2_sck_pi1 &spi2_miso_pb14 &spi2_mosi_pb15>; 114 | pinctrl-names = "default"; 115 | cs-gpios = <&gpioa 8 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; 116 | status = "okay"; 117 | }; 118 | 119 | &usart1 { 120 | pinctrl-0 = <&usart1_tx_pa9 &usart1_rx_pb7>; 121 | pinctrl-names = "default"; 122 | current-speed = <115200>; 123 | status = "okay"; 124 | }; 125 | 126 | &usart6 { 127 | pinctrl-0 = <&usart6_tx_pc6 &usart6_rx_pc7>; 128 | pinctrl-names = "default"; 129 | current-speed = <115200>; 130 | status = "okay"; 131 | }; 132 | 133 | zephyr_udc0: &usbotg_fs { 134 | pinctrl-0 = <&usb_otg_fs_dm_pa11 &usb_otg_fs_dp_pa12>; 135 | pinctrl-names = "default"; 136 | status = "okay"; 137 | }; 138 | 139 | &timers3 { 140 | st,prescaler = <10000>; 141 | status = "okay"; 142 | 143 | pwm3: pwm { 144 | status = "okay"; 145 | pinctrl-0 = <&tim3_ch1_pb4>; 146 | pinctrl-names = "default"; 147 | }; 148 | }; 149 | 150 | &rtc { 151 | clocks = <&rcc STM32_CLOCK_BUS_APB1 0x10000000>, 152 | <&rcc STM32_SRC_LSI RTC_SEL(2)>; 153 | status = "okay"; 154 | 155 | backup_regs { 156 | status = "okay"; 157 | }; 158 | }; 159 | 160 | &sdmmc1 { 161 | status = "okay"; 162 | pinctrl-0 = <&sdmmc1_d0_pc8 &sdmmc1_d1_pc9 163 | &sdmmc1_d2_pc10 &sdmmc1_d3_pc11 164 | &sdmmc1_ck_pc12 &sdmmc1_cmd_pd2>; 165 | pinctrl-names = "default"; 166 | cd-gpios = <&gpioc 13 GPIO_ACTIVE_LOW>; 167 | }; 168 | 169 | &mac { 170 | status = "okay"; 171 | pinctrl-0 = <ð_mdc_pc1 172 | ð_rxd0_pc4 173 | ð_rxd1_pc5 174 | ð_ref_clk_pa1 175 | ð_mdio_pa2 176 | ð_crs_dv_pa7 177 | ð_tx_en_pg11 178 | ð_txd0_pg13 179 | ð_txd1_pg14>; 180 | pinctrl-names = "default"; 181 | }; 182 | 183 | &quadspi { 184 | pinctrl-0 = <&quadspi_clk_pb2 &quadspi_bk1_ncs_pb6 185 | &quadspi_bk1_io0_pd11 &quadspi_bk1_io1_pd12 186 | &quadspi_bk1_io2_pe2 &quadspi_bk1_io3_pd13>; 187 | pinctrl-names = "default"; 188 | status = "okay"; 189 | 190 | n25q128a1: qspi-nor-flash@0 { 191 | compatible = "st,stm32-qspi-nor"; 192 | reg = <0>; 193 | qspi-max-frequency = <72000000>; 194 | size = ; 195 | status = "okay"; 196 | 197 | partitions { 198 | compatible = "fixed-partitions"; 199 | #address-cells = <1>; 200 | #size-cells = <1>; 201 | 202 | slot1_partition: partition@0 { 203 | label = "image-1"; 204 | reg = <0x00000000 DT_SIZE_K(640)>; 205 | }; 206 | 207 | storage_partition: partition@a0000 { 208 | label = "storage"; 209 | reg = <0x000a0000 DT_SIZE_M(15)>; 210 | }; 211 | }; 212 | }; 213 | }; 214 | 215 | &fmc { 216 | pinctrl-0 = <&fmc_nbl0_pe0 &fmc_nbl1_pe1 217 | &fmc_sdclk_pg8 &fmc_sdnwe_ph5 &fmc_sdcke0_pc3 218 | &fmc_sdne0_ph3 &fmc_sdnras_pf11 &fmc_sdncas_pg15 219 | &fmc_a0_pf0 &fmc_a1_pf1 &fmc_a2_pf2 &fmc_a3_pf3 &fmc_a4_pf4 220 | &fmc_a5_pf5 &fmc_a6_pf12 &fmc_a7_pf13 &fmc_a8_pf14 221 | &fmc_a9_pf15 &fmc_a10_pg0 &fmc_a11_pg1 222 | &fmc_a14_pg4 &fmc_a15_pg5 &fmc_d0_pd14 &fmc_d1_pd15 223 | &fmc_d2_pd0 &fmc_d3_pd1 &fmc_d4_pe7 &fmc_d5_pe8 &fmc_d6_pe9 224 | &fmc_d7_pe10 &fmc_d8_pe11 &fmc_d9_pe12 &fmc_d10_pe13 225 | &fmc_d11_pe14 &fmc_d12_pe15 &fmc_d13_pd8 &fmc_d14_pd9 226 | &fmc_d15_pd10>; 227 | pinctrl-names = "default"; 228 | status = "okay"; 229 | 230 | sdram { 231 | status = "okay"; 232 | power-up-delay = <100>; 233 | num-auto-refresh = <8>; 234 | mode-register = <0x220>; 235 | /* 236 | * Auto refresh command shall be issued every 15.625 us 237 | * and is calculated as ((15.625 * SDRAM_CLK_MHZ) - 20) 238 | * Note: SDRAM_CLK_MHZ = HCLK_MHZ / 2 (108 MHz) 239 | */ 240 | refresh-rate = <1667>; 241 | bank@0 { 242 | reg = <0>; 243 | st,sdram-control = ; 251 | st,sdram-timing = <2 6 4 6 2 2 2>; 252 | }; 253 | }; 254 | }; 255 | 256 | <dc { 257 | pinctrl-0 = <<dc_r0_pi15 <dc_r1_pj0 <dc_r2_pj1 <dc_r3_pj2 258 | <dc_r4_pj3 <dc_r5_pj4 <dc_r6_pj5 <dc_r7_pj6 259 | <dc_g0_pj7 <dc_g1_pj8 <dc_g2_pj9 <dc_g3_pj10 260 | <dc_g4_pj11 <dc_g5_pk0 <dc_g6_pk1 <dc_g7_pk2 261 | <dc_b0_pe4 <dc_b1_pj13 <dc_b2_pj14 <dc_b3_pj15 262 | <dc_b4_pg12 <dc_b5_pk4 <dc_b6_pk5 <dc_b7_pk6 263 | <dc_de_pk7 <dc_clk_pi14 <dc_hsync_pi10 <dc_vsync_pi9>; 264 | pinctrl-names = "default"; 265 | disp-on-gpios = <&gpioi 12 GPIO_ACTIVE_HIGH>; 266 | bl-ctrl-gpios = <&gpiok 3 GPIO_ACTIVE_HIGH>; 267 | ext-sdram = <&sdram1>; 268 | status = "okay"; 269 | 270 | width = <480>; 271 | height = <272>; 272 | pixel-format = ; 273 | display-timings { 274 | compatible = "zephyr,panel-timing"; 275 | de-active = <0>; 276 | pixelclk-active = <0>; 277 | hsync-active = <0>; 278 | vsync-active = <0>; 279 | hsync-len = <1>; 280 | vsync-len = <10>; 281 | hback-porch = <43>; 282 | vback-porch = <12>; 283 | hfront-porch = <8>; 284 | vfront-porch = <4>; 285 | }; 286 | def-back-color-red = <0xFF>; 287 | def-back-color-green = <0xFF>; 288 | def-back-color-blue = <0xFF>; 289 | }; 290 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/arm/stm32f7/stm32f7.yaml: -------------------------------------------------------------------------------- 1 | identifier: stm32f7 2 | name: ST STM32F746G Discovery 3 | type: mcu 4 | arch: arm 5 | simulation: renode 6 | simulation_exec: renode 7 | toolchain: 8 | - zephyr 9 | - gnuarmemb 10 | - xtools 11 | ram: 256 12 | flash: 1024 13 | vendor: st 14 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/arm/stm32f7/stm32f7_defconfig: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | CONFIG_SOC_SERIES_STM32F7X=y 4 | CONFIG_SOC_STM32F746XX=y 5 | 6 | # Enable MPU 7 | CONFIG_ARM_MPU=y 8 | 9 | # Enable HW stack protection 10 | CONFIG_HW_STACK_PROTECTION=y 11 | 12 | CONFIG_SERIAL=y 13 | 14 | # console 15 | CONFIG_CONSOLE=y 16 | CONFIG_UART_CONSOLE=y 17 | 18 | # enable GPIO 19 | CONFIG_GPIO=y 20 | 21 | # Enable Clocks 22 | CONFIG_CLOCK_CONTROL=y 23 | 24 | # enable pin controller 25 | CONFIG_PINCTRL=y 26 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/arm/stm32f7/support/openocd.cfg: -------------------------------------------------------------------------------- 1 | source [find board/stm32f746g-disco.cfg] 2 | 3 | $_TARGETNAME configure -event gdb-attach { 4 | echo "Debugger attaching: halting execution" 5 | reset halt 6 | gdb_breakpoint_override hard 7 | } 8 | 9 | $_TARGETNAME configure -event gdb-detach { 10 | echo "Debugger detaching: resuming execution" 11 | resume 12 | } 13 | 14 | if { [info exists _ZEPHYR_BOARD_SERIAL] } { 15 | adapter serial $_ZEPHYR_BOARD_SERIAL 16 | } 17 | 18 | # Event reset-init already uses the maximum speed however adapter speed 19 | # inherited from stm32f7x.cfg for reset-start defaults to 2000 kHz, so 20 | # override that speed setting it also to the maximum speed. 21 | $_TARGETNAME configure -event reset-start { 22 | adapter speed 4000 23 | } 24 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/arm/stm32f7/support/stm32f746g_disco.repl: -------------------------------------------------------------------------------- 1 | // autogenerated 2 | 3 | gpioi: GPIOPort.STM32_GPIOPort @ sysbus <0x40022000, +0x400> 4 | 5 | greenled1: Miscellaneous.LED @ gpioi 0x1 6 | 7 | gpioi: 8 | 1 -> greenled1@0 9 | 10 | nvic: IRQControllers.NVIC @ sysbus 0xe000e000 11 | -> cpu0@0 12 | 13 | cpu0: CPU.CortexM @ sysbus 14 | cpuType: "cortex-m7" 15 | nvic: nvic 16 | 17 | sram0: Memory.MappedMemory @ sysbus 0x20010000 18 | size: 0x40000 19 | 20 | mac: Network.SynopsysEthernetMAC @ sysbus 0x40028000 21 | ->nvic@61 22 | 23 | gpioa: GPIOPort.STM32_GPIOPort @ sysbus <0x40020000, +0x400> 24 | 25 | gpiob: GPIOPort.STM32_GPIOPort @ sysbus <0x40020400, +0x400> 26 | 27 | gpioc: GPIOPort.STM32_GPIOPort @ sysbus <0x40020800, +0x400> 28 | 29 | gpiod: GPIOPort.STM32_GPIOPort @ sysbus <0x40020c00, +0x400> 30 | 31 | gpioe: GPIOPort.STM32_GPIOPort @ sysbus <0x40021000, +0x400> 32 | 33 | gpiof: GPIOPort.STM32_GPIOPort @ sysbus <0x40021400, +0x400> 34 | 35 | gpiog: GPIOPort.STM32_GPIOPort @ sysbus <0x40021800, +0x400> 36 | 37 | gpioh: GPIOPort.STM32_GPIOPort @ sysbus <0x40021c00, +0x400> 38 | 39 | gpioj: GPIOPort.STM32_GPIOPort @ sysbus <0x40022400, +0x400> 40 | 41 | gpiok: GPIOPort.STM32_GPIOPort @ sysbus <0x40022800, +0x400> 42 | 43 | i2c1: I2C.STM32F7_I2C @ sysbus 0x40005400 44 | EventInterrupt->nvic@31 45 | ErrorInterrupt->nvic@32 46 | 47 | i2c3: I2C.STM32F7_I2C @ sysbus 0x40005c00 48 | EventInterrupt->nvic@72 49 | ErrorInterrupt->nvic@73 50 | 51 | flash0: Memory.MappedMemory @ sysbus 0x8000000 52 | size: 0x100000 53 | 54 | rcc: Python.PythonPeripheral @ sysbus 0x40023800 55 | size: 0x400 56 | initable: true 57 | filename: "scripts/pydev/rolling-bit.py" 58 | 59 | rtc: Timers.STM32F4_RTC @ sysbus 0x40002800 60 | AlarmIRQ->nvic@41 61 | 62 | spi2: SPI.STM32SPI @ sysbus 0x40003800 63 | IRQ->nvic@36 64 | 65 | timers3: Timers.STM32_Timer @ sysbus <0x40000400, +0x400> 66 | frequency: 10000000 67 | initialLimit: 0xFFFFFFFF 68 | ->nvic@29 69 | 70 | usart1: UART.STM32F7_USART @ sysbus 0x40011000 71 | frequency: 200000000 72 | IRQ->nvic@37 73 | 74 | usart6: UART.STM32F7_USART @ sysbus 0x40011400 75 | frequency: 200000000 76 | IRQ->nvic@71 77 | 78 | quadspimemory: Memory.MappedMemory @ sysbus 0x90000000 79 | size: 0x10000000 80 | 81 | sdram1: Memory.MappedMemory @ sysbus 0xc0000000 82 | size: 0x1000000 83 | 84 | // cortex-m overlay 85 | 86 | dwt: Miscellaneous.DWT @ sysbus 0xE0001000 87 | frequency: 72000000 88 | 89 | // st,stm32f7 overlay 90 | 91 | pwrCsr1: Python.PythonPeripheral @ sysbus 0x40007004 92 | size: 0x4 93 | initable: true 94 | filename: "scripts/pydev/flipflop.py" 95 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/arm/stm32f7/support/stm32f746g_disco.resc: -------------------------------------------------------------------------------- 1 | :description: This script is prepared to run Zephyr on stm32f746g_disco 2 | :name: stm32f746g_disco 3 | 4 | $name?="stm32f746g_disco" 5 | 6 | using sysbus 7 | mach create $name 8 | 9 | machine LoadPlatformDescription $ORIGIN/stm32f746g_disco.repl 10 | 11 | showAnalyzer usart1 12 | 13 | macro reset 14 | """ 15 | sysbus LoadELF $bin 16 | """ 17 | runMacro $reset 18 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/riscv/unleashed/Kconfig.board: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Katsuhiro Suzuki 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | config BOARD_UNLEASHED 5 | bool "HiFive Unleashed target" 6 | depends on SOC_RISCV_SIFIVE_FU540 7 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/riscv/unleashed/Kconfig.defconfig: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Katsuhiro Suzuki 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | if BOARD_UNLEASHED 5 | 6 | config BOARD 7 | default "unleashed" 8 | 9 | config SYS_CLOCK_TICKS_PER_SEC 10 | default 1000 11 | 12 | config SYS_CLOCK_HW_CYCLES_PER_SEC 13 | default 1000000 14 | 15 | endif 16 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/riscv/unleashed/board.cmake: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | set(SUPPORTED_EMU_PLATFORMS renode) 4 | set(RENODE_SCRIPT ${CMAKE_CURRENT_LIST_DIR}/support/hifive_unleashed.resc) 5 | set(RENODE_UART sysbus.uart0) 6 | set(OPENOCD_USE_LOAD_IMAGE NO) 7 | 8 | board_runner_args(openocd "--config=${BOARD_DIR}/support/openocd_hifive_unleashed.cfg") 9 | 10 | include(${ZEPHYR_BASE}/boards/common/openocd.board.cmake) 11 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/riscv/unleashed/support/hifive_unleashed.resc: -------------------------------------------------------------------------------- 1 | :description: This script is prepared to run Zephyr on SiFive-FU540 board. 2 | :name: SiFive-FU540 3 | 4 | $name?="SiFive-FU540" 5 | 6 | using sysbus 7 | mach create $name 8 | 9 | machine LoadPlatformDescription $ORIGIN/sifive-fu540.repl 10 | 11 | showAnalyzer uart0 12 | 13 | macro reset 14 | """ 15 | sysbus LoadELF $bin 16 | """ 17 | runMacro $reset 18 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/riscv/unleashed/support/openocd_hifive_unleashed.cfg: -------------------------------------------------------------------------------- 1 | adapter speed 10000 2 | 3 | adapter driver ftdi 4 | ftdi_device_desc "Dual RS232-HS" 5 | ftdi_vid_pid 0x0403 0x6010 6 | 7 | ftdi_layout_init 0x0008 0x001b 8 | ftdi_layout_signal nSRST -oe 0x0020 -data 0x0020 9 | 10 | set _CHIPNAME riscv 11 | jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x20000913 12 | 13 | set _TARGETNAME $_CHIPNAME.cpu 14 | target create $_TARGETNAME.0 riscv -chain-position $_TARGETNAME -rtos hwthread 15 | target create $_TARGETNAME.1 riscv -chain-position $_TARGETNAME -coreid 1 16 | target create $_TARGETNAME.2 riscv -chain-position $_TARGETNAME -coreid 2 17 | target create $_TARGETNAME.3 riscv -chain-position $_TARGETNAME -coreid 3 18 | target create $_TARGETNAME.4 riscv -chain-position $_TARGETNAME -coreid 4 19 | target smp $_TARGETNAME.0 $_TARGETNAME.1 $_TARGETNAME.2 $_TARGETNAME.3 $_TARGETNAME.4 20 | $_TARGETNAME.0 configure -work-area-phys 0x80000000 -work-area-size 0x4000 -work-area-backup 1 21 | 22 | flash bank onboard_spi_flash0 fespi 0x20000000 0 0 0 $_TARGETNAME.0 0x10040000 23 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/riscv/unleashed/support/sifive-fu540.repl: -------------------------------------------------------------------------------- 1 | // autogenerated 2 | 3 | ram0: Memory.MappedMemory @ sysbus 0x80000000 4 | size: 0xf0000000 5 | 6 | clint: IRQControllers.CoreLevelInterruptor @ sysbus 0x2000000 7 | 0->cpu0@3 8 | 1->cpu0@7 9 | 10 | dtim: Memory.MappedMemory @ sysbus 0x1000000 11 | size: 0x2000 12 | 13 | gpio0: GPIOPort.SiFive_GPIO @ sysbus 0x10060000 14 | 0->plic@7 15 | 1->plic@8 16 | 2->plic@9 17 | 3->plic@10 18 | 4->plic@11 19 | 5->plic@12 20 | 6->plic@13 21 | 7->plic@14 22 | 8->plic@15 23 | 9->plic@16 24 | 10->plic@17 25 | 11->plic@18 26 | 12->plic@19 27 | 13->plic@20 28 | 14->plic@21 29 | 15->plic@22 30 | 31 | maskrom: Memory.MappedMemory @ sysbus 0x10000 32 | size: 0x8000 33 | 34 | plic: IRQControllers.PlatformLevelInterruptController @ sysbus 0xc000000 35 | numberOfSources: 52 36 | numberOfContexts: 9 37 | prioritiesEnabled: true 38 | 0->cpu0@11 39 | 40 | uart0: UART.SiFive_UART @ sysbus 0x10010000 41 | IRQ->plic@4 42 | 43 | // sifive,FU540-C000 overlay 44 | 45 | cpu0: CPU.RiscV64 @ sysbus 46 | cpuType: "rv64imac" 47 | hartId: 0 48 | privilegeArchitecture: PrivilegeArchitecture.Priv1_10 49 | timeProvider: clint 50 | 51 | u54_1: CPU.RiscV64 @ sysbus 52 | cpuType: "rv64gc" 53 | hartId: 1 54 | privilegeArchitecture: PrivilegeArchitecture.Priv1_10 55 | timeProvider: clint 56 | 57 | u54_2: CPU.RiscV64 @ sysbus 58 | cpuType: "rv64gc" 59 | hartId: 2 60 | privilegeArchitecture: PrivilegeArchitecture.Priv1_10 61 | timeProvider: clint 62 | 63 | u54_3: CPU.RiscV64 @ sysbus 64 | cpuType: "rv64gc" 65 | hartId: 3 66 | privilegeArchitecture: PrivilegeArchitecture.Priv1_10 67 | timeProvider: clint 68 | 69 | u54_4: CPU.RiscV64 @ sysbus 70 | cpuType: "rv64gc" 71 | hartId: 4 72 | privilegeArchitecture: PrivilegeArchitecture.Priv1_10 73 | timeProvider: clint 74 | 75 | clint: 76 | frequency: 1000000 77 | numberOfTargets: 5 78 | [2, 3] -> u54_1@[3, 7] 79 | [4, 5] -> u54_2@[3, 7] 80 | [6, 7] -> u54_3@[3, 7] 81 | [8, 9] -> u54_4@[3, 7] 82 | 83 | plic: 84 | [1,2] -> u54_1@[11,9] 85 | [3,4] -> u54_2@[11,9] 86 | [5,6] -> u54_3@[11,9] 87 | [7,8] -> u54_4@[11,9] 88 | prioritiesEnabled : false 89 | 90 | ff0: Python.PythonPeripheral @ sysbus 0x10000004 91 | size: 0x4 92 | initable: true 93 | filename: "scripts/pydev/flipflop.py" 94 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/riscv/unleashed/unleashed.dts: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2021 Katsuhiro Suzuki 3 | * 4 | * SPDX-License-Identifier: Apache-2.0 5 | */ 6 | 7 | /dts-v1/; 8 | 9 | #include 10 | 11 | / { 12 | chosen { 13 | zephyr,console = &uart0; 14 | zephyr,shell-uart = &uart0; 15 | zephyr,sram = &ram0; 16 | }; 17 | 18 | ram0: ram0@80000000 { 19 | compatible = "memory"; 20 | reg = <0x80000000 0xf0000000>; 21 | reg-names = "mem"; 22 | }; 23 | 24 | lscon_96b: connector { 25 | compatible = "linaro,96b-lscon-1v8"; 26 | #gpio-cells = <2>; 27 | gpio-map-mask = <0xffffffff 0xffffffc0>; 28 | gpio-map-pass-thru = <0 0x3f>; 29 | gpio-map = <22 0 &gpio0 0 0>, /* GPIO-A */ 30 | <23 0 &gpio0 1 0>, /* GPIO-B */ 31 | <24 0 &gpio0 2 0>, /* GPIO-C */ 32 | <25 0 &gpio0 3 0>, /* GPIO-D */ 33 | <26 0 &gpio0 4 0>, /* GPIO-E */ 34 | <27 0 &gpio0 5 0>, /* GPIO-F */ 35 | <38 0 &gpio0 6 0>, /* GPIO-G */ 36 | <39 0 &gpio0 7 0>, /* GPIO-H */ 37 | <30 0 &gpio0 8 0>, /* GPIO-I */ 38 | <31 0 &gpio0 9 0>, /* GPIO-J */ 39 | <32 0 &gpio0 15 0>; /* GPIO-K */ 40 | /* GPIO-L not connected */ 41 | }; 42 | }; 43 | 44 | &uart0 { 45 | status = "okay"; 46 | current-speed = <115200>; 47 | }; 48 | 49 | /* disabled (used by Flash ROM by default) */ 50 | &spi0 { 51 | reg = <0x10040000 0x1000 0x20000000 0x2000000>; 52 | flash0: flash@0 { 53 | compatible = "issi,is25wp256d", "jedec,spi-nor"; 54 | status = "disabled"; 55 | size = <33554432>; 56 | jedec-id = [96 60 18]; 57 | reg = <0>; 58 | spi-max-frequency = <133000000>; 59 | }; 60 | }; 61 | 62 | &spi1 { 63 | status = "okay"; 64 | }; 65 | 66 | &spi2 { 67 | status = "okay"; 68 | }; 69 | 70 | &gpio0 { 71 | status = "okay"; 72 | }; 73 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/riscv/unleashed/unleashed.yaml: -------------------------------------------------------------------------------- 1 | identifier: unleashed 2 | name: SiFive HiFive Unleashed 3 | type: mcu 4 | arch: riscv64 5 | toolchain: 6 | - zephyr 7 | ram: 3840 8 | simulation: renode 9 | simulation_exec: renode 10 | testing: 11 | ignore_tags: 12 | - net 13 | - bluetooth 14 | - flash 15 | - newlib 16 | - crypto 17 | supported: 18 | - gpio 19 | - spi 20 | vendor: sifive 21 | -------------------------------------------------------------------------------- /03-twister/example-application/boards/riscv/unleashed/unleashed_defconfig: -------------------------------------------------------------------------------- 1 | CONFIG_SOC_SERIES_RISCV_SIFIVE_FREEDOM=y 2 | CONFIG_SOC_RISCV_SIFIVE_FU540=y 3 | CONFIG_BOARD_UNLEASHED=y 4 | CONFIG_CONSOLE=y 5 | CONFIG_GPIO=y 6 | CONFIG_SERIAL=y 7 | CONFIG_UART_SIFIVE_PORT_0=y 8 | CONFIG_UART_CONSOLE=y 9 | CONFIG_XIP=n 10 | -------------------------------------------------------------------------------- /03-twister/example-application/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 | -------------------------------------------------------------------------------- /03-twister/example-application/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 | -------------------------------------------------------------------------------- /03-twister/example-application/hello_world/prj.conf: -------------------------------------------------------------------------------- 1 | # nothing here 2 | -------------------------------------------------------------------------------- /03-twister/example-application/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 | harness: console 10 | harness_config: 11 | type: one_line 12 | regex: 13 | - "Hello World! (.*)" 14 | tests: 15 | sample.basic.helloworld: 16 | tags: introduction 17 | -------------------------------------------------------------------------------- /03-twister/example-application/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); 12 | return 0; 13 | } 14 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/boards/intel_socfpga_agilex5_socdk.conf: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2022-2023, Intel Corporation. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # Misc 5 | CONFIG_HEAP_MEM_POOL_SIZE=16384 6 | CONFIG_SHELL_STACK_SIZE=8192 7 | 8 | # Setting the Shell prompt 9 | CONFIG_SHELL_PROMPT_UART="agilex5$ " 10 | 11 | # Setting the max argc 12 | CONFIG_SHELL_ARGC_MAX=12 13 | 14 | # Enable the Zephyr boot banner 15 | CONFIG_BOOT_BANNER=y 16 | 17 | # Enable timer driver 18 | CONFIG_COUNTER=y 19 | 20 | # Enable Timer shell commands 21 | CONFIG_COUNTER_SHELL=y 22 | 23 | #SiP SVC Service 24 | CONFIG_ARM_SIP_SVC_DRIVER=y 25 | CONFIG_ARM_SIP_SVC_SUBSYS=y 26 | CONFIG_ARM_SIP_SVC_SUBSYS_SINGLY_OPEN=y 27 | 28 | #SiP SVC Service Shell 29 | CONFIG_ARM_SIP_SVC_SUBSYS_SHELL=y 30 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/boards/intel_socfpga_agilex5_socdk.overlay: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Intel Corporation 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | /* 7 | * The overlay file should be used to enable any 8 | * dts nodes required by this shell application for this 9 | * board. 10 | * 11 | * Nothing here as of now. 12 | */ 13 | 14 | &timer0 { 15 | status = "okay"; 16 | }; 17 | 18 | &timer1 { 19 | status = "okay"; 20 | }; 21 | 22 | &timer2 { 23 | status = "okay"; 24 | }; 25 | 26 | &timer3 { 27 | status = "okay"; 28 | }; 29 | 30 | &sip_smc { 31 | status = "okay"; 32 | zephyr,num-clients = <2>; 33 | }; 34 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/boards/intel_socfpga_agilex_socdk.conf: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2023, Intel Corporation. 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | # Misc 5 | CONFIG_HEAP_MEM_POOL_SIZE=16384 6 | CONFIG_SHELL_STACK_SIZE=8192 7 | 8 | # Setting the Shell prompt 9 | CONFIG_SHELL_PROMPT_UART="agilex$ " 10 | 11 | # Setting the max argc 12 | CONFIG_SHELL_ARGC_MAX=12 13 | 14 | # Enable the Zephyr boot banner 15 | CONFIG_BOOT_BANNER=y 16 | 17 | #SiP SVC Service 18 | CONFIG_ARM_SIP_SVC_DRIVER=y 19 | CONFIG_ARM_SIP_SVC_SUBSYS=y 20 | CONFIG_ARM_SIP_SVC_SUBSYS_SINGLY_OPEN=y 21 | 22 | #SiP SVC Service Shell 23 | CONFIG_ARM_SIP_SVC_SUBSYS_SHELL=y 24 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/boards/intel_socfpga_agilex_socdk.overlay: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2023 Intel Corporation 3 | * SPDX-License-Identifier: Apache-2.0 4 | */ 5 | 6 | /* 7 | * The overlay file should be used to enable any 8 | * dts nodes required by this shell application for this 9 | * board. 10 | */ 11 | 12 | &sip_smc { 13 | status = "okay"; 14 | zephyr,num-clients = <2>; 15 | }; 16 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/prj.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_CLOCK=y 12 | CONFIG_DATE_SHELL=y 13 | CONFIG_THREAD_RUNTIME_STATS=y 14 | CONFIG_THREAD_RUNTIME_STATS_USE_TIMING_FUNCTIONS=y 15 | CONFIG_STATS=y 16 | CONFIG_STATS_SHELL=y 17 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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_CLOCK=y 12 | CONFIG_DATE_SHELL=y 13 | CONFIG_THREAD_RUNTIME_STATS=y 14 | 15 | CONFIG_SHELL_CMDS_SELECT=y 16 | CONFIG_SHELL_START_OBSCURED=y 17 | CONFIG_SHELL_PROMPT_UART="login: " 18 | CONFIG_SHELL_CMD_ROOT="login" 19 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/sample.yaml: -------------------------------------------------------------------------------- 1 | sample: 2 | name: Shell Sample 3 | tests: 4 | sample.shell.shell_module: 5 | filter: CONFIG_SERIAL and dt_chosen_enabled("zephyr,shell-uart") 6 | tags: shell 7 | harness: keyboard 8 | min_ram: 40 9 | integration_platforms: 10 | - native_posix 11 | - intel_socfpga_agilex5_socdk 12 | sample.shell.shell_module.minimal: 13 | filter: CONFIG_SERIAL and dt_chosen_enabled("zephyr,shell-uart") 14 | tags: shell 15 | harness: keyboard 16 | extra_args: CONF_FILE="prj_minimal.conf" 17 | integration_platforms: 18 | - native_posix 19 | sample.shell.shell_module.robot: 20 | harness: robot 21 | harness_config: 22 | robot_test_path: shell_module.robot 23 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/shell_module.robot: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: Apache-2.0 2 | 3 | *** Settings *** 4 | Resource ${KEYWORDS} 5 | 6 | *** Test Cases *** 7 | Should Read Version From Shell 8 | # `Prepare Machine` keyword comes from $ZEPHYR_BASE/tests/robot/common.robot file, which is imported as a resource 9 | Prepare Machine 10 | Start Emulation 11 | Wait For Prompt On Uart uart:~$ 12 | Write Line To Uart version 13 | Wait For Line On Uart Zephyr version 14 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 | #define DEFAULT_PASSWORD "zephyr" 244 | 245 | static void login_init(void) 246 | { 247 | printk("Shell Login Demo\nHint: password = %s\n", DEFAULT_PASSWORD); 248 | if (!CONFIG_SHELL_CMD_ROOT[0]) { 249 | shell_set_root_cmd("login"); 250 | } 251 | } 252 | 253 | static int check_passwd(char *passwd) 254 | { 255 | /* example only -- not recommended for production use */ 256 | return strcmp(passwd, DEFAULT_PASSWORD); 257 | } 258 | 259 | static int cmd_login(const struct shell *sh, size_t argc, char **argv) 260 | { 261 | static uint32_t attempts; 262 | 263 | if (check_passwd(argv[1]) != 0) { 264 | shell_error(sh, "Incorrect password!"); 265 | attempts++; 266 | if (attempts > 3) { 267 | k_sleep(K_SECONDS(attempts)); 268 | } 269 | return -EINVAL; 270 | } 271 | 272 | /* clear history so password not visible there */ 273 | z_shell_history_purge(sh->history); 274 | shell_obscure_set(sh, false); 275 | shell_set_root_cmd(NULL); 276 | shell_prompt_change(sh, "uart:~$ "); 277 | shell_print(sh, "Shell Login Demo\n"); 278 | shell_print(sh, "Hit tab for help.\n"); 279 | attempts = 0; 280 | return 0; 281 | } 282 | 283 | static int cmd_logout(const struct shell *sh, size_t argc, char **argv) 284 | { 285 | shell_set_root_cmd("login"); 286 | shell_obscure_set(sh, true); 287 | shell_prompt_change(sh, "login: "); 288 | shell_print(sh, "\n"); 289 | return 0; 290 | } 291 | 292 | static int set_bypass(const struct shell *sh, shell_bypass_cb_t bypass) 293 | { 294 | static bool in_use; 295 | 296 | if (bypass && in_use) { 297 | shell_error(sh, "Sample supports setting bypass on single instance."); 298 | 299 | return -EBUSY; 300 | } 301 | 302 | in_use = !in_use; 303 | if (in_use) { 304 | shell_print(sh, "Bypass started, press ctrl-x ctrl-q to escape"); 305 | in_use = true; 306 | } 307 | 308 | shell_set_bypass(sh, bypass); 309 | 310 | return 0; 311 | } 312 | 313 | #define CHAR_1 0x18 314 | #define CHAR_2 0x11 315 | 316 | static void bypass_cb(const struct shell *sh, uint8_t *data, size_t len) 317 | { 318 | static uint8_t tail; 319 | bool escape = false; 320 | 321 | /* Check if escape criteria is met. */ 322 | if (tail == CHAR_1 && data[0] == CHAR_2) { 323 | escape = true; 324 | } else { 325 | for (int i = 0; i < (len - 1); i++) { 326 | if (data[i] == CHAR_1 && data[i + 1] == CHAR_2) { 327 | escape = true; 328 | break; 329 | } 330 | } 331 | } 332 | 333 | if (escape) { 334 | shell_print(sh, "Exit bypass"); 335 | set_bypass(sh, NULL); 336 | tail = 0; 337 | return; 338 | } 339 | 340 | /* Store last byte for escape sequence detection */ 341 | tail = data[len - 1]; 342 | 343 | /* Do the data processing. */ 344 | for (int i = 0; i < len; i++) { 345 | shell_fprintf(sh, SHELL_INFO, "%02x ", data[i]); 346 | } 347 | shell_fprintf(sh, SHELL_INFO, "| "); 348 | 349 | for (int i = 0; i < len; i++) { 350 | shell_fprintf(sh, SHELL_INFO, "%c", data[i]); 351 | } 352 | shell_fprintf(sh, SHELL_INFO, "\n"); 353 | 354 | } 355 | 356 | static int cmd_bypass(const struct shell *sh, size_t argc, char **argv) 357 | { 358 | return set_bypass(sh, bypass_cb); 359 | } 360 | 361 | static int cmd_dict(const struct shell *sh, size_t argc, char **argv, 362 | void *data) 363 | { 364 | int val = (intptr_t)data; 365 | 366 | shell_print(sh, "(syntax, value) : (%s, %d)", argv[0], val); 367 | 368 | return 0; 369 | } 370 | 371 | SHELL_SUBCMD_DICT_SET_CREATE(sub_dict_cmds, cmd_dict, 372 | (value_0, 0, "value 0"), (value_1, 1, "value 1"), 373 | (value_2, 2, "value 2"), (value_3, 3, "value 3") 374 | ); 375 | 376 | SHELL_STATIC_SUBCMD_SET_CREATE(sub_demo, 377 | SHELL_CMD(dictionary, &sub_dict_cmds, "Dictionary commands", NULL), 378 | SHELL_CMD(hexdump, NULL, "Hexdump params command.", cmd_demo_hexdump), 379 | SHELL_CMD(params, NULL, "Print params command.", cmd_demo_params), 380 | SHELL_CMD(ping, NULL, "Ping command.", cmd_demo_ping), 381 | SHELL_CMD(board, NULL, "Show board name command.", cmd_demo_board), 382 | #if defined CONFIG_SHELL_GETOPT 383 | SHELL_CMD(getopt_thread_safe, NULL, 384 | "Cammand using getopt in thread safe way" 385 | " looking for: \"abhc:\".", 386 | cmd_demo_getopt_ts), 387 | SHELL_CMD(getopt, NULL, "Cammand using getopt in non thread safe way" 388 | " looking for: \"abhc:\".\n", cmd_demo_getopt), 389 | #endif 390 | SHELL_SUBCMD_SET_END /* Array terminated. */ 391 | ); 392 | SHELL_CMD_REGISTER(demo, &sub_demo, "Demo commands", NULL); 393 | 394 | SHELL_CMD_ARG_REGISTER(version, NULL, "Show kernel version", cmd_version, 1, 0); 395 | 396 | SHELL_CMD_ARG_REGISTER(bypass, NULL, "Bypass shell", cmd_bypass, 1, 0); 397 | 398 | SHELL_COND_CMD_ARG_REGISTER(CONFIG_SHELL_START_OBSCURED, login, NULL, 399 | "", cmd_login, 2, 0); 400 | 401 | SHELL_COND_CMD_REGISTER(CONFIG_SHELL_START_OBSCURED, logout, NULL, 402 | "Log out.", cmd_logout); 403 | 404 | 405 | /* Create a set of commands. Commands to this set are added using @ref SHELL_SUBCMD_ADD 406 | * and @ref SHELL_SUBCMD_COND_ADD. 407 | */ 408 | SHELL_SUBCMD_SET_CREATE(sub_section_cmd, (section_cmd)); 409 | 410 | static int cmd1_handler(const struct shell *sh, size_t argc, char **argv) 411 | { 412 | ARG_UNUSED(sh); 413 | ARG_UNUSED(argc); 414 | ARG_UNUSED(argv); 415 | 416 | shell_print(sh, "cmd1 executed"); 417 | 418 | return 0; 419 | } 420 | 421 | /* Create a set of subcommands for "section_cmd cm1". */ 422 | SHELL_SUBCMD_SET_CREATE(sub_section_cmd1, (section_cmd, cmd1)); 423 | 424 | /* Add command to the set. Subcommand set is identify by parent shell command. */ 425 | SHELL_SUBCMD_ADD((section_cmd), cmd1, &sub_section_cmd1, "help for cmd1", cmd1_handler, 1, 0); 426 | 427 | SHELL_CMD_REGISTER(section_cmd, &sub_section_cmd, 428 | "Demo command using section for subcommand registration", NULL); 429 | 430 | int main(void) 431 | { 432 | if (IS_ENABLED(CONFIG_SHELL_START_OBSCURED)) { 433 | login_init(); 434 | } 435 | 436 | #if DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_shell_uart), zephyr_cdc_acm_uart) 437 | const struct device *dev; 438 | uint32_t dtr = 0; 439 | 440 | dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_shell_uart)); 441 | if (!device_is_ready(dev) || usb_enable(NULL)) { 442 | return 0; 443 | } 444 | 445 | while (!dtr) { 446 | uart_line_ctrl_get(dev, UART_LINE_CTRL_DTR, &dtr); 447 | k_sleep(K_MSEC(100)); 448 | } 449 | #endif 450 | return 0; 451 | } 452 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 cmd2", 46 | sub_cmd1_handler, 1, 0); 47 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 | -------------------------------------------------------------------------------- /03-twister/example-application/shell_module/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 | -------------------------------------------------------------------------------- /03-twister/example-application/west.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | manifest: 5 | 6 | remotes: 7 | - name: zephyrproject-rtos 8 | url-base: https://github.com/zephyrproject-rtos 9 | 10 | projects: 11 | - name: zephyr 12 | remote: zephyrproject-rtos 13 | revision: 916df03e7aeceb9164c62a326e81a86d74742bb7 14 | import: 15 | # By using name-allowlist we can clone only the modules that are 16 | # strictly needed by the application. 17 | name-allowlist: 18 | - cmsis # required by the ARM port 19 | - hal_nordic # required by the custom_plank board (Nordic based) 20 | - hal_stm32 # required by the nucleo_f302r8 board (STM32 based) 21 | -------------------------------------------------------------------------------- /03-twister/example-application/zephyr/module.yml: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2021 Nordic Semiconductor ASA 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | build: 5 | # Path to the Kconfig file that will be sourced into Zephyr Kconfig tree under 6 | # Zephyr > Modules > example-application. Path is relative from root of this 7 | # repository. 8 | kconfig: Kconfig 9 | # Path to the folder that contains the CMakeLists.txt file to be included by 10 | # Zephyr build system. The `.` is the root of this repository. 11 | cmake: . 12 | settings: 13 | # Additional roots for boards and DTS files. Zephyr will use the 14 | # `/boards` for additional boards. The `.` is the root of this 15 | # repository. 16 | board_root: . 17 | # Zephyr will use the `/dts` for additional dts files and 18 | # `/dts/bindings` for additional dts binding files. The `.` is 19 | # the root of this repository. 20 | dts_root: . 21 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Embedded CI on Steroids with Zephyr & Renode 2 | 3 | Copyright (c) 2023 [Antmicro](https://www.antmicro.com) 4 | 5 | This is a companion repository to the Zephyr Tech Talk. 6 | 7 | You can watch the talk on [YouTube](https://www.youtube.com/watch?v=hBODmrYUzV0). 8 | 9 | ## Table of contents 10 | 11 | * [01-renode-basics](01-renode-basics) - running a simple demo in Renode, scriptability 12 | * [02-automation](02-automation) - using Renode in batch mode 13 | * [03-twister](03-twister) - details on West and Twister integration. 14 | 15 | 16 | ## How to get Renode? 17 | 18 | Please refer to our [installation instructions in the Renode README](https://github.com/renode/renode/#installation). 19 | 20 | For Linux users, we recommend obtaining the [portable nightly build](https://builds.renode.io/renode-latest.linux-portable.tar.gz) or installing Renode via the [renode-run Python package](https://github.com/antmicro/renode-run). 21 | 22 | Packages for other OSes can be found on [builds.renode.io](https://builds.renode.io/). 23 | 24 | ## Setup Zephyr 25 | 26 | Some of the presented scenarios require you to use Zephyr's ``west`` tool and to have the Zephyr SDK installed. 27 | 28 | To set them up, follow the [Zephyr Getting Started Guide](https://docs.zephyrproject.org/latest/develop/getting_started/index.html). 29 | 30 | ## Renode links 31 | 32 | * [Renode homepage](https://renode.io) 33 | * [Renode sources](https://github.com/renode/renode) 34 | * [Renode documentation](https://docs.renode.io) 35 | * [Renode slide deck](https://about.renode.io) 36 | * [Renode nightly builds](https://builds.renode.io) 37 | * [renode-run](https://github.com/antmicro/renode-run) 38 | * [Renode Zephyr Dashboard](https://zephyr-dashboard.renode.io/) 39 | * [Renode U-Boot Dashboard](https://u-boot-dashboard.renode.io/) 40 | * [Renodepedia](https://renodepedia.renode.io/) 41 | * [dts2repl](https://github.com/antmicro/dts2repl) 42 | * [pyrenode](https://github.com/antmicro/pyrenode) 43 | * [Renode GitHub action](https://github.com/antmicro/renode-test-action) 44 | * [Renode Linux runner action](https://github.com/antmicro/renode-linux-runner-action/) 45 | * [Antmicro blog](https://antmicro.com/blog/) 46 | --------------------------------------------------------------------------------