{"id":28795670,"url":"https://github.com/bakerface/e3","last_synced_at":"2026-06-20T20:31:48.117Z","repository":{"id":11145951,"uuid":"13513481","full_name":"bakerface/e3","owner":"bakerface","description":"Jump-starting bare-metal embedded C projects.","archived":false,"fork":false,"pushed_at":"2014-01-12T15:49:49.000Z","size":348,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-18T03:09:50.645Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bakerface.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-10-12T01:35:06.000Z","updated_at":"2014-01-12T15:49:49.000Z","dependencies_parsed_at":"2022-08-30T21:11:06.428Z","dependency_job_id":null,"html_url":"https://github.com/bakerface/e3","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/bakerface/e3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bakerface%2Fe3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bakerface%2Fe3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bakerface%2Fe3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bakerface%2Fe3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bakerface","download_url":"https://codeload.github.com/bakerface/e3/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bakerface%2Fe3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34585195,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-20T02:00:06.407Z","response_time":98,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-18T03:09:50.067Z","updated_at":"2026-06-20T20:31:48.111Z","avatar_url":"https://github.com/bakerface.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# E3\n\nE3 is a minimalistic freestanding architecture intended to jump-start bare-metal embedded C projects. The goal of E3 is to provide a portable C framework with a tiny footprint.\n\n## Table of Contents\n\n- [Installation](#installation)\n- [Getting the source](#getting-the-source)\n- [Running the tests](#running-the-tests)\n- [Checking code coverage](#checking-code-coverage)\n- [Checking code complexity](#checking-code-complexity)\n- [Creating an archive](#creating-an-archive)\n- [Checking object size](#checking-object-size)\n- [Preparing for push](#preparing-for-push)\n- [Timer API](#timer-api)\n  - [e3_timer_interrupt](#e3_timer_interrupt)\n  - [e3_timer_tick](#e3_timer_tick)\n  - [e3_timer_create](#e3_timer_create)\n  - [e3_timer_delete](#e3_timer_delete)\n  - [Example](#timer-example)\n- [Hierarchical State Machine API](#hierarchical-state-machine-api)\n  - [E3_HSM_DEFINE](#e3_hsm_define)\n  - [e3_hsm_create](#e3_hsm_create)\n  - [e3_hsm_dispatch](#e3_hsm_dispatch)\n  - [e3_hsm_delete](#e3_hsm_delete)\n  - [Example](#hierarchical-state-machine-example)\n- [Event API](#event-api)\n  - [e3_event_create](#e3_event_create)\n  - [e3_event_delete](#e3_event_delete)\n  - [e3_event_fire](#e3_event_fire)\n  - [e3_event_listener_create](#e3_event_listener_create)\n  - [e3_event_listener_delete](#e3_event_listener_delete)\n  - [Example](#event-example)\n\n## Getting the source\nTo download the latest source, clone the GIT repository:\n\n```\ngit clone https://github.com/bakerface/e3.git\n```\n\nThis will create a directory named *e3* in your working directory.\n\n## Running the tests\nTo execute the unit tests, run the following:\n\n```\nmake\n```\n\nThis will execute each test and print the test statistics to your console window.\n\n## Checking code coverage\nTo generate code coverage statistics, run the following:\n\n```\nmake coverage\n```\n\nThis will generate a directory named *coverage* containing the code coverage statistics in HTML format. Simply open *index.html* in a web browser to view the coverage statistics. *Please note that each function must have 100% line, function, and branch coverage in order to be pushed to the repository.*\n\n## Checking code complexity\nTo generate code complexity metrics, run the following:\n\n```\nmake complexity\n```\n\nThis will dump a table to your console window showing cyclomatic complexity and other useful statistics for each function. *Please note that each function must have a cyclomatic complexity less than five in order to be pushed to the repository.*\n\n## Creating an archive\nTo generate a static archive of the code, run the following:\n\n```\nmake archive\n```\n\nThis will create a file named *libe3.a* in the working directory.\n\n## Checking object size\nTo generate object size statistics, run the following:\n\n```\nmake size\n```\n\nThis will dump a table to your console window showing the size of each section of the archive per object file. *Please note that to maintain the minimalistic nature of the framework, the source should be designed in such a way as to minimize the size of each section.*\n\n## Preparing for push\nBefore pushing code changes to the repository, run the following:\n\n```\nmake tidy\n```\n\nThis will tidy up all source files to ensure that they meet the formatting requirements and are compatible on all platforms.\n\n## Timer API\nBelow is the documentation for each of the timer functions, as well as a few examples showing how to use them.\n\n### e3_timer_interrupt\nThis function increments the internal system timer by one clock tick. *Please note that this function should be called from a timer interrupt service routine at a predefined interval.*\n\n### e3_timer_tick\nThis function uses the internal system timer to determine which (if any) timers have expired. If a timer has expired, the timer function is invoked and the timer is deleted. This function will return the idle time (in clock ticks) before the next timer is expected to expire, or zero if there are no timers scheduled. *Please note that this function should not be called from an interrupt service routine since there are no guarentees for its execution time. This function should be invoked at a predefined interval in the application.*\n\n| Return           | Description                                       |\n|:-----------------|:--------------------------------------------------|\n| e3_timer_ticks_t | The idle time, or zero if no timers are scheduled |\n\n### e3_timer_create\nThis function creates a timer that schedules a function to be called after the specified number of clock ticks has passed. *Please note that these are one-shot timers, which will be deleted automatically after they expire. To reschedule a timer, re-create the timer from within the timer function.*\n\n| Parameter                    | Description                                                  |\n|:-----------------------------|:-------------------------------------------------------------|\n| e3_timer_t *timer            | The timer to create                                          |\n| e3_timer_ticks_t ticks       | The number of clock ticks to wait before called the function |\n| e3_timer_function_t function | The function to invoke                                       |\n| void *cookie                 | The user-defined function argument                           |\n\n### e3_timer_delete\nThis function deletes a previously created timer, preventing the timer function from being called.\n\n| Parameter          | Description                                 |\n|:-------------------|:--------------------------------------------|\n| e3_timer_t *timer  | The timer to delete                         |\n\n### Timer Example\nBelow is an example showing how to create and use timers.\n\n``` c\n#include \u003cstdio.h\u003e\n#include \u003ce3-timer.h\u003e\n\nstatic void\ntimer_isr(void) {\n    e3_timer_interrupt();\n}\n\nstatic void\nsay(void *cookie) {\n    puts((const char *) cookie);\n}\n\nstatic int\nmain(void) {\n    e3_timer_t first, second;\n    \n    e3_timer_create(\u0026first, 10, say, \"this will never be called\");\n    e3_timer_delete(\u0026first);\n    \n    e3_timer_create(\u0026first, 20, say, \"this will be called first\");\n    e3_timer_create(\u0026second, 30, say, \"this will be called second\");\n\n    while (e3_timer_tick()) {\n        puts(\"there are still timers pending\");\n    }\n    \n    puts(\"all timers have expired\");\n    return 0;\n}\n```\n\n## Hierarchical State Machine API\nBelow is the documentation for each of the hierarchical state machine functions, as well as a few examples showing how to use them.\n\n### E3_HSM_DEFINE\nThis macro defines the structure of a hierarchical state machine in read-only memory.\n\n| Parameter   | Description                                                    |\n|:------------|:---------------------------------------------------------------|\n| #define HSM | The macro containing the hierarchical state machine definition |\n\n### e3_hsm_create\nThis function creates a new instance of a hierarchical state machine and transitions to the specified initial state.\n\n| Parameter                          | Description                              |\n|:-----------------------------------|:-----------------------------------------|\n| e3_hsm_t *hsm                      | The hierarchical state machine to create |\n| const e3_hsm_state_t * const state | The initial state                        |\n\n### e3_hsm_dispatch\n\nThis function dispatches the specified signal to the hierarchical state machine. If the signal was permitted for the current state, the hierarchical state machine transitions to, and returns, the destination state. If the signal was not permitted, then there is no state transition and NULL is returned. *Please note that when transitioning from one state to another, the least common ancestor of the two states is calculated. The exit function for each state is called in reverse order until the least common ancestor is reached, then the entrance function for each state is called in order until the destination state is reached.*\n\n| Parameter              | Description                                |\n|:-----------------------|:-------------------------------------------|\n| e3_hsm_t *hsm          | The hierarchical state machine             |\n| e3_hsm_signal_t signal | The signal to dispatch                     |\n\n| Return                 | Description                                    |\n|:-----------------------|:-----------------------------------------------|\n| const e3_hsm_state_t * | The destination state or NULL if not permitted |\n\n### e3_hsm_delete\nThis function deletes an instance of a hierarchical state machine and transitions out of the current state.\n\n| Parameter          | Description                                 |\n|:-------------------|:--------------------------------------------|\n| e3_hsm_t *hsm      | The hierarchical state machine to delete    |\n\n### Hierarchical State Machine Example\nBelow is an example showing how to define and use a hierarchical state machine.\n\n``` c\n#include \u003cstdio.h\u003e\n#include \u003ce3-hsm.h\u003e\n\n#define SLEEP_HSM(SIGNAL, STATE, SUBSTATE, PERMIT)             \\\n    SIGNAL(NOISE)                                              \\\n    SIGNAL(WHISPER)                                            \\\n    SIGNAL(SCREAM)                                             \\\n    STATE(AWAKE, awake_enter, awake_exit,                      \\\n        PERMIT(WHISPER, NODDING)                               \\\n        PERMIT(SCREAM,  AWAKE)                                 \\\n        PERMIT(SILENCE, NODDING))                              \\\n    SUBSTATE(AWAKE, NODDING, nodding_enter, nodding_exit,      \\\n        PERMIT(SILENCE, SLEEPING))                             \\\n    STATE(SLEEPING, sleeping_enter, sleeping_exit,             \\\n        PERMIT(WHISPER, SLEEPING)                              \\\n        PERMIT(SCREAM,  AWAKE)                                 \\\n        PERMIT(SILENCE, SNORING))                              \\\n    SUBSTATE(SLEEPING, SNORING, snoring_enter, snoring_exit,   \\\n        E3_PERMIT_NONE)\n\nstatic void\nawake_enter(e3_hsm_t *hsm) {\n    puts(\"awake entered\");\n}\n\nstatic void\nawake_exit(e3_hsm_t *hsm) {\n    puts(\"awake exited\");\n}\n\nstatic void\nnodding_enter(e3_hsm_t *hsm) {\n    puts(\"nodding entered\");\n}\n\nstatic void\nnodding_exit(e3_hsm_t *hsm) {\n    puts(\"nodding exited\");\n}\n\nstatic void\nsleeping_enter(e3_hsm_t *hsm) {\n    puts(\"sleeping entered\");\n}\n\nstatic void\nsleeping_exit(e3_hsm_t *hsm) {\n    puts(\"sleeping exited\");\n}\n\nstatic void\nsnoring_enter(e3_hsm_t *hsm) {\n    puts(\"snoring entered\");\n}\n\nstatic void\nsnoring_exit(e3_hsm_t *hsm) {\n    puts(\"snoring exited\");\n}\n\nE3_HSM_DEFINE(SLEEP_HSM)\n\nstatic int\nmain(void) {\n    e3_hsm_t hsm;\n    \n    e3_hsm_create(\u0026hsm, AWAKE);\n    e3_hsm_dispatch(\u0026hsm, WHISPER);\n    e3_hsm_dispatch(\u0026hsm, SILENCE);\n    e3_hsm_dispatch(\u0026hsm, SILENCE);\n    e3_hsm_dispatch(\u0026hsm, SCREAM);\n    e3_hsm_delete(\u0026hsm);\n    \n    return 0;\n}\n```\n\n## Event API\nBelow is the documentation for each of the event functions, as well as a few examples showing how to use them.\n\n### e3_event_create\nThis function creates an event with no listeners.\n\n| Parameter         | Description                                           |\n|:------------------|:------------------------------------------------------|\n| e3_event_t *event | The event to create                                   |\n\n### e3_event_delete\nThis function deletes an event and removes all listeners.\n\n| Parameter         | Description                                           |\n|:------------------|:------------------------------------------------------|\n| e3_event_t *event | The event to delete                                   |\n\n### e3_event_fire\nThis function fires the event, signaling all listeners.\n\n| Parameter         | Description                                           |\n|:------------------|:------------------------------------------------------|\n| e3_event_t *event | The event to delete                                   |\n| void *arg         | The event argument to pass to the listeners           |\n\n### e3_event_listener_create\nThis function creates an event listener and subscribes to an event. *Please note that the listener will be signaled every time the event is fired, and must be deleted to stop receiving the events.*\n\n| Parameter                     | Description                                  |\n|:------------------------------|:---------------------------------------------|\n| e3_event_listener_t *listener | The listener to create                       |\n| e3_event_t *event             | The event to subscribe to                    |\n| e3_event_handler_t function   | The function called when the event is fired  |\n| void *cookie                  | The user-defined function argument           |\n\n### e3_event_listener_delete\nThis function deletes an event listener and unsubscribes from the event.\n\n| Parameter                     | Description                               |\n|:------------------------------|:------------------------------------------|\n| e3_event_listener_t *listener | The listener to delete                    |\n\n### Event Example\nBelow is an example showing how to create and use events.\n\n``` c\n#include \u003cstdio.h\u003e\n#include \u003ce3-event.h\u003e\n\nstatic void\nsay(void *cookie, void *arg) {\n    printf(\"%s: %s\\r\\n\", (const char *) cookie, (const char *) arg);\n}\n\nstatic int\nmain(void) {\n    e3_event_t event;\n    e3_event_listener_t foo;\n    e3_event_listener_t bar;\n\n    e3_event_create(\u0026event);\n    e3_event_fire(\u0026event, \"not printed\");\n    \n    e3_event_listener_create(\u0026foo, \u0026event, say, \"FOO\");\n    e3_event_fire(\u0026event, \"printed by foo\");\n    \n    e3_event_listener_create(\u0026bar, \u0026event, say, \"BAR\");\n    e3_event_fire(\u0026event, \"printed by foo and bar\");\n    \n    e3_event_listener_delete(\u0026foo);\n    e3_event_fire(\u0026event, \"printed by bar\");\n    e3_event_delete(\u0026event);\n\n    return 0;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbakerface%2Fe3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbakerface%2Fe3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbakerface%2Fe3/lists"}