djtulan Music, Hackerspace, Retrocomputing

Calculate CRC-32 with STM32 HAL CRC unit

Die STM32 Mikrocontroller Familie bittet die Möglichkeit einen CRC (Cyclic redundancy check) über bestimmte Speicherbereiche zu berechnen. Jedoch war es mit den default Einstellungen nicht ohne Weiteres möglich, das selbe Ergebnis zu erzielen.

Ausgangspunkt war folgender:

Der CRC-32 für das Programm im Flashspeicher des Mikrocontrollers sollte mit dem CRC-32 über das Binärfile verglichen werden können.
Da die STM32 Chips einen Hardware CRC bereitstellen, sollte dieser auch genutzt werden.

Aktivierung des CRC im Cube MX

Die default Einstellungen im Cube MX, einem Tool zum Konfigurieren von STM32 Chips schaut wie folgt aus:

undefined

Im Quellcode wird dann folgender Hardware Init Code erzeugt:

/**
  * @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_ENABLE;
  hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
  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 */
}

Im Usercode lässt sich dann folgende HAL Funktion ausführen:

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

Dieser Funktion wird das HAL CRC Handle übergaben, ein Pointer auf den Beginn des Speicherbereichs und einer Länge des Bereiches.

Leider führten die default Einstellungen nicht zum gewünschten Ergebnis, wenn man die gleichen Daten mit einem Standard CRC-32 verglich. Beispielsweise, wenn man das Ergebnis mit diesem Online Tool verglich: https://emn178.github.io/online-tools/crc32_checksum.html

Nach einer längeren Suche im Internet wurde ich wie so oft auf stackoverflow.com fündig. In folgendem Beitrag wurde ein Lösungsweg vorgestellt: https://stackoverflow.com/questions/39646441/how-to-set-stm32-to-generate-standard-crc32

Richtige Einstellung Cube MX

Im Cude MX müssen die Einstellungen von "Input Data Inversion Mode" auf "Byte" und "Output Data Inversion Mode" auf "Enable" gesetzt werden.

undefined

Danach schaut der erzeugte Init Code folgendermaßen aus:

/**
  * @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_ENABLE;
  hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
  hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE;
  hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;
  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 */
}

Soweit so gut, ein kleiner Hack wird trotzdem noch benötigt.

Das Ergebnis muss noch einmal verXORt werden. Ich habe mir dazu einfach eine Funktion geschrieben, die über den gewünschten Bereich rechnet:

extern CRC_HandleTypeDef hcrc;

#define ROM_START    (( uint32_t*) 0x08000000)
#define ROM_SIZE      ( uint32_t)  0x20000

uint32_t GetCRC(void) {
   return ~HAL_CRC_Calculate(&hcrc, ROM_START, ROM_SIZE);
}

Mit dem XOR Operanden ~ erhält man schließlich das richtige Ergebnis.

Da beim Kompilieren des Binaries keine fixe Größe erzeugt wird, habe ich im Makefile eine Zeile Code eingefügt, die mein Binary fix auf 128kB vergrößert und den Rest mit 0en befüllt. Das geht unter Linux mit dem Befehl "truncate" sehr einfach.

$(BUILD_DIR)/%.bin: $(BUILD_DIR)/%.elf | $(BUILD_DIR)
	$(BIN) $< $@
	truncate $@ --size 131072

Man muss bei dieser Methode jedenfalls gut aufpassen, dass der erzeugte Programmcode nicht größer wird, als die eingestellte Größe!
Ansonsten wird das Programm unabsichtlich abgeschnitten. Ich habe einfach mal das doppelte an Platz reserviert.

Nun ergeben die CRC-32 über das gebaute Binary file und die Berechnung innerhalb des Mikrocontrollers die gleiche CRC-32.

Progressive Melodic House - Sep 2022

Tracklist:

Haze-M - Abrupt Journey
Supacooks - Kontrol
Guy Mantzur and Roy Rosenfeld - Epika
khen, Freedom Fighters - Levantine
James Harcourt - Sister
Marius Drescher - Data Entry (Original Mix)
Dachshund - Speechless
Hunter/Game - Beyond A Dream
Matt Fax Estiva - Found (Extended Mix)
Boris Brejcha - Night Owl
Resil - Miami Electro
Fat Sushi - Hana
Kevin Paul - Curiosity (Original Mix)
Mike Isai - Chrysalis (Gmj & Matter Remix)
Altman - Lost
Dee Montero - Moksa
Shai T - Oriki (Hernan Cattaneo & Marcelo Vasami Remix)
Boss Axis - Happy End (Original Mix)
Mollono.Bass, Bonfante - Tomorrow
Dahu - Solar Drone
Moonwalk - Dune
Hermanez - Dust Town

End of Summer Party @ Waki Martinsdorf - Sep 2022

Tracklist:

(01. Pablo Fierro - King del Bongo) -> leider nicht im Mix
02. Pablo Fierro - Tembo
03. Dennis Cruz - Los Tamales
04. Masters On Vacation - Puerto Rico Disco Club
05. Didje Doo - Bangka Boat
06. Roi Okev - Gosa (Atsou Remix)
07. Hamza Rahimtula - Latina
08. Rampa - Lavender Boogie
09. David Herrero - Don't Hold Back (Original Mix)
10. Gledd - Osun (DJ Mix)
11. Pablo Fierro - Nomada
12. Alex Breitling - Makasi (David Mayer Remix)
13. Sparrow & Barbossa - Coro (Original Mix)
14. Johan Dresser Reveh & Drezza - Contigue (Original Mix)
15. Ralf GUM - Gipsy In Love
16. Faze Action, Zeke Manyika - Maswera
17. Osibisa - Yo Luv Is Betta (Expansions NYC Dub)
18. David Herrero - The Present, the Future (Original Mix)
19. Oskar Konne - La Pluma (Original Mix)
20. Scruscru, Los Protos - El Rayero
21. Orange Tree Edits - Fo Ya (Jimmy Rouge Edit)
22. Sparrow & Barbossa Mo' Horizons Francis Coletta - Quando Te Veo
23. Didje Doo - Living Soul
24. MoBlack Emmanuel Jal Henrik Schwarz - Chagu (MoBlack Extended Version)

Deep Organic House - Aug 2022

Tracklist:

1 Ariadne’s Villa - Deek That
2 Ramdeesun - Deek That
3 Murmur - Nodo
4 Riders On The Calm - Scruscru
5 Ambience Effect - bdtom
6 Please Repost - Brigade
7 Solar Symphony - Somelee, Talemates
8 Onyx - Don Son
9 Snow Tiger - Eli Nissan
10 Kand - Pawas feat. Arooj Aftab
11 Ecro - Luke Garcia
12 Dreamer - Supacooks
13 Amal (Mollono.Bass Remix) - Abarra, Mollono.Bass
14 Respira - Pablo Fierro
15 Coro (Original Mix) - Sparrow & Barbossa
16 Camaleon - Pablo Fierro
17 Reality - T.Markakis
18 Strings & Pearls - Eli Nissan
19 You Now - M.O.S.
20 Sacré Coeur - Raw Main

Neuere Posts → Home ← Ältere Posts