Skip to content

Commit

Permalink
Implement MISRA compliant bit manipulation
Browse files Browse the repository at this point in the history
- MISRA compliant bit manipulation
  • Loading branch information
jciberlin committed Nov 19, 2023
1 parent cc8d392 commit c001768
Show file tree
Hide file tree
Showing 11 changed files with 261 additions and 45 deletions.
91 changes: 91 additions & 0 deletions Inc/bit_manipulation.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/****************************************************************************
*
* Copyright (c) 2023 IMProject Development Team. All rights reserved.
* Authors: Juraj Ciberlin <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name IMProject nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/

#ifndef UTILITY_BIT_MANIPULATION_H_
#define UTILITY_BIT_MANIPULATION_H_

#include "typedefs.h"

/**
* @brief This function reflects the bits in data around the center bit.
*
* @param[in] data The input data to be reflected.
* @param[in] n_bits The number of bits in the input data to be reflected.
*
* @return The reflected data.
*/
uint32_t BitManipulation_reflect(uint32_t data, uint8_t n_bits);

/**
* @brief This function checks if the bit at nth position is set.
*
* @param[in] data The input data.
* @param[in] n The position of the bit in the input data that will be checked.
* @param[out] bit_set True if bit at nth position is set, otherwise false.
*
* @return True if function is successfully performed, otherwise false.
*/
bool BitManipulation_bitSet(uint32_t data, uint8_t n, bool* bit_set);

/**
* @brief This function sets the bit at nth position and returns the result.
*
* @param[in] data The input data.
* @param[in] n The position of the bit in the input data that will be set.
*
* @return The result of the input data where the bit at the nth position is set.
*/
uint32_t BitManipulation_setBit(uint32_t data, uint8_t n);

/**
* @brief This function clears the bit at nth position and returns the result.
*
* @param[in] data The input data.
* @param[in] n The position of the bit in the input data that will be cleared.
*
* @return The result of the input data where the bit at the nth position is cleared.
*/
uint32_t BitManipulation_clearBit(uint32_t data, uint8_t n);

/**
* @brief This function toggles the bit at nth position and returns the result.
*
* @param[in] data The input data.
* @param[in] n The position of the bit in the input data that will be toggled.
*
* @return The result of the input data where the bit at the nth position is toggled.
*/
uint32_t BitManipulation_toggleBit(uint32_t data, uint8_t n);

#endif /* UTILITY_BIT_MANIPULATION_H_ */
10 changes: 0 additions & 10 deletions Inc/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,6 @@
#include "misra_c_2012_doc.h"
#include "typedefs.h"

/**
* @brief This function reflects the bits in data around the center bit.
*
* @param[in] data The input data to be reflected.
* @param[in] n_bits The number of bits in the input data to be reflected.
* @return uint32_t The reflected data.
*
*/
uint32_t Utils_BitReflect(uint32_t data, uint8_t n_bits);

/**
* @brief Converts a string to an unsigned 32-bit integer.
*
Expand Down
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ TARGET = $(TARGET_DIR)/$(TARGET_BASE)$(TARGET_EXTENSION)

IMUTILITY_FILES=\
Src/base64.c \
Src/bit_manipulation.c \
Src/bubble_sort.c \
Src/crc/crc8_base.c \
Src/crc/crc8_variants/crc8.c \
Expand Down Expand Up @@ -119,6 +120,7 @@ SRC_FILES+=$(IMUTILITY_FILES) \
Tests/Helper/sort_functions.c \
Tests/test_main.c \
Tests/test_base64.c \
Tests/test_bit_manipulation.c \
Tests/test_bubble_sort.c \
Tests/test_crc8.c \
Tests/test_crc16.c \
Expand Down
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,13 @@ Join us on the Discord channel https://discord.gg/R6nZxZqDH3
- Base64_encode
- Base64_decode

### Bit manipulation
- BitManipulation_reflect
- BitManipulation_bitSet
- BitManipulation_setBit
- BitManipulation_clearBit
- BitManipulation_toggleBit

### Bubble sort
- BubbleSort_sort

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

### Utils
- Utils_BitReflect
- Utils_StringToUint32
- Utils_SwapElements
- Utils_QuickUint32Pow10
Expand Down
86 changes: 86 additions & 0 deletions Src/bit_manipulation.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/****************************************************************************
*
* Copyright (c) 2023 IMProject Development Team. All rights reserved.
* Authors: Juraj Ciberlin <[email protected]>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name IMProject nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/

#include "bit_manipulation.h"

#define MAX_BIT_SHIFT (31U)

uint32_t
BitManipulation_reflect(uint32_t data, uint8_t n_bits) {
uint32_t reflection = 0u;
uint32_t temp_data = data;

/*
* Reflect the data around the center bit.
*/
for (uint8_t bit = 0u; bit < n_bits; ++bit) {
/*
* If the LSB bit is set, set the reflection of it.
*/
if (1u == (temp_data & 1u) ) {
/* -E> compliant MC3R1.R12.2 1 The shift count is granted to be between 0 and 31 due to bit masking. */
reflection |= (uint32_t)((uint32_t)1U << (0x1FU & ((n_bits - 1U) - bit)));
}

temp_data = (temp_data >> 1u);
}

return reflection;
}

bool
BitManipulation_bitSet(uint32_t data, uint8_t n, bool* bit_set) {
bool status = false;
if (n <= MAX_BIT_SHIFT) {
uint32_t temp = (uint32_t)1U << n;

Check warning

Code scanning / ECLAIR

right hand operand of shift expression is possibly not between 0 and 31 left hand operand has essential type width 32 bits and standard type ‘uint32_t’ (that is ‘unsigned’) ‘<<’ left shift operator Medium

right hand operand of shift expression is possibly not between 0 and 31
left hand operand has essential type width 32 bits and standard type ‘uint32_t’ (that is ‘unsigned’)

‘<<’ left shift operator
*bit_set = ((data & temp) != 0U);
status = true;
}
return status;
}

uint32_t
BitManipulation_setBit(uint32_t data, uint8_t n) {
return (data | ((uint32_t)1U << n));

Check warning

Code scanning / ECLAIR

right hand operand of shift expression is possibly not between 0 and 31 left hand operand has essential type width 32 bits and standard type ‘uint32_t’ (that is ‘unsigned’) ‘<<’ left shift operator Medium

right hand operand of shift expression is possibly not between 0 and 31
left hand operand has essential type width 32 bits and standard type ‘uint32_t’ (that is ‘unsigned’)

‘<<’ left shift operator
}

uint32_t
BitManipulation_clearBit(uint32_t data, uint8_t n) {
return (data & (~((uint32_t)1U << n)));

Check warning

Code scanning / ECLAIR

right hand operand of shift expression is possibly not between 0 and 31 left hand operand has essential type width 32 bits and standard type ‘uint32_t’ (that is ‘unsigned’) ‘<<’ left shift operator Medium

right hand operand of shift expression is possibly not between 0 and 31
left hand operand has essential type width 32 bits and standard type ‘uint32_t’ (that is ‘unsigned’)

‘<<’ left shift operator
}

uint32_t
BitManipulation_toggleBit(uint32_t data, uint8_t n) {
return (data ^ ((uint32_t)1U << n));

Check warning

Code scanning / ECLAIR

right hand operand of shift expression is possibly not between 0 and 31 left hand operand has essential type width 32 bits and standard type ‘uint32_t’ (that is ‘unsigned’) ‘<<’ left shift operator Medium

right hand operand of shift expression is possibly not between 0 and 31
left hand operand has essential type width 32 bits and standard type ‘uint32_t’ (that is ‘unsigned’)

‘<<’ left shift operator
}
6 changes: 3 additions & 3 deletions Src/crc/crc16_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

#include "crc16_base.h"

#include "utils.h"
#include "bit_manipulation.h"

#define REFLECTED_INPUT_BITS_NUM (8U)
#define REFLECTED_OUTPUT_BITS_NUM (16U)
Expand Down Expand Up @@ -77,7 +77,7 @@ Crc16Base(
uint8_t temp;

if (reflected_input) {
temp = (uint8_t)Utils_BitReflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
temp = (uint8_t)BitManipulation_reflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
} else {
temp = *temp_data_ptr;
}
Expand All @@ -87,7 +87,7 @@ Crc16Base(
}

if (reflected_output) {
crc = (uint16_t)Utils_BitReflect(crc, REFLECTED_OUTPUT_BITS_NUM);
crc = (uint16_t)BitManipulation_reflect(crc, REFLECTED_OUTPUT_BITS_NUM);
}

if (final_xor) {
Expand Down
6 changes: 3 additions & 3 deletions Src/crc/crc32_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

#include "crc32_base.h"

#include "utils.h"
#include "bit_manipulation.h"

#define REFLECTED_INPUT_BITS_NUM (8U)
#define REFLECTED_OUTPUT_BITS_NUM (32U)
Expand Down Expand Up @@ -77,7 +77,7 @@ Crc32Base(
uint8_t temp;

if (reflected_input) {
temp = (uint8_t)Utils_BitReflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
temp = (uint8_t)BitManipulation_reflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
} else {
temp = *temp_data_ptr;
}
Expand All @@ -88,7 +88,7 @@ Crc32Base(
}

if (reflected_output) {
crc = Utils_BitReflect(crc, REFLECTED_OUTPUT_BITS_NUM);
crc = BitManipulation_reflect(crc, REFLECTED_OUTPUT_BITS_NUM);
}

if (final_xor) {
Expand Down
6 changes: 3 additions & 3 deletions Src/crc/crc8_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@

#include "crc8_base.h"

#include "utils.h"
#include "bit_manipulation.h"

#define REFLECTED_INPUT_BITS_NUM (8U)
#define REFLECTED_OUTPUT_BITS_NUM (8U)
Expand Down Expand Up @@ -77,7 +77,7 @@ Crc8Base(
uint8_t temp;

if (reflected_input) {
temp = (uint8_t)Utils_BitReflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
temp = (uint8_t)BitManipulation_reflect(*temp_data_ptr, REFLECTED_INPUT_BITS_NUM);
} else {
temp = *temp_data_ptr;
}
Expand All @@ -88,7 +88,7 @@ Crc8Base(
}

if (reflected_output) {
crc = (uint8_t)Utils_BitReflect((uint32_t)crc, REFLECTED_OUTPUT_BITS_NUM);
crc = (uint8_t)BitManipulation_reflect((uint32_t)crc, REFLECTED_OUTPUT_BITS_NUM);
}

if (final_xor) {
Expand Down
25 changes: 0 additions & 25 deletions Src/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,31 +36,6 @@

#define MAX_UINT32_POW_10_EXPONENT 10U

uint32_t
Utils_BitReflect(uint32_t data, uint8_t n_bits) {

uint32_t reflection = 0u;
uint32_t temp_data = data;

/*
* Reflect the data around the center bit.
*/
for (uint8_t bit = 0u; bit < n_bits; ++bit) {
/*
* If the LSB bit is set, set the reflection of it.
*/
if (1u == (temp_data & 1u) ) {
/* -E> compliant MC3R1.R12.2 1 The shift count is granted to be between 0 and 31 due to bit masking. */
reflection |= (uint32_t)((uint32_t)1U << (0x1FU & ((n_bits - 1U) - bit)));
}

temp_data = (temp_data >> 1u);
}

return reflection;

}

bool
Utils_StringToUint32(const char* str, uint8_t str_length, uint32_t* integer) {
bool success = true;
Expand Down
Loading

0 comments on commit c001768

Please sign in to comment.