{"id":33244134,"url":"https://github.com/martinribelotta/elog","last_synced_at":"2026-01-22T05:06:53.179Z","repository":{"id":66498417,"uuid":"286354399","full_name":"martinribelotta/elog","owner":"martinribelotta","description":"Embedded logger with minimal footprint and memory usage","archived":false,"fork":false,"pushed_at":"2025-05-22T18:21:28.000Z","size":129,"stargazers_count":38,"open_issues_count":0,"forks_count":9,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-05-22T19:36:50.399Z","etag":null,"topics":["arm","armv7m","cortex-m","embedded","log","logger","microcontroller"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/martinribelotta.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2020-08-10T02:11:45.000Z","updated_at":"2025-05-22T18:21:32.000Z","dependencies_parsed_at":"2025-05-26T04:34:29.996Z","dependency_job_id":null,"html_url":"https://github.com/martinribelotta/elog","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/martinribelotta/elog","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinribelotta%2Felog","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinribelotta%2Felog/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinribelotta%2Felog/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinribelotta%2Felog/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/martinribelotta","download_url":"https://codeload.github.com/martinribelotta/elog/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/martinribelotta%2Felog/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28655165,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-22T01:17:37.254Z","status":"online","status_checked_at":"2026-01-22T02:00:07.137Z","response_time":144,"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":["arm","armv7m","cortex-m","embedded","log","logger","microcontroller"],"created_at":"2025-11-16T21:00:28.147Z","updated_at":"2026-01-22T05:06:53.174Z","avatar_url":"https://github.com/martinribelotta.png","language":"C","funding_links":[],"categories":["debug","User Interface"],"sub_categories":["log","Logging"],"readme":"# Embedded Logger\n\nThis log system is thinked for embedded systems with mininmal\nresource utilization. The log system is designed to minimize\nmemory compsumition in flash or RAM, enable an eficient in-ram\nloggin buffer with very efficient storage.\n\nThe main goal of this aproach, consist in move fixed strings\noutside of final binary. The big compsumition of memory in any\nlog system consist in the fixed strings used to format the text.\n\nOur aproach consist to move log strings to a special section in\nexecutable and remove this from final artifact.\n\nThe firmware only refer the string as a virtual address (the\npointer of string in discaded area) and append the data to format\n(if need).\n\nIn the host, the strings are stored in binary format indexable\nwith the offset of the address contained in log dataset.\n\n![schema](doc/schema.png)\n\n## Internal log format\n\nThe log is stored in memory as an array of \"architecture register\nsize\" data type (by example, in armv7m, the data type is uint32_t)\n\nThe first word is an Id formad by a bitfield of offset and \narghoment count, encoded in convenient way.\n\nBy example, for this schema, it reserved 4 bit for arg count (max\nof 16 args) and 28 bits for offset.\n\n![msg-format](doc/msg-format.png)\n\nThe `message id` is composed by two fields:\n\n - string offset in memory: Obtained by masking message id with\n `0x0FFFFFFF`\n - argument count: Obtaining shifting 28 bits rigth the word and\n masking with `0xF`\n - The arguments is `uint32_t` aligned data after the message id\n word.\n\n## Memory layout\n\nNext, you can view the memory layout of ELF in the left, and the\nfinal binary in the middle. This is made by traditional `objcopy`\nprocess but with the section `.log` ignored in the copy.\nThe `.log` section is previously moved by `objcopy` to the own\nbinary file. At now, the offset in this file is correlated with\noffset in the message id, serialized in logger.\n\n![mem-layout](doc/objcopy-process.png)\n\n# API and Usage\n\nFor usage, you need to define a `LOG` memory area in address\n`0x?0000000` (with `?` replaced by any of sector unused in your\nchip) and generate section with name `.elog` that contains all of\nsymbols like `.elog.*`\n\n## Compiler and stdlib support\n\nYou only need these files for compile:\n\n - `inc/elog.h`: Public API\n - `inc/elog-cpp.h`: Preprocessor helper\n - `inc/elog-internal.h`: Internal structures\n - `src/elog.c`: Implementation\n\nAdditionally you need the next standar C elements available in your\nenvironment:\n\n - Implementation of `string.h` for `memcpy` usage\n - At least, definitions in `limits.h`, `stddef.h` and `stdint.h`\n - A preprocessor with `__VA_ARGS__` support (C99 or gnu extension)\n - Compiler with `__section__` attribute support (gnu gcc or clang\n   compatible)\n\n## API and usage\n\nYou need to initialize a logger object with buffer arena to operate:\n\n```c\nstatic char arena[1024];\n\n...\nelog_t *logger = elog_init(arena, sizeof(arena));\n```\n\nAfter this, you can use logger memory buffer to store consecutive\nlogs. If the space is full, the next log is silently ignored and\nneed to flush the buffer in order to continue with loggin\n\nFor insert new log in the buffer ask:\n\n```c\nELOG(logger, \"printf like string format\", \u003cvariable argument list\u003e);\n```\n\nThe variable argument list is casted to `msgparam_t` (in this\nconcrete implementation `uint32_t`) and stored in buffer after\nmessage id.\n\n\u003e NOTE: Due the nature of storage, this not support to store string\nformat like `%s` specifier... this not work in any form (only store\nthe memory pointer of the string, maybe invalid at the moment of\nthe debug)\n\nBefore the buffer is full, you need to flush this over a suitable\ninterface, or move it into secondary storage.\n\n```c\nvoid flush_func(elog_entry_t *e, int len, void *ctx)\n{\n    /* Flush entry e with len bytes (included header)\n     * The pointer ctx is passed as thirth parameter\n     * in elog_flush call\n     */\n}\n\n...\nelog_flush(logger, flush_func, function_context);\n...\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinribelotta%2Felog","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmartinribelotta%2Felog","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmartinribelotta%2Felog/lists"}