巡回冗長検査 CRC(Cyclic Redundancy Check)

データの受け渡し時、データが正しく届いたか確認するために送出データの最後にCRCで計算したデータを追加して送出します。受取側で受け取ったデータもCRC計算し、送られてきたCRCと比較して等しかったら正しくデータを受け取れたと判断します。
CRCの仕組み及び詳細は他のサイトを見ていただくとして、ここでは実際に使用しているコードにつて説明します。
本件では実験基板(ファームウェア)とコンピュータ(アプリケーション)間で通信を行うので各々にCRC計算処理が必要です。
どちらも以下のC言語で実装しても良いのですが

// CRC計算

#define CRC16POLY 0x1021	// 生成多項式:x16+x12+x5+1

unsigned short crc16(unsigned short crc, unsigned char const* ptr, int len)
{
	int i, j;

	for (i = 0; i < len; i++) {
		crc ^= (((unsigned short)ptr[i]) << 8);
		for (j = 0; j < 8; j++) {
			if (crc & 0x8000) {
				crc = (crc << 1) ^ CRC16POLY;
			}
			else {
				crc <<= 1;
			}
		}
	}
	return crc;
}

// 使用方法

unsigned short crc = crc16(0x5abe, &data, size);	// data:データ	size:データサイズ

実験基板に使用しているCPUにはCRC計算モジュールが内蔵されているので、それを使用してファームウェアの負荷を減らします。
このモジュールの初期設定はCubeMXで生成してもらいます。
1.CubeMXの設定
2.CubeMXによる初期化コードの生成
3.モジュールを使ったCRC計算

1.CubeMXの設定

生成多項式:x16+x12+x5+1
初期値:0x5abe
ビットシフト方向:左送り
出力XOR:0x0000(非反転)
この設定は送り側と受け側のCRC計算で同じにする必要があります。

2.CubeMXによる初期化コードの生成

/**
  * @brief CRC Initialization Function
  * @param None
  * @retval None
  */
static void MX_CRC_Init(void)
{
  /* USER CODE BEGIN CRC_Init 0 */

  /* USER CODE END CRC_Init 0 */

  /* USER CODE BEGIN CRC_Init 1 */

  /* USER CODE END CRC_Init 1 */
  hcrc.Instance = CRC;
  hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;
  hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
  hcrc.Init.GeneratingPolynomial = 4129;		// 0x1021
  hcrc.Init.CRCLength = CRC_POLYLENGTH_16B;
  hcrc.Init.InitValue = 0x5abe;
  hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
  hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
  hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
  if (HAL_CRC_Init(&hcrc) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CRC_Init 2 */

  /* USER CODE END CRC_Init 2 */
}

3.モジュールを使ったCRC計算

// 前記プログラムによるCRC計算
unsigned short crc = crc16(0x5abe, &data, size);   // data:データ size:データサイズ


// CPU CRCモジュールによるCRC計算
CRC_HandleTypeDef hcrc;

hcrc.Init.InitValue = 0x5abe;
HAL_CRC_Init(&hcrc);
uint32_t uwCRCValue1 = HAL_CRC_Accumulate(&hcrc, (uint32_t *)&data, size);
crc = (uint16_t)(uwCRCValue1 & 0x0000ffff);


コンピュータ側のアプリケーションプログラムはC#で作成しているのでC#用に書き換えます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です