Open Model Railroad Network (OpenMRN)
Loading...
Searching...
No Matches
Serial.cxx
Go to the documentation of this file.
1
34#include <cstdint>
35#include <fcntl.h>
36#include "Devtab.hxx"
37#include "Serial.hxx"
38#include "can_ioctl.h"
39
43{
44 if (txBuf)
45 {
46 txBuf->flush();
47 }
48 if (rxBuf)
49 {
50 rxBuf->flush();
51 }
52}
53
61ssize_t Serial::read(File *file, void *buf, size_t count)
62{
63 unsigned char *data = (unsigned char *)buf;
64 ssize_t result = 0;
65
66 while (count)
67 {
68 portENTER_CRITICAL();
69 /* We limit the amount of bytes we read with each iteration in order
70 * to limit the amount of time that interrupts are disabled and
71 * preserve our real-time performance.
72 */
73 size_t bytes_read = rxBuf->get(data, count < 64 ? count : 64);
74 portEXIT_CRITICAL();
75
76 if (bytes_read == 0)
77 {
78 /* no more data to receive */
79 if ((file->flags & O_NONBLOCK) || result > 0)
80 {
81 break;
82 }
83 else
84 {
85 /* wait for data to come in, this call will release the
86 * critical section lock.
87 */
88 rxBuf->block_until_condition(file, true);
89 }
90 }
91
92 count -= bytes_read;
93 result += bytes_read;
94 data += bytes_read;
95 }
96
97 if (!result && (file->flags & O_NONBLOCK))
98 {
99 return -EAGAIN;
100 }
101
102 return result;
103}
104
112ssize_t Serial::write(File *file, const void *buf, size_t count)
113{
114 const unsigned char *data = (const unsigned char *)buf;
115 ssize_t result = 0;
116
117 while (count)
118 {
119 portENTER_CRITICAL();
120 /* We limit the amount of bytes we write with each iteration in order
121 * to limit the amount of time that interrupts are disabled and
122 * preserve our real-time performance.
123 */
124 size_t bytes_written = txBuf->put(data, count < 64 ? count : 64);
125
126 if (bytes_written == 0)
127 {
128 portEXIT_CRITICAL();
129 /* no more data to receive */
130 if ((file->flags & O_NONBLOCK) || result > 0)
131 {
132 break;
133 }
134 else
135 {
136 /* wait for space to be available, this call will release the
137 * critical section lock.
138 */
139 txBuf->block_until_condition(file, false);
140 }
141 }
142 else
143 {
144 tx_char();
145 portEXIT_CRITICAL();
146 count -= bytes_written;
147 result += bytes_written;
148 data += bytes_written;
149 }
150 }
151
152 if (!result && (file->flags & O_NONBLOCK))
153 {
154 return -EAGAIN;
155 }
156
157 return result;
158}
159
166int Serial::ioctl(File *file, unsigned long int key, unsigned long data)
167{
168 return -1;
169}
170
177bool Serial::select(File *file, int mode)
178{
179 bool retval = false;
180 switch (mode)
181 {
182 case FREAD:
183 portENTER_CRITICAL();
184 if (rxBuf->pending() > 0)
185 {
186 retval = true;
187 }
188 else
189 {
191 }
192 portEXIT_CRITICAL();
193 break;
194 case FWRITE:
195 portENTER_CRITICAL();
196 if (txBuf->space() > 0)
197 {
198 retval = true;
199 }
200 else
201 {
203 }
204 portEXIT_CRITICAL();
205 break;
206 default:
207 case 0:
208 /* we don't support any exceptions */
209 break;
210 }
211 return retval;
212}
void flush()
flush all the data out of the buffer and reset the buffer.
size_t space()
Return the number of items for which space is available.
size_t pending()
Return the number of items in the queue.
void select_insert()
Add client to list of clients needing woken.
size_t get(T *buf, size_t items)
remove a number of items from the buffer.
size_t put(const T *buf, size_t items)
Insert a number of items to the buffer.
DeviceBuffer< uint8_t > * rxBuf
receive buffer
Definition Serial.hxx:85
DeviceBuffer< uint8_t > * txBuf
transmit buffer
Definition Serial.hxx:84
bool select(File *file, int mode) OVERRIDE
Device select method.
Definition Serial.cxx:177
void flush_buffers() OVERRIDE
Discards all pending buffers.
Definition Serial.cxx:42
virtual void tx_char()=0
Function to try and transmit a character.
ssize_t write(File *file, const void *buf, size_t count) OVERRIDE
Write to a file or device.
Definition Serial.cxx:112
ssize_t read(File *file, void *buf, size_t count) OVERRIDE
Read from a file or device.
Definition Serial.cxx:61
int ioctl(File *file, unsigned long int key, unsigned long data) OVERRIDE
Request an ioctl transaction.
Definition Serial.cxx:166
#define FWRITE
Workaround for missing header defines on some newlib versions.
Definition fcntl.h:58
#define FREAD
Workaround for missing header defines on some newlib versions.
Definition fcntl.h:53
File information.
Definition Devtab.hxx:52
int flags
open flags
Definition Devtab.hxx:63