[elektro] STM32f4 interrupt : volatile tombok
Pal Lukacs
ekegep at yahoo.com
Tue Dec 10 20:09:03 CET 2013
Szia !
Eloszoris koszi a valaszt !
Igy nez ki:
struct DAC_BUF
{
float32_t left[DAC_BUF_MAX_L];
float32_t right[DAC_BUF_MAX_R];
uint16_t index_L;
uint16_t index_R;
enum {DAC_BUF_WRT, DAC_BUF_RDY} dac_buf_state ; //writabble, readyabble
} ;
volatile struct DAC_BUF dac_buf_1_inst, dac_buf_2_inst;
Ki fogom probalni, hogy nem adok volatile modositot.
Tudom hogy kikapcsolja az optimalizaciot,..az IT miatt tettem a tomboket es a tobbit volatilere, mert az IT irja, olvassa.
IT-ben:
switch(dac_channel_state)
{
case DAC_CH_L:
dac_channel_state = DAC_CH_R;
//...adat kivesz
if( dac_buf_1_inst.dac_buf_state == DAC_BUF_RDY)
{
if(dac_buf_1_inst.index_L <= (uint16_t) (DAC_BUF_MAX_L - 1) )
{
out_data = dac_buf_1_inst.left[dac_buf_1_inst.index_L++] ;
}
else{
dac_buf_1_inst.dac_buf_state = DAC_BUF_WRT;
dac_buf_1_inst.index_L = 0;
dac_buf_1_inst.index_R = 0;
dac_buf_2_inst.dac_buf_state = DAC_BUF_RDY ;
}
...
stb.
Udv
Szabi
On Tuesday, December 10, 2013 5:30 PM, hg12345 <hg12345 at freemail.hu> wrote:
Hi,
Ezzel a volatile-vel jól megkevered magadat.
A volatile a kiveszi az optimalicáióból a felhasznált változó kezelését. (olyan mint ha -O0 fordítanád)
leginkább HW kezelés megadásánál kell használni, nehogy csak egy részet olvassa vagy írja a változónak, perifériának.
Illetve olyan változóknál, ahol a fordító nem érzi (látja) hogy a kiértékelés közben az értékét változtatja. Ez esetben csak gyorsítás miatt még a feltétel előtt beolvassa és a feltétel kiértékelése közben már nem.
(egy külső bitre való várakozás e hiány végtelen ciklust okozhat)
Az IT és a nem it-s program közösen használt változóira, ha egyszerre irhatják... inkább az ATOMIC kezelés a fontos. Ez azt jelenti hogy írás vagy olvasás közben a vezérlés nem vehető el a programtól! Sokan azt hiszik, hogy ez triviális egy globális IT tiltással, de ez ennél tovább mutat. Ezt igazából SW nem megoldható, vagy támogatja a HW vagy nem.
Az optimalizáció okozhat meglepetéseket fordítás közben, és erre nem mindig a volatile kulcsszó a megoldás. Ha szükséges érdemes utána nézni a __schedule_barrier(),__force_stores(), __memory_change() beépített fordítási utasításoknak, és hasonlóan a ARM belső buffer/cache ürítő utasításoknak. Valószínüleg nem itt kell keresni a problémát.
Esetedben a tömb pointereket kell volatile-ként definiálni (szerintem az is felesleges), de a adattárolás biztos nem. (ha nem használsz optimalizációt, akkor a volatilenek nincs hatása!)
Amit írtál:
volatile struct adc_buf adc_buf_inst1, adc_buf_inst2;
ezt milyen fordító eszi meg?
struct {
int adc_buf_inst1; //int és real azonos tárolási terület
int adc_buf_inst2;
} adc_buf_t;
adc_buf_t adc[1024];
valami ilyesmire gondoltál? (ha struct elé irod a volatile-t akkor ez teljes elem kezelés nem lesz optimalizálva, ha csak a tag elé akkor az a tag nem lesz optimalizálva)
ez esetben a feldolgozás lehet pointeres vagy indexes, de a fordító mivel érzékeli, hogy nem ugyan azt írod olvasod a következő feldolgozási ciklusban, minden olvasáskor vagy íráskor új értéket fogadni a változódnak. Nem kell volatile!
Pal Lukacs <ekegep at yahoo.com> írta:
>Sziasztok !
>
>HW float szamolja a dolgokat. Ellenorizve, mukodik az FPU.
>
>Nem 12 bit, 24 ADC, 16 DAC :)
>Kimertem a szures idotartamat. ~25ms
>
>Ha igy szamolok, hogy 1/48kHz (mintaveteli freki) = ~20us, ez szorozva 1536-al (ennyi a tomb merete) ez kb 32ms. Ebben benne van az is hogy az IT-k kozben hozzak be az adatot, tehat beleszakitanak a szuresbe.
>Tehat amig megtelik a masik puffer, addig megtortenik a szures is, es meg ido is marad.
>
>A szuro algoritmusoknak tomb cime van megadva. (CMSIS DSP library)
>
>Kerdes:
>Van-e hatranya sebesseg szemontjabol annak, hogy a tomb(ok) (left/right) es a hozza tartozo indexek, meg allapotok strukturaban vannak tarolva ?
>A valtozo deklaralasoknal pedig volatile-t az elotag.
>
>Tehat: volatile struct adc_buf adc_buf_inst1, adc_buf_inst2;
>Igy remelem az egesz valtozo a strukturan belul volatile lesz?
>
>Udv.
>Szabi
>
>
>
>
>On Tuesday, December 10, 2013 1:06 PM, hg12345 <hg12345 at freemail.hu> wrote:
>
>Hi,
>
>az STM32 eleve 32bites (int) rendszer egy beolvasás és egy kiírás 32 biten történik.
>Ha a lebegö pontos változódat real ként definiáltad, akkor az méretre azonos egy int-tel vagyis ezen nem múlok a sebesség. Ha double ként annak a megfelelő long long ez 2x32bit tárolódik.
>A pointer (index) számításban lehet különbség, mert több belső ciklust használ el a címzésre, ez elérésben is különbség van, mert két beolvasás (kiírás) kell, de ezt is lehet optimalizálni, ha engedélyezed a blokkos ki és beolvasást, akkor kevesebb utasítás lehívás lesz.
>
>Milyen sebességgel veszed a mintákat, képtelenségnek tartom, hogy STM34F4xx uC egy ~40Khz 12bites adatfolyam kiüsse :-(
>
>A tömböt érték vagy pointerként adod át ? :-)
>
>
>
>
>Pal Lukacs <ekegep at yahoo.com> írta:
>>Sziasztok !
>>
>>Lehet hogy hulye kerdes,...a float adat elerese memoriaban tobb ido mint az int elerese?
>>
>>Mert en az adat behozas utan egybol konvertalom (int to float) es ugy irom, olvasom a memoriaba (memoriabol).
>>
>>
>>Udv.
>>Szabi
>>
>>
>>
>>
>>
>>
>>On Sunday, December 8, 2013 12:12 PM, Pal Lukacs <ekegep at yahoo.com> wrote:
>>
>>Hi!
>>
>>Vegulis mindegy milyen hosszu a tomb, ha egy adatot meg tud szurni addig amig jon a masik, akkor barmekkora hosszu tombot meg tud szurni, amig megtelik a masik puffer.
>>Itt csak azert kellett tomb, mertdecimalni , interpolalni kell, es nem mindegy hogy mekkora hosszu az adatsor.
>>
>>
>>
>>On Sunday, December 8, 2013 11:04 AM, hg12345 <hg12345 at freemail.hu> wrote:
>>
>>Hi
>>sokkal jobb a ping-pong buffer
>>1, DMA-val is kezelhető,
>>2, 1.5K nem memória foglalás
>>3, a szűrő algoritmus gyári megírt és csak a pointert kell átadni :-)
>>
>>De szerintem célszerű lenne 3 fix méretű tömböt lefoglalni a heap-en vagy fixeni, és
>> ezeket a tömböket cirkulárisan használni... Gondolom a tömb mérete határozza meg a hang késleltetését... A tömb méretét akkorára kell választani, hogy a szűrés tudjon vele végezni míg az következő szűrendő mennyiség beérkezik. (ez a szűk kapacitás, de ha növeli a felhasznált tömbök számát, ez ezen nem tud segíteni, csak a verseny helyzet esetén később fog adatot veszíteni, a folyamatos késlekedés növekedés mellett)
>>
>>egyiket tölti a DMA
>>másokban számol a szürő
>>harmadikat kiküldi a DMA
>>
>>
>>"Móczik Gábor" <pm_levlista at progzmaster.hu> írta:
>>>2013.12.07. 18:41 keltezéssel, Arnold Fuzesi írta:
>>>> Lehet cserelgetni a
>> buffer kezdocimet is, ugy gyors. Csak a kettos buffereles memoriazabalo, cirkular buffer jobb kihasznalast ad.
>>>
>>>Na jó, de jelen esetben mit érsz el buffer cím cserélgetéssel?
>>>
>>>Ugyanaz, mintha circular lenne, csak még egy plusz pointert cserélgetsz
>>>az rd/wr-en kívül, valamint jobban "kvantált" az anyag, csak diszkrét
>>>buffernyi darabokban férsz hozzá, a circ. bufferben meg tetszőleges
>>>hosszban, folyamatosan akár.
>>>
>>>Doublebuffer olyan esetben lehet jó, amikor nincs annyira ráhatás a
>>>kiolvasó folyamatra, pl. képernyőn megjelenítés. Ha nem a video drivert
>>>írod, hanem valami magasabb szintű rétegben vagy, nem tudod mikor fog
>>>kelleni a kijelzőnek egy adott sornyi pixel, jobb ha egyben odaadod
>> az
>>>egész képtartalmat, aztán majd kiírja amikor akarja, te meg a háttérben
>>>összeállítod a következő képet.
>>>
>>>-----------------------------------------
>>> elektro[-flame|-etc]
>>>
>>
>>-----------------------------------------
>> elektro[-flame|-etc]
>>-----------------------------------------
>> elektro[-flame|-etc]
>
>-----------------------------------------
> elektro[-flame|-etc]
>-----------------------------------------
> elektro[-flame|-etc]
-----------------------------------------
elektro[-flame|-etc]
More information about the Elektro
mailing list