GCC optimalizace, zahada
Jiří Nesvacil
nesvacil na posys.eu
Pátek Listopad 3 22:40:50 CET 2017
Zdravim,
u nejake starsi verze GCC jsem musel delat neco podobneho. Prekladac si
myslel, ze adresa je pamet a ne zarizeni. Provadel tedy optimalizace,
kde nemel. Pomohla novejsi verze GCC nebo pridani volatile na zakladni prvky
#define PERIPH_BASE ((uint32_t volatile)0x40000000) /*!<
Peripheral base address in the alias region */
Jirka
Dne 03.11.2017 v 20:40 Jaroslav Buchta napsal(a):
> Tak jeste jednou, ta funkce taky nebyla OK, jedine, co pri
> optimalizaci asi pomuze spolehlive je
> *volatile* uint32_t AH,AL,BH,BL,CH,CL;
> Je mozne, ze to jinak prehodi instrukce tak, ze neni dodrzeno poradi
> zapisu do GPIO registru, i kdyz jsou volatile?
>
>
> Dne 03.11.2017 v 20:19 Jaroslav Buchta napsal(a):
>> Jeste koukam, ze GPIO_PIN_x je uint16_t ale tohle taky nepomuze:
>>
>> #define PREPAREDOREGS(A,B,C,v) A = ((v)&0x01) ?
>> (uint32_t)TFT_D0_Pin : ((uint32_t)TFT_D0_Pin) << 16;\
>> C = ((v)&0x02) ?
>> (uint32_t)TFT_D1_Pin : ((uint32_t)TFT_D1_Pin) << 16;\
>> A |= ((v)&0x04) ?
>> (uint32_t)TFT_D2_Pin : ((uint32_t)TFT_D2_Pin) << 16;\
>> B = ((v)&0x08) ?
>> (uint32_t)TFT_D3_Pin : ((uint32_t)TFT_D3_Pin) << 16;\
>> B |= ((v)&0x10) ?
>> (uint32_t)TFT_D4_Pin : ((uint32_t)TFT_D4_Pin) << 16;\
>> B |= ((v)&0x20) ?
>> (uint32_t)TFT_D5_Pin : ((uint32_t)TFT_D5_Pin) << 16;\
>> B |= ((v)&0x40) ?
>> (uint32_t)TFT_D6_Pin : ((uint32_t)TFT_D6_Pin) << 16;\
>> A |= ((v)&0x80) ?
>> (uint32_t)TFT_D7_Pin : ((uint32_t)TFT_D7_Pin) << 16
>>
>> Dne 03.11.2017 v 20:08 Jaroslav Buchta napsal(a):
>>> Mam kod pro plneni displeje pripojeneho osmibitove k STM32F303, bity
>>> jsou namixovany na ruzne porty tak to neni uplne jednoduche. Po
>>> zapnuti optimalizace mi to zacne asi vynechavat nastaveni nekterych
>>> bitu, barvy jsou spatne, nefunguje to se zakomentovanym makrem
>>> APPLYDOREGS, tak jak to je to unguje OK. Pomuze take vypnout
>>> optimalizaci nebo AH,AL... definovat jako volatile.
>>>
>>> assembler je pri optimalizaci strasnej gulas, na prvni pohled se
>>> lisi kody pouzitim str vs str.w - jaky je v tom rozdil? Mel jsem za
>>> to, ze jen v delce kodu instrukce, kdyz jsou operace s registry...
>>> napr.:
>>>
>>> 08001720: str r5, [r3, #24]
>>> 08001722: str r1, [r4, #24]
>>> 08001724: str.w r6, [r8, #24]
>>>
>>> Tusi nekdo cim to je? GPIOx->BSRR je snad definovano jako volatile
>>> uint32_t. Reseni mam ale znervoznuje me to...
>>>
>>> #pragma GCC push_options
>>> #pragma GCC optimize ("O3")
>>>
>>>
>>> #define PREPAREDOREGS(A,B,C,v) A = ((v)&0x01) ? TFT_D0_Pin :
>>> TFT_D0_Pin << 16;\
>>> C = ((v)&0x02) ? TFT_D1_Pin :
>>> TFT_D1_Pin << 16;\
>>> A |= ((v)&0x04) ? TFT_D2_Pin :
>>> TFT_D2_Pin << 16;\
>>> B = ((v)&0x08) ? TFT_D3_Pin :
>>> TFT_D3_Pin << 16;\
>>> B |= ((v)&0x10) ? TFT_D4_Pin :
>>> TFT_D4_Pin << 16;\
>>> B |= ((v)&0x20) ? TFT_D5_Pin :
>>> TFT_D5_Pin << 16;\
>>> B |= ((v)&0x40) ? TFT_D6_Pin :
>>> TFT_D6_Pin << 16;\
>>> A |= ((v)&0x80) ? TFT_D7_Pin :
>>> TFT_D7_Pin << 16
>>>
>>> #define APPLYDOREGS(A,B,C) *(uint32_t *)(&GPIOA->BSRR) = A;\
>>> *(uint32_t *)(&GPIOB->BSRR) = B;\
>>> *(uint32_t *)(&GPIOC->BSRR) = C
>>>
>>> //#define APPLYDOREGS(A,B,C) GPIOA->BSRR = A;\
>>> // GPIOB->BSRR = B;\
>>> // GPIOC->BSRR = C
>>>
>>> static void TftFillData (uint16_t w, int len)
>>> {
>>> uint32_t AH,AL,BH,BL,CH,CL;
>>>
>>> TFT_RS_TPYA_GPIO_Port->BRR = TFT_RS_TPYA_Pin;
>>> TFT_NCS_GPIO_Port->BRR = TFT_NCS_Pin;
>>> PREPAREDOREGS(AH, BH, CH, 0x2c);
>>> APPLYDOREGS(AH, BH, CH);
>>> TFT_NWR_TPXA_GPIO_Port->BRR = TFT_NWR_TPXA_Pin;
>>> __DSB();
>>> __ISB();
>>> TFT_NWR_TPXA_GPIO_Port->BSRR = TFT_NWR_TPXA_Pin;
>>>
>>> TFT_RS_TPYA_GPIO_Port->BSRR = TFT_RS_TPYA_Pin;
>>> PREPAREDOREGS(AH, BH, CH, (uint8_t)(w >> 8));
>>> PREPAREDOREGS(AL, BL, CL, (uint8_t)(w & 0xff));
>>> while (len--)
>>> {
>>> APPLYDOREGS(AH, BH, CH);
>>> TFT_NWR_TPXA_GPIO_Port->BRR = TFT_NWR_TPXA_Pin;
>>> __DSB();
>>> __ISB();
>>> TFT_NWR_TPXA_GPIO_Port->BSRR = TFT_NWR_TPXA_Pin;
>>>
>>> APPLYDOREGS(AL, BL, CL);
>>> TFT_NWR_TPXA_GPIO_Port->BRR = TFT_NWR_TPXA_Pin;
>>> __DSB();
>>> __ISB();
>>> TFT_NWR_TPXA_GPIO_Port->BSRR = TFT_NWR_TPXA_Pin;
>>> }
>>> TFT_NCS_GPIO_Port->BSRR = TFT_NCS_Pin;
>>> }
>>>
>>> _______________________________________________
>>> 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 bywww.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ší část ---------------
HTML příloha byla odstraněna...
URL: <http://list.hw.cz/pipermail/hw-list/attachments/20171103/3a6804d2/attachment.html>
Další informace o konferenci Hw-list