ATtiny85 fla sh неизвестное использование памяти - PullRequest
0 голосов
/ 25 мая 2020

Я тестировал некоторые функции зуммера на ATtiny85 и заметил странные колебания использования памяти fla sh при изменении постоянных аргументов функции.

Более подробно, компилируя следующий код памяти занято 162 байта

int main(){
  beep_once(1000,500);
  silence(1000);
  beep_once(1000,500);
  silence(200);
  for(;;){ }
}

При изменении первого beep_once(1000,500); на beep_once(1500,500); размер программы становится 1378 байтов.

Кстати, я использую PlatformIO, которая компилируется через avr -g cc. Используя проверку памяти PlatformIO, я вижу, что c. 1кб памяти из-за unknown .

Надеюсь, кто-нибудь поможет мне понять, что происходит и на какой стороне проблема: PlatformIO, компилятор или это я.

Вот полный код, использованный для теста:

#include <avr/interrupt.h>

#define F_CLK 1000000

void silence(unsigned int);
void beep_once(unsigned int,  unsigned int);

int main(){
  beep_once(1500,500);
  silence(1000);
  beep_once(1000,500);
  silence(200);

  for(;;){ }
}


void silence(unsigned int duration)
{
    TCCR1 = 5; // Set the prescaler to 16 bit.
    OCR1A = 61; // Tops at 1ms with prescaler of 16x 
    unsigned int counter=duration;
    do
    {
        if ((TIFR >> OCF1A) & 0x01)
        {
            counter--;
            TCNT1 = 0;  // Reset counter to 0
            TIFR |= 1 << OCF1A; // Clear the flag
        }
    } while (counter);
    TCCR1 &= ~((1 << CS12) | (1 << CS11) | (1 << CS10));    // Stop the timer
}

void beep_once(unsigned int frequency /*Herz*/, const unsigned int duration /*milliseconds*/)
{
    /*
    *  The frequency is given by:
    *  Freq = F_CLK / (prescaler * (1 + OCR1C))
    */

    TCCR1 |= (5 << CS10) |(1 << CTC1);   // Set the prescaler to 16 bit (for 1MHz)(freq range from 31kHz to 250 Hz)
    OCR1C = (uint8_t)((F_CLK / frequency) >> 5); // divided by the prescaler (16)
    TIMSK &= ~(1 << OCIE1B); // Disable timer compare interrupt
    GTCCR |= 1 << COM1B0; // Timer Counter Comparator B connected to output pin OC1B.
    unsigned int counter  = duration * ((float)frequency / 1000.) * 2;;
    do
    {
        if ((TIFR >> OCF1B) & 0x01)
        {
            counter--;
            TIFR |= 1 << OCF1B; // Clear the flag
        }
    } while (counter);
    TCCR1 &= ~((1 << CS12) | (1 << CS11) | (1 << CS10));    // Stop the timer
    GTCCR &= ~(1 << COM1B0);           // Timer Counter Comparator B disconnected from output pin OC1B.
}
...