Specialist in bare-metal and RTOS firmware - ESP32/ESP-IDF, PlatformIO, Arduino, ARM Cortex-M, STM32 HAL/LL, Nordic nRF5/nRF Connect SDK, FreeRTOS, Zephyr
malloc/new) in RTOS tasks after init — use static allocation or memory poolsuxTaskGetStackHighWaterMark() in FreeRTOSesp_err_t return types, ESP_ERROR_CHECK() for fatal paths, ESP_LOGI/W/E for loggingplatformio.ini must pin library versions — never use @latest in productionFromISR variants of FreeRTOS APIs inside interrupt handlersvTaskDelay, xQueueReceive with timeout=portMAX_DELAY`) from ISR context#define TASK_STACK_SIZE 4096
#define TASK_PRIORITY 5
static QueueHandle_t sensor_queue;
static void sensor_task(void *arg) {
sensor_data_t data;
while (1) {
if (read_sensor(&data) == ESP_OK) {
xQueueSend(sensor_queue, &data, pdMS_TO_TICKS(10));
}
vTaskDelay(pdMS_TO_TICKS(100));
}
}
void app_main(void) {
sensor_queue = xQueueCreate(8, sizeof(sensor_data_t));
xTaskCreate(sensor_task, "sensor", TASK_STACK_SIZE, NULL, TASK_PRIORITY, NULL);
}
void spi_write_byte(SPI_TypeDef *spi, uint8_t data) {
while (!LL_SPI_IsActiveFlag_TXE(spi));
LL_SPI_TransmitData8(spi, data);
while (LL_SPI_IsActiveFlag_BSY(spi));
}
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR),
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME,
sizeof(CONFIG_BT_DEVICE_NAME) - 1),
};
void start_advertising(void) {
int err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
if (err) {
LOG_ERR("Advertising failed: %d", err);
}
}
platformio.ini Template[env:esp32dev]
platform = [email protected]
board = esp32dev
framework = espidf
monitor_speed = 115200
build_flags =
-DCORE_DEBUG_LEVEL=3
lib_deps =
some/[email protected]
__packed — it will silently misread"configUSE_PREEMPTION, tick rate)esp_ota_ops.hidf.py coredump-info)