µOS++ IIIe Reference 7.0.0
The third edition of µOS++, a POSIX inspired open source framework, written in C++
Loading...
Searching...
No Matches
block-device.h
Go to the documentation of this file.
1/*
2 * This file is part of the µOS++ distribution.
3 * (https://github.com/micro-os-plus)
4 * Copyright (c) 2015 Liviu Ionescu.
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom
12 * the Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 */
27
28#ifndef CMSIS_PLUS_POSIX_IO_BLOCK_DEVICE_H_
29#define CMSIS_PLUS_POSIX_IO_BLOCK_DEVICE_H_
30
31// ----------------------------------------------------------------------------
32
33#if defined(__cplusplus)
34
35// ----------------------------------------------------------------------------
36
37#if defined(OS_USE_OS_APP_CONFIG_H)
38#include <cmsis-plus/os-app-config.h>
39#endif
40
42
43// ----------------------------------------------------------------------------
44
45#pragma GCC diagnostic push
46
47#if defined(__clang__)
48#pragma clang diagnostic ignored "-Wc++98-compat"
49#endif
50
51// ----------------------------------------------------------------------------
52
53namespace os
54{
55 namespace posix
56 {
57 // ------------------------------------------------------------------------
58
59 class block_device_impl;
60
61 // ========================================================================
62
63 // TODO: add support to indicate that there is no media in drive.
64 // TODO: add support to indicate the media is write protected.
65
71 class block_device : public device
72 {
73 // ----------------------------------------------------------------------
74
75 public:
76
77 using blknum_t = std::size_t;
78
79 // ----------------------------------------------------------------------
80
86 public:
87
89
94 // The rule of five.
95 block_device (const block_device&) = delete;
96 block_device (block_device&&) = delete;
98 operator= (const block_device&) = delete;
100 operator= (block_device&&) = delete;
101
106 virtual
107 ~block_device () override;
108
113 // ----------------------------------------------------------------------
119 public:
120
121 virtual int
122 vioctl (int request, std::va_list args) override;
123
124 virtual ssize_t
125 read_block (void* buf, blknum_t blknum, std::size_t nblocks = 1);
126
127 virtual ssize_t
128 write_block (const void* buf, blknum_t blknum, std::size_t nblocks = 1);
129
130 // ----------------------------------------------------------------------
131
137 blocks (void);
138
143 std::size_t
145
146 std::size_t
148
149 // ----------------------------------------------------------------------
150 // Support functions.
151
153 impl (void) const;
154
159 // ----------------------------------------------------------------------
160 };
161
162 // ========================================================================
163
164#pragma GCC diagnostic push
165#pragma GCC diagnostic ignored "-Wpadded"
166
168 {
169 // ----------------------------------------------------------------------
170
171 friend class block_device;
172
173 public:
174
176
177 // ----------------------------------------------------------------------
178
184 public:
185
186 block_device_impl (void);
187
192 // The rule of five.
193 block_device_impl (const block_device_impl&) = delete;
196 operator= (const block_device_impl&) = delete;
198 operator= (block_device_impl&&) = delete;
199
204 virtual
205 ~block_device_impl () override;
206
211 // ----------------------------------------------------------------------
217 public:
218
219 virtual ssize_t
220 do_read (void* buf, std::size_t nbyte) override;
221
222 virtual ssize_t
223 do_write (const void* buf, std::size_t nbyte) override;
224
225 virtual off_t
226 do_lseek (off_t offset, int whence) override;
227
228 virtual ssize_t
229 do_read_block (void* buf, blknum_t blknum, std::size_t nblocks) = 0;
230
231 virtual ssize_t
232 do_write_block (const void* buf, blknum_t blknum,
233 std::size_t nblocks) = 0;
234
239 // ----------------------------------------------------------------------
240 protected:
241
246 std::size_t block_logical_size_bytes_ = 0;
247
248 std::size_t block_physical_size_bytes_ = 0;
249
250 blknum_t num_blocks_ = 0;
251
255 };
256
257#pragma GCC diagnostic pop
258
259 // ========================================================================
260
261 template<typename T>
263 {
264 // --------------------------------------------------------------------
265
266 public:
267
268 using value_type = T;
269
270 // --------------------------------------------------------------------
271
277 public:
278
279 template<typename ... Args>
280 block_device_implementable (const char* name, Args&&... args);
281
286 // The rule of five.
290 operator= (const block_device_implementable&) = delete;
292 operator= (block_device_implementable&&) = delete;
293
298 virtual
299 ~block_device_implementable () override;
300
305 // --------------------------------------------------------------------
311 public:
312
313 // Support functions.
314
316 impl (void) const;
317
322 // --------------------------------------------------------------------
323 protected:
324
329 // Include the implementation as a member.
330 value_type impl_instance_;
331
335 };
336
337 // ========================================================================
338
339 template<typename T, typename L>
341 {
342 // --------------------------------------------------------------------
343
344 public:
345
346 using value_type = T;
347 using lockable_type = L;
348
349 // --------------------------------------------------------------------
350
356 public:
357
358 template<typename ... Args>
359 block_device_lockable (const char* name, lockable_type& locker,
360 Args&&... args);
361
366 // The rule of five.
370 operator= (const block_device_lockable&) = delete;
372 operator= (block_device_lockable&&) = delete;
373
378 virtual
379 ~block_device_lockable () override;
380
385 // --------------------------------------------------------------------
391 public:
392
393 virtual int
394 close (void) override;
395
396 virtual ssize_t
397 read (void* buf, std::size_t nbyte) override;
398
399 virtual ssize_t
400 write (const void* buf, std::size_t nbyte) override;
401
402 virtual ssize_t
403 writev (const struct iovec* iov, int iovcnt) override;
404
405 virtual int
406 vfcntl (int cmd, std::va_list args) override;
407
408 virtual int
409 vioctl (int request, std::va_list args) override;
410
411 virtual off_t
412 lseek (off_t offset, int whence) override;
413
414 virtual ssize_t
415 read_block (void* buf, blknum_t blknum, std::size_t nblocks = 1)
416 override;
417
418 virtual ssize_t
419 write_block (const void* buf, blknum_t blknum, std::size_t nblocks = 1)
420 override;
421
422 virtual void
423 sync (void) override;
424
425 // --------------------------------------------------------------------
426 // Support functions.
427
429 impl (void) const;
430
435 // --------------------------------------------------------------------
436 protected:
437
442 value_type impl_instance_;
443
444 lockable_type& locker_;
445
449 };
450
451 // ==========================================================================
452 } /* namespace posix */
453} /* namespace os */
454
455// ===== Inline & template implementations ====================================
456
457namespace os
458{
459 namespace posix
460 {
461 // ========================================================================
462
465 {
466 return impl ().num_blocks_;
467 }
468
469 inline std::size_t
471 {
472 return impl ().block_logical_size_bytes_;
473 }
474
475 inline std::size_t
477 {
478 return impl ().block_physical_size_bytes_;
479 }
480
481 inline block_device_impl&
483 {
484 return static_cast<block_device_impl&> (impl_);
485 }
486
487 // ========================================================================
488
489 template<typename T>
490 template<typename ... Args>
492 const char* name, Args&&... args) :
494 { impl_instance_, name }, //
495 impl_instance_
496 { std::forward<Args>(args)... }
497 {
498#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
499 trace::printf ("block_device_implementable::%s(\"%s\")=@%p\n",
500 __func__, name_, this);
501#endif
502 }
503
504 template<typename T>
506 {
507#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
508 trace::printf ("block_device_implementable::%s() @%p %s\n", __func__,
509 this, name_);
510#endif
511 }
512
513 template<typename T>
516 {
517 return static_cast<value_type&> (impl_);
518 }
519
520 // ========================================================================
521
522 template<typename T, typename L>
523 template<typename ... Args>
525 const char* name, lockable_type& locker, Args&&... args) :
527 { impl_instance_, name }, //
528 impl_instance_
529 { std::forward<Args>(args)... }, //
530 locker_ (locker)
531 {
532#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
533 trace::printf ("block_device_lockable::%s(\"%s\")=@%p\n", __func__,
534 name_, this);
535#endif
536 }
537
538 template<typename T, typename L>
540 {
541#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
542 trace::printf ("block_device_lockable::%s() @%p %s\n", __func__, this,
543 name_);
544#endif
545 }
546
547 // ------------------------------------------------------------------------
548
549 template<typename T, typename L>
550 int
552 {
553#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
554 trace::printf ("block_device_lockable::%s() @%p\n", __func__, this);
555#endif
556
557 std::lock_guard<L> lock
558 { locker_ };
559
560 return block_device::close ();
561 }
562
563 template<typename T, typename L>
564 ssize_t
565 block_device_lockable<T, L>::read (void* buf, std::size_t nbyte)
566 {
567#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
568 trace::printf ("block_device_lockable::%s(0x0%X, %u) @%p\n", __func__,
569 buf, nbyte, this);
570#endif
571
572 std::lock_guard<L> lock
573 { locker_ };
574
575 return block_device::read (buf, nbyte);
576 }
577
578 template<typename T, typename L>
579 ssize_t
580 block_device_lockable<T, L>::write (const void* buf, std::size_t nbyte)
581 {
582#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
583 trace::printf ("block_device_lockable::%s(0x0%X, %u) @%p\n", __func__,
584 buf, nbyte, this);
585#endif
586
587 std::lock_guard<L> lock
588 { locker_ };
589
590 return block_device::write (buf, nbyte);
591 }
592
593 template<typename T, typename L>
594 ssize_t
595 block_device_lockable<T, L>::writev (const struct iovec* iov, int iovcnt)
596 {
597#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
598 trace::printf ("block_device_lockable::%s(0x0%X, %d) @%p\n", __func__,
599 iov, iovcnt, this);
600#endif
601
602 std::lock_guard<L> lock
603 { locker_ };
604
605 return block_device::writev (iov, iovcnt);
606 }
607
608 template<typename T, typename L>
609 int
610 block_device_lockable<T, L>::vfcntl (int cmd, std::va_list args)
611 {
612#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
613 trace::printf ("block_device_lockable::%s(%d) @%p\n", __func__, cmd,
614 this);
615#endif
616
617 std::lock_guard<L> lock
618 { locker_ };
619
620 return block_device::vfcntl (cmd, args);
621 }
622
623 template<typename T, typename L>
624 int
625 block_device_lockable<T, L>::vioctl (int request, std::va_list args)
626 {
627#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
628 trace::printf ("block_device_lockable::%s(%d) @%p\n", __func__, request,
629 this);
630#endif
631
632 std::lock_guard<L> lock
633 { locker_ };
634
635 return block_device::vioctl (request, args);
636 }
637
638 template<typename T, typename L>
639 off_t
640 block_device_lockable<T, L>::lseek (off_t offset, int whence)
641 {
642#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
643 trace::printf ("block_device_lockable::%s(%d, %d) @%p\n", __func__,
644 offset, whence, this);
645#endif
646
647 std::lock_guard<L> lock
648 { locker_ };
649
650 return block_device::lseek (offset, whence);
651 }
652
653 template<typename T, typename L>
654 ssize_t
656 std::size_t nblocks)
657 {
658#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
659 trace::printf ("block_device_lockable::%s(%p, %u, %u) @%p\n", __func__,
660 buf, blknum, nblocks, this);
661#endif
662
663 std::lock_guard<L> lock
664 { locker_ };
665
666 return block_device::read_block (buf, blknum, nblocks);
667 }
668
669 template<typename T, typename L>
670 ssize_t
672 blknum_t blknum,
673 std::size_t nblocks)
674 {
675#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
676 trace::printf ("block_device_lockable::%s(%p, %u, %u) @%p\n", __func__,
677 buf, blknum, nblocks, this);
678#endif
679
680 std::lock_guard<L> lock
681 { locker_ };
682
683 return block_device::write_block (buf, blknum, nblocks);
684 }
685
686 template<typename T, typename L>
687 void
689 {
690#if defined(OS_TRACE_POSIX_IO_BLOCK_DEVICE)
691 trace::printf ("block_device_lockable::%s() @%p\n", __func__, this);
692#endif
693
694 std::lock_guard<L> lock
695 { locker_ };
696
697 return block_device::sync ();
698 }
699
700 template<typename T, typename L>
703 {
704 return static_cast<value_type&> (impl_);
705 }
706
707 // ==========================================================================
708 } /* namespace posix */
709} /* namespace os */
710
711#pragma GCC diagnostic pop
712
713// ----------------------------------------------------------------------------
714
715#endif /* __cplusplus */
716
717// ----------------------------------------------------------------------------
718
719#endif /* CMSIS_PLUS_POSIX_IO_BLOCK_DEVICE_H_ */
virtual ssize_t do_read(void *buf, std::size_t nbyte) override
virtual off_t do_lseek(off_t offset, int whence) override
virtual ssize_t do_read_block(void *buf, blknum_t blknum, std::size_t nblocks)=0
virtual ~block_device_impl() override
virtual ssize_t do_write(const void *buf, std::size_t nbyte) override
virtual ssize_t do_write_block(const void *buf, blknum_t blknum, std::size_t nblocks)=0
block_device::blknum_t blknum_t
block_device_implementable(const char *name, Args &&... args)
virtual ~block_device_implementable() override
virtual int vfcntl(int cmd, std::va_list args) override
virtual ssize_t writev(const struct iovec *iov, int iovcnt) override
virtual ssize_t read(void *buf, std::size_t nbyte) override
virtual void sync(void) override
virtual off_t lseek(off_t offset, int whence) override
virtual int vioctl(int request, std::va_list args) override
virtual int close(void) override
virtual ssize_t write_block(const void *buf, blknum_t blknum, std::size_t nblocks=1) override
block_device_lockable(const char *name, lockable_type &locker, Args &&... args)
virtual ssize_t read_block(void *buf, blknum_t blknum, std::size_t nblocks=1) override
virtual ssize_t write(const void *buf, std::size_t nbyte) override
value_type & impl(void) const
virtual ~block_device_lockable() override
Block device class.
std::size_t block_physical_size_bytes(void)
virtual ~block_device() override
std::size_t block_logical_size_bytes(void)
block_device_impl & impl(void) const
virtual int vioctl(int request, std::va_list args) override
virtual ssize_t read_block(void *buf, blknum_t blknum, std::size_t nblocks=1)
virtual ssize_t write_block(const void *buf, blknum_t blknum, std::size_t nblocks=1)
Base device class.
Definition device.h:78
virtual int close(void) override
Definition device.cpp:125
virtual void sync(void)
Definition device.cpp:179
const char * name(void) const
Definition device.h:310
off_t offset(void)
Definition io.h:461
virtual off_t lseek(off_t offset, int whence)
Definition io.cpp:453
virtual ssize_t write(const void *buf, std::size_t nbyte)
Definition io.cpp:280
virtual ssize_t read(void *buf, std::size_t nbyte)
Definition io.cpp:229
virtual ssize_t writev(const struct iovec *iov, int iovcnt)
Definition io.cpp:333
virtual int vfcntl(int cmd, std::va_list args)
Definition io.cpp:387
int printf(const char *format,...)
Write a formatted string to the trace device.
Definition trace.cpp:74
System namespace.
Definition uio.h:56