redosdeviations.h 12 KB

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