Marco Zecchini
/
Example_RTOS
Rtos API example
Embed:
(wiki syntax)
Show/hide line numbers
common_functions.h
00001 /* 00002 * Copyright (c) 2014-2015 ARM Limited. All rights reserved. 00003 * SPDX-License-Identifier: Apache-2.0 00004 * Licensed under the Apache License, Version 2.0 (the License); you may 00005 * not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an AS IS BASIS, WITHOUT 00012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 #ifndef COMMON_FUNCTIONS_H_ 00017 #define COMMON_FUNCTIONS_H_ 00018 00019 #include "ns_types.h" 00020 00021 #ifdef __cplusplus 00022 extern "C" { 00023 #endif 00024 00025 /* 00026 * Common write 64-bit variable to 8-bit pointer. 00027 * 00028 * Write 64 bits in big-endian (network) byte order. 00029 * 00030 * \param value 64-bit variable 00031 * \param ptr pointer where data to be written 00032 * 00033 * \return updated pointer 00034 */ 00035 NS_INLINE uint8_t *common_write_64_bit(uint64_t value, uint8_t ptr[__static 8]); 00036 00037 /* 00038 * Common read 64-bit variable from 8-bit pointer. 00039 * 00040 * Read 64 bits in big-endian (network) byte order. 00041 * 00042 * \param data_buf pointer where data to be read 00043 * 00044 * \return 64-bit variable 00045 */ 00046 NS_INLINE uint64_t common_read_64_bit(const uint8_t data_buf[__static 8]); 00047 00048 /* 00049 * Common write 32-bit variable to 8-bit pointer. 00050 * 00051 * Write 32 bits in big-endian (network) byte order. 00052 * 00053 * \param value 32-bit variable 00054 * \param ptr pointer where data to be written 00055 * 00056 * \return updated pointer 00057 */ 00058 NS_INLINE uint8_t *common_write_32_bit(uint32_t value, uint8_t ptr[__static 4]); 00059 00060 /* 00061 * Common read 32-bit variable from 8-bit pointer. 00062 * 00063 * Read 32 bits in big-endian (network) byte order. 00064 * 00065 * \param data_buf pointer where data to be read 00066 * 00067 * \return 32-bit variable 00068 */ 00069 NS_INLINE uint32_t common_read_32_bit(const uint8_t data_buf[__static 4]); 00070 00071 /* 00072 * Common write 32-bit variable to 8-bit pointer. 00073 * 00074 * Write 32 bits in little-endian byte order. 00075 * 00076 * \param value 32-bit variable 00077 * \param ptr pointer where data to be written 00078 * 00079 * \return updated pointer 00080 */ 00081 NS_INLINE uint8_t *common_write_32_bit_inverse(uint32_t value, uint8_t ptr[__static 4]); 00082 00083 /* 00084 * Common read 32-bit variable from 8-bit pointer. 00085 * 00086 * Read 32 bits in little-endian byte order. 00087 * 00088 * \param data_buf pointer where data to be read 00089 * 00090 * \return 32-bit variable 00091 */ 00092 NS_INLINE uint32_t common_read_32_bit_inverse(const uint8_t data_buf[__static 4]); 00093 00094 /* 00095 * Common write 24-bit variable to 8-bit pointer. 00096 * 00097 * Write 24 bits in big-endian (network) byte order. 00098 * 00099 * \param value 24-bit variable 00100 * \param ptr pointer where data to be written 00101 * 00102 * \return updated pointer 00103 */ 00104 NS_INLINE uint8_t *common_write_24_bit(uint_fast24_t value, uint8_t ptr[__static 3]); 00105 00106 /* 00107 * Common read 24-bit variable from 8-bit pointer. 00108 * 00109 * Read 24 bits in big-endian (network) byte order. 00110 * 00111 * \param data_buf pointer where data to be read 00112 * 00113 * \return 24-bit variable 00114 */ 00115 NS_INLINE uint_fast24_t common_read_24_bit(const uint8_t data_buf[__static 3]); 00116 00117 /* 00118 * Common write 16-bit variable to 8-bit pointer. 00119 * 00120 * Write 16 bits in big-endian (network) byte order. 00121 * 00122 * \param value 16-bit variable 00123 * \param ptr pointer where data to be written 00124 * 00125 * \return updated pointer 00126 */ 00127 NS_INLINE uint8_t *common_write_16_bit(uint16_t value, uint8_t ptr[__static 2]); 00128 00129 /* 00130 * Common read 16-bit variable from 8-bit pointer. 00131 * 00132 * Read 16 bits in big-endian (network) byte order. 00133 * 00134 * \param data_buf pointer where data to be read 00135 * 00136 * \return 16-bit variable 00137 */ 00138 NS_INLINE uint16_t common_read_16_bit(const uint8_t data_buf[__static 2]); 00139 00140 /* 00141 * Common write 16-bit variable to 8-bit pointer. 00142 * 00143 * Write 16 bits in little-endian byte order. 00144 * 00145 * \param value 16-bit variable 00146 * \param ptr pointer where data to be written 00147 * 00148 * \return updated pointer 00149 */ 00150 NS_INLINE uint8_t *common_write_16_bit_inverse(uint16_t value, uint8_t ptr[__static 2]); 00151 00152 /* 00153 * Common read 16-bit variable from 8-bit pointer. 00154 * 00155 * Read 16 bits in little-endian byte order. 00156 * 00157 * \param data_buf pointer where data to be read 00158 * 00159 * \return 16-bit variable 00160 */ 00161 NS_INLINE uint16_t common_read_16_bit_inverse(const uint8_t data_buf[__static 2]); 00162 00163 /* 00164 * Count bits in a byte 00165 * 00166 * \param byte byte to inspect 00167 * 00168 * \return number of 1-bits in byte 00169 */ 00170 NS_INLINE uint_fast8_t common_count_bits(uint8_t byte); 00171 00172 /* 00173 * Count leading zeros in a byte 00174 * 00175 * \deprecated Use common_count_leading_zeros_8 00176 * 00177 * \param byte byte to inspect 00178 * 00179 * \return number of leading zeros in byte (0-8) 00180 */ 00181 NS_INLINE uint_fast8_t common_count_leading_zeros(uint8_t byte); 00182 00183 /* 00184 * Count leading zeros in a byte 00185 * 00186 * \param byte byte to inspect 00187 * 00188 * \return number of leading zeros in byte (0-8) 00189 */ 00190 NS_INLINE uint_fast8_t common_count_leading_zeros_8(uint8_t byte); 00191 00192 /* 00193 * Count leading zeros in a 16-bit value 00194 * 00195 * \param value value to inspect 00196 * 00197 * \return number of leading zeros in byte (0-16) 00198 */ 00199 NS_INLINE uint_fast8_t common_count_leading_zeros_16(uint16_t value); 00200 00201 /* 00202 * Count leading zeros in a 32-bit value 00203 * 00204 * \param value value to inspect 00205 * 00206 * \return number of leading zeros in byte (0-32) 00207 */ 00208 NS_INLINE uint_fast8_t common_count_leading_zeros_32(uint32_t value); 00209 00210 /* 00211 * Compare 8-bit serial numbers 00212 * 00213 * Compare two 8-bit serial numbers, according to RFC 1982 Serial Number 00214 * Arithmetic. 00215 * 00216 * \param s1 first serial number 00217 * \param s2 second serial number 00218 * 00219 * \return true if s1 > s2 00220 * \return false if s1 <= s2, or the comparison is undefined 00221 */ 00222 NS_INLINE bool common_serial_number_greater_8(uint8_t s1, uint8_t s2); 00223 00224 /* 00225 * Compare 16-bit serial numbers 00226 * 00227 * Compare two 16-bit serial numbers, according to RFC 1982 Serial Number 00228 * Arithmetic. 00229 * 00230 * \param s1 first serial number 00231 * \param s2 second serial number 00232 * 00233 * \return true if s1 > s2 00234 * \return false if s1 <= s2, or the comparison is undefined 00235 */ 00236 NS_INLINE bool common_serial_number_greater_16(uint16_t s1, uint16_t s2); 00237 00238 /* 00239 * Compare 32-bit serial numbers 00240 * 00241 * Compare two 32-bit serial numbers, according to RFC 1982 Serial Number 00242 * Arithmetic. 00243 * 00244 * \param s1 first serial number 00245 * \param s2 second serial number 00246 * 00247 * \return true if s1 > s2 00248 * \return false if s1 <= s2, or the comparison is undefined 00249 */ 00250 NS_INLINE bool common_serial_number_greater_32(uint32_t s1, uint32_t s2); 00251 00252 /* 00253 * Test a bit in an bit array. 00254 * 00255 * Check whether a particular bit is set in a bit string. The bit array 00256 * is in big-endian (network) bit order. 00257 * 00258 * \param bitset pointer to bit array 00259 * \param bit index of bit - 0 is the most significant bit of the first byte 00260 * 00261 * \return true if the bit is set 00262 */ 00263 NS_INLINE bool bit_test(const uint8_t *bitset, uint_fast8_t bit); 00264 00265 /* 00266 * Set a bit in an bit array. 00267 * 00268 * Set a bit in a bit array. The array is in big-endian (network) bit order. 00269 * 00270 * \param bitset pointer to bit array 00271 * \param bit index of bit - 0 is the most significant bit of the first byte 00272 */ 00273 NS_INLINE void bit_set(uint8_t *bitset, uint_fast8_t bit); 00274 00275 /* 00276 * Clear a bit in an bit array. 00277 * 00278 * Clear a bit in a bit array. The bit array is in big-endian (network) bit order. 00279 * 00280 * \param bitset pointer to bit array 00281 * \param bit index of bit - 0 is the most significant bit of the first byte 00282 */ 00283 NS_INLINE void bit_clear(uint8_t *bitset, uint_fast8_t bit); 00284 00285 /* 00286 * Compare two bitstrings. 00287 * 00288 * Compare two bitstrings of specified length. The bit strings are in 00289 * big-endian (network) bit order. 00290 * 00291 * \param a pointer to first string 00292 * \param b pointer to second string 00293 * \param bits number of bits to compare 00294 * 00295 * \return true if the strings compare equal 00296 */ 00297 bool bitsequal(const uint8_t *a, const uint8_t *b, uint_fast8_t bits); 00298 00299 /* 00300 * Copy a bitstring 00301 * 00302 * Copy a bitstring of specified length. The bit string is in big-endian 00303 * (network) bit order. Bits beyond the bitlength at the destination are not 00304 * modified. 00305 * 00306 * For example, copying 4 bits sets the first 4 bits of dst[0] from src[0], 00307 * the lower 4 bits of dst[0] are unmodified. 00308 * 00309 * \param dst destination pointer 00310 * \param src source pointer 00311 * \param bits number of bits to copy 00312 * 00313 * \return the value of dst 00314 */ 00315 uint8_t *bitcopy(uint8_t *restrict dst, const uint8_t *restrict src, uint_fast8_t bits); 00316 00317 /* 00318 * Copy a bitstring and pad last byte with zeros 00319 * 00320 * Copy a bitstring of specified length. The bit string is in big-endian 00321 * (network) bit order. Bits beyond the bitlength in the last destination byte are 00322 * zeroed. 00323 * 00324 * For example, copying 4 bits sets the first 4 bits of dst[0] from src[0], and 00325 * the lower 4 bits of dst[0] are set to 0. 00326 * 00327 * \param dst destination pointer 00328 * \param src source pointer 00329 * \param bits number of bits to copy 00330 * 00331 * \return the value of dst 00332 */ 00333 uint8_t *bitcopy0(uint8_t *restrict dst, const uint8_t *restrict src, uint_fast8_t bits); 00334 00335 /* Provide definitions, either for inlining, or for common_functions.c */ 00336 #if defined NS_ALLOW_INLINING || defined COMMON_FUNCTIONS_FN 00337 #ifndef COMMON_FUNCTIONS_FN 00338 #define COMMON_FUNCTIONS_FN NS_INLINE 00339 #endif 00340 00341 COMMON_FUNCTIONS_FN uint8_t *common_write_64_bit(uint64_t value, uint8_t ptr[__static 8]) 00342 { 00343 *ptr++ = value >> 56; 00344 *ptr++ = value >> 48; 00345 *ptr++ = value >> 40; 00346 *ptr++ = value >> 32; 00347 *ptr++ = value >> 24; 00348 *ptr++ = value >> 16; 00349 *ptr++ = value >> 8; 00350 *ptr++ = value; 00351 return ptr; 00352 } 00353 00354 COMMON_FUNCTIONS_FN uint64_t common_read_64_bit(const uint8_t data_buf[__static 8]) 00355 { 00356 uint64_t temp_64; 00357 temp_64 = (uint64_t)(*data_buf++) << 56; 00358 temp_64 += (uint64_t)(*data_buf++) << 48; 00359 temp_64 += (uint64_t)(*data_buf++) << 40; 00360 temp_64 += (uint64_t)(*data_buf++) << 32; 00361 temp_64 += (uint64_t)(*data_buf++) << 24; 00362 temp_64 += (uint64_t)(*data_buf++) << 16; 00363 temp_64 += (uint64_t)(*data_buf++) << 8; 00364 temp_64 += *data_buf++; 00365 return temp_64; 00366 } 00367 00368 COMMON_FUNCTIONS_FN uint8_t *common_write_32_bit(uint32_t value, uint8_t ptr[__static 4]) 00369 { 00370 *ptr++ = value >> 24; 00371 *ptr++ = value >> 16; 00372 *ptr++ = value >> 8; 00373 *ptr++ = value; 00374 return ptr; 00375 } 00376 00377 COMMON_FUNCTIONS_FN uint32_t common_read_32_bit(const uint8_t data_buf[__static 4]) 00378 { 00379 uint32_t temp_32; 00380 temp_32 = (uint32_t)(*data_buf++) << 24; 00381 temp_32 += (uint32_t)(*data_buf++) << 16; 00382 temp_32 += (uint32_t)(*data_buf++) << 8; 00383 temp_32 += *data_buf++; 00384 return temp_32; 00385 } 00386 00387 COMMON_FUNCTIONS_FN uint8_t *common_write_32_bit_inverse(uint32_t value, uint8_t ptr[__static 4]) 00388 { 00389 *ptr++ = value; 00390 *ptr++ = value >> 8; 00391 *ptr++ = value >> 16; 00392 *ptr++ = value >> 24; 00393 return ptr; 00394 } 00395 00396 COMMON_FUNCTIONS_FN uint32_t common_read_32_bit_inverse(const uint8_t data_buf[__static 4]) 00397 { 00398 uint32_t temp_32; 00399 temp_32 = *data_buf++; 00400 temp_32 += (uint32_t)(*data_buf++) << 8; 00401 temp_32 += (uint32_t)(*data_buf++) << 16; 00402 temp_32 += (uint32_t)(*data_buf++) << 24; 00403 return temp_32; 00404 } 00405 00406 COMMON_FUNCTIONS_FN uint8_t *common_write_24_bit(uint_fast24_t value, uint8_t ptr[__static 3]) 00407 { 00408 *ptr++ = value >> 16; 00409 *ptr++ = value >> 8; 00410 *ptr++ = value; 00411 return ptr; 00412 } 00413 00414 COMMON_FUNCTIONS_FN uint_fast24_t common_read_24_bit(const uint8_t data_buf[__static 3]) 00415 { 00416 uint_fast24_t temp_24; 00417 temp_24 = (uint_fast24_t)(*data_buf++) << 16; 00418 temp_24 += (uint_fast24_t)(*data_buf++) << 8; 00419 temp_24 += *data_buf++; 00420 return temp_24; 00421 } 00422 00423 COMMON_FUNCTIONS_FN uint8_t *common_write_16_bit(uint16_t value, uint8_t ptr[__static 2]) 00424 { 00425 *ptr++ = value >> 8; 00426 *ptr++ = value; 00427 return ptr; 00428 } 00429 00430 COMMON_FUNCTIONS_FN uint16_t common_read_16_bit(const uint8_t data_buf[__static 2]) 00431 { 00432 uint16_t temp_16; 00433 temp_16 = (uint16_t)(*data_buf++) << 8; 00434 temp_16 += *data_buf++; 00435 return temp_16; 00436 } 00437 00438 COMMON_FUNCTIONS_FN uint8_t *common_write_16_bit_inverse(uint16_t value, uint8_t ptr[__static 2]) 00439 { 00440 *ptr++ = value; 00441 *ptr++ = value >> 8; 00442 return ptr; 00443 } 00444 00445 COMMON_FUNCTIONS_FN uint16_t common_read_16_bit_inverse(const uint8_t data_buf[__static 2]) 00446 { 00447 uint16_t temp_16; 00448 temp_16 = *data_buf++; 00449 temp_16 += (uint16_t)(*data_buf++) << 8; 00450 return temp_16; 00451 } 00452 00453 COMMON_FUNCTIONS_FN uint_fast8_t common_count_bits(uint8_t byte) 00454 { 00455 /* First step sets each bit pair to be count of bits (00,01,10) */ 00456 /* [00-00 = 00, 01-00 = 01, 10-01 = 01, 11-01 = 10] */ 00457 uint_fast8_t count = byte - ((byte >> 1) & 0x55); 00458 /* Add bit pairs to make each nibble contain count of bits (0-4) */ 00459 count = (count & 0x33) + ((count >> 2) & 0x33); 00460 /* Final result is sum of nibbles (0-8) */ 00461 count = (count >> 4) + (count & 0x0F); 00462 return count; 00463 } 00464 00465 COMMON_FUNCTIONS_FN uint_fast8_t common_count_leading_zeros(uint8_t byte) 00466 { 00467 return common_count_leading_zeros_8(byte); 00468 } 00469 00470 COMMON_FUNCTIONS_FN uint_fast8_t common_count_leading_zeros_8(uint8_t byte) 00471 { 00472 #ifdef __CC_ARM 00473 return byte ? __clz((unsigned int) byte << 24) : 8; 00474 #elif defined __GNUC__ 00475 return byte ? __builtin_clz((unsigned int) byte << 24) : 8; 00476 #else 00477 uint_fast8_t cnt = 0; 00478 if (byte == 0) { 00479 return 8; 00480 } 00481 if ((byte & 0xF0) == 0) { 00482 byte <<= 4; 00483 cnt += 4; 00484 } 00485 if ((byte & 0xC0) == 0) { 00486 byte <<= 2; 00487 cnt += 2; 00488 } 00489 if ((byte & 0x80) == 0) { 00490 cnt += 1; 00491 } 00492 00493 return cnt; 00494 #endif 00495 } 00496 00497 COMMON_FUNCTIONS_FN uint_fast8_t common_count_leading_zeros_16(uint16_t value) 00498 { 00499 #ifdef __CC_ARM 00500 return value ? __clz((unsigned int) value << 16) : 16; 00501 #elif defined __GNUC__ 00502 return value ? __builtin_clz((unsigned int) value << 16) : 16; 00503 #else 00504 uint_fast8_t cnt = 0; 00505 if (value == 0) { 00506 return 16; 00507 } 00508 if ((value & 0xFF00) == 0) { 00509 value <<= 8; 00510 cnt += 8; 00511 } 00512 if ((value & 0xF000) == 0) { 00513 value <<= 4; 00514 cnt += 4; 00515 } 00516 if ((value & 0xC000) == 0) { 00517 value <<= 2; 00518 cnt += 2; 00519 } 00520 if ((value & 0x8000) == 0) { 00521 cnt += 1; 00522 } 00523 00524 return cnt; 00525 #endif 00526 } 00527 00528 COMMON_FUNCTIONS_FN uint_fast8_t common_count_leading_zeros_32(uint32_t value) 00529 { 00530 #ifdef __CC_ARM 00531 return __clz(value); 00532 #elif defined __GNUC__ 00533 return value ? __builtin_clz(value) : 32; 00534 #else 00535 uint_fast8_t cnt = 0; 00536 if (value == 0) { 00537 return 32; 00538 } 00539 if ((value & 0xFFFF0000) == 0) { 00540 value <<= 16; 00541 cnt += 16; 00542 } 00543 if ((value & 0xFF000000) == 0) { 00544 value <<= 8; 00545 cnt += 8; 00546 } 00547 if ((value & 0xF0000000) == 0) { 00548 value <<= 4; 00549 cnt += 4; 00550 } 00551 if ((value & 0xC0000000) == 0) { 00552 value <<= 2; 00553 cnt += 2; 00554 } 00555 if ((value & 0x80000000) == 0) { 00556 cnt += 1; 00557 } 00558 00559 return cnt; 00560 #endif 00561 } 00562 00563 COMMON_FUNCTIONS_FN bool common_serial_number_greater_8(uint8_t s1, uint8_t s2) 00564 { 00565 return (s1 > s2 && s1 - s2 < UINT8_C(0x80)) || (s1 < s2 && s2 - s1 > UINT8_C(0x80)); 00566 } 00567 00568 COMMON_FUNCTIONS_FN bool common_serial_number_greater_16(uint16_t s1, uint16_t s2) 00569 { 00570 return (s1 > s2 && s1 - s2 < UINT16_C(0x8000)) || (s1 < s2 && s2 - s1 > UINT16_C(0x8000)); 00571 } 00572 00573 COMMON_FUNCTIONS_FN bool common_serial_number_greater_32(uint32_t s1, uint32_t s2) 00574 { 00575 return (s1 > s2 && s1 - s2 < UINT32_C(0x80000000)) || (s1 < s2 && s2 - s1 > UINT32_C(0x80000000)); 00576 } 00577 00578 COMMON_FUNCTIONS_FN bool bit_test(const uint8_t *bitset, uint_fast8_t bit) 00579 { 00580 return bitset[bit >> 3] & (0x80 >> (bit & 7)); 00581 } 00582 00583 COMMON_FUNCTIONS_FN void bit_set(uint8_t *bitset, uint_fast8_t bit) 00584 { 00585 bitset[bit >> 3] |= (0x80 >> (bit & 7)); 00586 } 00587 00588 COMMON_FUNCTIONS_FN void bit_clear(uint8_t *bitset, uint_fast8_t bit) 00589 { 00590 bitset[bit >> 3] &= ~(0x80 >> (bit & 7)); 00591 } 00592 00593 #endif /* defined NS_ALLOW_INLINING || defined COMMON_FUNCTIONS_FN */ 00594 00595 #ifdef __cplusplus 00596 } 00597 #endif 00598 #endif /*__COMMON_FUNCTIONS_H_*/
Generated on Sun Jul 17 2022 08:25:21 by 1.7.2