STM32F0 periph. library

Josef Štengl ok1ced na nagano.cz
Čtvrtek Červenec 17 09:41:48 CEST 2014


Proč ne bitová pole? Tak tedy proč ne:-)

  ✔ nejde vytvořit ukazatel na položku - někdy to může vadit a už jsem se s tím setkal (to je obecně důvod, proč nemám rád 
bitová pole jako taková)

  ✔ jsou závislá na aktuální endianitě - existují architektury které jsou biendian (například ARM cortext R,A, netýká se 
M) a máte 2 projekty které používají 2 čipy s malým a velkým indiánem a až na jednu periférii jsou shodné (také jsem se 
setkal) - takže je píšete 2x

  ✔ delší kód - každý přístup do položky pole je vlastně fyzický přístup na periférii; ano podmínkou je, že adresový 
prostor je definován jako volatile ale to je nutnost už z důvodu časování nebo prostý zápis 1-0-1 na I/O nebo zabránění 
out-of-order vykonávání instrukcí při použití optimalizace.

  ✔ použití unionu aby jste se dostal k celému registru - pro bezpečnostní aplikace (a nemusí to být zrovna automotive ale 
i obyčejné pohony) je union nedoporučován. Ono to má rozumné důvody.
	- C norma nedefinuje že položky v unionu zabírají jeden adresový prostor - je to sice chování většiny kompilátorů, ale 
není to zaručeno, což norma výslovně uvádí.
	- opět problémy s endianitou
	- možné problémy se zarovnáním položek v poli, pokud je union složitější (ono je třeba si na to dát pozor i u struktury)
	- k položce/registru existuje více možností přístupu - to slušně napsané programy nedělají (proč doufám vysvětlovat nemusím)

  ✔ není specifikováno jak se k registru bude přistupovat; pokud zapisuji jeden bit tak jako byte? Nebo int? a co když 
nemá registr velikost int a podobně?

  ✔ možná ztráta informace - existují registry, většinou RO status flagy, jež jsou mazány čtením. Program samozřejmě 
nepřečte jen ten byte, který zrovna požadujeme.


Se všemi těmito problémy jsem se setkal během své profesní kariéry a někdy stály docela dost peněz. A ještě jsem nenarazil 
na problém kde by bitové pole nebo union bylo výhodnější použít oproti ostatním způsobům poskytovaným jazykem.

ced









Dne 16.7.2014 17:35, Miroslav Mraz napsal(a):
> No vidíte, mě se zase nelíbí tento styl kódování. Pokud C umožňuje
> zapouzdřit jediný nebo skupinu bitů do struktury, tak proč to neudělat.
> Spíš je otázkou, zda použít enum jako další pouzdro. Ale zase je to jen
> otázka vkusu. Pokud to mám udělat čistě objektově, tak to použiju, s
> vědomím určitých rizik. Není to však bezpodmínečně nutné. V bitovém poli
> samotném problém skutečně nevidím:
> - přenesení na jinou endianitu mě opravdu nezajímá, to co s tím chci
> dělat je obsloužit periferie u zcela konkrétního procesoru
> - dobrý kompilátor s rozumnou optimalizací to přeloží úplně stejně
> - dá se to číst ještě lépe protože
> - pro nastavení jednotlivých bitů použiju prosté =
>
> Jen je to víc psaní. To u objektů bývá. Nicméně se začínáme shodovat na
> tom, že enum ne.
>
> Mrazík
>
> On 07/16/2014 10:32 AM, Josef Štengl wrote:
>> Pokud myslíte ten kód v main() a ne tu union-bitové pole hrůzu*, tak
>> je to asi lepší řešení. Tedy
>>
>>   + je to nezávislé na endianitě (pokud pracujete s BiEndian procesorem
>> (například arm) a překládá se to podle projektu, tak je to nutnost –
>> jinak by jste musel definovat bitová pole 2x)
>>   + kompilátor to má šanci rozumě zoptimalizovat
>>   + dá se to číst
>>
>>   - pro nastavení jednotlivých bitů je nutno definovat makro/funkci.
>>
>> Používat k těmto účelům enum je hazard s infarktem. C definuje enum
>> jako int (problém s nastavením nejvyššího bitu pro unsigned registy) a
>> překladače jsou přednastaveny všelijak - většinou packed (velikost
>> typu podle hodnot v enumu + signed/unsigned), což přináší takové
>> zajímavé varování kompilátoru a statické analýzy kódu - většinou jsou
>> v rozporu a občas i v chování.
>>
>> Mimochodem místo definování OR bych použil knihovnu  <iso646.h>. Ale
>> chápu, že je makra jsou tam definována malými písmeny :-)
>>
>> Pro mě je elegantní definovat:
>>   - registr o celé šířce
>>   - konečné pozice jednotlivých složek bitů
>>   - makro na skládání/pozici
>>
>>
>> zjednodušený příklad:
>>
>> #define DEV_CTRL_A    0u
>> #define DEV_CTRL_B    1u
>> #define DEV_CTRL_C    3u
>>
>> #define rbval(val, bitpos)    ((uint32_t)val << bitpos)
>>
>> volatile struct dev
>> {
>>      uint32_t ctrl;
>>      uint32_t set;
>>      uint32_t clr;
>> ...
>> }
>> dev;
>>
>> dev.ctrl = rbval(0u, DEV_CTRL_A)
>>           | rbval(3u, DEV_CTRL_B)
>>           | rbval(1u, DEV_CTRL_C)
>>           | rbval(1u, 6u)    /* kdo by se s tím psal .. */
>>
>> Ano, je otázkou, jak jsou zpracované dodané knihovny registrů.
>> .. a je docela pracné napsat ty pozice bitů.
>>
>> ced
>>
>>
>> * opravdu mě nebaví se dívat co z toho kompilátor na které
>> architektuře vytvoří a při jaké optimalizaci a verzi. Je to zvrácenost
>> jako mrkev s bramborami (tedy pro mě :-).
> _______________________________________________
> HW-list mailing list  -  sponsored by www.HW.cz
> Hw-list na list.hw.cz
> http://list.hw.cz/mailman/listinfo/hw-list
>


Další informace o konferenci Hw-list