RE: pole bitového pole v C

Miroslav Draxal evik na volny.cz
Neděle Leden 13 11:23:11 CET 2013


Výhody unionu pro mcu jsou v tom,  že dokážu různým způsobem přinutit kompilátor aby šetřil paměti.

 

typedef union {

    unsigned char value;

    struct {

              unsigned CisloBitu : 6;

              unsigned SetClr : 1;

   } bits;

} _SetBitPole;

 

Pokud chci vynulavat cely byt SetBitPole.value=0; // přeloží jako clrf …

SetBitPole.bits.SetClr=1; //přeloží jako bsf…

 

Pokud to mám jenom jako char, a chci nastavitb jeden bit, tak automaticky používá 

movlw 0x01000000

andwf SetBitPole,f

Prostě se snažím co nejvíc podstrkovat kompilátoru jak udělat co nejkratší kód. Ono se řekne, vždyť je to jeden byt navíc. U dospělých MCU to nevadí, ale já šetřím pamětí. Takových hle pár vychytávek a mám volných dalších 100 bytů.

 

Prostě mám ve funkci vstupní hodnotu union, abych nemusel ve funkci použít

SetBitPole.value = VstupniHodnota;

 

Potřeboval bych, abych mohl volat funkci  àVoid funkce(_SetBitPole SetBitPole);

Tímto zápisem

Funkce ((24 - CisloSekce) | 0x40;)

Což samozřejmě nejde z pohledu C,  z pohledu ASM předávám jeden byt.

 

Důvod proč. Zjistil jsem, pokud volám funkci jako char, tak se parametr předá ve W, ale pokud předávám parametr jednobytového unionu, tak to přeloží jako

Movwf parametr

Call Funkce

…….

Funkce Movf parametr,w

 

Kompilátor by si to měl umět optimalizovat, ale neumí. Ušetřil bych 2 byty. Snažím se to obejít. Uznávám, že to je, jako když si pes honí ocas. Míra

 

Ps. Celkovou „mou optimalizací“ zápisu C kódu jsem již ušetřil 0,5kB paměti a stále jsou v zápisu rezervy. Nesmějte se vy, co používáte dospělé MCU. 

1/ na zařízení probíhá upgrade soft.

2/ cokoli předělávat na desce se mi nechce

3/ další výrobky nebudou

From: hw-list-bounces na list.hw.cz [mailto:hw-list-bounces na list.hw.cz] On Behalf Of Miroslav Šinko
Sent: Saturday, January 12, 2013 11:32 PM
To: HW-news
Subject: Re: pole bitového pole v C

 

Mierne sa stracam v tom, co presne chcete robit. Union poskytuje rozny
pristup k tej istej oblasti pamati. Vas pripad by som asi riesil takto
(ale vravim, neviem, ci chapem zadanie):
union ostane, az na char -> unsigned char
typedef union {
    unsigned char value;
    struct {
              unsigned CisloBitu : 6;
              unsigned SetClr : 1;
   } bits;
} _SetBitPole;

ale funkcii by som dal ako vstupny parameter char, opat unsigned
void VentilSet (unsigned char CisloVentilu);
 tmp bude typu union:
_SetBitPole tmp;

teraz si nastavim polozky, kedze mate CisloSekce a hodnotu, tak:
tmp.bits.CisloBitu=(24 - CisloSekce);
tmp.bits.SetClr=1;

funkcii predam value (vyuzivam ten rozny pristup k rovnakej pamati):
VentilSet(tmp.value);

Neviem, co vo funkcii potrebujete robit, ak potrebujete opat
pristupovat bitovo, tak Vas prototyp void VentilSet (_SetBitPole
CisloVentilu) bol OK, volanie jednoducho
VentilSet(tmp);
Len potom nechapem vyznam unionu, staci bitove pole:
typedef struct {
              unsigned CisloBitu : 6;
              unsigned SetClr : 1;
} _bits;
Premenna tmp, aj vstupny parameter do funkcie typu _bits.

Ak chcete zapis formou  (24 - CisloSekce) | 0x40; tak je zase zbytocne
bitove pole a stacia vam vsetky typy char, lepsie unsigned char.

Pretypovavacie zapisy budu fungovat, ale vobec nerozumiem preco by ste
ich pouzivat, kedze pri nich vobec nevyuzivate vyhody unionu.

miro


2013/1/12 Miroslav Draxal <evik na volny.cz>:
> Vlastně obklikou to dělám takhle
>
>                                   tmp.value = (24 - CisloSekce) | 0x40;
>
>                                   VentilSet (tmp);
>
>
>
> Chtěl bych
>
>     VentilSet ((24 - CisloSekce) | 0x40);
>
>
>
> From: hw-list-bounces na list.hw.cz [mailto:hw-list-bounces na list.hw.cz] On
> Behalf Of Jaroslav Buchta
> Sent: Saturday, January 12, 2013 9:44 PM
>
>
> To: HW-news
> Subject: Re: pole bitového pole v C
>
>
>
> Ja proste na tyhle prevody jdu pres ukazatele, takze bych to udelal zase
> takhle (nezkouseno)
>
> VentilSet (*((_SetBitPole*)&TMP));
>
> Proste se vezme adresa promenne TMP operatorem &, ukazatel na cokoli  jde
> pretypovat na ukazatel na cokoli jineho, cili i na union a pak se operatorem
> dereference * zase ziska objekt na odkazovane adrese (uz pretypovany). Mozna
> to jde i jednoduseji, ale ja takhle prevadim i typy z neznaminkovych na
> znamenkove, napr. v komunikacnich paketech, kdyz UINT uvnitr obsahuje
> hodnotu se znamenkem, napr.: float fTempSecIn =
> (float)*(short*)&ProcImgRO.r.tempSecInp100;
>
>
> Dne 12.1.2013 21:34, Miroslav Draxal napsal(a):
>
> Hmm, přiznávám, že tomu nehovím, neumím to přečíst. Nic. Ráno se k tomu
> vrátím, a budu se to snažit pochopit. Pro dnešek ještě jednu věc.
>
>
>
> Mějme podprogram
>
> void VentilSet (_SetBitPole CisloVentilu)
>
>
>
> kde
>
> typedef union {
>
>     char value;
>
>
>
>     struct {
>
>                unsigned CisloBitu : 6;
>
>                unsigned SetClr : 1;
>
>     } bits;
>
> } _SetBitPole;
>
>
>
> Pokud budu mí char TMP
>
> Jak to dostanu do volání toho podprogramu.
>
>
>
> VentilSet(TMP)
>
>
>
> Stále se jedná o 1byt.
>
> Je mi jasné že na začátku vytvořit TMP jako _ SetBitPole
>
> Přetypování char na union nejde. Jak na to? Míra
>
>
>
_______________________________________________
HW-list mailing list  -  sponsored by www.HW.cz
Hw-list na list.hw.cz
http://list.hw.cz/mailman/listinfo/hw-list 



__________ Informace od ESET NOD32 Antivirus, verze databaze 7887 (20130112) __________

Tuto zpravu proveril ESET NOD32 Antivirus.

http://www.eset.cz


__________ Informace od ESET NOD32 Antivirus, verze databaze 7888 (20130113) __________

Tuto zpravu proveril ESET NOD32 Antivirus.

http://www.eset.cz



__________ Informace od ESET NOD32 Antivirus, verze databaze 7888 (20130113) __________

Tuto zpravu proveril ESET NOD32 Antivirus.

http://www.eset.cz

------------- další část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20130113/c87ed2b4/attachment-0001.htm>


Další informace o konferenci Hw-list