diff --git a/examples/esp32_himem/Kconfig b/examples/esp32_himem/Kconfig new file mode 100644 index 000000000..c99c71f28 --- /dev/null +++ b/examples/esp32_himem/Kconfig @@ -0,0 +1,29 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_ESP32_HIMEM + tristate "ESP32 HIMEM Example" + default n + ---help--- + ESP32 HIMEM Example + +if EXAMPLES_ESP32_HIMEM + +config EXAMPLES_ESP32_HIMEM_PROGNAME + string "Program name" + default "esp32himem" + ---help--- + This is the name of the program that will be used when the NSH ELF + program is installed. + +config EXAMPLES_ESP32_HIMEM_PRIORITY + int "ESP32 HIMEM task priority" + default 100 + +config EXAMPLES_ESP32_HIMEM_STACKSIZE + int "ESP32 HIMEM stack size" + default DEFAULT_TASK_STACKSIZE + +endif diff --git a/examples/esp32_himem/Make.defs b/examples/esp32_himem/Make.defs new file mode 100644 index 000000000..5d80703dc --- /dev/null +++ b/examples/esp32_himem/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/examples/esp32himem/Make.defs +# Adds selected applications to apps/ build +# +# Copyright (C) 2015 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +ifneq ($(CONFIG_EXAMPLES_ESP32_HIMEM),) +CONFIGURED_APPS += $(APPDIR)/examples/esp32_himem +endif diff --git a/examples/esp32_himem/Makefile b/examples/esp32_himem/Makefile new file mode 100644 index 000000000..4b9f3a2ef --- /dev/null +++ b/examples/esp32_himem/Makefile @@ -0,0 +1,49 @@ +############################################################################ +# apps/examples/esp32himem/Makefile +# +# Copyright (C) 2008, 2010-2013 Gregory Nutt. All rights reserved. +# Author: Gregory Nutt +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# 3. Neither the name NuttX nor the names of its contributors may be +# used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS +# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED +# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +############################################################################ + +include $(APPDIR)/Make.defs + +# ESP32 HIMEM built-in application info + +PROGNAME = $(CONFIG_EXAMPLES_ESP32_HIMEM_PROGNAME) +PRIORITY = $(CONFIG_EXAMPLES_ESP32_HIMEM_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_ESP32_HIMEM_STACKSIZE) +MODULE = $(CONFIG_EXAMPLES_ESP32_HIMEM) + +# ESP32 HIMEM Example + +MAINSRC = esp32_himem_main.c + +include $(APPDIR)/Application.mk diff --git a/examples/esp32_himem/esp32_himem_main.c b/examples/esp32_himem/esp32_himem_main.c new file mode 100644 index 000000000..e07f614f2 --- /dev/null +++ b/examples/esp32_himem/esp32_himem_main.c @@ -0,0 +1,231 @@ +/**************************************************************************** + * apps/examples/esp32_himem/esp32_himem_main.c + * + * 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. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include +#include + +#include + +/* Fills the memory in 32-bit words for speed. */ + +static void fill_mem(void *mem, int len) +{ + uint32_t *p = (uint32_t *)mem; + unsigned int val = 0xa5a5a5a5; + for (int i = 0; i < len / 4; i++) + { + *p++ = val; + } +} + +/* Check the memory filled by fill_mem. Returns true if the data matches + * the data that fill_mem wrote. + * Returns true if there's a match, false when the region differs from what + * should be there. + */ + +static bool check_mem(void *mem, int len, int phys_addr) +{ + uint32_t *p = (uint32_t *)mem; + unsigned int val = 0xa5a5a5a5; + for (int i = 0; i < len / 4; i++) + { + if (val != *p) + { + printf("check_mem: %x has 0x%08x expected 0x%08x\n", + phys_addr + ((char *) p - (char *) mem), *p, val); + return false; + } + p++; + } + return true; +} + +/* Allocate a himem region, fill it with data, check it and release it. */ + +static int test_region(int fd, struct esp_himem_par *param) +{ + int ret; + int i; + + DEBUGASSERT(param != NULL); + + /* Set predefined parameters */ + + param->len = ESP_HIMEM_BLKSZ; + param->range_offset = 0; + param->flags = 0; + + /* Allocate the memory we're going to check. */ + + ret = ioctl(fd, HIMEMIOC_ALLOC_BLOCKS, (unsigned long)((uintptr_t)param)); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl(ALLOC_BLOCKS) failed: %d\n", errno); + return -ENOMEM; + } + + /* Allocate a block of address range */ + + ret = ioctl(fd, HIMEMIOC_ALLOC_MAP_RANGE, + (unsigned long)((uintptr_t)param)); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl(ALLOC_MAP_RANGE) failed: %d\n", errno); + return -ENOMEM; + } + + for (i = 0; i < param->memfree; i += ESP_HIMEM_BLKSZ) + { + param->ptr = NULL; + param->ram_offset = i; + + /* Map in block, write pseudo-random data, unmap block. */ + + ret = ioctl(fd, HIMEMIOC_MAP, (unsigned long)((uintptr_t)param)); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl(MAP) failed: %d\n", errno); + ret = -ENOMEM; + goto free_rammem; + } + + fill_mem(param->ptr, ESP_HIMEM_BLKSZ); + + ret = ioctl(fd, HIMEMIOC_UNMAP, (unsigned long)((uintptr_t)param)); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl(UNMAP) failed: %d\n", errno); + ret = -ENOMEM; + goto free_rammem; + } + } + + /* give the OS some time to do things so the task watchdog doesn't bark */ + + usleep(1); + + for (i = 0; i < param->memfree; i += ESP_HIMEM_BLKSZ) + { + param->ptr = NULL; + param->ram_offset = i; + + /* Map in block, check against earlier written pseudo-random data, + * unmap block. + */ + + ret = ioctl(fd, HIMEMIOC_MAP, (unsigned long)((uintptr_t)param)); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl(MAP) failed: %d\n", errno); + ret = -ENOMEM; + goto free_rammem; + } + + if (!check_mem(param->ptr, ESP_HIMEM_BLKSZ, i)) + { + printf("Error in block %d\n", i / ESP_HIMEM_BLKSZ); + ret = -ENOMEM; + goto free_rammem; + } + + ret = ioctl(fd, HIMEMIOC_UNMAP, (unsigned long)((uintptr_t)param)); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl(UNMAP) failed: %d\n", errno); + ret = -ENOMEM; + goto free_rammem; + } + } + + /* Free allocated memory */ + +free_rammem: + ret = ioctl(fd, HIMEMIOC_FREE_MAP_RANGE, + (unsigned long)((uintptr_t)param)); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl(FREE_MAP_RANGE) failed: %d\n", errno); + } + +free_memaddr: + ret = ioctl(fd, HIMEMIOC_FREE_BLOCKS, (unsigned long)((uintptr_t)param)); + if (ret < 0) + { + fprintf(stderr, "ERROR: ioctl(FREE_BLOCKS) failed: %d\n", errno); + } + + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * esp32_himem_main + ****************************************************************************/ + +int main(int argc, FAR char *argv[]) +{ + struct esp_himem_par param; + int ret; + int fd; + + fd = open("/dev/himem", O_RDONLY); + if (fd < 0) + { + printf("Failed to open /dev/himem, error = %d!\n", errno); + return -ENODEV; + } + + ret = ioctl(fd, HIMEMIOC_GET_PHYS_SIZE, ¶m); + if (ret < 0) + { + printf("Failed to run ioctl HIMEMIOC_GET_PHYS_SIZE, error = %d!\n", + errno); + close(fd); + return -ENOMEM; + } + + ret = ioctl(fd, HIMEMIOC_GET_FREE_SIZE, ¶m); + if (ret < 0) + { + printf("Failed to run ioctl HIMEMIOC_GET_FREE_SIZE, error = %d!\n", + errno); + close(fd); + return -ENOMEM; + } + + printf("Himem has %dKiB of memory, %dKiB of which is free.\ + \nTesting the free memory...\n", (int) param.memcnt / 1024, + (int) param.memfree / 1024); + + test_region(fd, ¶m); + printf("Done!\n"); +} +