RE: Záhada v C
Pavel Hudecek
edizon na seznam.cz
Sobota Leden 23 22:08:35 CET 2021
(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.
Od: Miroslav Mraz
ISR (ADC0_RESRDY_vect) { // 37,1 kHz / 16 ======
if (adSync) return; // nejaky problem zpracovani
. static uint8_t ind=0;
.
. //adDataRaw[ind]=(uint32_t)ADC0_RES;
. adDataRaw[ind]=(uint32_t)ind;
.
. if (++ind>=AD_chCount) ind=0;
. ADC0_MUXPOS=AD_chFirst+ind;
.
. adSync=1;
. ADC0_INTFLAGS=1;
}
Ve funkci cekej je mj. (i je lokální int):
if (adSync==1) { // -------------------------
. for (i=0; i<AD_chCount; i++) adData[i]=adDataRaw[i];
.
. adSync=0; // az zde
}
adSync by mělo být něco jako C ekvivalent std::atomic, nechce se mi to
hledat.
Mrazík
Dne 23. 01. 21 v 20:14 Pavel Hudecek napsal(a):
> Dobrý den všem,
>
> ATtiny816, Atmel Studio
>
> volatile uint32_t adDataRaw[AD_chCount];
>
> uint32_t adData[AD_chCount];
>
> ISR (ADC0_RESRDY_vect) { // 37,1 kHz / 16 ======
>
> . static uint8_t ind=0;
>
> .
>
> . //adDataRaw[ind]=(uint32_t)ADC0_RES;
>
> . *adDataRaw[ind]=(uint32_t)ind;*
>
> .
>
> . *if (++ind>=AD_chCount) ind=0;*
>
> . ADC0_MUXPOS=AD_chFirst+ind;
>
> .
>
> . adSync=1;
>
> . ADC0_INTFLAGS=1;
>
> }
>
> Ve funkci cekej je mj. (i je lokální int):
>
> if (adSync==1) { // -------------------------
>
> . adSync=0;
>
> .
>
> . *for (i=0; i<AD_chCount; i++) adData[i]=adDataRaw[i];*
>
> }
>
> V mainu je while(1) a tam mj. (n je lokální uint32_t):
>
> cekej(1000);
>
> for (n=0; n<AD_chCount; n++) {
>
> . cislo((uint32_t)adData[n]); text("/");
>
> . cislo((uint32_t)adDataRaw[n]); text(" ");
>
> }
>
> UART_crlf;
>
> A z terminálu leze:
>
> 5/5 6/1 2/2 3/3 4/4 0/5 1/6
>
> 5/5 6/1 2/2 3/3 4/4 0/5 1/6
>
> 0/5 6/1 2/2 3/3 4/4 0/5 1/6
>
> 5/5 1/1 2/2 3/3 4/4 0/5 1/6
>
> Proč z terminálu neleze
>
> 0/0 1/1 2/2 3/3 4/4 5/5 6/6
>
> ???
------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20210123/99adef4b/attachment.html>
Další informace o konferenci Hw-list