Skip to content

Erpc better mbf_static buffer implementation #195

Open
@kikass13

Description

Hi,

I couldn't stand the static buffer implementation because it

  • arbitrarily Creates more buffers than needed
  • Is unreadable because of random shifting
  • Does things at runtime that should be done at compile time (> c++17 is a thing)
  • is not templated

Im pretty sure there are people who would disagree with my statements (that's fine) :) , so I'll post my implementation here for anyone who likes a more modern approach for this buffer

How to use:

  • Create two buffers of length 256 * uint_8
  • erpc_mbf_t c_message_buffer_factory = erpc_mbf_static_fixed_init<2, 256>();
/*
 * Copyright (c) 2014-2016, Freescale Semiconductor, Inc.
 * Copyright 2016-2020 NXP
 * Copyright 2021 ACRIOS Systems s.r.o.
 * Copyright 2021 DroidDrive GmbH
 * All rights reserved.
 *
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */
#ifndef _ERPC_SETUP_MBF_STATIC_FIXED_H_
#define _ERPC_SETUP_MBF_STATIC_FIXED_H_

#include "erpc_config_internal.h"
#include "erpc_manually_constructed.h"
#include "erpc_mbf_setup.h"
#include "erpc_message_buffer.h"

#include <assert.h>
#include <string.h>
#include <array>

using namespace erpc;

////////////////////////////////////////////////////////////////////////////////
// Classes
////////////////////////////////////////////////////////////////////////////////

/*!
 * @brief Static Message buffer factory
 */
template <size_t BUFFER_COUNT, size_t WORD_COUNT, class WORD_SIZE=uint8_t>
class StaticFixedMessageBufferFactory : public MessageBufferFactory
{
private:
    static constexpr std::array<bool, BUFFER_COUNT> init_free_buffer_bitmap() {
        std::array<bool, BUFFER_COUNT> a{};
        for(size_t i = 0; i < BUFFER_COUNT; i++) {
            a[i] = true;
        }
        return a;
    };
    template<typename T>
    static constexpr void init_buffer(T* b) {
        for(size_t j = 0; j < WORD_COUNT; j++){
                b[j] = T{0};
        }
        return;
    };
    static constexpr std::array<std::array<WORD_SIZE, WORD_COUNT>, BUFFER_COUNT> init_buffers() {
        std::array<std::array<WORD_SIZE, WORD_COUNT>, BUFFER_COUNT> bufs = {{}};
        for(size_t i = 0; i < BUFFER_COUNT; i++) {
            init_buffer(bufs[i].data());
        }
        return bufs;
    };
public:
    /*!
     * @brief Constructor.
     */
    StaticFixedMessageBufferFactory(void) {}
    /*!
     * @brief This function creates new message buffer.
     *
     * @return MessageBuffer New created MessageBuffer.
     */
    virtual MessageBuffer create(void)
    {
        WORD_SIZE* bufPtr = nullptr;
        /// check free buffers and return first free one
        for(size_t i = 0; i < BUFFER_COUNT; i++){
            bool free = free_buffer_bitmap_[i];
            if(free)
            {
                free_buffer_bitmap_[i] = false;
                bufPtr = static_cast<WORD_SIZE*>(buffers_[i].data());
                break;
            }
        }
        // if free buffer found, return that
        assert(nullptr != bufPtr);
        uint8_t* buf = static_cast<uint8_t*>(bufPtr);
        return MessageBuffer(buf, WORD_COUNT);
    }

    /*!
     * @brief This function disposes message buffer.
     *
     * @param[in] buf MessageBuffer to dispose.
     */
    virtual void dispose(MessageBuffer *buf)
    {
        assert(buf);
        uint8_t* bufPtr = buf->get();
        if (bufPtr != nullptr)
        {
            // check buf ptr against all current buffers to see which one it was
            for(size_t i = 0; i < BUFFER_COUNT; i++)
            {
                uint8_t* internalBufPtr = static_cast<uint8_t*>(buffers_[i].data());
                if(bufPtr == internalBufPtr){
                    free_buffer_bitmap_[i] = true;
                    init_buffer(bufPtr);
                }
            }
        }
    }

protected:
    static inline auto free_buffer_bitmap_ = init_free_buffer_bitmap();
    static inline auto buffers_ = init_buffers();
};

#endif // _ERPC_SETUP_MBF_STATIC_FIXED_H_

Is there a need for this? :)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions