簡體   English   中英

如何使用輸入參數無符號 32 位數組在 function 中傳遞結構?

[英]How can I pass a struct in a function with input argument unsigned 32 bit array?

我想計算STM32 micro controller中一些數據的CRC值。 用於計算 CRC 的 HAL function 具有以下占用空間:

uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength);

我的數據存儲在一個結構中:

struct caldata_tag {
    float K_P_Htng;
    uint16_t K_I_Htng;
    uint16_t K_D_Htng;
    uint16_t K_P_Coolg; } caldata;

誰是將結構傳遞給 HAL_CRC_Calculate() function 的最安全和最合適的方法?

我正在考慮這個:

#define U32BUFFERSIZE sizeof(struct caldata_tag)/sizeof(uint32_t)
uint32_t buffer[U32BUFFERSIZE];
uint32_t crcValue;

/*  calculate the crc value of the data */
memcpy(buffer,&localStruct,U32BUFFERSIZE);

crcValue = HAL_CRC_Calculate(&CrcHandle,buffer,U32BUFFERSIZE);

但我認為這是一種丑陋的方式,你能告訴我是否可以嗎? 或者如果你有更好的主意?

誰是將結構傳遞給HAL_CRC_Calculate() function 的最安全和最合適的方法?

挑戰:

  • HAL_CRC_Calculate()顯然想根據uint32_t的倍數計算 CRC。

  • struct caldata_tag的大小可能不是uint32_t大小的倍數。

  • struct caldata_tag可能包含 caldata 中未知caldata的填充。

使用struct caldata_tag和足夠大的uint32_t數組的union 將其歸零,復制成員,然后計算 CRC。

我認為這是一種丑陋的方式,你能告訴我是否可以嗎? 或者如果你有更好的主意?

形成一個助手function。

// Find the quotient of sizeof caldata_tag / sizeof(uint32_t), rounded up
#define U32BUFFERSIZE ((sizeof(struct caldata_tag) + sizeof(uint32_t) - 1)/sizeof(uint32_t))

uint32_t caldata_CRC(CRC_HandleTypeDef *hcrc, const struct caldata_tag *p) {
  // u's size will be a multiple of sizeof uint32_t
  union {
    uint32_t u32[U32BUFFERSIZE];
    struct caldata_tag tag;
  } u = { {0} };  // zero every thing

  // copy the members, not the padding
  u.tag.K_P_Htng = p->K_P_Htng;
  u.tag.K_I_Htng = p->K_I_Htng;
  u.tag.K_D_Htng = p->K_D_Htng;
  u.tag.K_P_Coolg = p->K_P_Coolg;

  return HAL_CRC_Calculate(hcrc, u.u32, U32BUFFERSIZE);
}

利用

uint32_t crcValue =  caldata_CRC(&CrcHandle, &caldata);

[更新]

進一步研究表明, BufferLengthuint8_t, uint16_t, uint32_t的計數,具體取決於hcrc->InputDataFormat. OP 沒有提供,但如果可以將其設置為uint8_t 那么代碼只需要擔心struct caldata中的填充。

#define U8BUFFERSIZE sizeof(struct caldata_tag)

uint32_t caldata8_CRC(CRC_HandleTypeDef *hcrc, const struct caldata_tag *p) {
  // u's size will be a multiple of sizeof uint32_t
  union {
    uint32_t u32[U32BUFFERSIZE];
    struct caldata_tag tag;
  } u = { {0} };  // zero every thing

  // copy the members, not the padding
  u.tag.K_P_Htng = p->K_P_Htng;
  u.tag.K_I_Htng = p->K_I_Htng;
  u.tag.K_D_Htng = p->K_D_Htng;
  u.tag.K_P_Coolg = p->K_P_Coolg;

  return HAL_CRC_Calculate(hcrc, u.u32, U8BUFFERSIZE);
}

如果編譯器允許__attribute__((__packed__)) ,@sephiroth 答案是go的好方法。

您可以使用直接指向結構開頭的指針,而無需使用支持緩沖區:

uint32_t *p = (uint32_t*)&localStruct;

這有兩個問題:

第一個是如果編譯器在結構上進行填充,你可能會得到意想不到的結果; 您可以通過向結構添加 (packed) 屬性來告訴編譯器不要做任何填充來解決這個問題

struct __attribute__((__packed__)) caldata_tag { 
  //... 
}

另一個問題是您的結構大小不是 32 的倍數,因此如果在最后一個元素的末尾沒有 16 個隨機位,就無法在 uint32_t 數組中表示它。 您的示例也是如此,bur 我認為在這種情況下您將丟棄buffer的最后一個元素,因為U32BUFFERSIZE應該等於 2,因此您在計算 crc 時忽略K_P_Coolg及其旁邊的 16 個隨機位。

在使用 crc 和類似的東西時,我的建議是使用 8 位緩沖區而不是 32 位緩沖區,因為它完全消除了后一個問題。

不需要解決方法。 According to the documentation for the function HAL_CRC_Calculate: "By default, the API expects a uint32_t pointer as input buffer parameter. Input buffer pointers with other types simply need to be cast in uint32_t and the API will internally adjust its input data processing based on the處理字段 hcrc->InputDataFormat。”

因此在第一個參數中正確設置該字段,您可以將指向字節的指針傳遞給 function。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM