Essential Toolkit for Building an Excellent Embedded Software Framework

Click on the top “Embedded Application Research Institute“, select “Pin/Star the Official Account

Useful resources delivered to you first!

Source | Github

Compilation & Layout | Embedded Application Research Institute

Source: https://github.com/cproape/toolkit

1. Introduction

ToolKit is a general-purpose toolkit for embedded systems, which can be flexibly applied to programs with or without RTOS, implemented with C language object-oriented thinking to maximize code reuse. So far, the toolkit includes: circular queue, software timer, event set.

  • Queue Circular Queue

  1. 1. Supports dynamic and static ways to create and delete queues.

  2. 2. Independently configurable buffer size.

  3. 3. Supports data latest retention feature. When this mode is configured and the buffer is full, if new data is stored, the earliest data will be removed, keeping the buffer full.

  • Timer Software Timer

    1. 1. Supports dynamic and static ways to create and delete timers.

    2. 2. Supports loop and single modes.

    3. 3. Configurable timeout callback function.

    4. 4. Configurable timer to work in period or interval mode.

    5. 5. Uses a doubly linked list for unified timeout management, so adding timers does not increase timeout judgment code.

  • Event Event Set

    1. 1. Supports dynamic and static ways to create and delete event sets.

    2. 2. Each event supports up to 32 flags.

    3. 3. Event triggering can be configured as “AND” and “OR”.

    2. File Directory

    toolkit
    ├── include                         // Include file directory
    |   ├── toolkit.h                   // Toolkit header file
    |   └── toolkit_cfg.h               // Toolkit configuration file
    ├── src                             // Toolkit source code directory
    |   ├── tk_queue.c                  // Circular queue source code
    |   ├── tk_timer.c                  // Software timer source code
    |   └── tk_event.c                  // Event set source code
    ├── samples                         // Examples
    |   ├── tk_queue_samples.c          // Circular queue usage example source code
    |   ├── tk_timer_samples.c          // Software timer usage example source code
    |   └── tk_event_samples.c          // Event set usage example source code
    └── README.md                       // Documentation

    3. Function Definitions

    3.1 Configuration File

    • ToolKit Configuration Items

      Macro Definition Description
      TOOLKIT_USING_ASSERT ToolKit uses assertion functionality
      TOOLKIT_USING_QUEUE ToolKit uses circular queue functionality
      TOOLKIT_USING_TIMER ToolKit uses software timer functionality
      TOOLKIT_USING_EVENT ToolKit uses event set functionality
    • Queue Circular Queue Configuration Items

      Macro Definition Description
      TK_QUEUE_USING_CREATE Queue circular queue uses dynamic creation and deletion
    • Timer Software Timer Configuration Items

      Macro Definition Description
      TK_TIMER_USING_CREATE Timer software timer uses dynamic creation and deletion
      TK_TIMER_USING_INTERVAL Timer software timer uses interval mode
      TK_TIMER_USING_TIMEOUT_CALLBACK Timer software timer uses timeout callback function
    • Event Event Set Configuration Items

      Macro Definition Description
      TK_EVENT_USING_CREATE Event event set uses dynamic creation and deletion

    Note: When configuring TOOLKIT_USING_ASSERT, all functions will enable parameter checks.

    3.2 Queue Circular Queue API Functions

    The following are detailed API descriptions and brief example programs. Comprehensive demo can be viewed in tk_queue_samples.c example.

    3.2.1 Dynamic Queue Creation

    Note: This function can only be used when TOOLKIT_USING_QUEUE is configured. This function requires malloc.

    struct tk_queue *tk_queue_create(uint16_t queue_size, uint16_t max_queues, bool keep_fresh);
    Parameter Description
    queue_size Buffer size (in bytes)
    max_queues Maximum number of queues
    keep_fresh Whether to maintain the latest mode, true: keep latest; false: default (full cannot store more)
    Return Value The created queue object (NULL indicates creation failed)

    Queue creation example:

    int main(int argc, char *argv[])
    {
        /* Dynamically create a circular queue "queue", buffer size 50 bytes, do not keep latest */
        struct tk_queue *queue = tk_queue_create(50, 1, false);
        if( queue == NULL){
            printf("Queue creation failed!\n");
        }
        /* ... */
        /* You can add your code under here. */
        return 0;
    }

    3.2.2 Dynamic Queue Deletion

    Note: This function can only be used when TOOLKIT_USING_QUEUE is configured. This function requires free. It must be a dynamic created queue object.

    bool tk_queue_delete(struct tk_queue *queue);
    Parameter Description
    queue The queue object to be deleted
    Return Value true: deletion successful; false: deletion failed

    3.2.3 Static Initialization Queue

    bool tk_queue_init(struct tk_queue *queue, void *queuepool, uint16_t pool_size, uint16_t queue_size, bool keep_fresh);
    Parameter Description
    queue The queue object to be initialized
    *queuepool Queue buffer
    pool_size Buffer size (in bytes)
    queue_size Queue element size (in bytes)
    keep_fresh Whether to maintain the latest mode, true: keep latest; false: default (full cannot store more)
    Return Value true: initialization successful; false: initialization failed

    Queue creation example:

    int main(int argc, char *argv[])
    {
        /* Define a circular queue */
        struct tk_queue queue;
        /* Define circular queue buffer */
        uint8_t queue_pool[100];
        /* Statically create a circular queue "queue", buffer is queue_pool, size is the size of queue_pool, mode is to keep latest */
        if( tk_queue_init(&queue, queue_pool, sizeof(queue_pool), 
                          sizeof(queue_pool[0]), true) == false){
            printf("Queue creation failed!\n");
        }
        /* ... */
        /* You can add your code under here. */
    }
    

    3.2.4 Static Detach Queue

    Note: This will detach the buffer from the queue. It must be a static created queue object.

    bool tk_queue_detach(struct tk_queue *queue);
    Parameter Description
    queue The queue object to detach
    Return Value true: detachment successful; false: detachment failed

    3.2.5 Clear Queue

    bool tk_queue_clean(struct tk_queue *queue);
    Parameter Description
    queue The queue object to clear
    Return Value true: clear successful; false: clear failed

    3.2.6 Check if Queue is Empty

    bool tk_queue_empty(struct tk_queue *queue);
    Parameter Description
    queue The queue object to query
    Return Value true: empty; false: not empty

    3.2.7 Check if Queue is Full

    bool tk_queue_full(struct tk_queue *queue);
    Parameter Description
    queue The queue object to query
    Return Value true: full; false: not full

    3.2.8 Read an Element from the Queue (without removing it)

    bool tk_queue_peep(struct tk_queue *queue, void *pval);
    Parameter Description
    queue The queue object
    *pval Address to read value
    Return Value true: read successful; false: read failed

    3.2.9 Remove an Element

    bool tk_queue_remove(struct tk_queue *queue);
    Parameter Description
    queue The object to remove an element from
    Return Value true: removal successful; false: removal failed

    3.2.10 Push (enqueue) an Element into the Queue

    bool tk_queue_push(struct tk_queue *queue, void *val);
    Parameter Description
    queue The queue object to push into
    *val Value to push
    Return Value true: success; false: failure

    3.2.11 Pop (dequeue) an Element from the Queue

    bool tk_queue_pop(struct tk_queue *queue, void *pval);
    Parameter Description
    queue The queue object to pop from
    *pval Popped value
    Return Value true: success; false: failure

    3.2.12 Query Current Length of the Queue

    uint16_t tk_queue_curr_len(struct tk_queue *queue);
    Parameter Description
    queue The queue object to query
    Return Value Current length of the queue data

    3.2.13 Push (enqueue) Multiple Elements into the Queue

    uint16_t tk_queue_push_multi(struct tk_queue *queue, void *pval, uint16_t len);
    Parameter Description
    queue The queue object to push into
    *pval Address of the data to push
    len Number of elements to push
    Return Value Actual number of pushed elements

    3.2.14 Pop (dequeue) Multiple Elements from the Queue

    uint16_t tk_queue_pop_multi(struct tk_queue *queue, void *pval, uint16_t len);
    Parameter Description
    queue The queue object to pop from
    *pval Address to store popped data
    len Number of data to pop
    Return Value Actual number of popped elements

    3.3 Timer Software Timer API Functions

    The following are detailed API descriptions and brief example programs. Comprehensive demo can be viewed in tk_timer_samples.c example.

    3.3.1 Software Timer Function Initialization

    Note: This function is called initially when using the timer function, aiming to create the timer list head node and configure the tick acquisition callback function.

    bool tk_timer_func_init(uint32_t (*get_tick_func)(void));
    Parameter Description
    get_tick_func Callback function to get system tick
    Return Value true: initialization successful; false: initialization failed

    3.3.2 Dynamic Timer Creation

    Note: This function can only be used when TOOLKIT_USING_TIMER is configured. This function requires malloc.

    struct tk_timer *tk_timer_create(void(*timeout_callback)(struct tk_timer *timer));
    Parameter Description
    timeout_callback Timer timeout callback function, can be configured as NULL if not used
    Return Value The created timer object (NULL indicates creation failed)

    Timer creation example::

    /* Define get system tick callback function */
    uint32_t get_sys_tick(void)
    {
        return tick;
    }
    
    /* Timer timeout callback function */
    void timer_timeout_callback(struct tk_timer *timer)
    {
        printf("timeout_callback: timer timeout:%ld\n", get_sys_tick());
    }
    
    int main(int argc, char *argv[])
    {
        /* Initialize software timer function and configure tick acquisition callback function*/
        tk_timer_func_init(get_sys_tick);
        
        /* Define timer pointer */
        tk_timer_t timer = NULL;
        /* Dynamically create timer and configure timer timeout callback function */
        timer = tk_timer_create((tk_timer_timeout_callback *)timer_timeout_callback);
        if (timer == NULL)
        {
            printf("Timer creation failed!\n");
            return 0;
        }
        /* ... */
        /* You can add your code under here. */
        return 0;
    }
    

    3.3.3 Dynamic Timer Deletion

    When configuring TOOLKIT_USING_TIMER, this function can be used. This function requires free. It must be a dynamic created timer object.

    bool tk_timer_delete(struct tk_timer *timer);
    Parameter Description
    timer The timer object to delete
    Return Value true: deletion successful; false: deletion failed

    3.3.4 Static Timer Initialization

    bool tk_timer_init(struct tk_timer *timer, void (*timeout_callback)(struct tk_timer *timer));
    Parameter Description
    timer The timer object to initialize
    timeout_callback Timer timeout callback function, can be configured as NULL if not used
    Return Value true: creation successful; false: creation failed

    Queue creation example:

    /* Define get system tick callback function */
    uint32_t get_sys_tick(void)
    {
        return tick;
    }
    
    /* Timer timeout callback function */
    void timer_timeout_callback(struct tk_timer *timer)
    {
        printf("timeout_callback: timer timeout:%ld\n", get_sys_tick());
    }
    
    int main(int argc, char *argv[])
    {
        /* Define timer */
        struct tk_timer timer;
        bool result = tk_timer_init( &timer,(tk_timer_timeout_callback *)timer_timeout_callback);
        if (result == NULL)
        {
            printf("Timer creation failed!\n");
            return 0;
        }
        /* ... */
        /* You can add your code under here. */
        return 0;
    }
    

    3.3.5 Static Detach Timer

    Note: This will remove the timer from the timer linked list. It must be a static created timer object.

    bool tk_timer_detach(struct tk_timer *timer);
    Parameter Description
    timer The timer object to detach
    Return Value true: detachment successful; false: detachment failed

    3.3.6 Start Timer

    bool tk_timer_start(struct tk_timer *timer, tk_timer_mode mode, uint32_t delay_tick);
    Parameter Description
    timer The timer object to start
    mode Working mode, single: TIMER_MODE_SINGLE; loop: TIMER_MODE_LOOP
    delay_tick Timer duration (in ticks)
    Return Value true: start successful; false: start failed

    3.3.7 Stop Timer

    bool tk_timer_stop(struct tk_timer *timer);
    Parameter Description
    timer The timer object to stop
    Return Value true: stop successful; false: stop failed

    3.3.8 Continue Timer

    bool tk_timer_continue(struct tk_timer *timer);
    Parameter Description
    timer The timer object to continue
    Return Value true: continue successful; false: continue failed

    3.3.9 Restart Timer

    Note: Restart duration is the duration configured when the timer was last started.

    bool tk_timer_restart(struct tk_timer *timer);
    Parameter Description
    timer The timer object to restart
    Return Value true: restart successful; false: restart failed

    3.3.10 Get Timer Mode

    tk_timer_mode tk_timer_get_mode(struct tk_timer *timer);
    Parameter Description
    timer The timer object to get
    Return Value Timer mode
    Timer Mode Description
    TIMER_MODE_SINGLE Single mode
    TIMER_MODE_LOOP Loop mode

    3.3.11 Get Timer State

    tk_timer_state tk_timer_get_state(struct tk_timer *timer);
    Parameter Description
    timer The timer object to get
    Return Value Timer state
    Timer Mode Description
    TIMER_STATE_RUNNING Running state
    TIMER_STATE_STOP Stopped state
    TIMER_STATE_TIMEOUT Timeout state

    3.3.12 Timer Processing

    bool tk_timer_loop_handler(void);
    Parameter Description
    Return Value true: normal; false: abnormal, the timer function has not been initialized before calling this function “tk_timer_func_init

    Note: The tk_timer_loop_handler function must be called in a continuous loop.

    3.3.13 Timeout Callback Function

    Function Prototype:

    typedef void (*timeout_callback)(struct tk_timer *timer);

    Description: Multiple timeout callback functions can be defined, that is, one timer corresponds to one callback function, or multiple timers correspond to one callback function.

    One-to-One

    /* Define two callback functions, corresponding to timer1 and timer2 */
    void timer1_timeout_callback(struct tk_timer *timer){
        printf("Timer 1 timeout!\n");
    }
    void timer2_timeout_callback(struct tk_timer *timer){
        printf("Timer 2 timeout!\n");
    }
    /* Create two timers, configure separate timeout callback functions */
    timer1 = tk_timer_create((timeout_callback *)timer1_timeout_callback);
    timer2 = tk_timer_create((timeout_callback *)timer2_timeout_callback);
    

    Many-to-One

    /* Timer timer1 and timer2 share a callback function, distinguish in the callback function */
    void timer_timeout_callback(struct tk_timer *timer){
        if (timer == timer1)
            printf("Timer 1 timeout!\n");
        else if (timer == timer2)
            printf("Timer 2 timeout!\n");
    }
    /* Create two timers, using the same timeout callback function */
    timer1 = tk_timer_create((timeout_callback *)timer_timeout_callback);
    timer2 = tk_timer_create((timeout_callback *)timer_timeout_callback);
    

    3.4 Event Event Set API Functions

    The following are detailed API descriptions and brief example programs. Comprehensive demo can be viewed in tk_event_samples.c example.

    3.4.1 Dynamically Create an Event

    Note: This function can only be used when TOOLKIT_USING_EVENT is configured. This function requires malloc.

    struct tk_event *tk_event_create(void);
    Parameter Description
    Return Value The created event object (NULL indicates creation failed)

    3.4.2 Dynamically Delete an Event

    This function can only be used when TOOLKIT_USING_TIMER is configured. This function requires free. It must be a dynamic created event object.

    bool tk_event_delete(struct tk_event *event);
    Parameter Description
    event The event object to delete
    Return Value true: deletion successful; false: deletion failed

    3.4.3 Static Initialization of an Event

    bool tk_event_init(struct tk_event *event);
    Parameter Description
    event The event object to initialize
    Return Value true: creation successful; false: creation failed

    3.4.4 Send Event Flag

    bool tk_event_send(struct tk_event *event, uint32_t event_set);
    Parameter Description
    event The target event object to send
    event_set Event flag, each flag occupies 1Bit, multiple flags can be sent with “|”
    Return Value true: send successful; false: send failed

    3.4.5 Receive Event

    bool tk_event_recv(struct tk_event *event, uint32_t event_set, uint8_t option, uint32_t *recved);
    Parameter Description
    event The target event object to receive
    event_set Interested flags, each flag occupies 1Bit, multiple flags can be sent with “|”
    option Operation, flag AND: TK_EVENT_OPTION_AND; flag OR: TK_EVENT_OPTION_OR; clear flag: TK_EVENT_OPTION_CLEAR
    Return Value true: send successful; false: send failed

    This article is sourced from the internet, conveying knowledge for free. Copyright belongs to the original author. If there are copyright issues, please contact me for deletion.

    Note

    Due to recent changes in the WeChat public account push rules, to prevent being unable to find it, you can pin it to the top, so that the articles pushed each time will appear in your subscription list.

    You may also like:

    Sharing a method for log rollover

    Can’t solve the bug? Use the log method

    Some suggestions on embedded system log printing

    Sharing an embedded software tool checklist!

    Easy to understand | Step-by-step guide to writing your first upper computer

    Practical | Teach you to build an embedded web server in 10 minutes

    Animated diagrams of commonly used communication protocols for embedded systems, collect!

    A general library suitable for differential upgrades for embedded systems!

    Sharing a protocol format with high flexibility (with code examples)

    Sharing several practical code snippets (second edition)

    Leave a Comment

    ×