printf %lu overflow

Plaats reactie
pascal
Berichten: 174
Lid geworden op: za jan 18, 2020 9:36 pm

printf %lu overflow

Bericht door pascal »

Ik fabriek nogal wat embedded software voor mijn werk en voor het project waar ik al lange tijd mee bezig ben maak ik gebruik van een stm32 ARM processor.
Deze processor communiceert via een slim systeem (al zeg ik het zelf) met een FPGA waar het unsigned 24 bit getallen heen kan sturen
en idem dito terug kan lezen.
Nu doet zich daar een merkwaardig probleem voor wat ik niet helemaal kan verklaren.

Ik lees een getal uit en probeer dan vervolgens op het scherm te toveren
Naar analogie ziet dat er ongeveer als volgt uit.

Code: Selecteer alles

char msg[20];
uint32_t DataRead = GetDataFromFpga();
sprintf(msg, "%lu", DataRead);
SerialPortPrintLine(msg);
Again naar analogie, want de code ziet er uiteraard heel anders uit.

Het gekke is dat bij getallen groter dan ongeveer 260000 de sprintf functie overloopt en foutieve getallen schrijft.
Ik kan dat niet helemaal verklaren.. immers met 24 bits unsigned kan ik elk getal van 0 t/m 2^25 - 1 = 33554431 maken.
Compileer ik de zelfde code gewoon op mijn PC (intel 64bit) dan rollen er gewoon goede getallen uit.
Ik heb het nu maar opgelost door zelf een conversie functie te maken maar dat zou toch niet nodig moeten zijn.

Iemand een idee wat hier aan de hand is ?
Vivo ergo onus
iswrong
Berichten: 104
Lid geworden op: ma feb 10, 2020 9:16 am

Re: printf %lu overflow

Bericht door iswrong »

pascal schreef: vr jan 31, 2020 7:36 pm Ik kan dat niet helemaal verklaren.. immers met 24 bits unsigned kan ik elk getal van 0 t/m 2^25 - 1 = 33554431 maken.
Ik hoop [0, 2^24 -2], dus [0, 16777215] ;).
Het gekke is dat bij getallen groter dan ongeveer 260000 de sprintf functie overloopt en foutieve getallen schrijft.
Interessant!

Code: Selecteer alles

>>> math.log(260000, 2)
17.98815209769054
>>> 
>>> 2 ** 18 -1
262143
Vrij dicht bij de dichtstbijzijnde macht van 2, nl. 2^18.

Veronderstellende dat sprintf niet het probleem is en er geen corruptie van de stack is (C programmeurs maken nooit fouten, toch?), is er ergens iets dat beperkt is tot 18-bits in the hardware die je gebruikt?
pascal
Berichten: 174
Lid geworden op: za jan 18, 2020 9:36 pm

Re: printf %lu overflow

Bericht door pascal »

Gebruikte chip is een STM32, de hele stack komt van de fabrikant.

Het gaat om SPI communicatie naar een aantal FPGA's waarop ik steeds 2*32 registers van 24 bits heb geimplementeerd.
Vooraf gaande aan de data stuur ik eerst een 8bit bericht waarin ik aangeef welk van die registers ik wil hebben en wat ik er mee wil
Als je onbekend bent met SPI communicatie moet je weten dat dit altijd full duplex is en je altijd evenveel bits ontvangt als verstuurd.
Na het versturen van dit bericht verstuur ik drie keer een 0 (of zoals mijn implenmtatie werkt een willekeurig ander getal) maar ik lees wel de response data terug en schuif die in de variabele result.

Het is mogelijk dat de manier waarop ik de 24 bits data binnenhaal vanaf de SPI bus niet correct geconverteerd word.
Hier is ongeveer hoe ik het doe

Code: Selecteer alles

uint32_t result=0;

SpiFpga_SelectBoard(spi, SlaveId);
SpiFpga_WriteReadByte(spi, (RegisterId<<3));
result += ((uint32_t)SpiFpga_WriteReadByte(spi, 0)) << 16;
result += ((uint32_t)SpiFpga_WriteReadByte(spi, 0)) <<  8;
result += ((uint32_t)SpiFpga_WriteReadByte(spi, 0));
SpiFpga_SelectBoard(spi, 0);
C programmeurs maken nooit fouten, toch?
Ben blij dat je het nog steeds met mij eens bent :twisted:
Vivo ergo onus
Plaats reactie