{"id":32415983,"url":"https://github.com/larshei/lovelybuffer","last_synced_at":"2025-10-25T15:51:50.775Z","repository":{"id":60789722,"uuid":"263362961","full_name":"larshei/lovelyBuffer","owner":"larshei","description":"A FIFO and ring buffer implementation in C with custom data type and multiple buffers for e.g. double buffering or buffering multiple interfaces on embedded devices.","archived":false,"fork":false,"pushed_at":"2020-07-27T10:37:07.000Z","size":50,"stargazers_count":2,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2023-10-28T18:31:24.719Z","etag":null,"topics":["c","fifo","library","multiple-buffers","ring-buffer"],"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/larshei.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}},"created_at":"2020-05-12T14:37:11.000Z","updated_at":"2023-08-12T00:27:44.000Z","dependencies_parsed_at":"2022-10-04T21:51:59.724Z","dependency_job_id":null,"html_url":"https://github.com/larshei/lovelyBuffer","commit_stats":null,"previous_names":[],"tags_count":0,"template":null,"template_full_name":null,"purl":"pkg:github/larshei/lovelyBuffer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larshei%2FlovelyBuffer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larshei%2FlovelyBuffer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larshei%2FlovelyBuffer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larshei%2FlovelyBuffer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/larshei","download_url":"https://codeload.github.com/larshei/lovelyBuffer/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/larshei%2FlovelyBuffer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":280979467,"owners_count":26423964,"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","status":"online","status_checked_at":"2025-10-25T02:00:06.499Z","response_time":81,"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":["c","fifo","library","multiple-buffers","ring-buffer"],"created_at":"2025-10-25T15:51:44.854Z","updated_at":"2025-10-25T15:51:50.767Z","avatar_url":"https://github.com/larshei.png","language":"C","readme":"FIFO and ring buffer in C\n===\n\n![Unit\nTests](https://github.com/larshei/buffer_c/workflows/Unit%20Tests/badge.svg)\n\nThis is an implementation of a buffer in C, with the following attributes:\n\n- Buffer with user defined data type.\n- Manages read/write and mutliple buffer instances.\n- FIFO or ring buffer mode for each buffer instance.\n- Buffer instances / slots can be claimed and returned for repeated use.\n- The buffer struct is hidden to the user.\n- The buffer struct is managing data, not storing tha data itself.\n- Memory usage and execution time not known yet, both expected to be very low.\n  \nUnit tests in Ceedling are included.\n\nThe Buffer System\n===\n\nThe buffer system is designed to provide multiple FIFO-buffers and allow\nasynchronous data collection / data processing.\n\nAfter initialization, a buffer handle for each buffer is put on a stack and can\nbe claimed by the users program. The buffer can later be returned to the\nsystem and claimed again.\n\nExample Usage\n===\n\n## Configuration\n\nLets assume you have an SPI driver, that requires a buffer for both input and\noutput, and communication is based on exchanging bytes (= 8 bit length).\n\nConfigure the buffer system in `buf_buffer_config.h` like so:\n```\n#define DATA_TYPE          uint8_t\n#define BUF_BUFFER_COUNT   2\n```\n\n## System Init\n\nAt startup, the buffer system needs to be initialized, using\n```\nif (buf_init_system() != BUF_OK) {\n    // handle error\n}\n```\n\n## Buffer Init\n\nSystem init prepares the buffer system itself, not a specific buffer.\n\nEach buffer must be initialized by itself. The buffers only manage data and\ndont contain the data themselves, so the user needs to provide memory for\nstorage. Buffers will be used in the application based on their handle/pointer.\n\n```\nDATA_TYPE     buffer_array[100];\nbuf_buffer_t  buffer_handle;\n```\n\nTo give the data storage information to the buffer system, create a\n`buf_data_info_t` structure:\n```\nbuf_data_info_t             buffer_config;\nbuffer_config.array         = (DATA_TYPE*) buffer_array;\nbuffer_config.element_count = BUFFER_SIZE;\nbuffer_config.element_size  = sizeof(DATA_TYPE);\n```\nand pass it to the system to retrieve and initialize a buffer:\n```\nbuffer_handle = buf_claim_and_init_buffer((buf_data_info_t*)\u0026buffer_config);\n```\nMake sure to not claim more buffers than you have configured in\n`BUF_BUFFER_COUNT`, otherwise this function will return NULL instead of a buffer\nhandle.\n\n## Buffer Mode\n\nAfter buffer initialization, a buffer is used in FIFO mode. Users might want to\nswitch to ring buffer mode. The difference is:\n- FIFO: A FIFO blocks further write access when the buffer is full, making sure\n  all data that was put in the buffer is taken out.\n- Ring Buffer: A ring buffer always allows write access, overwriting old data\n  after a wrap around. Oftentimes, a ring buffer does not have a dedicated read\n  pointer (but we do!)\n```\nuint8_t  result1 = buf_fifo_buffer_mode(buffer_handle);\nuint8_t  result2 = buf_ring_buffer_mode(buffer_handle);\n```\nThe functions change the internal state of the buffer. It may be changed at any\ntime. Returns `BUF_OK`.\n\nGet the current buffer mode of either `BUF_RINGBUF` or `BUF_FIFOBUF` using\n```\nuint8_t  mode =  buf_get_buffer_mode(buffer_handle);\n```\n\n## Buffer Usage\n\nUsing a buffer is pretty straight forward adding and reading values, using\n```\nuint8_t    result = buf_add_element (buffer_handle, value);\nDATA_TYPE  value  = buf_read_element(buffer_handle);\n```\n\n`buf_add_element` returns `BUF_OK` or `BUF_FULL`.\n`buf_read_element` returns `value` or `NULL`.\n\nThe functions can be guarded by using\n```\nuint8_t  is_empty = buf_is_empty(buffer_handle);\nuint8_t  is_full  = buf_is_full (buffer_handle);\n```\n\n## Returning Buffers that are no longer used\n\nIn a scenario with continuous data collection and asynchronous data processing\nit may be a good idea to have the data collection task claim a buffer, fill it\nand then pass it on to one of many other tasks. These tasks can then return the\nbuffer once its content has been processed.\n```\nuint8_t  result = buf_return_buffer(buffer_handle);\n```\nThe function automtically checks, if the buffer_handle is a valid buffer\naddress and if the buffer is already on the stack or not. The return values are\n`BUF_OK`, `BUF_DUPLICATE` (buffer already on stack), `BUF_NULL` (invalid handle).\n\n# Changelog\n\n2020-05-12: Initial Version\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flarshei%2Flovelybuffer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flarshei%2Flovelybuffer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flarshei%2Flovelybuffer/lists"}