임베디드 시스템 (리틀 엔디안 ARM, 언어 C - 여기서 테스트 목적 C++ 용으로 사용)에도 첨부 된 코드를 작성했습니다. 나는 서로 다른 구성된 데이터를 전송하고 수신해야한다. 비트 정렬과 주어진 비트 길이. 같은 구성은 내가 보내야 할 각 변수에 대한 field_conf_t을 사용하여 수행됩니다 /납니다비트 정렬 바이트 단위 바이트 정렬 버퍼
이typedef struct field_conf_t { ... }; // see below
typedef struct {
field_conf_t a;
field_conf_t b;
field_conf_t c;
} tx_fields_conf_t;
const tx_fields_conf_t tx_fields_conf = {
{ 0, 8 }, // a - offset/length
{ 28, 12 }, // b - offset/length
{ 56, 8 } // c - offset/length
};
내가 가진 문제는 내가 단일 비트 작전에 대해 많은 생각 즉, 테스트는 실패합니다. 여기
코드 :
#include <stdint.h>
#define BOOST_TEST_MODULE BitFieldTest
#include <boost/test/unit_test.hpp>
typedef uint8_t uint8;
typedef uint16_t uint16;
typedef uint32_t uint32;
typedef unsigned long long uint64;
typedef struct {
uint8 offset; // [0-63]
uint8 length; // [1-32]
} field_conf_t;
typedef struct {
field_conf_t a;
field_conf_t b;
field_conf_t c;
} tx_fields_conf_t;
typedef union {
uint8 buf[8];
uint64 contents;
} msg_t;
void set_value(msg_t* const msg, const field_conf_t* const field, uint32 value)
{
const uint32 mask = (1 << field->length) - 1;
msg->contents &= ~(mask << field->offset); // clear old contens
msg->contents |= (value & mask) << field->offset; // set new contens
}
uint32 get_value(const msg_t* const msg, const field_conf_t* const field)
{
const uint32 mask = (1 << field->length) - 1;
uint64 value = (msg->contents >> field->offset);
value &= mask;
return (uint32)value;
}
// ########################################################################
struct TestFixture {
TestFixture() : a(0xAA), b(0xBBB), c(0xCC) {
conf.a.offset = 0; conf.a.length = 8;
conf.b.offset = 25; conf.b.length = 12;
conf.c.offset = 56; conf.a.length = 8;
}
uint32 a, b, c;
msg_t msg;
tx_fields_conf_t conf;
};
BOOST_FIXTURE_TEST_SUITE(MsgBitfieldTest, TestFixture);
BOOST_AUTO_TEST_CASE(Test_01)
{
set_value(&msg, &conf.a, a);
BOOST_CHECK(get_value(&msg, &conf.a) == a);
set_value(&msg, &conf.b, b);
BOOST_CHECK(get_value(&msg, &conf.a) == a);
BOOST_CHECK(get_value(&msg, &conf.b) == b);
set_value(&msg, &conf.c, c);
BOOST_CHECK(get_value(&msg, &conf.a) == a);
BOOST_CHECK(get_value(&msg, &conf.b) == b);
BOOST_CHECK(get_value(&msg, &conf.c) == c);
}
BOOST_AUTO_TEST_SUITE_END();
및 테스트 실행 출력
Running 1 test case...
d:/work/bugee/test/can_msg/msg_bitsfields/msg_bitsfields/main.cpp(65): error in
"Test_01": check get_value(&msg, &conf.b) == b failed
d:/work/bugee/test/can_msg/msg_bitsfields/msg_bitsfields/main.cpp(69): error in
"Test_01": check get_value(&msg, &conf.b) == b failed
d:/work/bugee/test/can_msg/msg_bitsfields/msg_bitsfields/main.cpp(70): error in
"Test_01": check get_value(&msg, &conf.c) == c failed
*** 3 failures detected in test suite "BitFieldTest"
버퍼 크기는 항상 8 바이트이고; 64 비트를 오래 사용할 수있어서 기쁩니다. 바이트 정렬 된 연산에도 실패하기 전에 (각각의 바이트에서 마스크와 비트 연산). 값은 int32/uint32보다 클 수 없습니다. 또한 C 비트 필드에 대해서도 알고 있습니다. 그들은 너무 느리고 임베디드 시스템에 대한 빠른 솔루션이 필요합니다 (다른 시간 소모적 인 작업도 있습니다).
나는 또한 lsb/msb 32 비트 또는 심지어 8 바이트 슬라이스 빠른 솔루션의 솔루션에 관심이 있지만 64 비트 데이터 유형을 사용하는 것이 컴파일러로 인해 더 많은 성능을 제공한다고 가정합니다.
감사합니다, 그러나 이것은 문제가되지 않습니다 64 비트에
mask
을 변경하면 64 비트 연산으로 수행 된 비트 변화를 얻기 위해 작동합니다. 최종 버전에서 사용하려는 구조 'API'. – user1630297