Skip to content

Commit ec932eb

Browse files
jciberlinIgor-Misic
authored andcommitted
Implement MISRA compliant bit manipulation
- MISRA compliant bit manipulation
1 parent cc8d392 commit ec932eb

11 files changed

Lines changed: 303 additions & 45 deletions

File tree

Inc/bit_manipulation.h

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
/****************************************************************************
2+
*
3+
* Copyright (c) 2023 IMProject Development Team. All rights reserved.
4+
* Authors: Juraj Ciberlin <jciberlin1@gmail.com>
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in
14+
* the documentation and/or other materials provided with the
15+
* distribution.
16+
* 3. Neither the name IMProject nor the names of its contributors may be
17+
* used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31+
* POSSIBILITY OF SUCH DAMAGE.
32+
*
33+
****************************************************************************/
34+
35+
#ifndef UTILITY_BIT_MANIPULATION_H_
36+
#define UTILITY_BIT_MANIPULATION_H_
37+
38+
#include "typedefs.h"
39+
40+
/**
41+
* @brief This function reflects the bits in data around the center bit.
42+
*
43+
* @param[in] data The input data to be reflected.
44+
* @param[in] n_bits The number of bits in the input data to be reflected.
45+
*
46+
* @return The reflected data.
47+
*/
48+
uint32_t BitManipulation_reflect(uint32_t data, uint8_t n_bits);
49+
50+
/**
51+
* @brief This function checks if the bit at nth position is set. Parameter n must be between 0 and 31.
52+
*
53+
* @param[in] data The input data.
54+
* @param[in] n The position of the bit in the input data that will be checked.
55+
* @param[out] *bit_set True if bit at nth position is set, otherwise false.
56+
*
57+
* @return True if function is successfully performed, otherwise false.
58+
*/
59+
bool BitManipulation_bitSet(uint32_t data, uint8_t n, bool* bit_set);
60+
61+
/**
62+
* @brief This function sets the bit at nth position and returns the result. Parameter n must be between 0 and 31.
63+
*
64+
* @param[in] data The input data.
65+
* @param[in] n The position of the bit in the input data that will be set.
66+
* @param[out] *out The result of the input data where the bit at the nth position is set.
67+
*
68+
* @return True if function is successfully performed, otherwise false.
69+
*/
70+
bool BitManipulation_setBit(uint32_t data, uint8_t n, uint32_t* out);
71+
72+
/**
73+
* @brief This function clears the bit at nth position and returns the result. Parameter n must be between 0 and 31.
74+
*
75+
* @param[in] data The input data.
76+
* @param[in] n The position of the bit in the input data that will be cleared.
77+
* @param[out] *out The result of the input data where the bit at the nth position is cleared.
78+
*
79+
* @return True if function is successfully performed, otherwise false.
80+
*/
81+
bool BitManipulation_clearBit(uint32_t data, uint8_t n, uint32_t* out);
82+
83+
/**
84+
* @brief This function toggles the bit at nth position and returns the result. Parameter n must be between 0 and 31.
85+
*
86+
* @param[in] data The input data.
87+
* @param[in] n The position of the bit in the input data that will be toggled.
88+
* @param[out] *out The result of the input data where the bit at the nth position is toggled.
89+
*
90+
* @return True if function is successfully performed, otherwise false.
91+
*/
92+
bool BitManipulation_toggleBit(uint32_t data, uint8_t n, uint32_t* out);
93+
94+
#endif /* UTILITY_BIT_MANIPULATION_H_ */

Inc/utils.h

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -38,16 +38,6 @@
3838
#include "misra_c_2012_doc.h"
3939
#include "typedefs.h"
4040

41-
/**
42-
* @brief This function reflects the bits in data around the center bit.
43-
*
44-
* @param[in] data The input data to be reflected.
45-
* @param[in] n_bits The number of bits in the input data to be reflected.
46-
* @return uint32_t The reflected data.
47-
*
48-
*/
49-
uint32_t Utils_BitReflect(uint32_t data, uint8_t n_bits);
50-
5141
/**
5242
* @brief Converts a string to an unsigned 32-bit integer.
5343
*

Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ TARGET = $(TARGET_DIR)/$(TARGET_BASE)$(TARGET_EXTENSION)
5656

5757
IMUTILITY_FILES=\
5858
Src/base64.c \
59+
Src/bit_manipulation.c \
5960
Src/bubble_sort.c \
6061
Src/crc/crc8_base.c \
6162
Src/crc/crc8_variants/crc8.c \
@@ -119,6 +120,7 @@ SRC_FILES+=$(IMUTILITY_FILES) \
119120
Tests/Helper/sort_functions.c \
120121
Tests/test_main.c \
121122
Tests/test_base64.c \
123+
Tests/test_bit_manipulation.c \
122124
Tests/test_bubble_sort.c \
123125
Tests/test_crc8.c \
124126
Tests/test_crc16.c \

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ Join us on the Discord channel https://discord.gg/R6nZxZqDH3
5252
- Base64_encode
5353
- Base64_decode
5454

55+
### Bit manipulation
56+
- BitManipulation_reflect
57+
- BitManipulation_bitSet
58+
- BitManipulation_setBit
59+
- BitManipulation_clearBit
60+
- BitManipulation_toggleBit
61+
5562
### Bubble sort
5663
- BubbleSort_sort
5764

@@ -147,7 +154,6 @@ Join us on the Discord channel https://discord.gg/R6nZxZqDH3
147154
- Scheduler_run
148155

149156
### Utils
150-
- Utils_BitReflect
151157
- Utils_StringToUint32
152158
- Utils_SwapElements
153159
- Utils_QuickUint32Pow10

Src/bit_manipulation.c

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/****************************************************************************
2+
*
3+
* Copyright (c) 2023 IMProject Development Team. All rights reserved.
4+
* Authors: Juraj Ciberlin <jciberlin1@gmail.com>
5+
*
6+
* Redistribution and use in source and binary forms, with or without
7+
* modification, are permitted provided that the following conditions
8+
* are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright
11+
* notice, this list of conditions and the following disclaimer.
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in
14+
* the documentation and/or other materials provided with the
15+
* distribution.
16+
* 3. Neither the name IMProject nor the names of its contributors may be
17+
* used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
23+
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
24+
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
25+
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
26+
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
27+
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
28+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29+
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30+
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31+
* POSSIBILITY OF SUCH DAMAGE.
32+
*
33+
****************************************************************************/
34+
35+
#include "bit_manipulation.h"
36+
37+
#define MAX_BIT_SHIFT (31U)
38+
39+
uint32_t
40+
BitManipulation_reflect(uint32_t data, uint8_t n_bits) {
41+
uint32_t reflection = 0u;
42+
uint32_t temp_data = data;
43+
44+
/*
45+
* Reflect the data around the center bit.
46+
*/
47+
for (uint8_t bit = 0u; bit < n_bits; ++bit) {
48+
/*
49+
* If the LSB bit is set, set the reflection of it.
50+
*/
51+
if (1u == (temp_data & 1u) ) {
52+
/* -E> compliant MC3R1.R12.2 1 The shift count is granted to be between 0 and 31 due to bit masking. */
53+
reflection |= (uint32_t)((uint32_t)1U << (0x1FU & ((n_bits - 1U) - bit)));
54+
}
55+
56+
temp_data = (temp_data >> 1u);
57+
}
58+
59+
return reflection;
60+
}
61+
62+
bool
63+
BitManipulation_bitSet(uint32_t data, uint8_t n, bool* bit_set) {
64+
bool status = false;
65+
if (n <= MAX_BIT_SHIFT) {
66+
/* -E> compliant MC3R1.R12.2 1 Right hand operand of shift expression is between 0 and 31 due to previous IF statement. */
67+
uint32_t temp = (uint32_t)1U << n;
68+
*bit_set = ((data & temp) != 0U);
69+
status = true;
70+
}
71+
return status;
72+
}
73+
74+
bool
75+
BitManipulation_setBit(uint32_t data, uint8_t n, uint32_t* out) {
76+
bool status = false;
77+
if (n <= MAX_BIT_SHIFT) {
78+
/* -E> compliant MC3R1.R12.2 1 Right hand operand of shift expression is between 0 and 31 due to previous IF statement. */
79+
*out = (data | ((uint32_t)1U << n));
80+
status = true;
81+
}
82+
return status;
83+
}
84+
85+
bool
86+
BitManipulation_clearBit(uint32_t data, uint8_t n, uint32_t* out) {
87+
bool status = false;
88+
if (n <= MAX_BIT_SHIFT) {
89+
/* -E> compliant MC3R1.R12.2 1 Right hand operand of shift expression is between 0 and 31 due to previous IF statement. */
90+
*out = (data & (~((uint32_t)1U << n)));
91+
status = true;
92+
}
93+
return status;
94+
}
95+
96+
bool
97+
BitManipulation_toggleBit(uint32_t data, uint8_t n, uint32_t* out) {
98+
bool status = false;
99+
if (n <= MAX_BIT_SHIFT) {
100+
/* -E> compliant MC3R1.R12.2 1 Right hand operand of shift expression is between 0 and 31 due to previous IF statement. */
101+
*out = (data ^ ((uint32_t)1U << n));
102+
status = true;
103+
}
104+
return status;
105+
}

Src/crc/crc16_base.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
#include "crc16_base.h"
3636

37-
#include "utils.h"
37+
#include "bit_manipulation.h"
3838

3939
#define REFLECTED_INPUT_BITS_NUM (8U)
4040
#define REFLECTED_OUTPUT_BITS_NUM (16U)
@@ -77,7 +77,7 @@ Crc16Base(
7777
uint8_t temp;
7878

7979
if (reflected_input) {
80-
temp = (uint8_t)Utils_BitReflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
80+
temp = (uint8_t)BitManipulation_reflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
8181
} else {
8282
temp = *temp_data_ptr;
8383
}
@@ -87,7 +87,7 @@ Crc16Base(
8787
}
8888

8989
if (reflected_output) {
90-
crc = (uint16_t)Utils_BitReflect(crc, REFLECTED_OUTPUT_BITS_NUM);
90+
crc = (uint16_t)BitManipulation_reflect(crc, REFLECTED_OUTPUT_BITS_NUM);
9191
}
9292

9393
if (final_xor) {

Src/crc/crc32_base.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
#include "crc32_base.h"
3636

37-
#include "utils.h"
37+
#include "bit_manipulation.h"
3838

3939
#define REFLECTED_INPUT_BITS_NUM (8U)
4040
#define REFLECTED_OUTPUT_BITS_NUM (32U)
@@ -77,7 +77,7 @@ Crc32Base(
7777
uint8_t temp;
7878

7979
if (reflected_input) {
80-
temp = (uint8_t)Utils_BitReflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
80+
temp = (uint8_t)BitManipulation_reflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
8181
} else {
8282
temp = *temp_data_ptr;
8383
}
@@ -88,7 +88,7 @@ Crc32Base(
8888
}
8989

9090
if (reflected_output) {
91-
crc = Utils_BitReflect(crc, REFLECTED_OUTPUT_BITS_NUM);
91+
crc = BitManipulation_reflect(crc, REFLECTED_OUTPUT_BITS_NUM);
9292
}
9393

9494
if (final_xor) {

Src/crc/crc8_base.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
#include "crc8_base.h"
3636

37-
#include "utils.h"
37+
#include "bit_manipulation.h"
3838

3939
#define REFLECTED_INPUT_BITS_NUM (8U)
4040
#define REFLECTED_OUTPUT_BITS_NUM (8U)
@@ -77,7 +77,7 @@ Crc8Base(
7777
uint8_t temp;
7878

7979
if (reflected_input) {
80-
temp = (uint8_t)Utils_BitReflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
80+
temp = (uint8_t)BitManipulation_reflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
8181
} else {
8282
temp = *temp_data_ptr;
8383
}
@@ -88,7 +88,7 @@ Crc8Base(
8888
}
8989

9090
if (reflected_output) {
91-
crc = (uint8_t)Utils_BitReflect((uint32_t)crc, REFLECTED_OUTPUT_BITS_NUM);
91+
crc = (uint8_t)BitManipulation_reflect((uint32_t)crc, REFLECTED_OUTPUT_BITS_NUM);
9292
}
9393

9494
if (final_xor) {

Src/utils.c

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,31 +36,6 @@
3636

3737
#define MAX_UINT32_POW_10_EXPONENT 10U
3838

39-
uint32_t
40-
Utils_BitReflect(uint32_t data, uint8_t n_bits) {
41-
42-
uint32_t reflection = 0u;
43-
uint32_t temp_data = data;
44-
45-
/*
46-
* Reflect the data around the center bit.
47-
*/
48-
for (uint8_t bit = 0u; bit < n_bits; ++bit) {
49-
/*
50-
* If the LSB bit is set, set the reflection of it.
51-
*/
52-
if (1u == (temp_data & 1u) ) {
53-
/* -E> compliant MC3R1.R12.2 1 The shift count is granted to be between 0 and 31 due to bit masking. */
54-
reflection |= (uint32_t)((uint32_t)1U << (0x1FU & ((n_bits - 1U) - bit)));
55-
}
56-
57-
temp_data = (temp_data >> 1u);
58-
}
59-
60-
return reflection;
61-
62-
}
63-
6439
bool
6540
Utils_StringToUint32(const char* str, uint8_t str_length, uint32_t* integer) {
6641
bool success = true;

0 commit comments

Comments
 (0)