1 /*             ----> DO NOT REMOVE THE FOLLOWING NOTICE <----
2  *
3  *                 Copyright (c) 2014-2015 Datalight, Inc.
4  *                     All Rights Reserved Worldwide.
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; use version 2 of the License.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty
12  *  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License along
16  *  with this program; if not, write to the Free Software Foundation, Inc.,
17  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 
20 /*  Businesses and individuals that for commercial or other reasons cannot
21  *  comply with the terms of the GPLv2 license may obtain a commercial license
22  *  before incorporating Reliance Edge into proprietary software for
23  *  distribution in any form.  Visit http://www.datalight.com/reliance-edge for
24  *  more information.
25  */
26 
27 /** @file
28  *  @brief Macros to encapsulate MISRA C:2012 deviations in OS-specific code.
29  */
30 #ifndef REDOSDEVIATIONS_H
31 #define REDOSDEVIATIONS_H
32 
33 
34 #if REDCONF_OUTPUT == 1
35 
36 /*  Needed for PRINT_ASSERT() and OUTPUT_CHARACTER().
37  */
38     #include <stdio.h>
39 #endif
40 
41 
42 #if ( REDCONF_ASSERTS == 1 ) && ( REDCONF_OUTPUT == 1 )
43 
44 /** Print a formatted message for an assertion.
45  *
46  *  Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required).  Using
47  *  printf() is the most convenient way to output this information; and the risk
48  *  of "unspecified, undefined and implementation-defined" behavior causing
49  *  problems (as cited in the rationale for the rule) is small.  The driver does
50  *  not depend on this string being outputted correctly.  Furthermore, use of
51  *  printf() disappears when either asserts or output are disabled.
52  *
53  *  As Rule 21.6 is required, a separate deviation record is required.
54  */
55     #define PRINT_ASSERT( file, line ) \
56     printf( "Assertion failed in \"%s\" at line %u\n\r", ( ( file ) == NULL ) ? "" : ( file ), ( unsigned ) ( line ) )
57 #endif
58 
59 
60 /** Cast a value to unsigned long.
61  *
62  *  Usages of this macro deviate from MISRA C:2012 Directive 4.6.  This macro is
63  *  used in two places to cast a uint64_t value (used by the block device
64  *  abstraction for sector numbers) to unsigned long, since third-party code
65  *  which is not under the control of this project uses unsigned long for sector
66  *  numbers.  The cast is guaranteed to not lose any information, since when the
67  *  disk is opened the sector count is verified to be less than or equal to an
68  *  unsigned long value.  The text of the directive mentions that "it might be
69  *  desirable not to apply this guideline when interfacing with ... code outside
70  *  the project's control", which describes the situation for this deviation.
71  *
72  *  As Directive 4.6 is advisory, a deviation record is not required.  This
73  *  notice is the only record of the deviation.
74  */
75 #define CAST_ULONG( ull )    ( ( unsigned long ) ( ull ) )
76 
77 
78 /** Cast a const-qualified pointer to a pointer which is *not* const-qualified.
79  *
80  *  Usages of this macro deviate from MISRA C:2012 Rule 11.8.  This macro is
81  *  used in exactly one place in order to cope with a poorly designed
82  *  third-party interface.  Reliance Edge, at every level of the stack, uses
83  *  const-qualified pointers for buffers used in write operations, since the
84  *  data is read from the buffer, and the buffer does not need to be modified
85  *  (consistent with Rule 8.13).  One of the third-party block device interfaces
86  *  that Reliance Edge interfaces with does not follow this convention: it uses
87  *  an unqualified pointer for the buffer parameter of its sector write
88  *  function.  This forces the need for the cast to avoid warnings.  The
89  *  implementation of the sector write function is provided by the user, so it
90  *  is to be hoped that the buffer is not actually modified.
91  *
92  *  As Rule 11.8 is required, a separate deviation record is required.
93  */
94 #define CAST_AWAY_CONST( type, ptr )    ( ( type * ) ( ptr ) )
95 
96 
97 /** Allocate zero-initialized (cleared) memory.
98  *
99  *  All usages of this macro deviate from MISRA C:2012 Directive 4.12 (required)
100  *  and Rule 21.3 (required).  In the context of the single place it is actually
101  *  used, this macro also deviates from Rule 22.1 (required).
102  *
103  *  This macro is used in the FreeRTOS block device code in order to allocate a
104  *  RAM disk, when that implementation of the block device is selected.  The
105  *  primary rationale for all these deviations is that a) the RAM disk cannot be
106  *  allocated statically (since the volume information is stored in a
107  *  structure), and b) the RAM disk is primarily intended as a temporary testing
108  *  tool for users who want to try out Reliance Edge before the real storage
109  *  media is available.  In most real systems, Reliance Edge is used with
110  *  non-volatile storage like SD/MMC or eMMC, not with RAM disks.
111  *
112  *  Rule 22.1 states that all resources which are allocated must also be
113  *  explicitly freed.  The RAM disk is allocated and never freed, deviating from
114  *  that rule.  This is done because the data in the RAM disk is emulating a
115  *  non-volatile storage medium, and thus needs to persist even after the block
116  *  device is closed, to allow the file system to be formatted and then mounted,
117  *  or unmounted and remounted in the course of a test.  Thus the memory will
118  *  remain allocated until the target device is rebooted.  This is assumed to be
119  *  acceptable for the primary purpose of the RAM disk, which is preliminary
120  *  testing.
121  *
122  *  As Directive 4.12, Rule 21.3, and Rule 22.1 are all required, separate
123  *  deviation records are required.
124  */
125 #define ALLOCATE_CLEARED_MEMORY( nelem, elsize )    calloc( nelem, elsize )
126 
127 
128 #if REDCONF_OUTPUT == 1
129 
130 /** Output a character to a serial port or other display device.
131  *
132  *  Usages of this macro deviate from MISRA C:2012 Rule 21.6 (required).
133  *  FreeRTOS does not include a standard method of printing characters, so
134  *  putchar() is the most convenient and portable way to accomplish the task.
135  *  The risk of "unspecified, undefined and implementation-defined" behavior
136  *  causing problems (as cited in the rationale for the rule) is small.  The
137  *  driver does not depend on the character being outputted correctly.
138  *  Furthermore, use of putchar() disappears when output is disabled.
139  *
140  *  As Rule 21.6 is required, a separate deviation record is required.
141  */
142     #define OUTPUT_CHARACTER( ch )    ( void ) putchar( ch )
143 #endif
144 
145 
146 #if ( REDCONF_TASK_COUNT > 1U ) && ( REDCONF_API_POSIX == 1 )
147 
148 /** Cast a TaskHandle_t (a pointer type) to uintptr_t.
149  *
150  *  Usage of this macro deviate from MISRA-C:2012 Rule 11.4 (advisory).  This
151  *  macro is used for the FreeRTOS version of RedOsTaskId().  Some RTOSes
152  *  natively use an integer for task IDs; others use pointers.  RedOsTaskId()
153  *  uses integers, FreeRTOS uses pointers; to reconcile this difference, the
154  *  pointer must be cast to integer.  This is fairly safe, since the resulting
155  *  integer is never cast back to a pointer; and although the integer
156  *  representation of a pointer is implementation-defined, the representation is
157  *  irrelevant provided that unique pointers are converted to unique integers.
158  *
159  *  As Rule 11.4 is advisory, a deviation record is not required.  This notice
160  *  is the only record of the deviation.
161  */
162     #define CAST_TASK_PTR_TO_UINTPTR( taskptr )    ( ( uintptr_t ) ( taskptr ) )
163 #endif
164 
165 
166 /** Ignore the return value of a function (cast to void)
167  *
168  *  Usages of this macro deviate from MISRA C:2012 Directive 4.7, which states
169  *  that error information must be checked immediately after a function returns
170  *  potential error information.
171  *
172  *  If asserts and output are enabled, then this macro is used to document that
173  *  the return value of printf() is ignored.  A failure of printf() does not
174  *  impact the filesystem core, nor is there anything the filesystem can do to
175  *  respond to such an error (especially since it occurs within an assert).
176  *  Thus, the most reasonable action is to ignore the error.
177  *
178  *  In the STM32 SDIO block device implementation, errors are also ignored in an
179  *  IRQ interrupt handler.  This is the most reasonable action to take for two
180  *  reasons: (a) it would be dangerous to spend processor time responding to the
181  *  error inside the IRQ handler; (b) it has been verified that the same error
182  *  is propagated to the DiskRead/Write method, which does return the error to
183  *  the core.
184  *
185  *  In the Atmel SD/MMC block device implementation, error information from
186  *  sd_mmc_read_capacity() is ignored.  This is a reasonable action because all
187  *  of the possible error conditions were eliminated by a previous check.
188  *  sd_mmc_read_capacity() fails under the same conditions as
189  *  sd_mmc_test_unit_ready(), which was checked earlier in the same function.
190  *
191  *  In the mutex module, error information returned from the mutex release
192  *  function is ignored when asserts are disabled.  This is a reasonable action
193  *  because the mutex release function (xSemaphoreGive) is documented only to
194  *  fail if the mutex was not obtained correctly, which can be demonstrably
195  *  avoided.
196  *
197  *  As Directive 4.7 is required, a separate deviation record is required.
198  */
199 #define IGNORE_ERRORS( fn )    ( ( void ) ( fn ) )
200 
201 
202 /** @brief Determine whether a pointer is aligned on a 32-bit boundary.
203  *
204  *  This is used to determine whether a data buffer meets the requirements of
205  *  the underlying block device implementation.  When transferring data via
206  *  DMA (Direct Memory Access) on an STM32 device, the data buffer must be cast
207  *  as a uint32 pointer, and unexpected behavior may occur if the buffer is not
208  *  aligned correctly.
209  *
210  *  There is no way to perform this check without deviating from MISRA C rules
211  *  against casting pointers to integer types.  Usage of this macro deviates
212  *  from MISRA C:2012 Rule 11.4 (advisory).  The main rationale the rule cites
213  *  against converting pointers to integers is that the chosen integer type may
214  *  not be able to represent the pointer; this is a non-issue here since we use
215  *  uintptr_t.  The text says the rule still applies when using uintptr_t due to
216  *  concern about unaligned pointers, but that is not an issue here since the
217  *  integer value of the pointer is not saved and not converted back into a
218  *  pointer and dereferenced.  The result of casting a pointer to a sufficiently
219  *  large integer is implementation-defined, but macros similar to this one have
220  *  been used by Datalight for a long time in a wide variety of environments and
221  *  they have always worked as expected.
222  *
223  *  This deviation only occurs when using the STM32 SDIO block device
224  *  implementation.
225  *
226  *  As Rule 11.4 is advisory, a deviation record is not required.  This notice
227  *  is the only record of deviation.
228  */
229 #define IS_UINT32_ALIGNED_PTR( ptr )    ( ( ( uintptr_t ) ( ptr ) & ( sizeof( uint32_t ) - 1U ) ) == 0U )
230 
231 
232 /** @brief Cast a 32-bit aligned void pointer to a uint32 pointer.
233  *
234  *  Usages of this macro deviate from MISRA C:2012 Rule 11.5 (advisory).  A
235  *  cast from a void pointer to an object pointer is discouraged because of
236  *  potential alignment issues.  However, this macro is only used to cast
237  *  pointers that have already been tested to be 32-bit aligned, so the
238  *  operation will be safe.
239  *
240  *  This deviation only occurs when using the STM32 SDIO block device
241  *  implementation.
242  *
243  *  As rule 11.5 is advisory, a deviation record is not required.  This notice
244  *  is the only record of the deviation.
245  */
246 #define CAST_UINT32_PTR( ptr )    ( ( uint32_t * ) ( ptr ) )
247 
248 
249 #endif /* ifndef REDOSDEVIATIONS_H */
250