ESP32 在Platform Arduino平台驱动外部PSAM,进行内存管理

一,基本介绍

        本文中主要介绍ESP32、ESP32S3系列单片机,基于Vscode Platform Arduino和Arduino框架下如何使用外部PSAM,以及必要的API调用函数进行内存分配和管理。

        使用前提是开发板有外部PSRAM。

二,平台配置

2.1 Arduino平台

2.2 Platform IO

; PlatformIO Project Configuration File
;
;   Build options: build flags, source filter
;   Upload options: custom upload port, speed and extra flags
;   Library options: dependencies, extra library storages
;   Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html

[env:esp32-s3-devkitc-1]
platform = espressif32
board = esp32-s3-devkitc-1
framework = arduino
;串口波特率
monitor_speed = 115200
;串口下载速度
upload_speed = 921600
;CPU的运行速度240Mhz
board_build.f_cpu = 240000000
;根据自己的开发板,选择分区表
board_build.partitions = default_16MB.csv
;外部PSRAM使用qio或者opi
board_build.arduino.memory_type = qio_opi
;通过该宏定义,启动外部的PSRAM
build_flags = -DBOARD_HAS_PSRAM
;外部Flash的大小
board_upload.flash_size = 16MB

三,内存测试代码

测试单片机为ESP32S3N16R8,具有16MB Flash 和8MB PSAM


#include <Arduino.h>
#include <esp_heap_caps.h>


void setup() {
  Serial.begin(115200);
  //查看ESP32堆的总共大小
  Serial.printf("ESP32 total Heap size :%d bytes\n",ESP.getHeapSize());
  //查看ESP32堆的可用大小
  Serial.printf("ESP32 free  Heap size :%d bytes\n",ESP.getFreeHeap());
  //查看ESP32的Flash的大小
  Serial.printf("Flash size: %d bytes\n", ESP.getFlashChipSize());

  //查看ESP32的内部和外部RAM的总共大小
  Serial.printf("Deafult total size: %d bytes\n", heap_caps_get_total_size(MALLOC_CAP_DEFAULT));
  //查看ESP32的内部和外部RAM的可用大小
  Serial.printf("Deafult free size: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_DEFAULT));

  //查看ESP32的内部RAM总共大小
  Serial.printf("Internal total size: %d bytes\n", heap_caps_get_total_size(MALLOC_CAP_INTERNAL));
  //查看ESP32的内部RAM可用大小
  Serial.printf("Internal free size: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));

  //查看ESP32的外部RAM的可用大小
  Serial.printf("PSRAM total size: %d bytes\n", heap_caps_get_total_size(MALLOC_CAP_SPIRAM));
  //查看ESP32的外部RAM的可用大小
  Serial.printf("PSRAM free size: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
}

void loop() {
  delay(10); 
}

串口输出结果

四,内存申请与释放代码

测试单片机为ESP32S3N16R8

 //从芯片内部申请PSARAM,大小为1000字节,数据类型为char型
 char* str1=(char *)heap_caps_malloc(1000,MALLOC_CAP_INTERNAL);  

 //从芯片外部申请PSARAM,大小为1000字节,数据类型为char型
 char* str1=(char *)heap_caps_malloc(1000,MALLOC_CAP_SPIRAM);  

 //内存释放
 heap_caps_free(str); 

#include <Arduino.h>
#include <esp_heap_caps.h>


void setup() {
  Serial.begin(115200);

  Serial.printf("内部RAM可使用大小: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
  char* str=(char *)heap_caps_malloc(1000,MALLOC_CAP_INTERNAL);
  sprintf(str,"hello world! I am a handsome boy!");
  Serial.println(str);
  Serial.printf("内部RAM可使用大小: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));

  Serial.printf("外部RAM可使用大小: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
  char* str1=(char *)heap_caps_malloc(1000,MALLOC_CAP_SPIRAM);
  sprintf(str1,"hello world! I am a pretty girl!");
  Serial.println(str1);
  Serial.printf("外部RAM可使用大小: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));

  Serial.println("释放内存!");
  heap_caps_free(str); 
  heap_caps_free(str1); 
  Serial.printf("内部RAM可使用大小: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
  Serial.printf("外部RAM可使用大小: %d bytes\n", heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
  
}

void loop() {

  delay(10); 
}

串口输出结果

<think>嗯,用户想要找关于ESP32-S3 N16R8模块在FreeRTOS下的使用指南、示例代码和配置方法。首先,我需要确认ESP32-S3和N16R8模块的基本信息。ESP32-S3是乐鑫推出的双核Xtensa LX7 MCU,支持Wi-Fi和蓝牙,而N16R8可能指的是模块的型号,可能带有16MB Flash和8MB PSRAM?这个需要核实一下。 接下来,用户提到了FreeRTOS,说明他们需要在ESP32-S3上使用实时操作系统。乐鑫的ESP-IDF框架默认使用FreeRTOS,所以可能需要从ESP-IDF入手。用户可能已经知道一些基本的环境搭建,但可能需要具体的配置步骤和示例代码。 然后,用户提供的引用中提到了PlatformIO和ESP-IDF的环境搭建,以及GPIO矩阵的配置。这些信息应该整合进去,特别是关于UART引脚配置的部分,因为引用3提到ESP32-S3的USART引脚是可配置的,这可能对用户的开发有帮助。 用户可能需要知道如何配置FreeRTOS的任务、队列、信号量等,以及如何利用双核特性。示例代码部分应该包括创建任务、使用GPIO、UART通信等基础内容。同时,需要确保代码符合ESP-IDF的最新版本,因为乐鑫的SDK更新较快。 另外,用户可能对内存配置感兴趣,特别是N16R8模块的16MB Flash和8MB PSRAM的使用方法。需要解释如何在sdkconfig中调整内存分配,比如PSRAM的使用配置。 还要考虑常见问题,比如如何优化FreeRTOS的任务堆栈大小,如何监控任务状态,以及如何解决外设驱动中的问题,比如UART的引脚映射。引用3中提到GPIO矩阵,这部分需要详细说明如何灵活配置UART引脚,避免用户在使用默认引脚时遇到冲突。 最后,生成相关问题时要覆盖环境搭建、多任务处理、外设驱动、内存优化和调试技巧等方面,确保用户能全面了解ESP32-S3在FreeRTOS下的开发流程。</think>### ESP32-S3 N16R8 FreeRTOS使用指南 #### 一、开发环境搭建 1. **PlatformIO配置** 推荐使用VSCode+PlatformIO组合开发: ```ini [env:esp32s3] platform = espressif32 board = esp32s3-devkitc-1 framework = espidf monitor_speed = 115200 ``` 通过`board_build.flash_size`参数可配置16MB Flash支持[^1] 2. **ESP-IDF环境配置** ```bash git clone --recursive https://github.com/espressif/esp-idf.git cd esp-idf ./install.sh source export.sh ``` #### 二、FreeRTOS核心配置 1. **任务创建示例** ```c void my_task(void *pvParameters) { while(1) { printf("Core %d running\n", xPortGetCoreID()); vTaskDelay(1000 / portTICK_PERIOD_MS); } } void app_main() { xTaskCreatePinnedToCore(my_task, "Task1", 4096, NULL, 5, NULL, 0); xTaskCreatePinnedToCore(my_task, "Task2", 4096, NULL, 5, NULL, 1); } ``` 2. **双核调度配置** 在`sdkconfig`中设置: ``` CONFIG_FREERTOS_UNICORE=n CONFIG_FREERTOS_HZ=1000 ``` #### 三、外设驱动配置 1. **GPIO矩阵配置(以UART为例)** ```c #define TX_PIN 17 #define RX_PIN 18 uart_config_t uart_config = { .baud_rate = 115200, .data_bits = UART_DATA_8_BITS, .parity = UART_PARITY_DISABLE, .stop_bits = UART_STOP_BITS_1, .flow_ctrl = UART_HW_FLOWCTRL_DISABLE }; uart_param_config(UART_NUM_1, &uart_config); uart_set_pin(UART_NUM_1, TX_PIN, RX_PIN, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE); ``` 2. **PSRAM配置** 在`sdkconfig`中启用: ``` CONFIG_ESP32S3_SPIRAM_SUPPORT=y CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_SIZE=8388608 # 8MB ``` #### 四、典型应用场景 1. **WiFi+BLE双模通信** ```c void wifi_init() { ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); } void bluetooth_init() { esp_bt_controller_config_t bt_cfg = BT_CONTROLLER_INIT_CONFIG_DEFAULT(); esp_bt_controller_init(&bt_cfg); } ``` #### 五、调试技巧 1. **FreeRTOS状态监控** ```c void print_task_info() { char buffer[1024]; vTaskList(buffer); printf("Task Name\tState\tPriority\tStack\tCore\n"); printf("%s\n", buffer); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值