Почему 23 032-байтовому скетчу Arduino требуется 36,32 секунды для загрузки через ISP на Atmega328p на макетной плате с отключенной проверкой кода?

"Sketch использует 23032 байта (71%) дискового пространства программы. Максимум - 32256 байт. Глобальные переменные используют 1342 байта (65%) динамической памяти, оставляя 706 байт для локальных переменных. Максимум - 2048 байт".

У меня отключена функция "проверка кода после загрузки". Если эта опция включена, для загрузки требуется дополнительно 20 секунд, в общей сложности 56 секунд.

Использование avr-программатора Sparkfun с USBtinyISP, win 10, arduino ide, библиотекой minicore. Код использует несколько библиотек от Mozzi. Внешний кристалл 16 МГц. Установите биты предохранителей на микросхеме для использования внешних часов, используя следующую команду: "avrdude -c usbtiny-p m328p -U lfuse: w: 0xFF: m".

Похоже, что это должно быть быстрее, если действительно загружать со скоростью 115200 бит / сек. Но, возможно, я что-то упускаю из виду в том, как это работает.

Спасибо!!

, 👍0


3 ответа


0

Похоже, пропускная способность ограничена. Я понятия не имею, сколько задержек добавляет ISP, но он должен добавить немного. Лучше всего было бы использовать USB со скоростью 115200 бод или быстрее, если вы сможете его получить.

,

1

У меня есть описание процесса загрузки, который, если вы экстраполируете из 1082 байт, загружаемых примерно за 0,15 секунды (плюс некоторые накладные расходы), должен означать, что вы получите 23032 байта, загруженных в 23032 / 1082 * 0.15 секунд, а именно около 3 секунд, включая проверку.

Тот факт, что вы этого не добиваетесь, наводит на мысль (как упоминал Гил в своем ответе), что существует проблема с тем, что ваш компьютер действительно так быстро отправляет данные через USB-порт.

Если бы вы подключили логический анализатор и посмотрели, что на самом деле поступает, то могли бы обнаружить, что промежутки между байтами (или пакетами байтов) больше, чем вы ожидали.

,

2

Программаторы ISP обычно по умолчанию используют низкие тактовые частоты ISP. Часто что-то вроде 10 кГц, иногда медленнее, вероятно, чтобы просто работать по умолчанию с очень медленными чипами AVR. Тактовая частота ISP должна быть примерно на одну восьмую больше тактовой частоты AVR. Например, установив по умолчанию низкую частоту, например 10 кГц, программатор будет успешно взаимодействовать с AVR с тактовой частотой 125 кГц с некоторым запасом. Около 4 кГц будет работать с часовым кристаллом с частотой 32,768 кГц.

Посмотрите в документации avrdude для опции -B. Обратите внимание на прописную букву "B", это опция для изменения скорости ISP, а не строчная буква -b, которая определяет скорость передачи данных от ПК к программатору (или загрузчику). Не все программаторы поддерживают -B, но многие поддерживают.

Обновить

Ну, я покопался в коде USBtinyISP и в avrdude, и похоже, что значение по умолчанию для -B равно 10. Итак, 10uS. То, как это значение используется в коде USBtinyISP, относится к высокому или низкому периоду, а не к общему тактовому периоду. Таким образом, это примерно 20uS на бит, или 50 кГц. Если это ваша скорость, то обычная синхронизация данных SPI составляет всего около 3,7 секунды. Так что это ставит под сомнение эту идею.

Но, возможно, все же стоит дважды проверить, что он работает со значением 10, а не с чем-то большим. Просто для того, чтобы представить это в перспективе: максимальное значение -B, по-видимому, равно 250, что приведет к тактовой частоте ISP 2 кГц и примерно полутора минутам для синхронизации ваших примерно 23 КБайт.

Дополнительные выводы: накладные расходы SPI на байт

Каждый байт флэш-страниц передается в интерфейс ISP посредством SPI-команд длиной 4 байта. Прошивка для программатора содержит следующий код для записи страницы в свой файл spi / main.c, где вы можете увидеть, как он вызывает spi ( cmd, res, 4):

extern  void    usb_out ( byte_t* data, byte_t len )
{
    byte_t  i;
    uint_t  usec;
    byte_t  r;

    for ( i = 0; i < len; i++ )
    {
        cmd[3] = data[i];
        spi_rw();
        cmd[0] ^= 0x60; // превратить запись в чтение
        for ( usec = 0; usec < timeout; usec += 32 * sck_period )
        {   // когда время ожидания> 0, опрашивать до тех пор, пока не будет записан байт
          spi( cmd, res, 4 );
            r = res[3];
            if  ( r == cmd[3] && r != poll1 && r != poll2 )
            {
                break;
            }
        }
    }
}

Этот код используется для доставки данных в буфер флэш-страницы во время программирования ISP.

Вы можете увидеть комментарий в коде avrdude, объясняющий, что каждый байт становится 4-байтовой транзакцией SPI, чтобы объяснить их вычисление для тайм-аута связи с программатором. Следующее находится в файле usbtiny.c avrdude для функции usbtiny_paged_write.

if (usb_out(pgm,
            function,       // Flash или EEPROM
            delay,          // Сколько ждать между добавлением каждого байта
            addr,           // Адрес в памяти
            m->buf + addr,  // Указатель на данные
            chunk,          // Количество байтов для записи
            32 * PDATA(pgm)->sck_period + delay  // каждый байт превращается в
                                 // 4-байтовый SPI cmd usb_out() умножает
                                 // это на байт. Затем добавьте cmd-delay
            ) < 0) {
  return -1;
}

Чтобы было понятно, эти две функции имеют одно и то же имя, но на самом деле являются двумя разными функциями; первая выполняется в программаторе, а вторая выполняется в avrdude.

Таким образом, на самом деле существуют значительные накладные расходы на транзакции SPI при простой доставке данных в буфер страницы. Помимо этого, существует вторая транзакция USB и SPI для фиксации буфера страницы во флэш-память.

,

Отличная информация, спасибо. Я заглянул в свои выходные данные и обнаружил: "avrdude: период использования SCK составляет 10 usec" Таким образом, похоже, что он установлен на значение по умолчанию 10uS., @cody blanchard

Я зашел в файл avrdude.conf и изменил значение "default_bitclock" на 1. Теперь код загружается за 10 секунд и отлично выполняется на чипе. Это улучшение на 66%, но все же кажется, что оно должно загружаться быстрее, исходя из математики., @cody blanchard

Или... может быть, это почти правильно. Если мы оцениваем около 3,5 секунд данных spi, а bitclock установлен на паузу в 2uS для каждого бита... если бы для записи каждого бита требовалось около 1uS, разве это не увеличило бы общее время примерно в три раза? Хотя я понятия не имею, сколько времени на самом деле уходит на написание одного бита..., @cody blanchard

@codyblanchard, смотрите расширенные результаты. "простая синхронизация данных SPI", вероятно, должна была быть написана так, чтобы сказать "данных программы". То, что я пытался сделать (и, вероятно, потерпел неудачу), было консервативным, говоря грубые 3,7 секунды для неприводимого (за исключением сжатия) времени SPI, связанного с самими данными программы. Помимо того, что я только что упомянул в обновлении, я уверен, что есть и другие задержки. Хотя отдача от них, вероятно, будет уменьшаться., @timemage