Skip to content

Commit cc1bf43

Browse files
committed
Add blocking support to CircularBufferFile
Safely add null termination char Dont need extra zero term Clean up code Fix pollout? Use default SIGIO. Future work: - Implement non-blocking read/writes - Do proper SIGIO Move CircularBufferFile into own files. CircularBufferFile is potentially useful to other methods. This commit makes the CircularBufferFile importable. Update deprecated wait call to sleep_for
1 parent e3b03e0 commit cc1bf43

File tree

4 files changed

+148
-1
lines changed

4 files changed

+148
-1
lines changed

platform/CircularBufferFile.cpp

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#include "platform/CircularBufferFile.h"
2+
#include "platform/mbed_retarget.h"
3+
4+
// For CircularFile
5+
#if MBED_CONF_RTOS_PRESENT
6+
#include "rtos/ThisThread.h"
7+
#else
8+
#include "platform/mbed_wait_api.h"
9+
#endif
10+
//End
11+
12+
using namespace mbed;
13+
14+
off_t CircularBufferFile::seek(off_t offset, int whence = SEEK_SET)
15+
{
16+
return -ESPIPE;
17+
}
18+
off_t CircularBufferFile::size()
19+
{
20+
return _buffer.size();
21+
}
22+
int CircularBufferFile::isatty()
23+
{
24+
return false;
25+
}
26+
int CircularBufferFile::close()
27+
{
28+
return 0;
29+
}
30+
31+
CircularBufferFile::~CircularBufferFile(){}
32+
33+
void CircularBufferFile::api_lock(void)
34+
{
35+
_mutex.lock();
36+
}
37+
38+
void CircularBufferFile::api_unlock(void)
39+
{
40+
_mutex.unlock();
41+
}
42+
43+
ssize_t CircularBufferFile::write(const void* buffer, size_t size) {
44+
const char* b = static_cast<const char*>(buffer);
45+
if (size == 0) {
46+
return 0;
47+
}
48+
api_lock();
49+
for ( size_t i = 0; i < size; i++){
50+
_buffer.push(b[i]);
51+
}
52+
api_unlock();
53+
size_t data_written = size % CIRCULAR_BUFFER_FILE_DEPTH;
54+
return data_written;
55+
}
56+
57+
// Read is a forward iterator stream
58+
ssize_t CircularBufferFile::read(void *buffer, size_t size){
59+
char* b = static_cast<char*>(buffer);
60+
size_t i = 0;
61+
if (size == 0) {
62+
return 0;
63+
}
64+
65+
api_lock();
66+
while (_buffer.empty()) {
67+
/*if (!_blocking) {
68+
api_unlock();
69+
return -EAGAIN;
70+
}*/
71+
api_unlock();
72+
wait_ms(1); // XXX todo - proper wait, WFE for non-rtos ?
73+
api_lock();
74+
}
75+
i = 0;
76+
while(i < size && !_buffer.empty())
77+
{
78+
_buffer.pop(b[i++]);
79+
}
80+
api_unlock();
81+
return i;
82+
}
83+
84+
void CircularBufferFile::wait_ms(uint32_t millisec)
85+
{
86+
/* wait_ms implementation for RTOS spins until exact microseconds - we
87+
* want to just sleep until next tick.
88+
*/
89+
#if MBED_CONF_RTOS_PRESENT
90+
// Can make this smarter in the future
91+
rtos::ThisThread::sleep_for(millisec);
92+
#else
93+
::wait_ms(millisec);
94+
#endif
95+
}
96+
97+
# if MBED_CONF_PLATFORM_SOFT_FILE_BUFFER
98+
FileHandle *mbed_override_console(int fd)
99+
{
100+
static CircularBufferFile console;
101+
return &console;
102+
}
103+
#endif

platform/CircularBufferFile.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#ifndef CIRCULAR_BUFFER_FILE_H
2+
#define CIRCULAR_BUFFER_FILE_H
3+
#include "platform/platform.h"
4+
#include "platform/FileHandle.h"
5+
#include "platform/CircularBuffer.h"
6+
#include "platform/PlatformMutex.h"
7+
8+
9+
#ifndef CIRCULAR_BUFFER_FILE_DEPTH
10+
#define CIRCULAR_BUFFER_FILE_DEPTH 512
11+
#endif
12+
13+
namespace mbed {
14+
class CircularBufferFile : public FileHandle {
15+
public:
16+
virtual ~CircularBufferFile();
17+
virtual ssize_t write(const void *buffer, size_t size);
18+
virtual ssize_t read(void *buffer, size_t size);
19+
virtual off_t seek(off_t offset, int whence);
20+
virtual off_t size();
21+
virtual int isatty();
22+
virtual int close();
23+
private:
24+
/** Acquire mutex */
25+
virtual void api_lock(void);
26+
27+
/** Release mutex */
28+
virtual void api_unlock(void);
29+
30+
void wait_ms(uint32_t millisec);
31+
private:
32+
CircularBuffer<char, CIRCULAR_BUFFER_FILE_DEPTH> _buffer;
33+
//Callback<void()> _sigio_cb; // Todo
34+
PlatformMutex _mutex;
35+
};
36+
37+
}
38+
#endif /* CIRCULAR_BUFFER_FILE_H */

platform/mbed_lib.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,12 @@
132132
"use-mpu": {
133133
"help": "Use the MPU if available to fault execution from RAM and writes to ROM. Can be disabled to reduce image size.",
134134
"value": true
135+
},
136+
"soft-file-buffer": {
137+
"help": "Use circular file buffer instead of serial",
138+
"value": false
135139
}
140+
136141
},
137142
"target_overrides": {
138143
"EFM32": {

platform/mbed_retarget.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
static SingletonPtr<PlatformMutex> _mutex;
4646

47+
4748
#if defined(__ARMCC_VERSION)
4849
# if __ARMCC_VERSION >= 6010050
4950
# include <arm_compat.h>
@@ -256,7 +257,7 @@ MBED_WEAK FileHandle *mbed::mbed_override_console(int fd)
256257

257258
static FileHandle *default_console()
258259
{
259-
#if DEVICE_SERIAL
260+
# if DEVICE_SERIAL
260261
# if MBED_CONF_PLATFORM_STDIO_BUFFERED_SERIAL
261262
static UARTSerial console(STDIO_UART_TX, STDIO_UART_RX, MBED_CONF_PLATFORM_STDIO_BAUD_RATE);
262263
# if CONSOLE_FLOWCONTROL == CONSOLE_FLOWCONTROL_RTS

0 commit comments

Comments
 (0)