Updated IDF, connect to TB.

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2023-05-21 18:43:13 +08:00
parent bc4499b02f
commit dfb86f939c
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
23 changed files with 732 additions and 332 deletions

12
.clang-format Normal file
View File

@ -0,0 +1,12 @@
BasedOnStyle: Google
IndentWidth: 4
AlignConsecutiveMacros: Consecutive
AlignConsecutiveDeclarations: Consecutive
AlignConsecutiveAssignments: Consecutive
AllowShortFunctionsOnASingleLine: None
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: false
AfterStruct: false
SplitEmptyFunction: false
ColumnLimit: 120

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
/assets/certs
/build
/cmake-build-*
/managed_components
/sdkconfig
/sdkconfig.old

View File

@ -4,7 +4,3 @@ cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake) include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(dht_temp) project(dht_temp)
# Add client certificate, private key and CA bundle to project:
target_add_binary_data(${CMAKE_PROJECT_NAME}.elf "assets/client.crt" TEXT)
target_add_binary_data(${CMAKE_PROJECT_NAME}.elf "assets/client.key" TEXT)

View File

@ -1,68 +1,64 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
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 9WslzbtdtaD4TSXd2OvbRehTPsU=
OBsrrOf8vtk=
-----END CERTIFICATE----- -----END CERTIFICATE-----
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
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
DXBx2FuyJRFR9As=
-----END CERTIFICATE----- -----END CERTIFICATE-----

View File

@ -1,29 +0,0 @@
-----BEGIN CERTIFICATE-----
MIIE5jCCAs6gAwIBAgIBBDANBgkqhkiG9w0BAQsFADB7MRMwEQYKCZImiZPyLGQB
GRYDbW9lMRMwEQYKCZImiZPyLGQBGRYDaW1pMQ8wDQYDVQQKDAZpTS5JbmMxHjAc
BgNVBAsMFWlNLkluYyBJb1QgU2lnbmluZyBDQTEeMBwGA1UEAwwVaU0uSW5jIElv
VCBTaWduaW5nIENBMB4XDTIyMDcwNDEzNDkxNVoXDTI0MDcwMzEzNDkxNVowZzET
MBEGCgmSJomT8ixkARkWA21vZTETMBEGCgmSJomT8ixkARkWA2ltaTEPMA0GA1UE
CgwGaU0uSW5jMRMwEQYDVQQLDApJb1QgU3lzdGVtMRUwEwYDVQQDDAxFU1BfREhU
X1RlbXAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtKqSGU7OsJQKE
/ap3FWFS8d9P0ZPDhwr8FBfGnU9Os9tuERENM7mDFdAISUiKD3t3xfGX+hOLStYm
9A0vZtWoq6Qhl2pPd7O7yi7Jw5OLSlNmoovClp78dyA82ECszYsEp32fw6nSbhmL
YKTZMYYcdGQO96NWUXvHjuimpCbcUeaDD8yad2TYkb57na3DJp+UNxdf+mvR2beY
RGkmsIn84UP9edmV2lPgx8rNQOGH8mxTMDtU4D0taQF+n/2W/awi+yMtsdjf811+
CwSipyVvo8Sb2zl3IHBcI2uD3gSpJ6pjMkExB6TnO+bE3o4iby+iBAmm9rREiO5l
y9WmGYsfAgMBAAGjgYgwgYUwDgYDVR0PAQH/BAQDAgeAMAkGA1UdEwQCMAAwEwYD
VR0lBAwwCgYIKwYBBQUHAwIwHQYDVR0OBBYEFPealnfk4PmDut1rni1pUF5c7lPq
MB8GA1UdIwQYMBaAFPqAn5YOzFFakCDyAz5Gjxpuy1buMBMGA1UdEQQMMAqCCGRo
dF90ZW1wMA0GCSqGSIb3DQEBCwUAA4ICAQAFwWkFP/qrYamU7JCRsReW0BTtPxQD
qPYkdff7IO5mwXcbJZKK9HaueCtItMgl8l9SUMdiNdHETodOAuTRtjI9vaDm1bai
nnQdxNYUQHDZc0NHurTKzLr7gTlE61Hk84Y6Erd/AiwfyqT+832jCinjS3bpY37s
rWMxRbo1Abe+4V/+giV4Qqk5yYUHyevkO2zliyCk1FLpczRAGYBvQFBN+2Ggvimj
lcGhi6O5UCUgqbral3pgNgJ3W0ZPCZqd03B4aaauTvQ7QHk3d++kc/RYanHuWaD+
SEVgMVv13pG7ITggQxoRgKv51sNFcib3WZeJnisIQ4CnzILVaKTNbHKOg0K2YCk0
xnfcESJazQiaGHC0PFoVBqdO3NP/ISstr6vltJ1hHP6hUeOii0zJXbecD+I5rnsN
L6UapEfWvP+/Wt0Hv2ROp8Y2vPkjn9MXCgv5+MsbafnlpP98C8aifexgeygTXZGJ
pQCeqD39ZMvLwoMHjD9y+Qn6prJHrOAaH41S0mmYF7UirRjVVUp9J8BAnfTLhvgX
0CCWVipPChXM3r+w4j2+/Y7KuBuOtmPxLDVp6d/Tf96Bg33ZvD2GY7PetPeB7j5x
Ps+5+9X8cVfNUngzf8LlwTNDsUmECDXpLWri8rRfBBJiGT0CP4EqELvhTrle4uu3
8PHQZfCgDH9WJQ==
-----END CERTIFICATE-----

View File

@ -1,31 +0,0 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,18E77130CD1EB69EB57399009D3AED8D
wEtOb6CifHIbPIXUnIWxUVkwyMWx0B4/y6JGEN//1v6zS0tvLKwKw0kUp6ZQlZEU
mHujXTIP4u/4X1Na6SacibDHeNi4GYP1T3Sp4rc1xKFTU4lQ4FlCXMmmGOKm05gZ
gFXyxqOjBlqYkqWYZnh+C2YEov6xX/OrAkZcSzQ6onjgwsrpbfQffiMxt1zDjCl9
OsDp3xn1TLmwH33oy1qpqxvn2TxETh+gF2HLWqQtnF4dugxun11E/PCiHCTT0QCP
E/xh4EJvUXtW7kwvqRW2kXFwnrRUzGTLnBfDGTEte9Dh1bJN+/tcmU7noU+WIw7j
0CzTfOMHv5tF1KcowLSU67Nofx7L3jWD2Ac6bwZv1uWlCJEltRO0G1WCcoDAw/Ha
SWCzk9CEf8x80IObAjgC3C3cdZfTYnfonMgdBC9yK1dS5zllq9Q4EbNPvhbjNz4L
UggiXEfu3N9DFvt0EZVGeqipqIThs7wJBiYp9WK7yruMeTRmSPbNlu1nITiwQEcy
bFC8nGU5QCt0mBymAxQ4YXeMdTmIbartuSoTivyNkgkzWOkGKjDP5oxb8F0ENCb8
a2Dbu4kXIgTJSVj4w1Hy/UiNiQSKEjlVNJwHm6WDEB7VC2GlfNeVKfhpfAxTAl4F
xF69A+aUalcT7pCOMtS5gPJCFHM+Up73fBnm5Ahh5psvNlIA0ZwjElVxkQCdrGDw
EUG0b7VurSe1+nnYoq+7LlUGMNAUb4VZkFofOG+3SszoKaK5CFwgLliWiQNByJSz
C0Wm8qDqUQNWAP5f0dKkNxCz7HP/lgmm6ZHwMIWzUWmgynHPre805ZM8zKkdA6eE
7WeUzdovl4skSG4DaSULXROXsHfnO4xySi+xc8pIYujBbmKOOqvwsN4trqz2kY9j
dSYrj12DGvvl1PCZQVCyUzVAsGGQLK4nRsf5viKLP5ghWa1MIA4/3Dlf5QxIIFPl
03+vRUjdOxtQssOZ1huyQA2Bvimw1nvRr2l4XJtgLbwkls7ikUot+rKMOn11QGCp
SVynTr2xL6XsvZy9pFt3TxcVmyuIu0DWsDx2Mc0I/vSMsXPmHLaBGNk8T8FLT3Y4
r1e2iPnwRuS4POsXr0VS4d+U0SbV51O3+OL2kD6iCS06UJE/XGJG1PhS1PgbNDPI
nmcr1ZRTTFDwmpgvdrQg+kAXW4OcsjCdFxeD6XnZaZRHpNjkNXIKSsd3N1j0DDJn
qFhHuWkJtRLCdssEQ8BNCHPfrSNID4NOnDJaP35hO5EulMqYleojKHoq2zPDpJiV
fl4HnuhQseiv5RxyF/XKfwZjG+nojI7IfQWEvQQ4Ny3jGzEmuXPYnh/wxgHSUhtq
B4wDfStM+YBixIXP6WKc+YpAgkxHoOpOtxX1RfrzcQr/4vciPIzvlMHWEl241Pq+
TPx9VT7FBsxf2CK0vfTWvOnInctg1FAJLO55rvC4Dk/ME0s/PSr6L+tIGADan38B
H3Xa1A72JhE3IKLdwjQud4kjIFhPVTaM14f3WbuRjb+/Xa7ATFAAlooY/d0KG4we
uB9qkU70SgXVCVxuE0almKQBEYoZFDO6tkZ/LGWo+uKd0wLpnmjRgCn/eMpAa5If
-----END RSA PRIVATE KEY-----

View File

@ -2,6 +2,7 @@ idf_component_register(
SRCS SRCS
"app_dht.c" "app_dht.c"
"app_mqtt.c" "app_mqtt.c"
"app_report_rb.c"
"app_wifi.c" "app_wifi.c"
"main.c" "main.c"
"aht10/aht10.c" "aht10/aht10.c"

View File

@ -1,4 +1,4 @@
menu "Application Configuration" menu "Application specific configuration"
config APP_I2C_SCL_PIN config APP_I2C_SCL_PIN
int "I2C SCL IO number" int "I2C SCL IO number"
default 22 default 22
@ -21,29 +21,17 @@ menu "Application Configuration"
string "WiFi SSID" string "WiFi SSID"
default "myssid" default "myssid"
help help
SSID (network name) for the application to connect to. SSID for the access point.
config APP_WIFI_PASSWORD config APP_WIFI_PASSWORD
string "WiFi Password" string "WiFi Password"
default "mypassword" default "mypassword"
help help
WiFi password (WPA or WPA2) for the application to use. Password for the access point.
config APP_MAXIMUM_RETRY
int "Maximum retry"
default 5
help
Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.
config APP_MQTT_BROKER_ADDR config APP_MQTT_BROKER_ADDR
string "MQTT broker connection string" string "MQTT broker connection string"
default "mqtt://127.0.0.1:1883" default "mqtt://127.0.0.1:1883"
help help
Connection string for MQTT broker, use scheme://host:port format. Connection string for MQTT broker, use scheme://host:port format.
config APP_MQTT_TLS_CLIENT_PASSPHRASE
string "MQTT TLS Client Passphrase"
default "AAAAAAAAAAAAAAAA"
help
Passphrase to decrypt MQTT client private key.
endmenu endmenu

View File

@ -21,22 +21,21 @@ typedef aht10_ret_t (*aht10_i2c_xfer_t)(void *pdev, aht10_xfer_desc_t *xfer);
typedef aht10_ret_t (*aht10_delay_t)(void *pdev, uint32_t delay_msec); typedef aht10_ret_t (*aht10_delay_t)(void *pdev, uint32_t delay_msec);
typedef struct { typedef struct {
double temperature; float temperature;
double humidity; float humidity;
} aht10_result_t; } aht10_result_t;
typedef struct { typedef struct {
aht10_i2c_xfer_t xfer; aht10_i2c_xfer_t xfer;
aht10_delay_t delay; aht10_delay_t delay;
} aht10_cb_t; } aht10_cb_t;
typedef struct { typedef struct {
aht10_cb_t cb; aht10_cb_t cb;
void *user_data; void *user_data;
} aht10_t; } aht10_t;
aht10_ret_t aht10_init(aht10_t *aht); aht10_ret_t aht10_init(aht10_t *aht);
aht10_ret_t aht10_measure(aht10_t *aht, aht10_result_t *result); aht10_ret_t aht10_measure(aht10_t *aht, aht10_result_t *result);
#endif #endif

View File

@ -12,7 +12,7 @@
/* MQTT */ /* MQTT */
#include "app_mqtt.h" #include "app_mqtt.h"
/* AHT10 */ /* DHT sensor */
#include "aht10/aht10.h" #include "aht10/aht10.h"
/* Log tag */ /* Log tag */
@ -25,29 +25,25 @@
#define APP_DHT_I2C_TIMEOUT 100 #define APP_DHT_I2C_TIMEOUT 100
#define APP_DHT_AHT10_ADDR 0x38 #define APP_DHT_AHT10_ADDR 0x38
#define INFLUX_TOPIC "iot/metric"
#define INFLUX_HOSTNAME "DHT_Temp"
#define INFLUX_FORMATTED_STRING \
"dht,hostname=" INFLUX_HOSTNAME \
" " \
"temperature=%.02lf," \
"humidity=%.02lf" \
" " \
"%llu"
static void app_dht_task(void *pvParameters);
static uint64_t app_get_nsec_timestamp(void);
static aht10_ret_t app_dht_impl_xfer(void *pdev, aht10_xfer_desc_t *xfer); static aht10_ret_t app_dht_impl_xfer(void *pdev, aht10_xfer_desc_t *xfer);
static aht10_ret_t app_dht_impl_delay(void *pdev, uint32_t delay_msec); static aht10_ret_t app_dht_impl_delay(void *pdev, uint32_t delay_msec);
static aht10_t aht = {
.cb =
{
.xfer = app_dht_impl_xfer,
.delay = app_dht_impl_delay,
},
};
esp_err_t app_dht_init(void) { esp_err_t app_dht_init(void) {
i2c_config_t cfg = { i2c_config_t cfg = {
.mode = I2C_MODE_MASTER, .mode = I2C_MODE_MASTER,
.sda_io_num = APP_DHT_I2C_SDA_IO, .sda_io_num = APP_DHT_I2C_SDA_IO,
.scl_io_num = APP_DHT_I2C_SCL_IO, .scl_io_num = APP_DHT_I2C_SCL_IO,
.sda_pullup_en = GPIO_PULLUP_DISABLE, .sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_DISABLE, .scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 400000, .master.clk_speed = 100000,
}; };
i2c_param_config(APP_DHT_I2C_INSTANCE, &cfg); i2c_param_config(APP_DHT_I2C_INSTANCE, &cfg);
@ -56,46 +52,22 @@ esp_err_t app_dht_init(void) {
return ESP_FAIL; return ESP_FAIL;
} }
if (xTaskCreate(app_dht_task, "DHT_TASK", 2048, NULL, 1U, NULL) != pdPASS) { aht10_init(&aht);
return ESP_FAIL;
}
return ESP_OK; return ESP_OK;
} }
static void app_dht_task(void *pvParameters) { esp_err_t app_dht_read(float *temperature, float *humidity) {
aht10_t aht = { esp_err_t ret = ESP_OK;
.cb =
{
.xfer = app_dht_impl_xfer,
.delay = app_dht_impl_delay,
},
};
aht10_init(&aht);
aht10_result_t result; aht10_result_t result;
char report_buf[256]; if (aht10_measure(&aht, &result) != AHT10_OK) {
uint64_t ns_ts; return -1;
for (;;) {
aht10_measure(&aht, &result);
ns_ts = app_get_nsec_timestamp();
/* Simple check to see if NTP is synchronized... */
if (ns_ts > (uint64_t)(1600000000L) * 1000000000) {
snprintf(report_buf, 256, INFLUX_FORMATTED_STRING, result.temperature, result.humidity, ns_ts);
app_mqtt_publish(INFLUX_TOPIC, report_buf);
}
vTaskDelay(pdMS_TO_TICKS(500));
} }
}
static uint64_t app_get_nsec_timestamp(void) { *temperature = result.temperature;
struct timeval tv_now; *humidity = result.humidity;
gettimeofday(&tv_now, NULL);
int64_t time_ns = (int64_t)tv_now.tv_sec * 1000000000L + (int64_t)tv_now.tv_usec * 1000; return ret;
return time_ns;
} }
static aht10_ret_t app_dht_impl_xfer(void *pdev, aht10_xfer_desc_t *xfer) { static aht10_ret_t app_dht_impl_xfer(void *pdev, aht10_xfer_desc_t *xfer) {
@ -122,4 +94,4 @@ static aht10_ret_t app_dht_impl_delay(void *pdev, uint32_t delay_msec) {
vTaskDelay(pdMS_TO_TICKS(delay_msec)); vTaskDelay(pdMS_TO_TICKS(delay_msec));
return AHT10_OK; return AHT10_OK;
} }

View File

@ -1,11 +1,12 @@
/* ESP drivers */ /* ESP drivers */
#include "esp_log.h" #include "esp_log.h"
#include "esp_partition.h"
#include "esp_system.h" #include "esp_system.h"
#include "esp_tls.h" #include "esp_tls.h"
/* FreeRTOS */ /* FreeRTOS */
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/queue.h" #include "freertos/semphr.h"
#include "freertos/task.h" #include "freertos/task.h"
/* Cert bundle */ /* Cert bundle */
@ -14,87 +15,167 @@
/* MQTT client */ /* MQTT client */
#include "mqtt_client.h" #include "mqtt_client.h"
#define APP_LOG_TAG "APP_MQTT" #define LOG_TAG "APP_MQTT"
#define APP_MQTT_PART_TYPE ((esp_partition_type_t)0x40)
#define APP_MQTT_PART_CRT_NAME "tls_crt"
#define APP_MQTT_PART_KEY_NAME "tls_key"
#define APP_MQTT_PART_CRT_SUBTYPE 0x00
#define APP_MQTT_PART_KEY_SUBTYPE 0x01
#define APP_MQTT_PART_HEADER_VALID_SIGNATURE (0x66CCFFAA)
typedef struct { typedef struct {
char *topic; uint32_t signature;
char *payload; uint32_t length;
} app_mqtt_queue_item_t; char data;
} app_mqtt_part_header_t;
extern const char mqtt_client_cert_start[] asm("_binary_client_crt_start"); static SemaphoreHandle_t s_mqtt_semaphore;
extern const char mqtt_client_cert_end[] asm("_binary_client_crt_end");
extern const char mqtt_client_key_start[] asm("_binary_client_key_start"); static esp_mqtt_client_handle_t s_mqtt_client;
extern const char mqtt_client_key_end[] asm("_binary_client_key_end"); static esp_partition_mmap_handle_t s_mqtt_crt_mmap_handle;
static esp_partition_mmap_handle_t s_mqtt_key_mmap_handle;
static void app_mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void app_mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
static void app_mqtt_task(void *pvParameters);
static QueueHandle_t s_app_mqtt_publish_queue; esp_err_t app_mqtt_init(uint32_t timeout_ms) {
esp_err_t ret = ESP_OK;
esp_err_t app_mqtt_init(void) { s_mqtt_semaphore = xSemaphoreCreateBinary();
s_app_mqtt_publish_queue = xQueueCreate(4, sizeof(app_mqtt_queue_item_t)); if (s_mqtt_semaphore == NULL) {
if(s_app_mqtt_publish_queue == NULL) { ESP_LOGE(LOG_TAG, "Failed to create semaphore");
return ESP_FAIL; return ESP_ERR_NO_MEM;
} }
if (xTaskCreate(app_mqtt_task, "MQ_TASK", 2048, NULL, 2U, NULL) != pdPASS) { const esp_partition_t *part_crt =
return ESP_FAIL; esp_partition_find_first(APP_MQTT_PART_TYPE, APP_MQTT_PART_CRT_SUBTYPE, APP_MQTT_PART_CRT_NAME);
const esp_partition_t *part_key =
esp_partition_find_first(APP_MQTT_PART_TYPE, APP_MQTT_PART_KEY_SUBTYPE, APP_MQTT_PART_KEY_NAME);
if (part_crt == NULL) {
ESP_LOGE(LOG_TAG, "Failed to find certificate partition.");
goto destroy_semaphore_exit;
} }
ESP_LOGI(LOG_TAG, "Found certificate partition at 0x%08lx", part_crt->address);
if (part_key == NULL) {
ESP_LOGE(LOG_TAG, "Failed to find key partition.");
goto destroy_semaphore_exit;
}
ESP_LOGI(LOG_TAG, "Found key partition at 0x%08lx", part_key->address);
app_mqtt_part_header_t *ptr_crt;
app_mqtt_part_header_t *ptr_key;
ret = esp_partition_mmap(part_crt, 0, part_crt->size, ESP_PARTITION_MMAP_DATA, (const void **)(&ptr_crt),
&s_mqtt_crt_mmap_handle);
if (ret != ESP_OK) {
ESP_LOGE(LOG_TAG, "Failed to map certificate partition");
goto destroy_semaphore_exit;
}
ret = esp_partition_mmap(part_key, 0, part_key->size, ESP_PARTITION_MMAP_DATA, (const void **)(&ptr_key),
&s_mqtt_key_mmap_handle);
if (ret != ESP_OK) {
ESP_LOGE(LOG_TAG, "Failed to map key partition");
goto unmap_cert_exit;
}
if (ptr_crt->signature != APP_MQTT_PART_HEADER_VALID_SIGNATURE) {
ESP_LOGE(LOG_TAG, "Certificate partition content is invalid");
goto unmap_cert_exit;
}
ESP_LOGI(LOG_TAG, "Certificate length: %ld", ptr_crt->length);
if (ptr_key->signature != APP_MQTT_PART_HEADER_VALID_SIGNATURE) {
ESP_LOGE(LOG_TAG, "Key partition content is invalid");
goto unmap_cert_exit;
}
ESP_LOGI(LOG_TAG, "Key length: %ld", ptr_key->length);
const esp_mqtt_client_config_t mqtt_cfg = {
.broker =
{
.address.uri = CONFIG_APP_MQTT_BROKER_ADDR,
.verification.crt_bundle_attach = esp_crt_bundle_attach,
},
.credentials.authentication =
{
.certificate = &ptr_crt->data,
.key = &ptr_key->data,
},
};
s_mqtt_client = esp_mqtt_client_init(&mqtt_cfg);
if (s_mqtt_client == NULL) {
ret = ESP_ERR_NO_MEM;
goto unmap_cert_exit;
}
ret = esp_mqtt_client_register_event(s_mqtt_client, ESP_EVENT_ANY_ID, app_mqtt_event_handler, NULL);
if (ret != ESP_OK) {
ESP_LOGE(LOG_TAG, "Failed to register MQTT event.");
goto destroy_client_exit;
}
ret = esp_mqtt_client_start(s_mqtt_client);
if (ret != ESP_OK) {
ESP_LOGE(LOG_TAG, "Failed to start MQTT client.");
goto destroy_client_exit;
}
if (xSemaphoreTake(s_mqtt_semaphore, pdMS_TO_TICKS(timeout_ms)) != pdPASS) {
ESP_LOGE(LOG_TAG, "Failed to connect to broker in time.");
goto destroy_client_exit;
}
return ESP_OK;
destroy_client_exit:
esp_mqtt_client_destroy(s_mqtt_client);
unmap_cert_exit:
esp_partition_munmap(s_mqtt_crt_mmap_handle);
destroy_semaphore_exit:
vSemaphoreDelete(s_mqtt_semaphore);
return ret;
}
esp_err_t app_mqtt_deinit(void) {
esp_err_t ret;
esp_mqtt_client_stop(s_mqtt_client);
ret = esp_mqtt_client_destroy(s_mqtt_client);
if (ret != ESP_OK) {
return ret;
}
vSemaphoreDelete(s_mqtt_semaphore);
esp_partition_munmap(s_mqtt_crt_mmap_handle);
esp_partition_munmap(s_mqtt_key_mmap_handle);
return ESP_OK; return ESP_OK;
} }
esp_err_t app_mqtt_publish(char *topic, char *payload) { esp_err_t app_mqtt_publish(char *topic, char *payload) {
app_mqtt_queue_item_t item; return esp_mqtt_client_publish(s_mqtt_client, topic, payload, (int)strlen(payload), 0, 0);
item.topic = malloc(strlen(topic) + 1);
if(item.topic == NULL) return ESP_FAIL;
item.payload = malloc(strlen(payload) + 1);
if(item.payload == NULL) {
free(item.topic);
return ESP_FAIL;
}
strcpy(item.topic, topic);
strcpy(item.payload, payload);
if(xQueueSend(s_app_mqtt_publish_queue, &item, portMAX_DELAY) != pdPASS) {
free(item.topic);
free(item.payload);
return ESP_FAIL;
}
return ESP_OK;
}
static void app_mqtt_task(void *pvParameters) {
const esp_mqtt_client_config_t mqtt_cfg = {
.uri = CONFIG_APP_MQTT_BROKER_ADDR,
.client_cert_pem = mqtt_client_cert_start,
.client_key_pem = mqtt_client_key_start,
.clientkey_password = CONFIG_APP_MQTT_TLS_CLIENT_PASSPHRASE,
.clientkey_password_len = strlen(CONFIG_APP_MQTT_TLS_CLIENT_PASSPHRASE),
.crt_bundle_attach = esp_crt_bundle_attach,
};
esp_mqtt_client_handle_t client = esp_mqtt_client_init(&mqtt_cfg);
esp_mqtt_client_register_event(client, ESP_EVENT_ANY_ID, app_mqtt_event_handler, NULL);
esp_mqtt_client_start(client);
app_mqtt_queue_item_t item;
for (;;) {
if(xQueueReceive(s_app_mqtt_publish_queue, &item, portMAX_DELAY) == pdPASS) {
esp_mqtt_client_publish(client, item.topic, item.payload, strlen(item.payload), 0, 0);
/* This is alloc'ed by us. */
free(item.topic);
free(item.payload);
}
}
} }
static void app_mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { static void app_mqtt_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
/**/ switch ((esp_mqtt_event_id_t)event_id) {
case MQTT_EVENT_CONNECTED:
ESP_LOGI(LOG_TAG, "Connected to broker.");
xSemaphoreGive(s_mqtt_semaphore);
break;
default:
break;
}
} }

107
main/app_report_rb.c Normal file
View File

@ -0,0 +1,107 @@
#include <string.h>
/* FreeRTOS */
#include "freertos/FreeRTOS.h"
#include "freertos/semphr.h"
#include "freertos/task.h"
/* App */
#include "app_report_rb.h"
#define APP_REPORT_RB_SIZE 4800
static app_report_rb_t s_report_rb[APP_REPORT_RB_SIZE];
static volatile uint32_t s_report_rb_rptr = 0U;
static volatile uint32_t s_report_rb_wptr = 0U;
static SemaphoreHandle_t s_report_rb_semphr = NULL;
int app_report_rb_init(void) {
s_report_rb_semphr = xSemaphoreCreateMutex();
if (s_report_rb_semphr == NULL) {
return -1;
}
s_report_rb_rptr = 0U;
s_report_rb_wptr = 0U;
return 0;
}
void app_report_rb_append(app_report_rb_t *rpt) {
if (xSemaphoreTake(s_report_rb_semphr, portMAX_DELAY) != pdPASS) {
return;
}
memcpy(&s_report_rb[s_report_rb_wptr], rpt, sizeof(app_report_rb_t));
if (s_report_rb_wptr < APP_REPORT_RB_SIZE - 1) {
s_report_rb_wptr++;
} else {
s_report_rb_wptr = 0UL;
}
xSemaphoreGive(s_report_rb_semphr);
}
void app_report_rb_consume(app_report_rb_t *rpt) {
if (xSemaphoreTake(s_report_rb_semphr, portMAX_DELAY) != pdPASS) {
return;
}
memcpy(rpt, &s_report_rb[s_report_rb_rptr], sizeof(app_report_rb_t));
if (s_report_rb_rptr < APP_REPORT_RB_SIZE - 1) {
s_report_rb_rptr++;
} else {
s_report_rb_rptr = 0UL;
}
xSemaphoreGive(s_report_rb_semphr);
}
void app_report_rb_flush(void) {
if (xSemaphoreTake(s_report_rb_semphr, portMAX_DELAY) != pdPASS) {
return;
}
s_report_rb_wptr = 0U;
s_report_rb_rptr = 0U;
xSemaphoreGive(s_report_rb_semphr);
}
uint32_t app_report_rb_get_count(void) {
uint32_t ret = 0;
if (xSemaphoreTake(s_report_rb_semphr, portMAX_DELAY) != pdPASS) {
return ret;
}
if (s_report_rb_wptr >= s_report_rb_rptr) {
ret = s_report_rb_wptr - s_report_rb_rptr;
} else {
ret = (APP_REPORT_RB_SIZE - s_report_rb_rptr) + s_report_rb_wptr;
}
xSemaphoreGive(s_report_rb_semphr);
return ret;
}
uint32_t app_report_rb_get_total_size(void) {
return APP_REPORT_RB_SIZE;
}
void app_report_rb_discard(uint32_t num) {
if (num > app_report_rb_get_count()) {
return;
}
uint32_t tmp_ptr = s_report_rb_wptr + num;
if (tmp_ptr > APP_REPORT_RB_SIZE) {
tmp_ptr -= APP_REPORT_RB_SIZE;
}
s_report_rb_wptr = tmp_ptr;
}

View File

@ -14,21 +14,24 @@
#define APP_LOG_TAG "APP_WIFI" #define APP_LOG_TAG "APP_WIFI"
EventGroupHandle_t g_app_wifi_event_group; #define APP_WIFI_EVENT_GROUP_EVENT_CONNECTED (1 << 0U)
static uint8_t s_retries = 0U; EventGroupHandle_t s_app_wifi_event_group;
static uint8_t s_retries = 0U;
static esp_netif_t *s_sta_netif;
static void app_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data); static void app_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data);
esp_err_t app_wifi_init(void) { esp_err_t app_wifi_init(void) {
g_app_wifi_event_group = xEventGroupCreate(); s_app_wifi_event_group = xEventGroupCreate();
if (g_app_wifi_event_group == NULL) { if (s_app_wifi_event_group == NULL) {
return ESP_FAIL; return ESP_FAIL;
} }
ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default()); ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta(); s_sta_netif = esp_netif_create_default_wifi_sta();
wifi_init_config_t wifi_init_cfg = WIFI_INIT_CONFIG_DEFAULT(); wifi_init_config_t wifi_init_cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_cfg)); ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_cfg));
@ -55,11 +58,34 @@ esp_err_t app_wifi_init(void) {
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config)); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start()); ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(APP_LOG_TAG, "WiFi initialized, heap free: %d.", esp_get_free_heap_size()); ESP_LOGI(APP_LOG_TAG, "WiFi initialized, heap free: %lu.", esp_get_free_heap_size());
return ESP_OK; return ESP_OK;
} }
esp_err_t app_wifi_deinit(void) {
esp_wifi_stop();
esp_wifi_deinit();
esp_netif_destroy_default_wifi(s_sta_netif);
esp_event_loop_delete_default();
vEventGroupDelete(s_app_wifi_event_group);
return ESP_OK;
}
app_wifi_event_t app_wifi_wait_event(uint32_t max_timeout_ms) {
EventBits_t bits = xEventGroupWaitBits(s_app_wifi_event_group, APP_WIFI_EVENT_GROUP_EVENT_CONNECTED, pdFALSE,
pdFALSE, pdMS_TO_TICKS(max_timeout_ms));
if (bits & APP_WIFI_EVENT_GROUP_EVENT_CONNECTED) {
return APP_WIFI_EVENT_CONNECTED;
} else {
return APP_WIFI_EVENT_TIMEOUT;
}
}
static void app_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) { static void app_wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data) {
/* Event handler */ /* Event handler */
@ -69,25 +95,17 @@ static void app_wifi_event_handler(void *arg, esp_event_base_t event_base, int32
} }
if (event_id == WIFI_EVENT_STA_DISCONNECTED) { if (event_id == WIFI_EVENT_STA_DISCONNECTED) {
if (s_retries < CONFIG_APP_MAXIMUM_RETRY) { esp_wifi_connect();
esp_wifi_connect(); ESP_LOGI(APP_LOG_TAG, "Disconnected");
s_retries++;
ESP_LOGI(APP_LOG_TAG, "Connection lost, retrying #%d/%d...", s_retries, CONFIG_APP_MAXIMUM_RETRY);
} else {
xEventGroupSetBits(g_app_wifi_event_group, APP_WIFI_EVENT_GROUP_EVENT_FAILED);
ESP_LOGW(APP_LOG_TAG, "Connection lost, maximum retries reached.");
}
} }
} else if(event_base == IP_EVENT) { } else if (event_base == IP_EVENT) {
if(event_id == IP_EVENT_STA_GOT_IP) { if (event_id == IP_EVENT_STA_GOT_IP) {
xEventGroupSetBits(g_app_wifi_event_group, APP_WIFI_EVENT_GROUP_EVENT_CONNECTED); xEventGroupSetBits(s_app_wifi_event_group, APP_WIFI_EVENT_GROUP_EVENT_CONNECTED);
s_retries = 0U; s_retries = 0U;
ip_event_got_ip_t *event = event_data; ip_event_got_ip_t *event = event_data;
ESP_LOGI(APP_LOG_TAG, "Connected, IP address: "IPSTR, IP2STR(&event->ip_info.ip)); ESP_LOGI(APP_LOG_TAG, "Connected, IP address: " IPSTR, IP2STR(&event->ip_info.ip));
} }
} }
} }

View File

@ -4,5 +4,6 @@
#include "esp_system.h" #include "esp_system.h"
esp_err_t app_dht_init(void); esp_err_t app_dht_init(void);
esp_err_t app_dht_read(float *temperature, float *humidity);
#endif #endif

View File

@ -3,7 +3,8 @@
#include "esp_system.h" #include "esp_system.h"
esp_err_t app_mqtt_init(void); esp_err_t app_mqtt_init(uint32_t timeout_ms);
esp_err_t app_mqtt_deinit(void);
esp_err_t app_mqtt_publish(char *topic, char *payload); esp_err_t app_mqtt_publish(char *topic, char *payload);
#endif #endif

View File

@ -0,0 +1,18 @@
#ifndef APP_REPORT_RB_H
#define APP_REPORT_RB_H
typedef struct {
uint64_t ts;
uint32_t voltage;
float temperature;
float humidity;
} app_report_rb_t;
int app_report_rb_init(void);
void app_report_rb_append(app_report_rb_t *rpt);
void app_report_rb_consume(app_report_rb_t *rpt);
uint32_t app_report_rb_get_count(void);
uint32_t app_report_rb_get_total_size(void);
void app_report_rb_flush(void);
#endif // APP_REPORT_RB_H

View File

@ -8,11 +8,13 @@
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h" #include "freertos/event_groups.h"
#define APP_WIFI_EVENT_GROUP_EVENT_CONNECTED (1 << 0U) typedef enum {
#define APP_WIFI_EVENT_GROUP_EVENT_FAILED (1 << 1U) APP_WIFI_EVENT_TIMEOUT,
APP_WIFI_EVENT_CONNECTED,
extern EventGroupHandle_t g_app_wifi_event_group; } app_wifi_event_t;
esp_err_t app_wifi_init(void); esp_err_t app_wifi_init(void);
esp_err_t app_wifi_deinit(void);
app_wifi_event_t app_wifi_wait_event(uint32_t max_timeout_ms);
#endif #endif

View File

@ -4,10 +4,17 @@
* SPDX-License-Identifier: CC0-1.0 * SPDX-License-Identifier: CC0-1.0
*/ */
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
/* ESP drivers */ /* ESP drivers */
#include "driver/gpio.h"
#include "esp_adc/adc_cali.h"
#include "esp_adc/adc_cali_scheme.h"
#include "esp_adc/adc_oneshot.h"
#include "esp_log.h" #include "esp_log.h"
#include "esp_sleep.h"
#include "esp_sntp.h" #include "esp_sntp.h"
/* FreeRTOS */ /* FreeRTOS */
@ -18,43 +25,290 @@
#include "nvs_flash.h" #include "nvs_flash.h"
/* Config */ /* Config */
#include "app_dht.h"
#include "app_mqtt.h"
#include "app_wifi.h"
#include "sdkconfig.h" #include "sdkconfig.h"
#define APP_LOG_TAG "APP_MAIN" /* App */
#include "app_dht.h"
#include "app_mqtt.h"
#include "app_report_rb.h"
#include "app_wifi.h"
#define LOG_TAG "APP_MAIN"
#define APP_WIFI_TIMEOUT_SECS 120
#define APP_MQTT_TIMEOUT_SECS 10
#define APP_SNTP_TIMEOUT_SECS 60
#define APP_SENSOR_INTERVAL_SECS 1
#define APP_SENSOR_REPORT_TRIGGER_POINTS 20 /* Count of the trigger points which triggers telemetry reporting */
#define APP_SENSOR_REPORT_WATERMARK_PERCENT 80 /* when the buffer reaches this watermark in each trigger point */
#define APP_SENSOR_REPORT_CRITICAL_PERCENT 95 /* Critical level, when this is reached, reports will be flushed */
/* Report interval: (RB Size / Nr. Trigger Points) * (Watermark / 100) * Interval secs */
#define APP_LED_PIN 16
#define APP_ADC_CH ADC_CHANNEL_6
static void app_report_task(void *pvParameters);
static uint64_t app_get_msec_timestamp(void);
static void app_led_init(void);
static void app_led_set(uint8_t on);
static void app_adc_init(void);
static uint32_t app_adc_read(void);
static volatile uint8_t s_report_task_running = 0;
static adc_oneshot_unit_handle_t s_adc_handle;
static adc_cali_handle_t s_adc_cal_handle = NULL;
void app_main(void) { void app_main(void) {
printf("Hello world!\n"); esp_err_t ret;
esp_err_t ret = nvs_flash_init(); ESP_LOGI(LOG_TAG, "Main application started.");
ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) { if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGW(LOG_TAG, "NVS content appears to be corrupted or outdated, erase and recreate NVS structure.");
/* Erase NVS region and give it another try. */
ESP_ERROR_CHECK(nvs_flash_erase()); ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init(); ret = nvs_flash_init();
ESP_LOGW(APP_LOG_TAG, "NVS content corrupted or outdated, cleared.");
} }
/* NVS initialization reported failure, this should not happen. In this case, abort! */
ESP_ERROR_CHECK(ret); ESP_ERROR_CHECK(ret);
ESP_ERROR_CHECK(app_wifi_init()); ESP_ERROR_CHECK(app_wifi_init());
EventBits_t bits = xEventGroupWaitBits(g_app_wifi_event_group, app_wifi_event_t a_wifi_evt = app_wifi_wait_event(APP_WIFI_TIMEOUT_SECS * 1000);
APP_WIFI_EVENT_GROUP_EVENT_CONNECTED | APP_WIFI_EVENT_GROUP_EVENT_FAILED, if (a_wifi_evt != APP_WIFI_EVENT_CONNECTED) {
pdFALSE, pdFALSE, portMAX_DELAY); ESP_LOGE(LOG_TAG, "WiFi failed to come up within time limit.");
if (bits & APP_WIFI_EVENT_GROUP_EVENT_FAILED) { esp_restart();
return;
} }
/* On first start, we need to know the actual start time for timestamp tracking in report */
sntp_setoperatingmode(SNTP_OPMODE_POLL); sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, CONFIG_APP_SNTP_POOL_ADDR); sntp_setservername(0, CONFIG_APP_SNTP_POOL_ADDR);
sntp_init(); sntp_init();
ESP_ERROR_CHECK(app_mqtt_init()); uint16_t sntp_trials = APP_SNTP_TIMEOUT_SECS;
/* If the NTP does not finish synchronization in 10 seconds... Required for initial boot up */
while (sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED) {
vTaskDelay(pdMS_TO_TICKS(1000));
sntp_trials--;
if (sntp_trials == 0U) {
ESP_LOGE(LOG_TAG, "Failed to synchronize NTP in-time.");
esp_restart();
}
}
sntp_stop();
ESP_ERROR_CHECK(app_mqtt_init(APP_MQTT_TIMEOUT_SECS * 1000));
ESP_ERROR_CHECK(app_mqtt_deinit());
/*
* We have acquired NTP time, de-init Wi-Fi.
* Something terribly wrong happens if this function is not completed successfully.
*/
ESP_ERROR_CHECK(app_wifi_deinit());
/* Some indication... */
app_led_init();
app_adc_init();
/* Initialize DHT sensors, abort if error occurs */
ESP_ERROR_CHECK(app_dht_init()); ESP_ERROR_CHECK(app_dht_init());
/* This task will be deleted if this function returns. */ if (app_report_rb_init() < 0) {
ESP_LOGE(LOG_TAG, "Failed to init RB");
esp_restart();
}
app_report_rb_t rpt;
for (;;) {
app_led_set(1);
ret = app_dht_read(&rpt.temperature, &rpt.humidity);
if (ret != ESP_OK) {
continue;
}
rpt.voltage = app_adc_read() * 2;
app_led_set(0);
rpt.ts = app_get_msec_timestamp();
app_report_rb_append(&rpt);
uint32_t current_count = app_report_rb_get_count();
uint32_t rb_size = app_report_rb_get_total_size();
if (current_count % 10 == 0) {
ESP_LOGI(LOG_TAG, "Last: %.2fC, %.2f%%", rpt.temperature, rpt.humidity);
ESP_LOGI(LOG_TAG, "RB level: %lu%%", current_count * 100 / rb_size);
ESP_LOGI(LOG_TAG, "Battery voltage: %lumV", rpt.voltage);
}
/**
* Trigger report task at each threshold point or above the last threshold point.
* If the last threshold trigger failed, the ring buffer will be cleared.
*/
uint32_t rb_trigger_level = rb_size / APP_SENSOR_REPORT_TRIGGER_POINTS;
uint32_t rb_trigger_watermark = rb_trigger_level * APP_SENSOR_REPORT_WATERMARK_PERCENT / 100;
uint32_t rb_critical_point = rb_size * APP_SENSOR_REPORT_CRITICAL_PERCENT / 100;
if (((current_count % rb_trigger_level) == rb_trigger_watermark) || (current_count > rb_critical_point)) {
if (!s_report_task_running) {
xTaskCreate(app_report_task, "RPT_TASK", 4096, NULL, 4, NULL);
s_report_task_running = 1U;
}
}
if (s_report_task_running) {
vTaskDelay(pdMS_TO_TICKS(1000));
} else {
esp_sleep_enable_timer_wakeup(APP_SENSOR_INTERVAL_SECS * 1000 * 1000);
esp_light_sleep_start();
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_TIMER);
}
}
} }
static void app_report_task(void *pvParameters) {
app_report_rb_t rpt;
char *rpt_buffer;
ESP_ERROR_CHECK(app_wifi_init());
app_wifi_event_t a_wifi_evt = app_wifi_wait_event(APP_WIFI_TIMEOUT_SECS * 1000);
if (a_wifi_evt != APP_WIFI_EVENT_CONNECTED) {
ESP_LOGE(LOG_TAG, "WiFi failed to come up within time limit.");
goto drop_data_exit;
}
sntp_init();
uint16_t sntp_trials = APP_SNTP_TIMEOUT_SECS;
/* If the NTP does not finish synchronization in 10 seconds... Required for initial boot up */
while (sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED) {
vTaskDelay(pdMS_TO_TICKS(1000));
sntp_trials--;
if (sntp_trials == 0U) {
ESP_LOGE(LOG_TAG, "Failed to synchronize NTP in-time.");
goto stop_sntp_exit;
}
}
ESP_ERROR_CHECK(app_mqtt_init(APP_MQTT_TIMEOUT_SECS * 1000));
rpt_buffer = malloc(512);
while (app_report_rb_get_count() > 0) {
app_report_rb_consume(&rpt);
// TODO: Create new report
// app_mqtt_publish(INFLUX_TOPIC, rpt_buffer);
}
free(rpt_buffer);
ESP_ERROR_CHECK(app_mqtt_deinit());
sntp_stop();
ESP_ERROR_CHECK(app_wifi_deinit());
s_report_task_running = 0U;
vTaskDelete(NULL);
return;
stop_sntp_exit:
sntp_stop();
drop_data_exit:
ESP_ERROR_CHECK(app_wifi_deinit());
/* Flush ring buffer */
if (app_report_rb_get_count() > (app_report_rb_get_total_size() * APP_SENSOR_REPORT_CRITICAL_PERCENT / 100)) {
app_report_rb_flush();
}
s_report_task_running = 0U;
vTaskDelete(NULL);
}
static uint64_t app_get_msec_timestamp(void) {
struct timeval tv_now;
gettimeofday(&tv_now, NULL);
uint64_t time_ms = (int64_t)tv_now.tv_sec * 1000 + (int64_t)tv_now.tv_usec / 1000;
return time_ms;
}
static void app_adc_init(void) {
adc_oneshot_unit_init_cfg_t init_cfg = {
.unit_id = ADC_UNIT_1,
};
ESP_ERROR_CHECK(adc_oneshot_new_unit(&init_cfg, &s_adc_handle));
adc_oneshot_chan_cfg_t chan_cfg = {
.atten = ADC_ATTEN_DB_11,
.bitwidth = ADC_BITWIDTH_DEFAULT,
};
ESP_ERROR_CHECK(adc_oneshot_config_channel(s_adc_handle, APP_ADC_CH, &chan_cfg));
adc_cali_line_fitting_config_t cali_config = {
.unit_id = ADC_UNIT_1,
.atten = ADC_ATTEN_DB_11,
.bitwidth = ADC_BITWIDTH_DEFAULT,
};
ESP_ERROR_CHECK(adc_cali_create_scheme_line_fitting(&cali_config, &s_adc_cal_handle));
}
static uint32_t app_adc_read(void) {
int result;
int voltage;
ESP_ERROR_CHECK(adc_oneshot_read(s_adc_handle, APP_ADC_CH, &result));
ESP_ERROR_CHECK(adc_cali_raw_to_voltage(s_adc_cal_handle, result, &voltage));
return voltage;
}
static void app_led_init(void) {
gpio_config_t io_cfg = {
.mode = GPIO_MODE_OUTPUT_OD,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.pin_bit_mask = (1U << APP_LED_PIN),
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io_cfg);
gpio_set_level(APP_LED_PIN, 1);
}
static void app_led_set(uint8_t on) {
if (on) {
gpio_set_level(APP_LED_PIN, 0);
} else {
gpio_set_level(APP_LED_PIN, 1);
}
}

View File

@ -1,5 +1,9 @@
# ESP-IDF Partition Table # ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags # Name, Type, SubType, Offset, Size, Flags
nvs, data, nvs, 0x9000, 0x6000, nvs, data, nvs, 0x00009000, 0x00004000,
phy_init, data, phy, 0xf000, 0x1000, otadata, data, ota, 0x0000d000, 0x00002000,
factory, app, factory, 0x10000, 3M, phy_init, data, phy, 0x0000f000, 0x00001000,
ota_0, app, ota_0, 0x00010000, 0x00180000,
ota_1, app, ota_1, 0x00190000, 0x00180000,
tls_crt, 0x40, 0x00, 0x00310000, 0x00008000,
tls_key, 0x40, 0x01, 0x00318000, 0x00008000,
1 # ESP-IDF Partition Table
2 # Name, Type, SubType, Offset, Size, Flags # Name, Type, SubType, Offset, Size, Flags
3 nvs, data, nvs, 0x9000, 0x6000, nvs, data, nvs, 0x00009000, 0x00004000,
4 phy_init, data, phy, 0xf000, 0x1000, otadata, data, ota, 0x0000d000, 0x00002000,
5 factory, app, factory, 0x10000, 3M, phy_init, data, phy, 0x0000f000, 0x00001000,
6 ota_0, app, ota_0, 0x00010000, 0x00180000,
7 ota_1, app, ota_1, 0x00190000, 0x00180000,
8 tls_crt, 0x40, 0x00, 0x00310000, 0x00008000,
9 tls_key, 0x40, 0x01, 0x00318000, 0x00008000,

View File

@ -1,22 +0,0 @@
# SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
# SPDX-License-Identifier: CC0-1.0
from typing import Callable
import pytest
from pytest_embedded_idf.dut import IdfDut
from pytest_embedded_qemu.dut import QemuDut
@pytest.mark.supported_targets
@pytest.mark.generic
def test_hello_world(dut: IdfDut, log_minimum_free_heap_size: Callable[..., None]) -> None:
dut.expect('Hello world!')
log_minimum_free_heap_size()
@pytest.mark.esp32 # we only support qemu on esp32 for now
@pytest.mark.host_test
@pytest.mark.qemu
def test_hello_world_host(dut: QemuDut) -> None:
dut.expect('Hello world!')

View File

View File

@ -1,11 +1,14 @@
# Minimum flash size set to 4MB # Minimum flash size set to 4MB
CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y CONFIG_ESPTOOLPY_FLASHSIZE_4MB=y
# Use custom partition table, 3MB application. # Use custom partition table
CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM=y
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv" CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
# Custom CA bundle for mbedTLS # Custom CA bundle for mbedTLS
CONFIG_MBEDTLS_SSL_OUT_CONTENT_LEN=16384
CONFIG_MBEDTLS_DYNAMIC_BUFFER=y
CONFIG_MBEDTLS_DYNAMIC_FREE_CONFIG_DATA=y
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE=y
CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="assets/ca" CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="assets/ca"

23
tools/gen_credentials.rb Normal file
View File

@ -0,0 +1,23 @@
if ARGV.length < 1 then
puts 'No parameter given'
exit 255
end
File.open(ARGV[0], 'r') do |f|
raw_size = f.size
puts "Credential file size: #{raw_size}"
hdr = [0xAA, 0xFF, 0xCC, 0x66]
hdr.push raw_size & 0xFF
hdr.push (raw_size >> 8) & 0xFF
hdr.push (raw_size >> 16) & 0xFF
hdr.push (raw_size >> 24) & 0xFF
File.open("#{ARGV[0]}.bin", 'w+') do |wf|
wf.write(hdr.pack('C*'))
wf.write(f.read)
wf.write([0].pack('C*'))
end
end