<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <div class="moz-cite-prefix">Mam spravny pocit, ze dokonceni vsech
      zapisu by mela zajistit instrukce DSB? Nebo nejaka podobna z tech
      cca 3, se mi furt pletou.</div>
    <div class="moz-cite-prefix">Ale asi az u novejsich.</div>
    <div class="moz-cite-prefix">Mam ale vyzkouseno, ze kdyz to melo byt
      rychle (simulace SPI kdyz se netrefily piny...), nasazel jsem za
      sebe instrukce zapisu do 32b registru S/R, kazda menila hodiny ,
      kazda druha data a chodilo to jak vino maximalni rychlosti, kdyz
      jsem vyhazel DSB, tak rychleji  ale stale dobre. Sbernice mely
      stejnou frekvenci a byl to tusim M4.<br>
    </div>
    <div class="moz-cite-prefix">Tak se toho asi netreba uplne bat a
      cekam, ze to je nejak interne poresene.<br>
    </div>
    <div class="moz-cite-prefix"><br>
    </div>
    <div class="moz-cite-prefix">Dne 27.12.2023 v 18:06 dresler
      napsal(a):<br>
    </div>
    <blockquote type="cite"
      cite="mid:20231227170623.28915223604@alik.hw.cz">
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <div dir="auto">Bavíme-li se klasických STM32, zápisy se
        neztrácejí. Podle typu architektury je tam 0-1 write buffer mezi
        jádrem a hlavní sběrnicí, pak (AXI-)AHB-APB bridge. Zde je
        zpoždění dané tím, že se data resynchronizují mezi různými
        hodinami, kde platí nejdelší zpoždění (1+ratio) a zpoždění
        vnější periferie. Není tedy potřeba psát opakovaně. </div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">Aby se zajistilo, že program pokračuje po
        dokončení zápisu do registru, prostě ten registr přečtěte zpět. </div>
      <div dir="auto"><br>
      </div>
      <div dir="auto">Tomáš </div>
      <div dir="auto"><br>
      </div>
      <div dir="auto"><br>
      </div>
      <div dir="auto"><br>
      </div>
      <div id="composer_signature" dir="auto">
        <div style="font-size:12px;color:#575757" dir="auto">Odesláno z
          mého zařízení Galaxy</div>
      </div>
      <div dir="auto"><br>
      </div>
      <div><br>
      </div>
      <div dir="auto" style="font-size:100%;color:#000000" align="left">
        <div>-------- Původní zpráva --------</div>
        <div>Od: Petr Labaj <a class="moz-txt-link-rfc2396E" href="mailto:labaj@volny.cz"><labaj@volny.cz></a> </div>
        <div>Datum: 26.12.23 22:27 (GMT+01:00) </div>
        <div>Komu: <a class="moz-txt-link-abbreviated" href="mailto:hw-list@list.hw.cz">hw-list@list.hw.cz</a> </div>
        <div>Předmět: Re: Fwd: STM32F103 UART DMA </div>
        <div><br>
        </div>
      </div>
      Tak v tom případě i já pošlu odpověď, kterou jsem Vám posílal
      soukromě, <br>
      do konference:<br>
      <br>
      Hmmm.<br>
      A díval jste se prosím na to, čeho se Vámi vysmívaná "rada nad
      zlato" <br>
      vlastně týkala?<br>
      Psal jsem o prvním zápisu do nějakého registru, kdy obecně nemusím
      <br>
      vědět, jaký je předchozí stav daného registru.<br>
      Takže pokud tam zapíšu ORem, tak tam můžou zůstat nahozené nějaké
      bity, <br>
      které nechci, ale byly tam v jedničce už dřív.<br>
      <br>
      V tomto případě přece naplatí, že by se mohl ztratit nějaký zápis
      kvůli <br>
      asynchronnosti přístupu na danou periferii.<br>
      Jedná se o _první_ zápis na tuto periferii.<br>
      Všechny případné další zápisy už samozřejmě musí být ORem, protože
      jinak <br>
      by zmizela předchozí konfigurace.<br>
      <br>
      PL<br>
      <br>
      *****************<br>
      <br>
      Dne 26.12.2023 v 22:06 František Burian napsal(a):<br>
      > Omlouvám se, asi jsem to neposlal do konference ale p.
      Labajovi, ale <br>
      > mířilo to do konference.<br>
      ><br>
      ><br>
      ><br>
      ><br>
      > Zdravíčko,<br>
      ><br>
      >   Obvykle nepřispívám ale tady musím, protože zde je
      nastíněna "rada <br>
      > nad zlato", která tomu, kdo se jí bude řídit způsobí mnoho
      bezesných <br>
      > nocí.<br>
      ><br>
      >   Nezapomínejte, že ARM je architektura mnoha sběrnic,
      různých keší a <br>
      > to, co napíšete do programu nikdy není to, co se provede.
      Zkuste si <br>
      > udělat<br>
      > rychlý program, který bude pouze zapisovat do GPIO portu a
      nahazovat <br>
      > všechny bity na 1 a shazovat všechny bity do 0, připojte
      osciloskop k <br>
      > pinu<br>
      > a pozorujte, co uvidíte.<br>
      ><br>
      > Operace = je převedena do instrukce STRB která nezapisuje na
      paměťové <br>
      > místo, ale do cache, která to posílá na pomalejší sběrnici. A
      pokud se<br>
      > sejdou dva STRB do stejné paměťové pozice, je předchozí zápis
      ztracen <br>
      > a na pomalejší sběrnici se populuje později zapsaná hodnota.
      GPIO jsou na<br>
      > STMku za dvěma takovými cachemi, AHB, APB a dokážete si
      představit <br>
      > jakýpak krásný náhodný děj se na GPIO povede vyrobit.<br>
      ><br>
      > Aby byly zápisy jednoznačně orderované, musí mezi nimi být
      LDRB který <br>
      > počká na úplnou invalidaci všech keší po cestě před další
      instrukcí. <br>
      > Když tedy<br>
      > převedete původní sekvenci (pseudokód)<br>
      ><br>
      > while (1) { PORTB = 0; PORTB=255;  }<br>
      ><br>
      > na<br>
      ><br>
      > while (1) { PORTB &=0; PORTB|=255; }<br>
      ><br>
      > dosáhnete výrazně pomalejšího programu, ale krásného
      obdélníku ikdyž z <br>
      > logiky věci by ty programy měly dělat totéž. Ještě krásnější
      je, že<br>
      > druhý příklad se může přeložit na první kvůli optimalizacím
      překladače <br>
      > když někdo při definici PORTB zapoměl na volatile u každého
      prvku.<br>
      ><br>
      > Toto samosemou platí pro každý přístup na jakoukoliv paměť
      která má po <br>
      > cestě nějakou cache (tedy je na pomalejší sběrnici). Proto
      musí být<br>
      > všechny přístupy k řídícím registrům které musí být vždy
      sekvenční <br>
      > (nejprv nastav tento bit, pak tento bit) buďto provedeny
      pomocí operátorů<br>
      > |= nebo &= nebo použít instrukci dmb, která ale čeká na
      všechny cache, <br>
      > ne jen na tu, kterou chcete zapsat, takže ještě víc zpomalí.<br>
      ><br>
      > Registry konfigurace periferií jsou přesně ty, které mají v
      podmínkách <br>
      > nejprv toto pak toto a když na tento postup nemyslíte, "ono
      to nějak <br>
      > funguje"<br>
      > ale jednou za čas to selže a daná periferie se jeví jako
      zmrzlá <br>
      > protože jste nastavili bity ve stejný okamžik, ne jeden po
      druhém.<br>
      ><br>
      > Cache mezi sběrnicemi má omeznou velokost, takže pokud za
      sebou <br>
      > zapíšete dostatečný počet zápisů do stejné sběrnice, tak
      můžete zase ten<br>
      > první, protože se čeká na ostatní zápisy. Jak je cache dlouhá
      je <br>
      > nedokumentovaná funkce a mění se to mezi výrobními dávkami <br>
      > (odpozorováno 2-8<br>
      > zápisů u stejného čipu jen z jiných dávek, dokonce jsem nabyl
      dojmu že <br>
      > se hloubka mění podle poměru frekvencí ale tam nemám ověřeno)
      takže<br>
      > nelze spoléhat na konkrétní velikost cache.<br>
      ><br>
      > Stejný problém je když takto přistoupíte na dvě po sobě
      jdoucí <br>
      > paměťové místa, tak ty čipy s delší cachí zápis uvnitř keše
      převedou <br>
      > na jeden přístup<br>
      > do paměti s delším slovem a na některých architekturách hard
      fault <br>
      > jako vyšitý, když ale použijete RMW, hardfault zmizí. (Nevím
      jestli to <br>
      > je aktuální,<br>
      > takto se chovaly staré čipy)<br>
      ><br>
      > Pokud se podíváte do implementace CMSIS, je tam vždy RMW
      operace s <br>
      > registry, nikdy to není čistý zápis právě kvůli tomuto
      fenoménu.<br>
      ><br>
      > S tímto jsem si při psaní vlastních rychlých knihoven užil
      více než <br>
      > dost. Probíralo se to i v intelektuálním klubu v Patronce, je
      dobré <br>
      > číst backlogy<br>
      > nebo se účastnit :-)<br>
      ><br>
      > S pozdravem a přáním pěkných svátků<br>
      ><br>
      >   František Burian<br>
      ><br>
      ><br>
      > Dne 26. 12. 23 v 17:14 Petr Labaj napsal(a):<br>
      >> Můžu drobnou poznámku, která je ale obecnější a s daným
      problémem <br>
      >> nesouvisí?<br>
      >><br>
      >> Vy všude používáte "orování" parametrů, které zadáváte do
      řídících <br>
      >> registrů.<br>
      >> Např.:<br>
      >> USART2->CR1 |= USART_CR1_TE | USART_CR1_RE;<br>
      >> nebo<br>
      >> DMA1_Channel6->CCR |= DMA_CCR_MINC | DMA_CCR_CIRC |
      DMA_CCR_TCIE;<br>
      >><br>
      >> Ale používáte to i při prvním zápisu do daného registru.<br>
      >> Tedy jinými slovy spoléháte na to, že předtím tam byly
      samé nuly.<br>
      >> Což může být velice zrádné, když tu konstrukci použijete
      třeba i <br>
      >> někdy později, kdy už v těch registrech něco je.<br>
      >><br>
      >> Takže by podle mě měl první zápis vypadat takhle:<br>
      >> USART2->CR1 = USART_CR1_TE | USART_CR1_RE;<br>
      >> nebo<br>
      >> DMA1_Channel6->CCR = DMA_CCR_MINC | DMA_CCR_CIRC |
      DMA_CCR_TCIE;<br>
      >><br>
      >> A orování použít až když tam už dodatečně něco přidáváte.<br>
      >><br>
      >> PL<br>
      <br>
      _______________________________________________<br>
      HW-list mailing list  -  sponsored by <a class="moz-txt-link-abbreviated" href="http://www.HW.cz">www.HW.cz</a><br>
      <a class="moz-txt-link-abbreviated" href="mailto:Hw-list@list.hw.cz">Hw-list@list.hw.cz</a><br>
      <a class="moz-txt-link-freetext" href="http://list.hw.cz/mailman/listinfo/hw-list">http://list.hw.cz/mailman/listinfo/hw-list</a><br>
      <br>
      <fieldset class="moz-mime-attachment-header"></fieldset>
      <pre class="moz-quote-pre" wrap="">_______________________________________________
HW-list mailing list  -  sponsored by <a class="moz-txt-link-abbreviated" href="http://www.HW.cz">www.HW.cz</a>
<a class="moz-txt-link-abbreviated" href="mailto:Hw-list@list.hw.cz">Hw-list@list.hw.cz</a>
<a class="moz-txt-link-freetext" href="http://list.hw.cz/mailman/listinfo/hw-list">http://list.hw.cz/mailman/listinfo/hw-list</a>
</pre>
    </blockquote>
    <p><br>
    </p>
  </body>
</html>