esp8266, hw_timer_init(); jakie include dołączyć
hw_timer_init()
na ESP8266 wystarczy dołączyć plik nagłówkowy z lokalizacji odpowiadającej używanemu SDK: /* ESP8266 RTOS-SDK ≥ v3.x */
#include "driver/hw_timer.h"
/* ESP8266 Non-OS-SDK lub Arduino Core for ESP8266 */
#include <hw_timer.h> // czasem wymaga bloku extern "C" { … }
Kluczowe punkty
• RTOS-SDK: ścieżka esp8266/include/driver/hw_timer.h
• Non-OS/Arduino: sam hw_timer.h
, ewentualnie dodatkowo user_interface.h
, os_type.h
dla starszych wersji
• Jeżeli kompilujesz plik .cpp
, owiń dołączane nagłówki w blok extern "C" { … }
, by uniknąć konfliktu nazw manglowanych przez C++.
Różnice środowisk
• RTOS-SDK (CMake / ESP-IDF-style build) – plik jest w module driver
.
• Non-OS-SDK – starsze projekty Makefile; hw_timer.h
leży bezpośrednio w katalogu include
.
• Arduino Core for ESP8266 – framework dostarcza hw_timer.h
w cores/esp8266/
. Nagłówek jest widoczny globalnie, ale nadal warto dołączyć go jawnie dla czytelności.
Deklaracja funkcji
Nagłówek zawiera m.in.:
typedef void (*hw_timer_callback_t)(void* arg);
esp_err_t hw_timer_init(hw_timer_callback_t cb, void *arg);
void hw_timer_arm(uint32_t us, bool repeat);
W Non-OS-SDK podpis jest nieco inny:
void hw_timer_init(os_timer_func_t *cb, uint8 req);
void hw_timer_arm(uint32 val);
Typowe wymagania kompilatora C++
extern "C" {
#include <hw_timer.h>
#include <user_interface.h> // dla Non-OS lub Arduino
}
Blok extern "C"
wyłącza C++ name-mangling, dzięki czemu linker znajdzie funkcje z biblioteki skompilowanej w C.
Minimalny przykład (Arduino Core)
#include <Arduino.h>
extern "C" {
#include <hw_timer.h>
}
void ICACHE_RAM_ATTR onTimer() {
// ISR – krótki, bezblokujący kod!
digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));
}
void setup() {
pinMode(LED_BUILTIN, OUTPUT);
hw_timer_init(FRC1_SOURCE, 1); // 1 = autoload (cykliczny)
hw_timer_set_func(onTimer);
hw_timer_arm(500000); // 500 000 µs = 0,5 s
}
void loop() { /* pusta pętla */ }
• Espressif rozwija jedynie RTOS-SDK; Non-OS utrzymywany wyłącznie w trybie „maintenance”.
• W Arduino Core zaleca się użycie wyższopoziomowej biblioteki Ticker
lub ESP8266TimerInterrupt
, która wewnętrznie korzysta z FRC1, eliminując problemy z ISR w IRAM.
• W nowych wersjach RTOS-SDK (od v3.4) dodano obsługę wywołania zwrotnego z argumentem i stanowi to preferowany interfejs.
• Zegar FRC1 taktowany jest 5 MHz (0,2 µs/tick) w najnowszym RTOS-SDK; w starszych Non-OS-SDK 2,5 MHz (0,4 µs/tick).
• ISR musi znajdować się w IRAM (ICACHE_RAM_ATTR
), w przeciwnym razie podczas operacji flash dojdzie do wyjątku Illegal Instruction
lub wdt reset
.
• Jeden sprzętowy timer użytkownika oznacza, że PWM (Timer0) lub Wi-Fi mogą kolidować tylko przy nieprawidłowej konfiguracji.
Brak szczególnych implikacji prawnych; należy jedynie przestrzegać licencji MIT GPL/LGPL zależnie od fragmentu SDK i bibliotek.
• Upewnij się, że ISR nie wykonuje logowania przez Serial.print()
.
• Przy krótszych interwałach (<25 µs) testuj, czy Wi-Fi nie gubi pakietów; w razie problemów rozważ Ticker lub przeniesienie krytycznej logiki na ESP32.
• W RTOS-SDK używaj flagi repeat
w hw_timer_arm
, by uniknąć nieintencjonalnych pojedynczych strzałów.
• Dokumentacja Non-OS-SDK bywa niespójna; nazwy parametrów różnią się między wersjami 1.5.x a 2.2.x.
• W Arduino Core stosowanie niskopoziomowego FRC1 uniemożliwia późniejsze wykorzystanie biblioteki Servo / analogWrite(pin, duty) – oba używają tego samego timera.
• Analiza „Hardware Timer – ESP8266 RTOS-SDK” (docs.espressif.com).
• Porównanie z nową implementacją ESP32 esp_timer
(dokładność 1 µs, 4 timery soft-hardware).
• Biblioteka ESP8266TimerInterrupt
– źródło: GitHub/khoih-prog – przykład zaawansowanych ISR.
Do funkcji hw_timer_init()
na ESP8266 dołącz:
#include "driver/hw_timer.h" // RTOS-SDK
#include <hw_timer.h> // Non-OS-SDK / Arduino
oraz – w kodzie C++ – owiń w extern "C"
. Pamiętaj o umieszczeniu ISR w IRAM i ograniczeniu jej długości; rozważ bibliotekę Ticker
, jeśli nie potrzebujesz pojedynczego timera o bardzo niskich opóźnieniach.