ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ESP-IDF 메모리 - Flash (vscode)
    소프트웨어 2023. 3. 25. 22:40

    #esp32 윈도우 vscode 환경
    #선행(필수) ESP-IDF 윈도우 개발환경 세팅(vscode)
    #선행(필수) ESP-IDF 외부 폴더에서 예제 파일 실행(vscode)


    1) Flash 메모리

    ESP32는 SRAM, ROM, Flash 메모리 세 종류를 가지고 있습니다. ESP-IDF 메모리 - SRAM (vscode)
    그 중 Flash메모리는 전원이 꺼졌을 때도 데이터가 저장되는 비휘발성 메모리로 ESP32는 보통 4mb의 Flash 메모리를 가지고 있습니다.

    *8mb, 16mb등 커스텀 제품도 있습니다.

    사용 예시로, 스마트팜의 LED밝기 , 펌프 작동 주기 등 유저에게 입력 받은 세팅 값을
    Flash 메모리에 저장하고 ESP32가 리부팅시 최종 설정을 그대로 불러올 수 있습니다.
     
     

    2) 수명

    Flash 메모리는 수명이 짧습니다.
    10,000~100,000cycle 의 쓰기 수명을 갖습니다.

    *데이터를 읽기는 수명에 영향을 주지 않습니다.

    Flash 메모리가 비휘발성인 이유는 전원이 꺼져도,
    Floating Gate를 막고 있는 절연층이 전자가 못 빠져 나가게 막고 있기 때문입니다.
    반대로 절연층을 넘어 Floating Gate로 전자를 이동 시키려면 10~20V의 높은 전압이 필요합니다.
    전자가 이동할 때 마다 절연층이 조금씩 손상을 입는데 아예 못 쓰게 될 때 까지가 약100,000cycle 입니다.

    출처 : https://www.curtisswrightds.com

    ESP-IDF의 wear leveling API를 이용하면 수명을 연장할 수 있습니다.
    wear leveling API를 활용하면,
    'Flash 메모리에 쓰기' 명령 횟수와 쓰기한 메모리 블록의 위치 등을 기록할 수 있습니다.
    partitioning 을 통해 집중적으로 사용되는 메모리 블록이 적도록 관리할 수 있습니다.
    -> 포스팅 예정

     
     
    3) NVS (Non-Volatile Storage)
    Flash memory 에 읽기/쓰기 API인 NVS를 활용해 보겠습니다.
    NVS로 읽고 쓰기한 데이터는 아래와 같은 namespace key/value 구조를 갖습니다.

     데이터의 위치는 크게 namespace로 분류되고, 그 안에서 key/value 값을 갖습니다.
    - 서로 다른 namespace안의 key값은 이름이 같아도 됩니다.
    - 하나의 namespace 안에 각기 다른 자료형이 들어갈 수 있습니다.

    *저장 가능한 데이터 타입은 int8_t~uint32_t , float, double, bool , char* , blob

     
     
    아래 예제 코드들은, 프로그램 실행 후
    읽기 시도 -> 없으면 데이터 없음 출력, 있으면 출력 -> 데이터 쓰기
    이렇게 진행 됩니다.
     
    4-1) 예제 코드 - int

    #include <stdio.h>
    #include "nvs_flash.h"
    #include "nvs.h"
    
    #define MY_NVS_NAMESPACE "my_namespace1"
    #define MY_INT_KEY "my_key1"
    
    void app_main()
    {
        // Initialize NVS
        // ESP_ERR_NVS_NO_FREE_PAGES : NVS 공간이 꽉 찬 경우
        // ESP_ERR_NVS_NEW_VERSION_FOUND : ESP32의 이전 어플리케이션에서 저장된 데이터가 있는 경우
        esp_err_t err = nvs_flash_init(); // NVS 초기화, 에러 없으면 'ESP_OK' 반환. 에러 발생시 에러 유형 반환.esp_err_t는 int32_t와 동일한 자료형
        if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
            ESP_ERROR_CHECK(nvs_flash_erase()); // NVS 포맷, 포맷 실패시 에러 출력
            err = nvs_flash_init(); // NVS 다시 초기화.
        }
        ESP_ERROR_CHECK(err); // NVS 초기화 실패시 에러 출력
    
        // Open NVS
        nvs_handle_t nvs_handle; // NVS 핸들 선업
        err = nvs_open(MY_NVS_NAMESPACE, NVS_READWRITE, &nvs_handle); // nvs_handle이 "my_namespace1"의 읽기/쓰기 권한 획득
        if (err != ESP_OK) { // 실패시
            printf("Error (%s) opening NVS handle\n", esp_err_to_name(err));
            return;
        }
    
        // Try to restore integer value from NVS
        int my_int_value = 0;
        err = nvs_get_i32(nvs_handle, MY_INT_KEY, &my_int_value); // my_key1값을 32비트 메모리 크기 만큼 불러와 my_int_value에 대입. 
        if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) { // 에러 발생시,
            printf("Error (%s) reading value from NVS\n", esp_err_to_name(err)); // 에러 유형 출력
        }
    
        if (err == ESP_ERR_NVS_NOT_FOUND) { // "my_namespace1"에 "my_key1" 키 값이 없다면,
            printf("There is no data stored.\n");
        } else {
            printf("Retrieved value: %d\n", my_int_value); // 값이 있다면 출력
        }
    
        // Store value in NVS
        my_int_value = 35;
        err = nvs_set_i32(nvs_handle, MY_INT_KEY, my_int_value);  // my_key1에 32비트 메모리 크기를 확보하고 35 입력
        if (err != ESP_OK) { // 실패시
            printf("Error (%s) storing value in NVS\n", esp_err_to_name(err)); // 에러 유형 출력
        }
    
        // Close NVS
        nvs_close(nvs_handle);
    }

     
     

    4-2) 예제 코드 - String

    #include <stdio.h>
    #include "nvs_flash.h"
    #include "nvs.h"
    
    #define MY_NVS_NAMESPACE "my_namespace"
    #define MY_STRING_KEY "my_string_key"
    
    void app_main()
    {
        // Initialize NVS
        esp_err_t err = nvs_flash_init();
        if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
            ESP_ERROR_CHECK(nvs_flash_erase());
            err = nvs_flash_init();
        }
        ESP_ERROR_CHECK(err);
    
        // Open NVS
        nvs_handle_t nvs_handle;
        err = nvs_open(MY_NVS_NAMESPACE, NVS_READWRITE, &nvs_handle);
        if (err != ESP_OK) {
            printf("Error (%s) opening NVS handle\n", esp_err_to_name(err));
            return;
        }
    
        // Try to retrieve the string value from NVS
        size_t required_size;
        err = nvs_get_str(nvs_handle, MY_STRING_KEY, NULL, &required_size);
        if (err == ESP_ERR_NVS_NOT_FOUND) {
            printf("There is no data stored.\n");
        } else if (err != ESP_OK) {
            printf("Error (%s) getting the size of string value from NVS\n", esp_err_to_name(err));
        } else {
            char *retrieved_string_value = malloc(required_size);
            err = nvs_get_str(nvs_handle, MY_STRING_KEY, retrieved_string_value, &required_size);
            if (err != ESP_OK) {
                printf("Error (%s) retrieving string value from NVS\n", esp_err_to_name(err));
            } else {
                printf("Retrieved string value: %s\n", retrieved_string_value);
            }
            free(retrieved_string_value);
        }
    
        // Perform other program tasks and operations
    
        // Store a string value in NVS while the program is running
        const char *my_string_value = "Hello, NVS!";
        err = nvs_set_str(nvs_handle, MY_STRING_KEY, my_string_value);
        if (err != ESP_OK) {
            printf("Error (%s) storing string value in NVS\n", esp_err_to_name(err));
        }
        nvs_commit(nvs_handle);
    
        // Close NVS
        nvs_close(nvs_handle);
    }


    4-3) 예제 코드 - Array
     
    4-4) 예제 코드 - Blob
     
     
    *공부하는 입장에서 정리중인 자료들 입니다.


    ESP-IDF 윈도우 개발환경 세팅 (VSCODE)
    ESP-IDF 외부 폴더에서 예제 파일 실행 (VSCODE)
    ESP-IDF GPIO 인풋, 아웃풋 (VSCODE)
    ESP-IDF 인터럽트 (VSCODE)

    ESP-IDF 디바운싱 (esp32, vscode)
    ESP-IDF .c .h 참조 cMakeLists (vscode)

    ESP-IDF components 참조 cMakeLists (vscode)
    ESP-IDF LCD 출력(vscode)
    ESP-IDF 메모리 - Flash (vscode)
    ESP-IDF 메모리 - SRAM (vscode)
    ESP-IDF FreeRTOS - buffer (vscode)

    ESP-IDF 쿨링팬 FG센서, PWM제어(vscode)

     



    <포스트 예정>

    *ESP-IDF 메모리 - ROM
    *LCD - 메뉴 만들고 버튼으로 메뉴 이동(터미널로 작업)
    *LCD - 2차원 배열로 메뉴 진입, 뒤로가기(터미널로 작업)
    *LCD - 메뉴 만든 것 LCD 출력
    *LCD - 메뉴 UI 제작.  연두색 블럭은 메인 메뉴 회색 블럭은 서브 메뉴
            (1.팬  1-1.ON  1-2.OFF  1-3.BACK   2.LED  2-1.밝기 약  2-2.밝기 중  2-3.밝기 강   2-4.BACK   3.빛 밝기 출력 lux(+PPFD 변환)
    *Easy EDA툴 활용하여 커스텀 ESP32 보드 제작
    *LCD - LCD , 팬 , 펌프 ,  ESP32 연결 가능한 PCB 제작 주문.
    *LCD - 간이 스마트팜 제작
    *ESP32 JTAG 디버그
    *FreeRTOS
    *FreeRTOS - QUEUE
    *FreeRTOS - timer
    *FreeRTOS - Semaphore , mutex
    *FreeRTOS - event group , notification
    *ESP-IDF I2C SPI UART
    *ESP-IDF wifi
    *ESP-IDF MQTT
    *ESP-IDF Server (XAMPP 로컬 서버 연결)

    *DIY 컨테이너 / 유리온실 스마트팜 제작

     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
Designed by PixelSpace