{"id":22728508,"url":"https://github.com/6arms1leg/cirqu","last_synced_at":"2025-06-14T15:36:53.957Z","repository":{"id":253685462,"uuid":"407730009","full_name":"6arms1leg/cirqu","owner":"6arms1leg","description":"Simple and tiny library of a circular/ring/FIFO/LIFO buffer/queue to manage elements in a storage","archived":false,"fork":false,"pushed_at":"2025-02-16T22:14:15.000Z","size":1382,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-16T23:20:42.756Z","etag":null,"topics":["buffer","circular","embedded","embedded-systems","fifo","library","lifo","queue","ring","template"],"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/6arms1leg.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","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}},"created_at":"2021-09-18T02:07:56.000Z","updated_at":"2022-02-26T15:27:20.000Z","dependencies_parsed_at":"2024-08-18T19:42:02.998Z","dependency_job_id":"246e544a-1c69-4849-9d54-1c886415be9c","html_url":"https://github.com/6arms1leg/cirqu","commit_stats":null,"previous_names":["6arms1leg/cirqu"],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/6arms1leg%2Fcirqu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/6arms1leg%2Fcirqu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/6arms1leg%2Fcirqu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/6arms1leg%2Fcirqu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/6arms1leg","download_url":"https://codeload.github.com/6arms1leg/cirqu/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246262515,"owners_count":20749170,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["buffer","circular","embedded","embedded-systems","fifo","library","lifo","queue","ring","template"],"created_at":"2024-12-10T17:16:23.448Z","updated_at":"2025-03-30T00:27:35.759Z","avatar_url":"https://github.com/6arms1leg.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!--\nKeywords:\nbuffer, circular, embedded, embedded-systems, fifo, library, lifo, queue, ring,\ntemplate\n--\u003e\n\n# CirQu - Simple circular queue library\n\nThis library employs a simple and tiny\n\n*circular/ring/FIFO/LIFO buffer/queue*\n\nto manage items in a storage.\n\n\u003e Used terminology in this documentation:\n\u003e\n\u003e * Queue - Architectural concept to asynchronously storing produced data and\n\u003e   consuming it\n\u003e * Buffer - Detailed design component to arrange storage into items on which\n\u003e   the queue operates\n\u003e * Storage - The abstracted, physical memory managed by the buffer\n\u003e * Item - One of multiple items, handled by the queue (or storage units,\n\u003e   which constitute the buffer)\n\n## Requirements specification\n\nThe following loosely lists requirements, constraints, features and goals.\n\n* Circular/ring/FIFO/LIFO buffering/queueing management of multiple items\n  within a storage in embedded systems for real-time applications\n* Item type (and optional type qualifiers) can be chosen at compile time\n* Library can be \"instantiated\" multiple times in one project (without name\n  conflicts) for different item types via C++-like template imitation with\n  preprocessor macros (facilitates type safety in contrast to `void*` usage)\n* A new item can be pushed into the queue at its head or tail and the next\n  item can be pulled from the tail of the queue\n* Each stored item in the queue can be peeked at (i.e. accessed through\n  pointer without removal) by its relative index starting from the tail\n  position\n* Queue can be queried about its count of available free buffer item slots\n* Queue size can be configured at queue object instantiation/initialization by\n  linking allocated memory (storage managed by a buffer) to it\n* Lock-free access possible (with only one producer and consumer) if the queue\n  never overflows, that is, if `pushHead`/`pushTail` is never issued on a full\n  queue\n\n\u003c!-- Separator --\u003e\n\n* Library design\n* Deployment in embedded systems\n* Code implementation in the C programming language (\"C99\", ISO/IEC 9899:1999)\n* Interfaces with the application software through item storage arrays\n\n\u003c!-- Separator --\u003e\n\n* \"Design by Contract\" approach via \"dynamic\" assertions (`assert(...)`)\n* Low impact on technical budgets\n    * Low CPU utilization\n    * Small memory footprint in ROM (text, data) and RAM (data, heap, stack)\n    * Runs (also) well on \"small\" MCUs (e.g., AVR ATmega328P/Arduino Uno)\n* Quality model\n    * \"Simple\" (low complexity of software architecture and detailed design,\n      essential features only)\n    * Modular\n    * Re-usable\n    * Portable\n    * Unit tested with 100 % coverage (LOC executed, branches taken, functions\n      called)\n    * Defined quality metrics (see table below)\n    * MISRA C:2012 compliant\n    * Static code analysis pass\n    * No dynamic memory allocation (via `malloc()` or similar)\n    * SCM via Git with [Semantic Versioning](https://semver.org)\n* Well documented (from requirements over architecture to detailed design),\n  using Doxygen, Markdown, custom diagrams, UML\n* Traceability from requirements specification to implementation by\n  transitivity\n\nQuality metrics:\n\n| Metric                                       | Target   |\n| -------------------------------------------- | -------- |\n| No. of parameters/arguments (per func.)      | \\\u003c= 6    |\n| No. of instructions (per func.)              | \\\u003c= 60   |\n| No. of nested control structures (per func.) | \\\u003c= 5    |\n| Cyclomatic complexity number (per func.)     | \\\u003c= 10   |\n| Comment rate (per file)                      | \\\u003e= 20 % |\n| Unit test (decision) coverage                | = 100 %  |\n\n## How to deploy\n\nThe library can be \"instantiated\" multiple times in one project for different\nitem types via C++-like template imitation.\nIn contrast to the alternative solution of using `void*` item types, this\nfacilitates type safety.\nHowever, this comes with a slight increase in deployment complexity.\n\nThere are two options to deploy this library:\n\n**Option A - Wrapper module with multiple library \"instances\"**\n\n\u003e The example application uses this option.\n\nWith this option, the library is not directly `#include`d and compiled but\ninstead wrapped in another module, which unites all library \"instances\" by\nconfiguring and `#include`ing them.\nIt unconventionally requires to include implementation files in *exactly one\nsection* of the code as a tradeoff to keep the build process simple.\n\nBelow is a header and implementation file of such a wrapper module for an\nexample with two library \"instances\" with the suffix IDs `0` and `1`.\nOf course, there can be more or less \"instances\" and the ID names can be\nchanged as well.\n\nHeader file:\n\n```c\n#ifndef CQWRAP_H\n#define CQWRAP_H\n\n/* CirQu lib. interface configured with ID */\n#define CQTEMPLSEUP_ID 0\n#include \"CQqu.h\"\n#undef CQTEMPLSEUP_ID\n\n/* CirQu lib. interface configured with ID */\n#define CQTEMPLSEUP_ID 1\n#include \"CQqu.h\"\n#undef CQTEMPLSEUP_ID\n\n#endif /* CQWRAP_H */\n```\n\nImplementation file:\n\n```c\n/* Implementation of CirQu lib. configured with ID */\n#define CQTEMPLSEUP_ID 0\n#include \"CQqu.c\"\n#undef CQTEMPLSEUP_ID\n\n/* Implementation of CirQu lib. configured with ID */\n#define CQTEMPLSEUP_ID 1\n#include \"CQqu.c\"\n#undef CQTEMPLSEUP_ID\n```\n\n*Only* this wrapper module is then compiled and linked and its interface\nincluded, e.g.:\n\n```c\n/* Wrapper module with multiple \"instances\" of CirQu lib. */\n#include \"CQwrap.h\"\n```\n\n**Option B - Build library multiple times with different configurations**\n\n\u003e The unit tests use this option (as test coverage can only be measured this\n\u003e way).\n\nWith this option, the library is directly configured, `#include`d, compiled and\nlinked multiple times.\nIt unconventionally requires to wrap each interface inclusion in \"external\"\ninclude guards (since the interface has none to allow multiple inclusions) and\nto configure each interface beforehand.\n\nBelow is an example code snipped of such `#include`s for two library\n\"instances\" with the suffix IDs `0` and `1`.\nOf course, there can be more or less \"instances\" and the ID names can be\nchanged as well.\n\n```c\n/* CirQu lib. interface configured with ID */\n#ifndef CQQU_H0\n#define CQQU_H0\n#define CQTEMPLSEUP_ID 0\n#include \"CQqu.h\"\n#undef CQTEMPLSEUP_ID\n#endif /* CQQU_H0 */\n\n/* CirQu lib. interface configured with ID */\n#ifndef CQQU_H1\n#define CQQU_H1\n#define CQTEMPLSEUP_ID 1\n#include \"CQqu.h\"\n#undef CQTEMPLSEUP_ID\n#endif /* CQQU_H1 */\n```\n\nEach library \"instance\" must then be compiled into a separate object file by\nsupplying the ID name to the compiler, e.g.:\n\n```sh\n$ gcc -DCQTEMPLSEUP_ID=0 ... -c -I... CQqu.c -o CQqu0.o\n$ gcc -DCQTEMPLSEUP_ID=1 ... -c -I... CQqu.c -o CQqu1.o\n```\n\nAnd then all those library \"instance\" obejct files must be provided to the\nlinker when linking the application in which this library is used.\n\n**API usage for option A and B**\n\nTo use a library \"instance\"’s API (e.g. function calls, variable\ndeclaration/definition), the ID suffix must be appended, e.g. for ID `0`:\n\n```c\nCQqu_qu_t0 ...;\n\nCQqu_init0(...);\n```\n\n## Architecture\n\n![UML class diagram](./doc/arc/figures/cirqu-cd.png)\n\n![Example queue object](./doc/arc/figures/cirqu-ex-qu-obj-cstmd.png)\n\n![UML package diagram](./doc/arc/figures/cirqu-pd.png)\n\n## Coding standard\n\n### Applicable guidelines\n\nThis project aims to adhere to the following guidelines (with exceptions):\n\n* The Power of Ten - Rules for Developing Safety Critical Code (NASA/JPL; G. J.\n  Holzmann)\n* MISRA C:2012 - Guidelines for the use of the C language in critical systems\n\nIf necessary, deviations from the guidelines are allowed but must be justified\nand documented by means of inline comments.\n\n### Further style conventions\n\nFurthermore, the style is only loosely defined:\n\nNew added code should use the same style (i.e. \"look similar\") as the already\nexisting code base.\n\nSome remarks on the non-obvious points of this style convention:\n\n* Files are divided into an \"attributes\" and \"operations\" section (just like\n  classes in a UML class diagram)\n* `#include`s are placed in a module’s implementation (`*.c`) file(s), except\n  when they include header files external to the project (e.g. libc) or if a\n  module already uses another project-internal API in its own API (in both\n  exceptional cases those `#include`s are then placed in the module’s header\n  file)\n* Multiple instructions (ending with `;`) within a macro are enclosed in a\n  `do {...} while (false)` loop\n* The limit for line breaks is 80 characters (slight overshoots are acceptable\n  if it increases readability and if used sparingly)\n* Whitespace is inserted after control flow structure keywords (e.g.\n  `if/for/while/switch/return (...)`)\n* Comments\n    * ... can be placed above one or multiple line(s) (code block), addressing\n      all following line(s) until the next empty line or lesser indentation\n      level\n    * ... can be placed at the end of a line, addressing this line only\n    * ... can be placed below a long line with one additional indentation level\n      to address this one long line in a code block where a comment does not\n      fit at the end of the line\n* Far away closing brackets/keywords of control structures are commented to\n  indicate to what they belong (e.g. `#endif /* MODULENAME_H */`)\n* API functions/macros/variables (\"globals\") etc. are prefixed with their\n  module’s (abbreviated) name + `_`;  \n  if the project is intended to be included in another project (e.g. the\n  project is a library or framework), the prefix also starts with up to 3\n  characters that abbreviate the project name\n* Private, file-scope (`static`) variables are prefixed with `pv_`\n* Pointers are prefixed with `p_`\n* Types are suffixed with `_t`\n* In object-oriented code, the pointer argument to an object of a class’\n  function is named `me`\n\n## Workflow\n\nThis project uses a simple topic branch Git workflow.\nThe only permanently existing branches are \"develop\" (development status;\nunstable) and \"master\" (release status; stable).\nNew development efforts are done in separate topic branches, which are then\nmerged into develop once ready.\nFor releases, the \"develop\" branch is then merged into \"master\".\nFast-forward merges are preferred, if possible.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F6arms1leg%2Fcirqu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F6arms1leg%2Fcirqu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F6arms1leg%2Fcirqu/lists"}