bubao/esp_cron

0.0.5

Latest
uploaded 3 days ago
ESP-IDF cron expression component

readme

# CRON-like component for the ESP-IDF framework

> 中文版请见 [README_zh.md](./README_zh.md)

## Component Features

This component provides CRON-style task scheduling for the ESP-IDF framework, leveraging `esp_timer.h` for high-precision timing. It's optimized for embedded scenarios, supporting CRON syntax with second-level precision and seamless integration with ESP32/ESP8266 hardware.

## Usage Guide

The API design prioritizes simplicity, including core functions for task creation, destruction, and scheduler control. The workflow is straightforward: define at least one task, start the scheduler, then manage tasks dynamically. A smart power-saving mechanism automatically puts the scheduler into low-power mode when no tasks are scheduled, minimizing CPU overhead.

**Key Note**: Timing relies on `esp_timer` for hardware-accelerated precision, eliminating the need for system time management. Ensure proper timer initialization before creating tasks to maintain scheduling accuracy.

### Code Structure

```tree
esp-cron/
├── esp_cron.c            # Core scheduling logic & API implementation
├── include/
│   ├── esp_cron.h        # Public header exposing APIs
│   └── cron_internal.h   # Internal header for scheduler internals
├── library/
│   ├── ccronexpr/       # CRON expression parser (open-source component)
│   └── jobs/            # Task linked list management
└── examples/            # Usage examples
```

## Quick Start Guide

### Include Header

```c
#include "esp_cron.h"
```

### 1. Create a Scheduled Task

```c
cron_job *cron_job_create(const char *schedule, cron_job_callback callback, void *data)
```

- `schedule` supports CRON expressions with second-level precision:
  ```txt
    ┌────────────── second (0 - 59)
    | ┌───────────── minute (0 - 59)
    | │ ┌───────────── hour (0 - 23)
    | │ │ ┌───────────── day of month (1 - 31)
    | │ │ │ ┌───────────── month (1 - 12)
    | │ │ │ │ ┌───────────── day of week (0 - 6, Sunday=0; 7=Sunday in some systems)
    | │ │ │ │ │
    * * * * * *
  ```
- `callback` is a task handler function pointer, defined as:
  ```c
  typedef void (*cron_job_callback)(cron_job *);
  ```
  Callbacks are designed to be lightweight; the scheduler manages execution cycles automatically.
- `data` is a user-defined pointer passed to the callback with the task handle.

### Destroy a Task

Stop an existing task with:

```c
int cron_job_destroy(cron_job *job);
```

### Start the Scheduler

Launch the scheduler after defining at least one task:

```c
int cron_start();
```

### Stop the Scheduler

Shut down the scheduler:

```c
int cron_stop();
```

### Clear All Tasks

Remove all scheduled tasks:

```c
int cron_job_clear_all();
```

### Example Usage

```c
/* Initialize ESP-Timer (project-dependent, not component-required) */
esp_timer_init();

/* Create two scheduled tasks */
cron_job *jobs[2];
jobs[0] = cron_job_create("* * * * * *", on_timer_trigger, (void *)0);
jobs[1] = cron_job_create("*/5 * * * * *", on_timer_trigger, (void *)10000);

/* Start scheduler */
cron_start();

/* Simulate main program execution (replace with business logic) */
vTaskDelay(pdMS_TO_TICKS(60000));  // Run for 60 seconds

/* Cleanup resources */
cron_stop();
cron_job_clear_all();
```

Callback function example:

```c
void on_timer_trigger(cron_job *job)
{
  uint32_t task_id = (uint32_t)job->data;
  printf("Task %u triggered at %lu ms\n", task_id, esp_timer_get_time() / 1000);
}
```

## Core API Reference

### Task Management

| Function                  | Description                          |
|---------------------------|--------------------------------------|
| `cron_job* cron_job_create(const char* schedule, cron_job_callback callback, void* data);` | Create and register a task           |
| `int cron_job_destroy(cron_job* job);` | Destroy a specific task              |
| `int cron_job_clear_all();` | Clear all scheduled tasks            |

### Scheduler Control

| Function          | Description                        |
|-------------------|------------------------------------|
| `int cron_start();` | Start the task scheduler           |
| `int cron_stop();` | Stop the task scheduler            |

### Task Scheduling Operations

| Function                | Description                          |
|-------------------------|--------------------------------------|
| `int cron_job_schedule(cron_job* job);` | Manually schedule a task             |
| `int cron_job_unschedule(cron_job* job);` | Unscheduled a task                   |
| `void cron_schedule_task(void* args);` | Special scheduling (e.g., run once)  |

### Status Queries

| Function                          | Description                          |
|-----------------------------------|--------------------------------------|
| `int cron_job_load_expression(cron_job* job, const char* schedule);` | Dynamically load a CRON expression   |
| `int cron_job_has_loaded(cron_job* job);` | Check if an expression is loaded     |
| `time_t cron_job_seconds_until_next_execution();` | Get seconds until next execution     |

## Time Synchronization & Precision Optimization

### Local Timezone Configuration

For projects requiring timezone-aware time display:

1. **Timezone environment configuration**:
   ```c
   setenv("TZ", "CST-8", 1);  // Beijing Time (UTC+8)
   tzset();  // Apply timezone settings
   ```
   This affects functions like `localtime` but **does not impact scheduling precision**—tasks run based on hardware timer absolute time, independent of system timezone.
2. **SNTP time synchronization (optional)**:
   For standard time in logs or displays:
   ```c
   void init_system_time(void) {
       sntp_setoperatingmode(SNTP_OPMODE_POLL);
       sntp_setservername(0, "pool.ntp.org");  // Use domestic servers like "cn.ntp.org"
       sntp_init();

       int retry = 0;
       const int max_retry = 10;
       while (sntp_get_sync_status() != SNTP_SYNC_STATUS_COMPLETED && retry < max_retry) {
           vTaskDelay(pdMS_TO_TICKS(1000));
           retry++;
       }
       time_t now = 0;
       time(&now);
       printf("System time synced: %s", ctime(&now));
   }
   ```
   **Note**: SNTP syncs only the system time for display; scheduling relies on `esp_timer` hardware timing, unaffected by network latency.

### Precision Optimization Guide

1. **Hardware timer configuration**:
   ```c
   /* Enable high-precision timer mode (ESP32-specific) */
   esp_timer_create_args_t timer_args = {
       .callback = NULL,
       .arg = NULL,
       .flags = ESP_TIMER_FLAG_HIGH_PRECISION,  // Key: enable APB clock source
   };
   esp_timer_init(&timer_args);
   ```
2. **Scheduler parameter tuning**:
   ```c
   /* Configure minimum scheduling interval (default: 1ms, adjust for power consumption) */
   #define MIN_SCHEDULE_INTERVAL_US 100000  // 100ms interval for light sleep

   cron_start();  // Apply configuration on startup
   ```
3. **Low-power scenario adaptation**:
   ```c
   /* Combine with timer wakeup for low-power scheduling */
   esp_sleep_enable_timer_wakeup(5000000);  // Wake up every 5 seconds
   esp_light_sleep_start();
   ```
   The scheduler checks task triggers during wakeup cycles, balancing precision and power consumption.

### Why No Timezone Dependence for Scheduling?

This component uses **direct hardware timer timing** with these advantages:

1. **Precision isolation**: Triggers rely on ESP32 internal timers, unaffected by system time or timezone, with microsecond-level accuracy.
2. **No network dependency**: Stable scheduling without SNTP, ideal for offline embedded scenarios.
3. **Power optimization**: Timers work independently during CPU sleep, avoiding constant wakeups in traditional time systems.

**Actual role of timezone configuration**: Only affects time display formats via functions like `localtime`, fully decoupled from scheduling logic.

## Acknowledgments

- [esp_cron](https://github.com/DavidMora/esp_cron) by David Mora Rodriguez
- [ccronexpr](https://github.com/staticlibs/ccronexpr) expression parser

## License

This project is licensed under the [Apache License 2.0](http://www.apache.org/licenses/LICENSE-2.0).

> English documentation: This page is in English. 中文文档请见 [README_zh.md](./README_zh.md)

Links

Supports all targets

License: Apache-2.0

To add this component to your project, run:

idf.py add-dependency "bubao/esp_cron^0.0.5"

or download archive

Stats

  • Archive size
    Archive size ~ 177.01 KB
  • Downloaded in total
    Downloaded in total 4 times
  • Downloaded this version
    This version: 2 times

Badge

bubao/esp_cron version: 0.0.5
|