psram: add configuration macros to move workaround libc functions to flash

Workaround libc can be moved to flash thanks to KConfig macros.
However, the following functions: `itoa`, `memcmp`, `memcpy`, `memset`, `strcat`, `strcmp`, and `strlen` are always kept it in IRAM.
This commit is contained in:
Omar Chebib 2021-06-08 18:44:01 +08:00
parent e31049eacc
commit da731a7eeb
3 changed files with 288 additions and 122 deletions

View File

@ -169,8 +169,129 @@ menu "ESP32-specific"
config SPIRAM_WORKAROUND_NEED_VOLATILE_SPINLOCK
bool
default "y" if SPIRAM_CACHE_WORKAROUND_STRATEGY_DUPLDST
endmenu
menu "SPIRAM workaround libraries placement"
visible if SPIRAM_CACHE_WORKAROUND
config SPIRAM_CACHE_LIBJMP_IN_IRAM
bool "Put libc's jump related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: longjmp and setjmp.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBMATH_IN_IRAM
bool "Put libc's math related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: abs, div, labs, ldiv, quorem, fpclassify,
and nan.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBNUMPARSER_IN_IRAM
bool "Put libc's number parsing related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: utoa, itoa, atoi, atol, strtol, and strtoul.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBIO_IN_IRAM
bool "Put libc's I/O related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: wcrtomb, fvwrite, wbuf, wsetup, fputwc, wctomb_r,
ungetc, makebuf, fflush, refill, and sccl.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBTIME_IN_IRAM
bool "Put libc's time related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: asctime, asctime_r, ctime, ctime_r, lcltime, lcltime_r,
gmtime, gmtime_r, strftime, mktime, tzset_r, tzset, time, gettzinfo, systimes, month_lengths,
timelocal, tzvars, tzlock, tzcalc_limits, and strptime.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBCHAR_IN_IRAM
bool "Put libc's characters related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: ctype_, toupper, tolower, toascii, strupr, bzero,
isalnum, isalpha, isascii, isblank, iscntrl, isdigit, isgraph, islower, isprint, ispunct,
isspace, and isupper.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBMEM_IN_IRAM
bool "Put libc's memory related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: memccpy, memchr memmove, and memrchr.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBSTR_IN_IRAM
bool "Put libc's string related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: strcasecmp, strcasestr, strchr, strcoll,
strcpy, strcspn, strdup, strdup_r, strlcat, strlcpy, strlen, strlwr, strncasecmp,
strncat, strncmp, strncpy, strndup, strndup_r, strrchr, strsep, strspn, strstr,
strtok_r, and strupr.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBRAND_IN_IRAM
bool "Put libc's random related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: srand, rand, and rand_r.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBENV_IN_IRAM
bool "Put libc's environment related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: environ, envlock, and getenv_r.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBFILE_IN_IRAM
bool "Put libc's file related functions in IRAM"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: lock, isatty, fclose, open, close, creat, read,
rshift, sbrk, stdio, syssbrk, sysclose, sysopen, creat, sysread, syswrite, impure, fwalk,
and findfp.
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
config SPIRAM_CACHE_LIBMISC_IN_IRAM
bool "Put libc's miscellaneous functions in IRAM, see help"
depends on SPIRAM_CACHE_WORKAROUND
default "y"
help
The functions affected by this option are: raise and system
Putting these function in IRAM will allow them to be called when flash cache is disabled
but it will also reduce the available size of free IRAM for the user application.
endmenu
config SPIRAM_BANKSWITCH_ENABLE

View File

@ -16,132 +16,156 @@ archive:
libc.a
entries:
if SPIRAM_CACHE_WORKAROUND = y:
lib_a-utoa (noflash)
lib_a-longjmp (noflash)
lib_a-setjmp (noflash)
lib_a-abs (noflash)
lib_a-div (noflash)
lib_a-labs (noflash)
lib_a-ldiv (noflash)
lib_a-quorem (noflash)
lib_a-utoa (noflash)
# The following libs are either used in a lot of places or in critical
# code. (such as panic or abort)
# Thus, they shall always be placed in IRAM.
lib_a-itoa (noflash)
lib_a-atoi (noflash)
lib_a-atol (noflash)
lib_a-strtol (noflash)
lib_a-strtoul (noflash)
lib_a-wcrtomb (noflash)
lib_a-fvwrite (noflash)
lib_a-wbuf (noflash)
lib_a-wsetup (noflash)
lib_a-fputwc (noflash)
lib_a-wctomb_r (noflash)
lib_a-ungetc (noflash)
lib_a-makebuf (noflash)
lib_a-fflush (noflash)
lib_a-refill (noflash)
lib_a-s_fpclassify (noflash)
lib_a-asctime (noflash)
lib_a-ctime (noflash)
lib_a-ctime_r (noflash)
lib_a-lcltime (noflash)
lib_a-lcltime_r (noflash)
lib_a-gmtime (noflash)
lib_a-gmtime_r (noflash)
lib_a-strftime (noflash)
lib_a-mktime (noflash)
lib_a-syswrite (noflash)
lib_a-tzset_r (noflash)
lib_a-tzset (noflash)
lib_a-toupper (noflash)
lib_a-tolower (noflash)
lib_a-toascii (noflash)
lib_a-systimes (noflash)
lib_a-time (noflash)
lib_a-gettzinfo (noflash)
lib_a-strupr (noflash)
lib_a-asctime_r (noflash)
lib_a-bzero (noflash)
lib_a-close (noflash)
lib_a-creat (noflash)
lib_a-environ (noflash)
lib_a-fclose (noflash)
lib_a-isalnum (noflash)
lib_a-isalpha (noflash)
lib_a-isascii (noflash)
lib_a-isblank (noflash)
lib_a-iscntrl (noflash)
lib_a-isdigit (noflash)
lib_a-isgraph (noflash)
lib_a-islower (noflash)
lib_a-isprint (noflash)
lib_a-ispunct (noflash)
lib_a-isspace (noflash)
lib_a-isupper (noflash)
lib_a-memccpy (noflash)
lib_a-memchr (noflash)
lib_a-memcmp (noflash)
lib_a-memcpy (noflash)
lib_a-memmove (noflash)
lib_a-memrchr (noflash)
lib_a-memset (noflash)
lib_a-open (noflash)
lib_a-rand (noflash)
lib_a-rand_r (noflash)
lib_a-read (noflash)
lib_a-rshift (noflash)
lib_a-sbrk (noflash)
lib_a-srand (noflash)
lib_a-strcasecmp (noflash)
lib_a-strcasestr (noflash)
lib_a-strcat (noflash)
lib_a-strchr (noflash)
lib_a-strcmp (noflash)
lib_a-strcoll (noflash)
lib_a-strcpy (noflash)
lib_a-strcspn (noflash)
lib_a-strdup (noflash)
lib_a-strlcat (noflash)
lib_a-strlcpy (noflash)
lib_a-strlen (noflash)
lib_a-strlwr (noflash)
lib_a-strncasecmp (noflash)
lib_a-strncat (noflash)
lib_a-strncmp (noflash)
lib_a-strncpy (noflash)
lib_a-strndup (noflash)
lib_a-strnlen (noflash)
lib_a-strrchr (noflash)
lib_a-strsep (noflash)
lib_a-strspn (noflash)
lib_a-strstr (noflash)
lib_a-strtok_r (noflash)
lib_a-strupr (noflash)
lib_a-stdio (noflash)
lib_a-syssbrk (noflash)
lib_a-sysclose (noflash)
lib_a-sysopen (noflash)
creat (noflash)
lib_a-sysread (noflash)
lib_a-syswrite (noflash)
lib_a-impure (noflash)
lib_a-tzvars (noflash)
lib_a-sf_nan (noflash)
lib_a-tzcalc_limits (noflash)
lib_a-month_lengths (noflash)
lib_a-timelocal (noflash)
lib_a-findfp (noflash)
lock (noflash)
lib_a-getenv_r (noflash)
isatty (noflash)
lib_a-fwalk (noflash)
lib_a-getenv_r (noflash)
lib_a-tzlock (noflash)
lib_a-ctype_ (noflash)
lib_a-sccl (noflash)
lib_a-strptime (noflash)
lib_a-envlock (noflash)
lib_a-raise (noflash)
lib_a-strdup_r (noflash)
lib_a-system (noflash)
lib_a-strndup_r (noflash)
if SPIRAM_CACHE_LIBJMP_IN_IRAM = y:
lib_a-longjmp (noflash)
lib_a-setjmp (noflash)
if SPIRAM_CACHE_LIBMATH_IN_IRAM = y:
lib_a-abs (noflash)
lib_a-div (noflash)
lib_a-labs (noflash)
lib_a-ldiv (noflash)
lib_a-quorem (noflash)
lib_a-s_fpclassify (noflash)
lib_a-sf_nan (noflash)
if SPIRAM_CACHE_LIBNUMPARSER_IN_IRAM = y:
lib_a-utoa (noflash)
lib_a-atoi (noflash)
lib_a-atol (noflash)
lib_a-strtol (noflash)
lib_a-strtoul (noflash)
if SPIRAM_CACHE_LIBIO_IN_IRAM = y:
lib_a-wcrtomb (noflash)
lib_a-fvwrite (noflash)
lib_a-wbuf (noflash)
lib_a-wsetup (noflash)
lib_a-fputwc (noflash)
lib_a-wctomb_r (noflash)
lib_a-ungetc (noflash)
lib_a-makebuf (noflash)
lib_a-fflush (noflash)
lib_a-refill (noflash)
lib_a-sccl (noflash)
if SPIRAM_CACHE_LIBTIME_IN_IRAM = y:
lib_a-asctime (noflash)
lib_a-asctime_r (noflash)
lib_a-ctime (noflash)
lib_a-ctime_r (noflash)
lib_a-lcltime (noflash)
lib_a-lcltime_r (noflash)
lib_a-gmtime (noflash)
lib_a-gmtime_r (noflash)
lib_a-strftime (noflash)
lib_a-mktime (noflash)
lib_a-tzset_r (noflash)
lib_a-tzset (noflash)
lib_a-time (noflash)
lib_a-gettzinfo (noflash)
lib_a-systimes (noflash)
lib_a-month_lengths (noflash)
lib_a-timelocal (noflash)
lib_a-tzvars (noflash)
lib_a-tzlock (noflash)
lib_a-tzcalc_limits (noflash)
lib_a-strptime (noflash)
if SPIRAM_CACHE_LIBCHAR_IN_IRAM = y:
lib_a-ctype_ (noflash)
lib_a-toupper (noflash)
lib_a-tolower (noflash)
lib_a-toascii (noflash)
lib_a-strupr (noflash)
lib_a-bzero (noflash)
lib_a-isalnum (noflash)
lib_a-isalpha (noflash)
lib_a-isascii (noflash)
lib_a-isblank (noflash)
lib_a-iscntrl (noflash)
lib_a-isdigit (noflash)
lib_a-isgraph (noflash)
lib_a-islower (noflash)
lib_a-isprint (noflash)
lib_a-ispunct (noflash)
lib_a-isspace (noflash)
lib_a-isupper (noflash)
if SPIRAM_CACHE_LIBMEM_IN_IRAM = y:
lib_a-memccpy (noflash)
lib_a-memchr (noflash)
lib_a-memmove (noflash)
lib_a-memrchr (noflash)
if SPIRAM_CACHE_LIBSTR_IN_IRAM = y:
lib_a-strcasecmp (noflash)
lib_a-strcasestr (noflash)
lib_a-strchr (noflash)
lib_a-strcoll (noflash)
lib_a-strcpy (noflash)
lib_a-strcspn (noflash)
lib_a-strdup (noflash)
lib_a-strdup_r (noflash)
lib_a-strlcat (noflash)
lib_a-strlcpy (noflash)
lib_a-strlwr (noflash)
lib_a-strncasecmp (noflash)
lib_a-strncat (noflash)
lib_a-strncmp (noflash)
lib_a-strncpy (noflash)
lib_a-strndup (noflash)
lib_a-strndup_r (noflash)
lib_a-strnlen (noflash)
lib_a-strrchr (noflash)
lib_a-strsep (noflash)
lib_a-strspn (noflash)
lib_a-strstr (noflash)
lib_a-strtok_r (noflash)
lib_a-strupr (noflash)
if SPIRAM_CACHE_LIBRAND_IN_IRAM = y:
lib_a-srand (noflash)
lib_a-rand (noflash)
lib_a-rand_r (noflash)
if SPIRAM_CACHE_LIBENV_IN_IRAM = y:
lib_a-environ (noflash)
lib_a-envlock (noflash)
lib_a-getenv_r (noflash)
if SPIRAM_CACHE_LIBFILE_IN_IRAM = y:
lock (noflash)
isatty (noflash)
lib_a-fclose (noflash)
lib_a-open (noflash)
lib_a-close (noflash)
lib_a-creat (noflash)
lib_a-read (noflash)
lib_a-rshift (noflash)
lib_a-sbrk (noflash)
lib_a-stdio (noflash)
lib_a-syssbrk (noflash)
lib_a-sysclose (noflash)
lib_a-sysopen (noflash)
creat (noflash)
lib_a-sysread (noflash)
lib_a-syswrite (noflash)
lib_a-impure (noflash)
lib_a-fwalk (noflash)
lib_a-findfp (noflash)
if SPIRAM_CACHE_LIBMISC_IN_IRAM = y:
lib_a-raise (noflash)
lib_a-system (noflash)

View File

@ -136,6 +136,27 @@ The following options will reduce IRAM usage of some ESP-IDF features:
- Disabling :ref:`CONFIG_SPI_MASTER_ISR_IN_IRAM` prevents spi_master interrupts from being serviced while writing to flash, and may otherwise reduce spi_master performance, but will save some IRAM.
- Setting :ref:`CONFIG_HAL_DEFAULT_ASSERTION_LEVEL` to disable assertion for HAL component will save some IRAM especially for HAL code who calls `HAL_ASSERT` a lot and resides in IRAM.
.. only:: esp32
When compiling for ESP32 revisions older than ECO3 (:ref:`CONFIG_ESP32_REV_MIN`), PSRAM cache bug workaround (:ref:`CONFIG_SPIRAM_CACHE_WORKAROUND`) option is enabled, and the C library functions normally located in ROM are recompiled with the workaround and placed into IRAM instead. For most applications, it is safe to move many of the C library functions into Flash, reclaiming some IRAM. Corresponding options include:
.. list::
- :ref:`CONFIG_SPIRAM_CACHE_LIBJMP_IN_IRAM`: affects the functions ``longjmp`` and ``setjump``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBMATH_IN_IRAM`: affects the functions ``abs``, ``div``, ``labs``, ``ldiv``, ``quorem``, ``fpclassify`` and ``nan``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBNUMPARSER_IN_IRAM`: affects the functions ``utoa``, ``itoa``, ``atoi``, ``atol``, ``strtol``, and ``strtoul``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBIO_IN_IRAM`: affects the functions ``wcrtomb``, ``fvwrite``, ``wbuf``, ``wsetup``, ``fputwc``, ``wctomb_r``, ``ungetc``, ``makebuf``, ``fflush``, ``refill``, and ``sccl``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBTIME_IN_IRAM`: affects the functions ``asctime``, ``asctime_r``, ``ctime``, ``ctime_r``, ``lcltime``, ``lcltime_r``, ``gmtime``, ``gmtime_r``, ``strftime``, ``mktime``, ``tzset_r``, ``tzset``, ``time``, ``gettzinfo``, ``systimes``, ``month_lengths``, ``timelocal``, ``tzvars``, ``tzlock``, ``tzcalc_limits``, and ``strptime``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBCHAR_IN_IRAM`: affects the functions ``ctype_``, ``toupper``, ``tolower``, ``toascii``, ``strupr``, ``bzero``, ``isalnum``, ``isalpha``, ``isascii``, ``isblank``, ``iscntrl``, ``isdigit``, ``isgraph``, ``islower``, ``isprint``, ``ispunct``, ``isspace``, and ``isupper``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBMEM_IN_IRAM`: affects the functions ``memccpy``, ``memchr``, ``memmove``, and ``memrchr``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBSTR_IN_IRAM`: affects the functions ``strcasecmp``, ``strcasestr``, ``strchr``, ``strcoll``, ``strcpy``, ``strcspn``, ``strdup``, ``strdup_r``, ``strlcat``, ``strlcpy``, ``strlen``, ``strlwr``, ``strncasecmp``, ``strncat``, ``strncmp``, ``strncpy``, ``strndup``, ``strndup_r``, ``strrchr``, ``strsep``, ``strspn``, ``strstr``, ``strtok_r, and ``strupr``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBRAND_IN_IRAM`: affects the functions ``srand``, ``rand``, and ``rand_r``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBENV_IN_IRAM`: affects the functions ``environ``, ``envlock``, and ``getenv_r``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBFILE_IN_IRAM`: affects the functions lock``, ``isatty``, ``fclose``, ``open``, ``close``, ``creat``, ``read``, ``rshift``, ``sbrk``, ``stdio``, ``syssbrk``, ``sysclose``, ``sysopen``, ``creat``, ``sysread``, ``syswrite``, ``impure``, ``fwalk``, and ``findfp``.
- :ref:`CONFIG_SPIRAM_CACHE_LIBMISC_IN_IRAM`: affects the functions ``raise`` and ``system``.
The exact amount of IRAM saved will depend on how much C library code is actually used by the application. In addition to these, the following options may be used to move more of the C library code into Flash, however note that this may result in reduced performance. Also take care to not use corresponding C library functions from interrupts which may be called while cache is disabled (allocated with :c:macro:`ESP_INTR_FLAG_IRAM` flag), refer to :ref:`iram-safe-interrupt-handlers` for more details. For these reasons, the functions ``itoa``, ``memcmp``, ``memcpy``, ``memset``, ``strcat``, ``strcmp``, and ``strlen`` are always put in IRAM.
.. note::
Moving frequently-called functions from IRAM to flash may increase their execution time.