Skip to content

Feature circular file buffer #8221

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions platform/CircularBufferFile.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#include "platform/CircularBufferFile.h"
#include "platform/mbed_retarget.h"

// For CircularFile
#if MBED_CONF_RTOS_PRESENT
#include "rtos/ThisThread.h"
#else
#include "platform/mbed_wait_api.h"
#endif
//End

using namespace mbed;

off_t CircularBufferFile::seek(off_t offset, int whence = SEEK_SET)
{
return -ESPIPE;
}
off_t CircularBufferFile::size()
{
return _buffer.size();
}
int CircularBufferFile::isatty()
{
return false;
}
int CircularBufferFile::close()
{
return 0;
}

CircularBufferFile::~CircularBufferFile() {}

void CircularBufferFile::api_lock(void)
{
_mutex.lock();
}

void CircularBufferFile::api_unlock(void)
{
_mutex.unlock();
}

ssize_t CircularBufferFile::write(const void *buffer, size_t size)
{
const char *b = static_cast<const char *>(buffer);
if (size == 0) {
return 0;
}
api_lock();
for (size_t i = 0; i < size; i++) {
_buffer.push(b[i]);
}
api_unlock();
size_t data_written = size % CIRCULAR_BUFFER_FILE_DEPTH;
return data_written;
}

// Read is a forward iterator stream
ssize_t CircularBufferFile::read(void *buffer, size_t size)
{
char *b = static_cast<char *>(buffer);
size_t i = 0;
if (size == 0) {
return 0;
}

api_lock();
while (_buffer.empty()) {
/*if (!_blocking) {
api_unlock();
return -EAGAIN;
}*/
api_unlock();
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
api_lock();
}
i = 0;
while (i < size && !_buffer.empty()) {
_buffer.pop(b[i++]);
}
api_unlock();
return i;
}

void CircularBufferFile::wait_ms(uint32_t millisec)
{
/* wait_ms implementation for RTOS spins until exact microseconds - we
* want to just sleep until next tick.
*/
#if MBED_CONF_RTOS_PRESENT
// Can make this smarter in the future
rtos::ThisThread::sleep_for(millisec);
#else
::wait_ms(millisec);
#endif
}

# if MBED_CONF_PLATFORM_SOFT_FILE_BUFFER
FileHandle *mbed_override_console(int fd)
{
static CircularBufferFile console;
return &console;
}
#endif
37 changes: 37 additions & 0 deletions platform/CircularBufferFile.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#ifndef CIRCULAR_BUFFER_FILE_H
#define CIRCULAR_BUFFER_FILE_H
#include "platform/platform.h"
#include "platform/FileHandle.h"
#include "platform/CircularBuffer.h"
#include "platform/PlatformMutex.h"


#ifndef CIRCULAR_BUFFER_FILE_DEPTH
#define CIRCULAR_BUFFER_FILE_DEPTH 512
#endif

namespace mbed {
class CircularBufferFile : public FileHandle {
public:
virtual ~CircularBufferFile();
virtual ssize_t write(const void *buffer, size_t size);
virtual ssize_t read(void *buffer, size_t size);
virtual off_t seek(off_t offset, int whence);
virtual off_t size();
virtual int isatty();
virtual int close();
private:
/** Acquire mutex */
virtual void api_lock(void);

/** Release mutex */
virtual void api_unlock(void);
void wait_ms(uint32_t millisec);
private:
CircularBuffer<char, CIRCULAR_BUFFER_FILE_DEPTH> _buffer;
//Callback<void()> _sigio_cb; // Todo
PlatformMutex _mutex;
};

}
#endif /* CIRCULAR_BUFFER_FILE_H */
5 changes: 5 additions & 0 deletions platform/mbed_lib.json
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,12 @@
"use-mpu": {
"help": "Use the MPU if available to fault execution from RAM and writes to ROM. Can be disabled to reduce image size.",
"value": true
},
"soft-file-buffer": {
"help": "Use circular file buffer instead of serial",
"value": false
}

},
"target_overrides": {
"EFM32": {
Expand Down
3 changes: 2 additions & 1 deletion platform/mbed_retarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@

static SingletonPtr<PlatformMutex> _mutex;


#if defined(__ARMCC_VERSION)
# if __ARMCC_VERSION >= 6010050
# include <arm_compat.h>
Expand Down Expand Up @@ -256,7 +257,7 @@ MBED_WEAK FileHandle *mbed::mbed_override_console(int fd)

static FileHandle *default_console()
{
#if DEVICE_SERIAL
# if DEVICE_SERIAL
# if MBED_CONF_PLATFORM_STDIO_BUFFERED_SERIAL
static UARTSerial console(STDIO_UART_TX, STDIO_UART_RX, MBED_CONF_PLATFORM_STDIO_BAUD_RATE);
# if CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTS
Expand Down