Bitove polia v C

Ales Povalac alpov na alpov.net
Středa Duben 4 22:20:30 CEST 2012


Pristup do bit band regionu jsem resil na STM procesorech a GCC
prekladaci v baliku od CodeSourcery, postup je z examplu od ST
(StdPeriph_Examples/CortexM3/BitBand), akorat trochu upraveny a
zjednoduseny:

#define BitBand(VarAddr, BitNumber) \
    (*(__IO uint32_t *) (SRAM_BB_BASE + \
    (((uint32_t)(&VarAddr) - SRAM_BASE) << 5) + \
    ((BitNumber) << 2)))

Pouziti makra je pak snadne pro cteni i zapis:

uint32_t promenna;

BitBand(promenna, 10) = 1; // 10. bit promenne nahodit
vystup = BitBand(promenna, 12); // nastavit vystup dle 12. bitu

Takhle se da bitove pristupovat do libovolne promenne. Akorat si
clovek musi sam hlidat, ze nezapisuje do bitu mimo alokovanou pamet,
ale tak to je zaklad.

Zdravim
Ales Povalac


2012/4/4 Stano <stano.hw na gmail.com>:
> Dakujem ale nepotesili ste ma.
> Chapem to spravne, menili ste 2 bity a medzi zmenami bola este nejaka
> instrukcia/instrukcie ale MCU(SoC ako chcete) vykonal zapis na port naraz a
> oba bity sucastne?
> Toto spravanie by som este bol ochotny akceptovat, neakceptovatelne by vsak
> bolo keby citanie nasledujuce bezprostredne po zapise vratilo nezmenenu
> hodnotu alebo keby zapis ineho bitu v interrupte sposobil poskodenie dat.
> Klasicky problem s atomicitou.
> Co sa RM0008 tyka vypocet adries mi je jasny. To co by ma viac zaujimalo su
> moznosti zapisu v C aby compiler pouzil dany sposob prace s pamatou. Ako mu
> naznacit aky je moj umysel.
> Z RM0008 som mal mylny dojem ze sa jedna o jednpduchy read/write na danu
> adresu. Ziadne podozrenie s casovanim som nemal, kedze sa jedna o pamat RAM.
> Co sa periferii tyka, tam uz som opatrny, s casovanim som si tam uzil vela
> "zabavy".
> Problem je ze tieto detaily uz niesu v manualoch podrobne vysvetlene,
> napriklad ten medzikus co spominate otom nebola nikde ani zmienka.
>
> Stano
>
> Jan Waclawek  wrote / napísal(a):
>
>> Tak toto zhodou okolnosti nema s bitovymi polami v C nic spolocne, len
>> slovo "bit".
>>
>> Jadro ARM Cortex-M3 ktore je (ak sa nemylim) pouzite v spomenutom mcu, ma
>> implementovane tzv. bit-banding, co znamena, ze jednotlive bity z urcitej
>> pamatovej oblasti sa daju citat/zapisovat po jednom citanim/zapisovanim
>> celych slov v inej oblasti.
>> bit_word_addr = bit_band_base + (byte_offset x 32) + (bit_number × 4)
>>
>> Detaily najdete v Reference Manual (RM0008) od ST a v  Cortex-M3 Technical
>> Reference Manual od ARMu.
>>
>> Navonok sa teda jedna o vykonanie jednej instrukcie, interne vsak hardware
>> na rozhrani procesora a zbernice AHB vykona operaciu read-modify-write (ak
>> sa jedna o pisanie) resp. read-mask (ak sa jedna o citanie). Toto je
>> neprerusitelna ("atomicka") operacia.
>>
>> V C teda jednoducho pisete 32-bitovu 0x00000000 alebo 0x00000001 na
>> horeuvedenu premapovanu adresu bit_word_addr (vyrobite si podla uvedeneho
>> vzorca smernik a do neho zapisete).
>>
>> Upozornujem vsak na jeden zaujimavy gotcha - aj ked je ta operacia
>> neprerusitelna, nie je zarucene, ze sa z hladiska casovania vykona uplne
>> presne tak, ako by si clovek predstavoval. Je to nasledok toho, ze tie ARMy
>> nie su mikrokontrolery ale SoC, t.j. procesor zlepeny s periferiami roznymi
>> medzikusmi na jednom cipe, pricom tie medzikusy su zlozite a ich presne
>> casovanie nie je zverejnene a nemusi byt uplne priamociare. Pri hratkach s
>> LPC17xx som napriklad zistil, ze ked som cez bit-banding robil bit-banged
>> (naschval som pouzil tento davno zauzivany a podobne znejuci vyraz, aby bolo
>> jasne co si myslim o idiocii ARMovskeho nazvu pre to bitove premapovanie)
>> SPI, tak sa mi pri urcitom poradi instrukcii menili dva piny (dva bity z
>> jedneho wordu prisluchajuceho danemu vystupnemu portu) naraz, aj ked som ich
>> menil dvomi roznymi instrukciami ktore dokonca ani nenasledovali tesne za
>> sebou. Ten bit-bandovaci medzikus zrejme pri prvej instrukcii urobil to
>> "read" z "read-modify-write",  ale skor nez stihol nastat "write" prisla
>> poziadavka na "read-modify-write" pre ten isty word (pricom tie medzilahle
>> instrukcie fungovali len na registroch procesora, cize sa tym z pohladu
>> periferii nic nepokazilo), a tak medzikus uz nerobil dalsi "read" ale len
>> dalsie "modify" a potom to finalne "write" zahrnujuce obe zmeny.
>>
>>
>> wek
>>
>>
>>
>>>
>>> Zdravim konferenci
>>> Podobna tema sa tu pravdepodobne prebelala ale opakovanie je matka
>>> mudrosti.
>>> Prosim, existuje nejaky standardny zapis v C ako implementovat bitove
>>> pole? Bezne pouzivam maskovanie a rotaciu ale vzhladom na to ze pouzity MCU
>>> (STM32F103) obsahuje bitovu pamat, rad by som ju vyuzit.
>>> Problem je ze potrebujem aby dana implementacia bola zarucene atomicka.
>>>
>>> Dakujem za rady
>>> Stano
>>>
>>
>>
>> _______________________________________________
>> HW-list mailing list  -  sponsored by www.HW.cz
>> Hw-list na list.hw.cz
>> http://list.hw.cz/mailman/listinfo/hw-list
>>
>
>
>
> _______________________________________________
> 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