Programuję C w systemie wbudowanym. Architektura procesora ma 32 bity (sizeof(int)
to 32 bity, sizeof(short)
to 16 bitów). Istnieje 32-bitowa zmienna, która jest odwzorowanym w pamięci rejestrem kontrolnym (CTRL_REG
), który jest określony jako tylko dolne 16 bitów, które są używane, i zawierają one 16-bitową liczbę całkowitą ze znakiem (zapisywanie do wyższych bitów nie daje żadnego efektu). Dostęp do pamięci musi być wyrównany do 32-bitów, więc nie mogę po prostu uderzyć wskaźnika przez kilka bajtów, a także nie mogę założyć endianness. Obawiam się, że automatyczna promocja typu będzie szaleć z tym, co przechowuję, przedłużając bit znaku na bit 31 zamiast pozostawiając go w bit 15, gdzie chcę. Jaki jest najlepszy sposób przechowywania czegoś w tej lokalizacji?przechowywanie podpisanego skrótu w niższych 16 bitach unsigned int
Tu był mój oryginalny kod, którego jestem prawie pewna jest źle:
#define CTRL_REG *((volatile unsigned int *)0x4000D008u)
short calibrationValue;
CTRL_REG = -2 * calibrationValue;
Potem próbowałem, ale myślę, że nadal może podlegać całkowitych promocji w momencie cesji:
CTRL_REG = (short)(-2 * calibrationValue);
wreszcie pomyślałem o tym:
CTRL_REG = (unsigned short)(short)(-2 * calibrationValue);
nie mogę ocenić te opcje bardzo dobrze, ponieważ wszystkie działają w moich testach, ponieważ calibrationValue
ma wartość ujemną (jest to parametr kalibracyjny charakterystyczny dla każdego urządzenia, a więc może być dodatni na niektórych urządzeniach), więc po pomnożeniu przez -2, kończę przechowywanie wartości dodatniej i w ten sposób nie napotkam problemu, którego oczekuję w testach.
Twoja pomoc jest bardzo doceniana, nawet jeśli chodzi o stwierdzenie "za dużo myślisz".
Jeśli chcesz mieć pewność, że zmienna ma 32 bity, zamiast tego możesz użyć 'uint32_t', ze stdint.h. Zauważ, że 'int' [nie musi być 32-bitowe] (http://codinghorror.typepad.com/.a/6a0120a85dcdae970b0128776ff992970c-pi), nawet w systemach 32-bitowych. –
@WTP: dziękuję za troskę. mamy nagłówek specyficzny dla kompilatora, który zawiera definicje typów, które gwarantują rozmiar. Nie są one standardowym uint32_t ani żadną nomenklaturą, więc zamiast mylić mój post z niestandardowymi typami, zdecydowałem się przekonwertować wszystko na typy, które każdy widział wcześniej. – rmeador
Proponuję co najmniej jedną dodatkową parę nawiasów wokół makra: "(* ((volatile unsigned int *) 0x4000d008u))" – wildplasser