diff --git a/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/ulp_makefile b/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/ulp_makefile new file mode 100644 index 00000000000..015cbfb1e17 --- /dev/null +++ b/Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/ulp_makefile @@ -0,0 +1,29 @@ +############################################################################ +# Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/ulp_makefile +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. The +# ASF licenses this file to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance with the +# License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +############################################################################ + +ULP_APP_USE_TEST_BIN = y + +ULP_APP_NAME = esp_ulp +ULP_APP_FOLDER = $(TOPDIR)$(DELIM)arch$(DELIM)risc-v$(DELIM)src$(DELIM)$(CHIP_SERIES) +ULP_APP_BIN = $(TOPDIR)$(DELIM)Documentation$(DELIM)platforms$(DELIM)risc-v$(DELIM)esp32c6$(DELIM)boards$(DELIM)esp32c6-devkitc$(DELIM)ulp_blink.bin + +include $(TOPDIR)$(DELIM)arch$(DELIM)risc-v$(DELIM)src$(DELIM)common$(DELIM)espressif$(DELIM)esp_ulp.mk diff --git a/Documentation/platforms/risc-v/esp32c6/index.rst b/Documentation/platforms/risc-v/esp32c6/index.rst index 77016d48679..98fdab1f66b 100644 --- a/Documentation/platforms/risc-v/esp32c6/index.rst +++ b/Documentation/platforms/risc-v/esp32c6/index.rst @@ -641,17 +641,41 @@ and the resulting .bin file has to be integrated into NuttX. This workflow, whil With NuttX internal build system, the ULP binary code can be built and flashed from a single location. It is more convenient but using build system has some dependencies on example side. -Both methods requires `CONFIG_ESPRESSIF_USE_LP_CORE` variable to enable ULP core and -`CONFIG_ESPRESSIF_ULP_PROJECT_PATH` variable to set the path to the ULP project or prebuilt binary file -relative to NuttX root folder. -These variables can be set using `make menuconfig` or `kconfig-tweak` commands. +Both methods requires ``CONFIG_ESPRESSIF_USE_LP_CORE`` variable to enable ULP core +and it can be set using ``make menuconfig`` or ``kconfig-tweak`` commands. -Here is an example for enabling ULP and using a prebuilt binary for ULP core:: +Additionally, a Makefile needs to be provided to specify the ULP application name, +source path of the ULP application, and either the binary (for prebuilt) or the source files (for internal build). +This Makefile must include the ULP makefile after the variable set process on ``arch/risc-v/src/common/espressif/esp_ulp.mk`` integration script. +For more information please refer to :ref:`ulp example Makefile. ` + +Makefile Variables for ULP Core Build: +-------------------------------------- + +- ``ULP_APP_NAME``: Sets name for the ULP application. This variable also be used as prefix (e.g. ULP application bin variable name) +- ``ULP_APP_FOLDER``: Specifies the directory containing the ULP application's source codes. +- ``ULP_APP_BIN``: Defines the path of the prebuilt ULP binary. +- ``ULP_APP_C_SRCS``: Lists all C source files (.c) that need to be compiled for the ULP application. +- ``ULP_APP_ASM_SRCS``: Lists all assembly source files (.S or .s) to be assembled. +- ``ULP_APP_INCLUDES``: Specifies additional include directories for the compiler and assembler. + +Here is an Makefile example when using prebuilt binary for ULP core: + +.. code-block:: console + + ULP_APP_NAME = esp_ulp + ULP_APP_FOLDER = $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)$(CHIP_SERIES) + ULP_APP_BIN = $(TOPDIR)$(DELIM)Documentation$(DELIM)platforms$(DELIM)$(CONFIG_ARCH)$(DELIM)$(CONFIG_ARCH_CHIP)$(DELIM)boards$(DELIM)$(CONFIG_ARCH_BOARD)$(DELIM)ulp_riscv_blink.bin + + include $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)common$(DELIM)espressif$(DELIM)esp_ulp.mk + + +Here is an example for enabling ULP and using the prebuilt test binary for ULP core:: make distclean ./tools/configure.sh esp32c6-devkitc:nsh kconfig-tweak -e CONFIG_ESPRESSIF_USE_LP_CORE - kconfig-tweak --set-str CONFIG_ESPRESSIF_ULP_PROJECT_PATH "Documentation/platforms/risc-v/esp32c6/boards/esp32c6-devkitc/ulp_blink.bin" + kconfig-tweak -e CONFIG_ESPRESSIF_ULP_USE_TEST_BIN make olddefconfig make -j @@ -660,11 +684,11 @@ Creating an ULP LP-Core Application To use NuttX's internal build system to compile the bare-metal LP binary, check the following instructions. -First, create a folder for the ULP source and header files. This folder is just for ULP project and it is -an independent project. Therefore, the NuttX example guide should not be followed, and no Makefile or similar -build files should be added. Also folder location could be anywhere. To include ULP folder into build -system don't forget to set `CONFIG_ESPRESSIF_ULP_PROJECT_PATH` variable with path of the ULP project folder relative to -NuttX root folder. Instructions for setting up can be found above. +First, create a folder for the ULP source and header files into your NuttX example. +This folder is just for ULP project and it is an independent project. Therefore, the NuttX example guide should not be followed +for ULP example (folder location is irrelevant. It can be the same of the `nuttx-apps` repository, for instance). +To include the ULP folder in the build system, don't forget to include the ULP Makefile in the NuttX example Makefile. Lastly, configuration variables +needed to enable ULP core instructions can be found above. NuttX's internal functions or POSIX calls are not supported. @@ -701,8 +725,10 @@ For more information about ULP Core Coprocessor examples `check here `__ guide, +this example will demonstrate how to add ULP code into a custom application: - Tree view: @@ -712,9 +738,84 @@ to create a subfolder for ULP but folder that includes ULP source code can be an ├── nuttx/ └── apps/ └── ulp_example/ + └── Makefile + └── Kconfig + └── ulp_example.c └── ulp/ + └── Makefile └── ulp_main.c + +- Contents in Makefile: + +.. code-block:: console + + include $(APPDIR)/Make.defs + + PROGNAME = $(CONFIG_EXAMPLES_ULP_EXAMPLE_PROGNAME) + PRIORITY = $(CONFIG_EXAMPLES_ULP_EXAMPLE_PRIORITY) + STACKSIZE = $(CONFIG_EXAMPLES_ULP_EXAMPLE_STACKSIZE) + MODULE = $(CONFIG_EXAMPLES_ULP_EXAMPLE) + + MAINSRC = ulp_example.c + + include $(APPDIR)/Application.mk + + include ulp/Makefile + +- Contents in Kconfig: + +.. code-block:: console + + config EXAMPLES_ULP_EXAMPLE + bool "ULP Example" + default n + +- Contents in ulp_example.c: + +.. code-block:: C + + #include + #include + #include + #include + #include + #include + #include + #include + + #include "ulp/ulp/ulp_main.h" + /* Files that holds ULP binary header */ + + #include "ulp/ulp/ulp_code.h" + + int main (void) + { + int fd; + fd = open("/dev/ulp", O_WRONLY); + if (fd < 0) + { + printf("Failed to open ULP: %d\n", errno); + return -1; + } + /* ulp_example is the prefix which can be changed with ULP_APP_NAME makefile + * variable to access ULP binary code variable */ + write(fd, ulp_example_bin, ulp_example_bin_len); + return 0; + } + +.. _ulp_makefile: + +- Contents in ulp/Makefile: + +.. code-block:: console + + ULP_APP_NAME = ulp_example + ULP_APP_FOLDER = $(APPDIR)$(DELIM)ulp_example$(DELIM)ulp + ULP_APP_C_SRCS = ulp_main.c + + include $(TOPDIR)$(DELIM)arch$(DELIM)$(CONFIG_ARCH)$(DELIM)src$(DELIM)common$(DELIM)espressif$(DELIM)esp_ulp.mk + - Contents in ulp_main.c: .. code-block:: C @@ -751,24 +852,82 @@ to create a subfolder for ULP but folder that includes ULP source code can be an kconfig-tweak -e CONFIG_ESPRESSIF_GPIO_IRQ kconfig-tweak -e CONFIG_DEV_GPIO kconfig-tweak -e CONFIG_ESPRESSIF_USE_LP_CORE - kconfig-tweak --set-str CONFIG_ESPRESSIF_ULP_PROJECT_PATH "../ulp_example/ulp" + kconfig-tweak -e CONFIG_EXAMPLES_ULP_EXAMPLE make olddefconfig make -j +Here is an example of a single ULP application. However, support is not limited to just +one application. Multiple ULP applications are also supported. +By following the same guideline, multiple ULP applications can be created and loaded using ``write`` POSIX call. +Each NuttX application can build one ULP application. Therefore, to build multiple ULP applications, multiple NuttX +applications are needed to create each ULP binary. This limitation only applies when using the NuttX build system to +build multiple ULP applications; it does not affect the ability to load multiple ULP applications built by other means. + +ULP binary can be included in NuttX application by adding +``#include "ulp/ulp/ulp_code.h"`` line. Then, the ULP binary is accessible by using the ULP application +prefix (defined by the ``ULP_APP_NAME`` variable in the ULP application Makefile) with the ``bin`` keyword to +access the binary data (e.g., if ``ULP_APP_NAME`` is ``ulp_test``, the binary variable will be ``ulp_test_bin``) +and ``bin_len`` keyword to access its length (e.g., ``ulp_test_bin_len`` for ``ULP_APP_NAME`` is ``ulp_test``). + +Accessing the ULP LP-Core Program Variables +------------------------------------------- + +Global symbols defined in the ULP application are available to the HP core through a shared memory region. To read or write ULP variables, +direct reading/writing to such memory positions are not allowed. POSIX calls are needed instead. To access the ULP variable through the HP core, +consider that its name is defined by the ULP application prefix (defined by the ``ULP_APP_NAME`` variable in the ULP application Makefile) + the ULP application variable. +For example if HP core tries to access a ULP application variable named ``result`` and ``ULP_APP_NAME`` in the ULP application Makefile set as ``ulp_app``, required name for +that variable will be ``ulp_app_result``. +``FIONREAD`` or ``FIONWRITE`` ioctl calls are, then, performed with the address of a ``struct symtab_s`` previously defined with the name of the variable to be read or written. + +.. warning:: + Ensure that the related ULP application is running. Otherwise, another ULP application may interfere by using the same memory space for a different variables. + + +Here is a snippet for reading and writing to a ULP variable named ``var_test`` (assuming the ``ULP_APP_NAME`` is set to ``ulp``) through the HP core: + +.. code-block:: C + + #include + #include + #include + #include + #include + #include "nuttx/symtab.h" + + int main (void) + { + uint32_t ulp_var; + int fd; + struct symtab_s sym = + { + .sym_name = "ulp_var_test", + .sym_value = &ulp_var, + }; + fd = open("/dev/ulp", O_RDWR); + ioctl(fd, FIONREAD, &sym); + if (ulp_var != 0) + { + ulp_var = 0; + ioctl(fd, FIONWRITE, &sym); + } + + return OK; + } + Debugging ULP LP-Core --------------------- To debug ULP LP-Core please first refer to :ref:`Debugging section. ` Debugging ULP core consist same steps with some small differences. First of all, configuration file -needs to be changed from `board/esp32c6-builtin.cfg` or `board/esp32c6-ftdi.cfg` to -`board/esp32c6-lpcore-builtin.cfg` or `board/esp32c6-lpcore-ftdi.cfg` depending on preferred debug adapter. +needs to be changed from ``board/esp32c6-builtin.cfg`` or ``board/esp32c6-ftdi.cfg`` to +``board/esp32c6-lpcore-builtin.cfg`` or ``board/esp32c6-lpcore-ftdi.cfg`` depending on preferred debug adapter. LP core supports limited set of HW exceptions, so, for example, writing at address 0x0 will not cause a panic as it would be for the code running on HP core. This can be overcome to some extent by enabling undefined behavior sanitizer for LP core application, so ubsan can help to catch some errors. But note that it will increase code size significantly and it can happen that application won't fit into RTC RAM. -To enable ubsan for ULP please add `CONFIG_ESPRESSIF_ULP_ENABLE_UBSAN` in menuconfig. +To enable ubsan for ULP please add ``CONFIG_ESPRESSIF_ULP_ENABLE_UBSAN`` in menuconfig. _`Managing esptool on virtual environment` ==========================================