Esp32字符串长度限制

Esp32 string length limit

我发现在 esp32 上运行的应用程序中的行的长度是有限的。 下面是一个生成字符串的应用程序:

main :
  loop ::= 2459
  text  := ""
  stamp := "1234567890"
  loop.repeat :
    text += stamp
  print ("$text.size")  

如果loop ::= 2458一切正常:

micrcx@micrcx-desktop:~/toit_apps/Hsm3/tests$ toit run test_str.toit
2021-06-02T17:03:43.237309Z: <process initiated>
24580
2021-06-02T17:03:44.575860Z: <process terminated - exit code: 0>

如果loop ::= 2459,出现内存分配错误:

micrcx@micrcx-desktop:~/toit_apps/Hsm3/tests$ toit run test_str.toit
2021-06-02T17:04:03.507773Z: <process initiated>
2021-06-02T17:04:04.907154Z: <stack trace>
EXCEPTION error. 
ALLOCATION_FAILED
  0: string.+                  <sdk>/core/string.toit:274:5
  1: main.<block>              /home/micrcx/toit_apps/Hsm3/tests/test_str.toit:6:10
  2: SmallInteger_.repeat      <sdk>/core/numbers.toit:209:3
  3: main                      /home/micrcx/toit_apps/Hsm3/tests/test_str.toit:5:8
  4: __entry__.<lambda>        <sdk>/core/entry.toit:46:20
2021-06-02T17:04:04.954257Z: <process terminated - exit code: 1>

所有这些错误当然都不是致命的,知道真实的数字就好了,例如,字符串的最大长度、列表、哈希映射等,以便编写一个应用程序不会下降,因为json文件的大小已经超过了允许的数量。

字符串、列表、映射等没有任何实际大小限制

系统只是尝试为这些对象分配space,并在剩余内存不足时报告错误。显然,这对所有对象施加了基本限制:ESP32 最多有 520K RAM,因此任何数据结构都不能超过该大小。

但是,还有更多的限制在起作用。例如,IRAM 内存具有与 DRAM 不同的属性,并且不太适合普通数据。同样,还有一些内存被系统占用了。

对于某些数据结构,如字符串,内存位于连续区域也很重要。碎片会导致无法再分配更大的字符串的情况,因为所有可用内存都位于字符串不适合的较小空洞中。

请注意,使用 + 构建字符串还意味着始终存在前一个字符串的副本,这使程序所需的 space 翻倍。

这是一个示例,表明字符串从根本上不限于 ~25K:

main :
  loop ::= 4500
  stamp := "1234567890"
  text := stamp * loop
  print "$text.size"

字符串上的 * 运算符预先分配所需的大小,因此不需要任何其他副本(如在循环中)。

使用 Arduino ESP32 webserver library 我意识到,当我尝试打印构成网页的 HTML 字符串时,我收到以下错误,即使 520K RAM 是相当多的 RAM,而且我有 173K 的空闲堆:

    String WEBPAGE = "lots of chars"
    Serial.println(WEBPAGE);
    Serial.printf("Free heap: %u\n", ESP.getFreeHeap());

我有控制台

    E (49837) uart: uart_write_bytes(1159): buffer null
    Free heap: 173831

我发现原因是字符串 WEBPAGE 太大(大约 50k 个字符),使用较小的字符串则不会发生错误。 所以下面的函数也不起作用,而是发送和空字符串,我在浏览器上看到一个白色的空白页面。

server.send(200, "text/html", WEBPAGE);

我认为在 ESP32 上使用字符串是一个很大的限制

更多详情here