RE: Záhada v C -Vyřešeno a otázky

Pavel Hudecek edizon na seznam.cz
Neděle Leden 24 00:12:44 CET 2021


Od začátku mi bylo jasný, že je to nějaká blbina vzniklá při nějakém zmatkování:-)
Celá tahle část byla zkopírovaná z funkčního projektu, ale tady jsem se navíc rozhod použít HW akumulaci hodnot ADC. Tak jsem typ dat v poli změnil na uint32_t, aby se to tam vešlo. Jenže jsem ho změnil v extern deklaraci v .h, ale ne v tý hlavní v .c. A to způsobilo všechny následující problémy. Normálně při podobných rozdílech překladač protestuje, není mi jasné, proč tentokrát neprotestoval.

A stejně by mě zajímalo, jak je to tedy s tím volatile, mějme:
volatile uint8_t prom1=0, prom2=0, prom3=0;
Budou volatile všechny 3, nebo jenom ta první?
volatile uint8_t pole[] = {0, 0, 0};
Bude volatile celý pole, nebo jen ukazatel na něj?

A jak je to s tou atomicitou v C?

PH

Od: Pavel Hudecek
Preventivně jsem to zkusil oddělit, ale nepomohlo. Po zapnutí optimalizace stejné nesmysly. Na druhou stranu jsem ještě víc debutoval a zavěr je ještě šílenější:
Rozdíl mezi výpisem pole v debugu a v memory view:-)

Najedu myší na adData, ukáže mi to 0x3e00 a po rozbalení data 0010203
V memory view je na 0x3e00:
00 00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00
Tedy to co by tam mělo bejt, ne co ukazuje debug, ani co leze z terminálu.

Najedu na adDataRaw: 0x3e14 a data 5623456
V memory view je na 0x3e14:
05 00 00 00 06 00 00 00 02 00 00 00 03 00 00 00 04 00 00 00 05 00 00 00 06 00 00 00
Tentokrát souhlasí se zobrazeným výčtem v debugu, ale zase nesouhlasí s terminálem.

Z terminálu leze (data/raw):
0/0  1/1  2/2  3/3  4/4  0/5  1/6  
0/0  1/1  2/2  3/3  4/4  0/5  1/6  
0/0  1/1  2/2  3/3  4/4  0/5  1/6  
0/5  1/1  2/2  3/3  4/4  0/5  1/6  
0/0  1/1  2/2  3/3  4/4  0/5  1/6  

WTF?

PH

Od: Miroslav Šinko
Nechce sa mi to hladat v norme, ale co si pamatam, tak volatile sa 
vztahuje na jednu premennu. T.j. (podla mna) v tomto riadku je ako 
volatile definovana iba premenna msSync:
> volatile uint8_t msSync=0, sekSync=0, adSync=0; // =1 po int

miro

On 23.1.2021 22:08, Pavel Hudecek wrote:
> (Zajímavé je, jak se v těch mailech množí řádky a taky kde se berou ty
> hvězdičky… Mě to přišlo nenamnožené a bez přidaných hvězdiček, jako je
> to vidět v archivu na webu. Jen tečky jsou moje, dal jsem je na začátky
> řádků, abych zabránil zrušení odsazení.)
>
> adSync je definováno v souboru deklarace.c:
>
> volatile uint8_t msSync=0, sekSync=0, adSync=0; // =1 po int
>
> a potom v deklarace.h:
>
> extern volatile uint8_t   msSync, sekSync, adSync; // =1 po int
>
> a ten se includuje všude.
>
> Myslel jsem si, že volatile právě onen problém řeší.
>
> Kombinaci adSync, sekSyns, msSync používám běžně tímto stejným způsobem
> a vždycky to fungovalo (a msSync+Seksync tady funguje). Čímž netvrdím,
> že jsem si 100% jist správností a adSync je asi 37x rychlejší než msSync.
>
> Teď jsem zkoušel hledat atomic, atomic variables a pod, ale bohužel
> všechno nalezené je jen pro C++, ne C.
>
> Při debugu byl obsah obou polí odlišný, i když to zastavím hned za forem
> co to má kopírovat.
>
> Po vypnutí optimalizace je výpis krásně 0/0 … 6/6, akorát občas je
> 65539/3 místo 3/3.
>
> Zkusil jsem při kpírování zakázat int:
>
> __asm__("cli");
>
> for (i=0; i<AD_chCount; i++) adData[i]=adDataRaw[i];
>
> __asm__("nop");
>
> __asm__("sei");
>
> Kupodivu 65539/3 podstatně přibylo:-)
>
> Na nop jsem dal breakpoint a výsledkem je, že v adDataRaw jsou normálně
> čísla 0-6 a v adData je namícháno 0010203.
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20210124/a284bc0a/attachment.html>


Další informace o konferenci Hw-list