Говнокомпилер AVR-GCC

AVR, ARM

Postby TS-Labs » Mon, 12.05.2014 02:40:32

... поел многие годы моей жизни.

Очередной шедевр.
В обновлении софта по I2C в контроллере дата передается блоками по 64 байта. Не мог понять, почему первый байт даты всегда флэшуется какой то левый.
Искал места где портится буфер даты - нет таких мест.
Code: Select all
    volatile U8 dbuf[256];      // Data buffer
...
void program_page(U16 page, volatile U8 *buf)
{
    U16 w;
...
   U16 i;
   for (i = 0; i < SPM_PAGESIZE; i += 2)
   {
      w = *buf++;
        w += (*buf++) << 8;
      boot_page_fill(page + i, w);
   }
...
}
...
int main (void)
{
   ...
   sei();

   while(1)
   {
      while (!event)
      {
         wdt_reset();
         sleep_cpu();
      }

      switch(event)
      {
         ...
         /* Page flash request */
         case EVENT_FLPG:
                wdt_disable();
            program_page(ufpage, dbuf);
                wdt_enable(WDT_TIME);
            break;
         ...
      }
   }
}

Вышеозначенный dbuf используется на ISR для приема даты по I2C.
Мало того, что компилер не раздупляет, что одни и те же глобальные переменные юзаются на иср и в мейне, хуй бы с ним. Обозначен же: волатайл!
В сумме этот мегаоптимайзер генерит такую хуйню: dbuf[0] (самый первый байт буфера) читается один раз сразу после sei() и потом передается в готовом виде в program_page(). Охуенная оптимизация!
Code: Select all
    18b4:   78 94          sei
    18b6:   c0 91 6f 00    lds   r28, 0x006F ;dbuf[0]

В компилированном коде полный бардак, но замечу, что этот lds r28, 0x006F находится ОЧЕНЬ далеко от вылета по ивенту (когда дата загружена), мало того - инструкция SPM встречается несколько раз (!) - "первый" и "все остальные".
Обошел это костылем:
Code: Select all
static U16 w;

После костыля все стало более менее на место, бинарь уменьшился на 6 байт :bang:
Как это исправить по-нормальному, не знаю.

avr-c++ (AVR_8_bit_GNU_Toolchain_3.4.3_1072) 4.8.1
User avatar
TS-Labs
 
Posts: 5151
Joined: Thu, 26.07.2012 01:29:56

Postby TS-Labs » Mon, 12.05.2014 08:30:10

DimkaM подкинул идею. Переделал:
Code: Select all
void program_page(U16 page, U16 *buf)
{
...
   for (i = 0; i < SPM_PAGESIZE; i += 2)
      boot_page_fill(page + i, *buf++);
...
}

...
program_page(ufpage, (U16*)dbuf);
...

Компилит нормально, но описанной проблемы не отменяет.
User avatar
TS-Labs
 
Posts: 5151
Joined: Thu, 26.07.2012 01:29:56


Return to MCU

Who is online

Users browsing this forum: No registered users and 1 guest

x