geky/equeue

Platform implementation for bare metal.

Opened this issue · 1 comments

How would I go about implementing the platform functions for a bare metal application?

geky commented

Hi @andrewwade, sorry about taking so long to get to this. The best starting point would be to start with one of the existing porting layers:
https://github.com/geky/equeue/blob/master/equeue_platform.h
https://github.com/geky/equeue/blob/master/equeue_mbed.cpp

This is something that needs more documentation (and honestly this repo needs quite a bit of work), but you basically need these things:

  1. A timer of some sort, if you can configure a hardware timer to count milliseconds, you should be able to just return it here:

    // Platform millisecond counter
    //
    // Return a tick that represents the number of milliseconds that have passed
    // since an arbitrary point in time. The granularity does not need to be at
    // the millisecond level, however the accuracy of the equeue library is
    // limited by the accuracy of this tick.
    //
    // Must intentionally overflow to 0 after 2^32-1
    unsigned equeue_tick(void);
  2. A "mutex" for synchronization. On bare metal this can disable interrupts and enable interrupts:

    // Platform mutex operations
    //
    // The equeue_mutex_create and equeue_mutex_destroy manage the lifetime
    // of the mutex. On error, equeue_mutex_create should return a negative
    // error code.
    //
    // The equeue_mutex_lock and equeue_mutex_unlock lock and unlock the
    // underlying mutex.
    int equeue_mutex_create(equeue_mutex_t *mutex);
    void equeue_mutex_destroy(equeue_mutex_t *mutex);
    void equeue_mutex_lock(equeue_mutex_t *mutex);
    void equeue_mutex_unlock(equeue_mutex_t *mutex);
  3. A "semaphore". This is the API that equeue uses to put the device to sleep. At minimum equeue_sema_wait can immediately return (the value is ignored), though this will mean the device is effectively polling.

    // Platform semaphore operations
    //
    // The equeue_sema_create and equeue_sema_destroy manage the lifetime
    // of the semaphore. On error, equeue_sema_create should return a negative
    // error code.
    //
    // The equeue_sema_signal marks a semaphore as signalled such that the next
    // equeue_sema_wait will return true.
    //
    // The equeue_sema_wait waits for a semaphore to be signalled or returns
    // immediately if equeue_sema_signal had been called since the last
    // equeue_sema_wait. The equeue_sema_wait returns true if it detected that
    // equeue_sema_signal had been called.
    int equeue_sema_create(equeue_sema_t *sema);
    void equeue_sema_destroy(equeue_sema_t *sema);
    void equeue_sema_signal(equeue_sema_t *sema);
    bool equeue_sema_wait(equeue_sema_t *sema, int ms);

    Another option is to wait-for-interrupts (WFI) in equeue_sema_wait if that is available.

Hopefully that information helps.