加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

在没有uint8_t数据类型的MCU上使用uint8_t进行结构化

发布时间:2020-12-14 02:21:35 所属栏目:Windows 来源:网络整理
导读:我是嵌入式软件开发人员,我想与外部设备连接.该器件通过SPI发送数据.该数据的结构是从外部设备制造商预定义的,无法编辑.制造商提供一些Header文件,其中包含通过SPI发送的所有数据的许多typedef. 制造商还提供了一个API来以正确的方式处理收到的数据包(我可以
我是嵌入式软件开发人员,我想与外部设备连接.该器件通过SPI发送数据.该数据的结构是从外部设备制造商预定义的,无法编辑.制造商提供一些Header文件,其中包含通过SPI发送的所有数据的许多typedef.
制造商还提供了一个API来以正确的方式处理收到的数据包(我可以访问该API的源代码).

现在我的问题:
typedefed结构包含许多uint8_t数据类型.不幸的是,我们的MCU不支持uint8_t数据类型,因为最小的类型是16位宽(因此即使char有16位).

要正确使用API??,必须使用通过SPI接收的数据填充结构.由于传入的数据是字节数据包,我们不能只将这些数据复制到结构中,因为我们的结构对这些8位类型使用16位.
因此,我们需要执行许多位移操作来正确分配接收的数据.

示例:(制造商typedef结构)

typedef struct NETX_COMMUNICATION_CHANNEL_INFOtag
{
  uint8_t   bChannelType;              //uint16_t in our system
  uint8_t   bChannelId;                //uint16_t in our system
  uint8_t   bSizePositionOfHandshake;  //uint16_t in our system
  uint8_t   bNumberOfBlocks;           //uint16_t in our system
  uint32_t  ulSizeOfChannel;           
  uint16_t  usCommunicationClass;      
  uint16_t  usProtocolClass;           
  uint16_t  usProtocolConformanceClass;
  uint8_t   abReserved[2];             //uint16_t in our system
} NETX_COMMUNICATION_CHANNEL_INFO;

任何人都可以想到这个问题的简单解决方法吗?
我真的不想为每个接收的数据包类型写一个单独的bitshift操作. (性能/时间/空间浪费)

我的想法
(使用位域将2xuint8_t填充到uint16_t或4xuint8_t到uint32_t)

typedef struct NETX_COMMUNICATION_CHANNEL_INFOtag
{
  struct packet_uint8{
    uint32_t  bChannelType              :8;
    uint32_t  bChannelId                :8;
    uint32_t  bSizePositionOfHandshake  :8;
    uint32_t  bNumberOfBlocks           :8;
  }packet_uint8;
  uint32_t  ulSizeOfChannel;               
  uint16_t  usCommunicationClass;          
  uint16_t  usProtocolClass;               
  uint16_t  usProtocolConformanceClass;    
  uint16_t  abReserved;                    
} NETX_COMMUNICATION_CHANNEL_INFO;

现在我不确定这个解决方案是否会起作用,因为位域内的位顺序不一定是源文件中的顺序. (或者如果所有的位域都具有相同的大小?)

我希望我能够很好地描述这个问题,让你明白.

感谢致敬.

解决方法

您的编译器手册应描述位域的布局方式.仔细阅读.还有一些叫__attribute __((byte_peripheral))的东西应该有助于在内存映射设备中合理地打包位域.

如果您不确定位域,只需将uint16_t用于这些字段,并使用带位移的访问宏,例如

#define FIRST(x) ((x) >> 8)
#define SECOND(x) ((x) & 0xFF)

...
    uint16_t channel_type_and_id;
...

int channel_type = FIRST(x->channel_type_and_id);
int channel_id = SECOND(x->channel_type_and_id);

然后你只需要确定平台的字节顺序.如果您需要更改MCU似乎支持的字节顺序?你可以重新定义这些宏.

一个位域很可能仍然会在位移方面实现,因此不会有太多的节省 – 如果寄存器有字节访问函数,那么编译器就会知道优化x& 0xff使用它们

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读