From e01f967c993d9ccb1ca6a89519d362fd19c8a239 Mon Sep 17 00:00:00 2001 From: Eren Terzioglu Date: Fri, 26 Sep 2025 15:45:54 +0200 Subject: [PATCH] arch/risc-v/esp32c6: Add ULP shared memory encapsulation Add ULP shared memory encapsulation for esp32c6 Signed-off-by: Eren Terzioglu --- arch/risc-v/src/common/espressif/esp_ulp.c | 107 +++++++++++++++++++- arch/risc-v/src/common/espressif/esp_ulp.mk | 26 +++++ 2 files changed, 128 insertions(+), 5 deletions(-) diff --git a/arch/risc-v/src/common/espressif/esp_ulp.c b/arch/risc-v/src/common/espressif/esp_ulp.c index 3ac3fd8b1e4..598dd0848bb 100644 --- a/arch/risc-v/src/common/espressif/esp_ulp.c +++ b/arch/risc-v/src/common/espressif/esp_ulp.c @@ -25,9 +25,14 @@ ****************************************************************************/ #include +#include +#include +#include +#include #include "ulp_lp_core.h" #include "ulp/ulp_code.h" +#include "ulp/ulp_var_map.h" /**************************************************************************** * Pre-processor Definitions @@ -41,10 +46,24 @@ * Private Function Prototypes ****************************************************************************/ +static int esp_ulp_ioctl(struct file *filep, int cmd, unsigned long arg); + /**************************************************************************** * Private Data ****************************************************************************/ +static const struct file_operations g_esp_ulp_fops = +{ + .ioctl = esp_ulp_ioctl, /* ioctl */ +}; + +/* Configuration for ULP LP Core */ + +ulp_lp_core_cfg_t cfg = +{ + .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, +}; + /**************************************************************************** * Public Data ****************************************************************************/ @@ -53,6 +72,88 @@ * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: esp_ulp_ioctl + * + * Description: + * Lower-half logic may support platform-specific ioctl commands + * + * Input Parameters: + * filep - The pointer of file, represents each user using the sensor + * cmd - The ioctl command + * arg - The argument accompanying the ioctl command + * + * Returned Value: + * Zero on success; a negated errno value on failure + * + ****************************************************************************/ + +static int esp_ulp_ioctl(struct file *filep, int cmd, unsigned long arg) +{ + int ret = 0; + int index = -1; + struct symtab_s *sym = (struct symtab_s *)arg; + int var_map_size = sizeof(ulp_var_map) / sizeof(ulp_var_map[0]); + + DEBUGASSERT(sym); + + /* Decode and dispatch the driver-specific IOCTL command */ + + for (int i = 0; i < var_map_size; i++) + { + if (strcmp(ulp_var_map[i].sym.sym_name, sym->sym_name) == 0) + { + index = i; + break; + } + } + + if (index == -1) + { + ferr("Symbol name does not exist\n"); + return ERROR; + } + + switch (cmd) + { + case FIONREAD: + memcpy((void *)sym->sym_value, ulp_var_map[index].sym.sym_value, + ulp_var_map[index].size); + break; + + case FIONWRITE: + memcpy((void *)ulp_var_map[index].sym.sym_value, sym->sym_value, + ulp_var_map[index].size); + break; + + default: + ferr("Unrecognized IOCTL command: %d\n", cmd); + ret = -ENOTTY; + break; + } + + return ret; +} + +/**************************************************************************** + * Name: esp_ulp_register + * + * Description: + * This function registers ULP. + * + * Input Parameters: + * None + * + * Returned Value: + * None + * + ****************************************************************************/ + +static void esp_ulp_register(void) +{ + register_driver("/dev/ulp", &g_esp_ulp_fops, 0666, NULL); +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -73,13 +174,9 @@ void esp_ulp_init(void) { - ulp_lp_core_cfg_t cfg = - { - .wakeup_source = ULP_LP_CORE_WAKEUP_SOURCE_HP_CPU, - }; - ulp_lp_core_load_binary(esp_ulp_bin, sizeof(esp_ulp_bin)); + esp_ulp_register(); ulp_lp_core_run(&cfg); } diff --git a/arch/risc-v/src/common/espressif/esp_ulp.mk b/arch/risc-v/src/common/espressif/esp_ulp.mk index d4761429213..dc76a565b3c 100644 --- a/arch/risc-v/src/common/espressif/esp_ulp.mk +++ b/arch/risc-v/src/common/espressif/esp_ulp.mk @@ -143,6 +143,7 @@ ULP_READELF = $(CROSSDEV)readelf ULP_MAPGEN_TOOL_PATH = chip$(DELIM)$(ESP_HAL_3RDPARTY_REPO)$(DELIM)components$(DELIM)ulp$(DELIM)esp32ulp_mapgen.py ULP_PREFIX = ulp_ ULP_BASE = 0 +ULP_VAR_MAP_HEADER_STRING = '\#include "nuttx/symtab.h"\n\nstruct ulp_var_map_s\n{\n struct symtab_s sym;\n size_t size;\n};\n' # To prevent redefining error of other header files in nuttx folder, nuttx/config.h file # will be moved during ULP compilation. This step will only effect ULP @@ -224,11 +225,35 @@ $(ULP_ELF_FILE): $(ULP_OBJS) $(Q) $(CC) $(ULP_LDFLAGS) $(ULP_OBJS) -o $@ $(ULP_BIN_FILE): $(ULP_ELF_FILE) checkpython3 + $(Q) echo -e $(ULP_VAR_MAP_HEADER_STRING) > $(ULP_FOLDER)$(DELIM)ulp_var_map.h + $(Q) echo -e "\n\nstruct ulp_var_map_s ulp_var_map[] =\n{\n" >> $(ULP_FOLDER)$(DELIM)ulp_var_map.h + $(Q) echo -e "\n};" >> $(ULP_FOLDER)$(DELIM)ulp_var_map.h ifneq ($(suffix $(ULP_PROJECT_PATH)),.bin) $(Q) echo "Creating bin for ULP" $(Q) $(OBJCOPY) -O binary $(ULP_ELF_FILE) $(ULP_BIN_FILE) $(Q) $(ULP_READELF) -sW $(ULP_ELF_FILE) > $(ULP_SYM_FILE) $(Q) python3 $(ULP_MAPGEN_TOOL_PATH) -s $(ULP_SYM_FILE) -o $(ULP_FOLDER)$(DELIM)ulp_main --base $(ULP_BASE) --prefix $(ULP_PREFIX) +# Creating map header file for accessing shared memory region of ULP variables + $(Q) echo -e $(ULP_VAR_MAP_HEADER_STRING) > $(ULP_FOLDER)$(DELIM)ulp_var_map.h + $(Q) grep "extern uint32_t" $(ULP_FOLDER)$(DELIM)ulp_main.h >> $(ULP_FOLDER)$(DELIM)ulp_var_map.h + $(Q) echo -e "\n\nstruct ulp_var_map_s ulp_var_map[] =\n{\n" >> $(ULP_FOLDER)$(DELIM)ulp_var_map.h + $(Q) grep "$(ULP_PREFIX)" $(ULP_FOLDER)$(DELIM)ulp_main.h | while IFS= read -r line; do \ + var=$$(echo $$line | grep -oP "$${ULP_PREFIX}\w+(?=[;\[])"); \ + if [ -n "$$var" ]; then \ + size=$$(echo "$$line" | grep -oP "\[\d+\]" | grep -oP "\d+"); \ + if [ -n "$$size" ]; then \ + size=$$(( $$size * 4 )); \ + else \ + size=4; \ + fi; \ + echo -e " {" >> $(ULP_FOLDER)$(DELIM)ulp_var_map.h; \ + echo -e " .sym.sym_name = \"$${var}\"," >> $(ULP_FOLDER)$(DELIM)ulp_var_map.h; \ + echo -e " .sym.sym_value = &$${var}," >> $(ULP_FOLDER)$(DELIM)ulp_var_map.h; \ + echo -e " .size = $${size}," >> $(ULP_FOLDER)$(DELIM)ulp_var_map.h; \ + echo -e " }," >> $(ULP_FOLDER)$(DELIM)ulp_var_map.h; \ + fi; \ + done + $(Q) echo -e "\n};" >> $(ULP_FOLDER)$(DELIM)ulp_var_map.h endif $(Q) echo "Converting bin for ULP into header file" $(Q) xxd -i $(ULP_BIN_FILE_PATH) >$(ULP_CODE_HEADER) || { echo "xxd of $< failed" ; exit 1 ; } @@ -243,6 +268,7 @@ $(ULP_FOLDER): context:: $(ULP_FOLDER) $(Q) touch $(ULP_CODE_HEADER) $(Q) touch $(ULP_FOLDER)$(DELIM)ulp_main.h + $(Q) touch $(ULP_FOLDER)$(DELIM)ulp_var_map.h depend: $(ULP_BIN_FILE)