Существует ли максимальная длина массива в ПЗУ?

Рассмотрим следующий код:

    #include <Arduino.h>
    
    unsigned char testimage [] = {
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    ... many more rows ...
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    
    void setup()
    {
        Serial.begin(115200);
        while(!Serial);
    
        Serial.println("start");
    
        for (int i = 0; i < 10; i++) {
            Serial.println((int)(testimage[i]));
        }
    
        Serial.println("stop");
    
    }
    void loop()
    {}

Я обнаружил, что после достижения массивом определенного размера на последовательный монитор ничего не отправляется. Похоже, вся программа зависает. Я даже не вижу сообщения start.

Я не пытался найти точный размер, но он где-то между 4500 и 8000. (При размере около 4500 работает, при размере около 8000 — нет).

Однако, когда я не обращаюсь к массиву, я вижу сообщения start и stop.

Я использую Arduino ATMega2560.

, 👍1

Обсуждение

«не работает» — это расплывчатое описание проблемы... что именно происходит? ... чего ты ожидал? ... пожалуйста, добавьте информацию к вопросу ... не пишите комментарий, @jsotola

Mega имеет SRAM объемом 8000 байт., @Juraj


2 ответа


Лучший ответ:

4

Неясно, имели ли вы в виду размещение массива в ПЗУ, как следует из вашего вопроса, но представленный вами код назначает его ОЗУ. Это наверняка ограничит ваш массив размером менее 8 КБ ОЗУ минус все, что необходимо (глобальные значения + статика ваших библиотек + статика вашего кода + стек).

Обновление:

Я предполагал, что раздел данных кода окажется в ПЗУ.

Фактически, образ раздела инициализированные данные становится частью образа ПЗУ. Исходные значения необходимо где-то сохранить, чтобы ОЗУ можно было инициализировать каждый раз при (пере)запуске программы, но к ней нельзя обращаться из ПЗУ во время выполнения. (Обратите внимание, что здесь мы не говорим о данных PROGMEM, которые хранятся в ПЗУ и доступны оттуда даже во время выполнения.)

,

Спасибо. Я предполагал, что раздел данных кода окажется в ПЗУ. Я думаю, что пример кода кажется совершенно неправильным;)., @Bart Friederichs


3

В данном случае предельным является размер оперативной памяти. И вам понадобится место для стека/кучи...

Если вы используете неконстантный массив, он будет скопирован из флэш-памяти в ОЗУ при запуске

На mega2560 даже при использовании const данные все равно копируются в ОЗУ, поскольку каждая FLASH/RAM/EEPROM имеет разное адресное пространство

Единственный способ — использовать PROGMEM, и его нельзя использовать напрямую. (опять разные адресные пространства для flash/ram)

Вы можете догадаться, что у mega2560 8 КБ ОЗУ, и вам следует оставить немного ОЗУ для работы. Если места недостаточно, стек и куча будут разбивать друг друга и вести себя совершенно непредсказуемо (перезаписывать адреса возврата, неконтролируемый код и т. д.)

,