mirror of
https://gitee.com/beecue/fastbee.git
synced 2025-12-19 17:35:54 +08:00
添加智能灯固件代码
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
# The following lines of boilerplate have to be in your project's CMakeLists
|
||||
# in this exact order for cmake to work correctly
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
project(nvs-rw-blob)
|
||||
@@ -0,0 +1,9 @@
|
||||
#
|
||||
# This is a project Makefile. It is assumed the directory this Makefile resides in is a
|
||||
# project subdirectory.
|
||||
#
|
||||
|
||||
PROJECT_NAME := nvs-rw-blob
|
||||
|
||||
include $(IDF_PATH)/make/project.mk
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# Non-Volatile Storage (NVS) Read and Write Example
|
||||
|
||||
(See the README.md file in the upper level 'examples' directory for more information about examples.)
|
||||
|
||||
This example demonstrates how to read and write a single integer value and a blob (binary large object) using NVS to preserve them between ESP32 module restarts.
|
||||
|
||||
* value - tracks number of ESP32 module soft and hard restarts.
|
||||
* blob - contains a table with module run times. The table is read from NVS to dynamically allocated RAM. New run time is added to the table on each manually triggered soft restart and written back to NVS. Triggering is done by pulling down GPIO0.
|
||||
|
||||
Example also shows how to implement diagnostics if read / write operation was successful.
|
||||
|
||||
Detailed functional description of NVS and API is provided in [documentation](https://docs.espressif.com/projects/esp-idf/en/latest/api-reference/storage/nvs_flash.html).
|
||||
|
||||
If not done already, consider checking simpler example *storage/nvs_rw_value*, that has been used as a starting point for preparing this one.
|
||||
|
||||
## How to use example
|
||||
|
||||
### Hardware required
|
||||
|
||||
This example can be run on most common development boards which have an active button connected to GPIO0. On most boards, this button is labeled as "Boot". When pressed, the button connects GPIO0 to ground.
|
||||
|
||||
### Build and flash
|
||||
|
||||
Build the project and flash it to the board, then run monitor tool to view serial output:
|
||||
|
||||
```
|
||||
idf.py -p PORT flash monitor
|
||||
```
|
||||
|
||||
(To exit the serial monitor, type ``Ctrl-]``.)
|
||||
|
||||
See the Getting Started Guide for full steps to configure and use ESP-IDF to build projects.
|
||||
|
||||
## Example Output
|
||||
|
||||
First run:
|
||||
```
|
||||
Restart counter = 0
|
||||
Run time:
|
||||
Nothing saved yet!
|
||||
```
|
||||
|
||||
At this point, press "Boot" button and hold it for a second. The board will perform software restart, printing:
|
||||
|
||||
```
|
||||
Restarting...
|
||||
```
|
||||
|
||||
After booting again, restart counter and run time array will be printed:
|
||||
|
||||
```
|
||||
Restart counter = 1
|
||||
Run time:
|
||||
1: 5110
|
||||
```
|
||||
|
||||
After pressing "Boot" once more:
|
||||
|
||||
```
|
||||
Restart counter = 2
|
||||
Run time:
|
||||
1: 5110
|
||||
2: 5860
|
||||
```
|
||||
|
||||
To reset the counter and run time array, erase the contents of flash memory using `idf.py erase_flash`, then upload the program again as described above.
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
idf_component_register(SRCS "nvs_blob_example_main.c"
|
||||
INCLUDE_DIRS ".")
|
||||
@@ -0,0 +1,5 @@
|
||||
#
|
||||
# "main" pseudo-component makefile.
|
||||
#
|
||||
# (Uses default behaviour of compiling all source files in directory, adding 'include' to include path.)
|
||||
|
||||
@@ -0,0 +1,189 @@
|
||||
/* Non-Volatile Storage (NVS) Read and Write a Blob - Example
|
||||
|
||||
For other examples please check:
|
||||
https://github.com/espressif/esp-idf/tree/master/examples
|
||||
|
||||
This example code is in the Public Domain (or CC0 licensed, at your option.)
|
||||
|
||||
Unless required by applicable law or agreed to in writing, this
|
||||
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
||||
CONDITIONS OF ANY KIND, either express or implied.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "esp_system.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "nvs.h"
|
||||
#include "driver/gpio.h"
|
||||
|
||||
#define STORAGE_NAMESPACE "storage"
|
||||
|
||||
/* Save the number of module restarts in NVS
|
||||
by first reading and then incrementing
|
||||
the number that has been saved previously.
|
||||
Return an error if anything goes wrong
|
||||
during this process.
|
||||
*/
|
||||
esp_err_t save_restart_counter(void)
|
||||
{
|
||||
nvs_handle_t my_handle;
|
||||
esp_err_t err;
|
||||
|
||||
// Open
|
||||
err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// Read
|
||||
int32_t restart_counter = 0; // value will default to 0, if not set yet in NVS
|
||||
err = nvs_get_i32(my_handle, "restart_conter", &restart_counter);
|
||||
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;
|
||||
|
||||
// Write
|
||||
restart_counter++;
|
||||
err = nvs_set_i32(my_handle, "restart_conter", restart_counter);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// Commit written value.
|
||||
// After setting any values, nvs_commit() must be called to ensure changes are written
|
||||
// to flash storage. Implementations may write to storage at other times,
|
||||
// but this is not guaranteed.
|
||||
err = nvs_commit(my_handle);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// Close
|
||||
nvs_close(my_handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Save new run time value in NVS
|
||||
by first reading a table of previously saved values
|
||||
and then adding the new value at the end of the table.
|
||||
Return an error if anything goes wrong
|
||||
during this process.
|
||||
*/
|
||||
esp_err_t save_run_time(void)
|
||||
{
|
||||
nvs_handle_t my_handle;
|
||||
esp_err_t err;
|
||||
|
||||
// Open
|
||||
err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// Read the size of memory space required for blob
|
||||
size_t required_size = 0; // value will default to 0, if not set yet in NVS
|
||||
err = nvs_get_blob(my_handle, "run_time", NULL, &required_size);
|
||||
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;
|
||||
|
||||
// Read previously saved blob if available
|
||||
uint32_t* run_time = malloc(required_size + sizeof(uint32_t));
|
||||
if (required_size > 0) {
|
||||
err = nvs_get_blob(my_handle, "run_time", run_time, &required_size);
|
||||
if (err != ESP_OK) {
|
||||
free(run_time);
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
// Write value including previously saved blob if available
|
||||
required_size += sizeof(uint32_t);
|
||||
run_time[required_size / sizeof(uint32_t) - 1] = xTaskGetTickCount() * portTICK_PERIOD_MS;
|
||||
err = nvs_set_blob(my_handle, "run_time", run_time, required_size);
|
||||
free(run_time);
|
||||
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// Commit
|
||||
err = nvs_commit(my_handle);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// Close
|
||||
nvs_close(my_handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/* Read from NVS and print restart counter
|
||||
and the table with run times.
|
||||
Return an error if anything goes wrong
|
||||
during this process.
|
||||
*/
|
||||
esp_err_t print_what_saved(void)
|
||||
{
|
||||
nvs_handle_t my_handle;
|
||||
esp_err_t err;
|
||||
|
||||
// Open
|
||||
err = nvs_open(STORAGE_NAMESPACE, NVS_READWRITE, &my_handle);
|
||||
if (err != ESP_OK) return err;
|
||||
|
||||
// Read restart counter
|
||||
int32_t restart_counter = 0; // value will default to 0, if not set yet in NVS
|
||||
err = nvs_get_i32(my_handle, "restart_conter", &restart_counter);
|
||||
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;
|
||||
printf("Restart counter = %d\n", restart_counter);
|
||||
|
||||
// Read run time blob
|
||||
size_t required_size = 0; // value will default to 0, if not set yet in NVS
|
||||
// obtain required memory space to store blob being read from NVS
|
||||
err = nvs_get_blob(my_handle, "run_time", NULL, &required_size);
|
||||
if (err != ESP_OK && err != ESP_ERR_NVS_NOT_FOUND) return err;
|
||||
printf("Run time:\n");
|
||||
if (required_size == 0) {
|
||||
printf("Nothing saved yet!\n");
|
||||
} else {
|
||||
uint32_t* run_time = malloc(required_size);
|
||||
err = nvs_get_blob(my_handle, "run_time", run_time, &required_size);
|
||||
if (err != ESP_OK) {
|
||||
free(run_time);
|
||||
return err;
|
||||
}
|
||||
for (int i = 0; i < required_size / sizeof(uint32_t); i++) {
|
||||
printf("%d: %d\n", i + 1, run_time[i]);
|
||||
}
|
||||
free(run_time);
|
||||
}
|
||||
|
||||
// Close
|
||||
nvs_close(my_handle);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
esp_err_t err = nvs_flash_init();
|
||||
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
|
||||
// NVS partition was truncated and needs to be erased
|
||||
// Retry nvs_flash_init
|
||||
ESP_ERROR_CHECK(nvs_flash_erase());
|
||||
err = nvs_flash_init();
|
||||
}
|
||||
ESP_ERROR_CHECK( err );
|
||||
|
||||
err = print_what_saved();
|
||||
if (err != ESP_OK) printf("Error (%s) reading data from NVS!\n", esp_err_to_name(err));
|
||||
|
||||
err = save_restart_counter();
|
||||
if (err != ESP_OK) printf("Error (%s) saving restart counter to NVS!\n", esp_err_to_name(err));
|
||||
|
||||
gpio_pad_select_gpio(GPIO_NUM_0);
|
||||
gpio_set_direction(GPIO_NUM_0, GPIO_MODE_DEF_INPUT);
|
||||
|
||||
/* Read the status of GPIO0. If GPIO0 is LOW for longer than 1000 ms,
|
||||
then save module's run time and restart it
|
||||
*/
|
||||
while (1) {
|
||||
if (gpio_get_level(GPIO_NUM_0) == 0) {
|
||||
vTaskDelay(1000 / portTICK_PERIOD_MS);
|
||||
if(gpio_get_level(GPIO_NUM_0) == 0) {
|
||||
err = save_run_time();
|
||||
if (err != ESP_OK) printf("Error (%s) saving run time blob to NVS!\n", esp_err_to_name(err));
|
||||
printf("Restarting...\n");
|
||||
fflush(stdout);
|
||||
esp_restart();
|
||||
}
|
||||
}
|
||||
vTaskDelay(200 / portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
from tiny_test_fw import Utility
|
||||
import random
|
||||
import re
|
||||
import time
|
||||
import ttfw_idf
|
||||
|
||||
|
||||
@ttfw_idf.idf_example_test(env_tag='Example_GENERIC')
|
||||
def test_examples_nvs_rw_blob(env, extra_data):
|
||||
|
||||
dut = env.get_dut('nvs_rw_blob', 'examples/storage/nvs_rw_blob')
|
||||
dut.start_app()
|
||||
|
||||
def expect_start_msg(index):
|
||||
dut.expect_all('Restart counter = {}'.format(index),
|
||||
'Run time:',
|
||||
timeout=10)
|
||||
|
||||
expect_start_msg(0)
|
||||
dut.expect('Nothing saved yet!', timeout=5)
|
||||
|
||||
nvs_store = []
|
||||
for i in range(1, 10):
|
||||
time.sleep(random.uniform(0.1, 2)) # in order to randomize the runtimes stored in NVS
|
||||
try:
|
||||
# Pulling GPIO0 low using DTR
|
||||
dut.port_inst.setDTR(True)
|
||||
dut.expect('Restarting...', timeout=5) # the application waits for a second
|
||||
finally:
|
||||
dut.port_inst.setDTR(False)
|
||||
|
||||
expect_start_msg(i)
|
||||
|
||||
dut.expect_all(*nvs_store, timeout=10)
|
||||
Utility.console_log('Received: {}'.format(', '.join(nvs_store)))
|
||||
|
||||
new_runtime = dut.expect(re.compile(r'{}: (\d+)'.format(i)), timeout=10)[0]
|
||||
nvs_store.append('{}: {}'.format(i, new_runtime))
|
||||
Utility.console_log('loop {} has finished with runtime {}'.format(i, new_runtime))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_examples_nvs_rw_blob()
|
||||
Reference in New Issue
Block a user