2016-12-22 5 views
0

Я пишу прошивку для контроллера Atmel Mega645A с использованием AtmelStudio7. У меня есть куча сообщений, которые я показываю на 16-значном дисплее. Чтобы сохранить пространство SRAM, я пытаюсь сохранить эти сообщения в памяти программ ROM. Моя проблема в том, что кажется, что я переписываю части памяти программ, которые уже используются для другого кода. Вот подробности:Объем памяти программы перезаписывается

Я следующие утверждения около начала основной программы:

#include "adht.h" 
#include "languages.h" 

в adht.h я следующее:

#include <avr/pgmspace.h> 

Я считаю гайку моя проблема в моем файле header.h, который я создал. В languages.h у меня есть сотни строк кода, которые выглядят следующим образом:

const char M1_1_1[] PROGMEM = {32,32,32,32,69,110,116,101,114,105,110,103}; 
const char M1_2_1[] PROGMEM = {32,32,83,116,97,110,100,98,121,32,77,111,100,101}; 
const char M2_1_1[] PROGMEM = {32,32,70,87,32,82,101,118,105,115,105,111,110}; 
const char M2_2_1[] PROGMEM = {32,32,32,32,40,110,117,109,98,101,114,41}; 
const char M3_1_1[] PROGMEM = {32,78,79,46,32,79,70,32,84,72,69,82,65,80,89}; 
const char M3_2_1[] PROGMEM = {32,32,32,32,83,69,83,83,73,79,78,83,58}; 
    . 
    . 
    . etc. etc. 

Когда я компилирую с ~ 660 строк, как это, AtmelStudio сообщает следующее: Program Использование памяти: 34892 байт 53,2% Полная данных Использование памяти: 2919 байт 71,3% Использование Полного EEPROM памяти: 170 байт 8,3% Полного

Если я закомментировать большую часть «сопзИ голец ....» линию, и восстановить, я получаю это:

Использование памяти программы: 34896 байт 53,2% Полный Data Mem ory Использование: 2919 байт 71,3% Полный EEPROM Использование памяти: 170 байт 8.3% Полный

... который выглядит примерно одинаково. Однако обе сборки позволят остальной части моей программы работать без проблем.

Здесь я бегу в беду. Далее в languages.h У меня есть следующий код:

PGM_P const string_table[] PROGMEM = 
{ 
    M1_1_1 , M1_1_2 , M1_1_3 , M1_1_4 , M1_1_5 , M1_1_6}; /* , 
    M1_2_1 , M1_2_2 , M1_2_3 , M1_2_4 , M1_2_5 , M1_2_6 , 
    M2_1_1 , M2_1_2 , M2_1_3 , M2_1_4 , M2_1_5 , M2_1_6 , 
    M2_2_1 , M2_2_2 , M2_2_3 , M2_2_4 , M2_2_5 , M2_2_6 , 
    M3_1_1 , M3_1_2 , M3_1_3 , M3_1_4 , M3_1_5 , M3_1_6 , 
    . 
    . 
    . etc. etc. 

Теперь вы обратите внимание, что после первой линии M1_1_1 ... Я закомментирована «/ » остальные «указатель задания» , Будьте уверены, что у меня есть « /» в конце заданий. Если у меня есть только 6 указателей, мой код работает нормально. Если я переместил «/ *» на пару строк, чтобы скомпилировать еще пару строк кода, остальная часть моей программы начнет волноваться, как если бы я вышел из памяти программы. Моя программа не работает по-разному, в зависимости от того, какая часть «присваиваний указателей» скомпилирована. (Заметьте, что у меня проблемы с вводом «обратной косой черты» на этом форуме). Когда я компилирую с восьми строк кода, которые не прокомментирована, компилятор сообщает следующее:

Program Использование памяти: 35530 байт 54,2% Полное использование Память данных: 2919 байт 71,3% полное использование памяти EEPROM: 170 байты 8,3% Полный

И когда я не-закомментировать все эти строки, компилятор сообщает следующее:

Program Использование памяти: 44690 байт 68,2% Полное использование Память данных: 2919 байт 71,3% Полная EEPROM памяти Использование: 170 байт 8.3% Полный

Так что я четко заполняю память программ, но не приближаюсь к пределу.

Чтобы быть полным, в основной программе скопировать сообщения из программы памяти в SRAM следующим образом:

char line1[16]; 
char line2[16]; 
PGM_P p; 
memcpy_P(&p, &string_table[0], sizeof(PGM_P)); 
strcpy_P(line1, p); 
memcpy_P(&p, &string_table[1], sizeof(PGM_P)); 
strcpy_P(line2, p); 

Позже я посылаю line1 и line2 на дисплее.

Так что, мне кажется, что проблема в моем

PGM_P const string_table[] PROGMEM = 

линии (линий). Может кто-нибудь, пожалуйста, скажите мне, как я это делаю, чтобы не переписывать остальную часть моей программы?

UPDATE: в основной программе, если я закомментируйте следующие строки кода перед компиляцией, капли использования памяти программ (до 54%), а остальная часть программы работает отлично:

char line1[16]; 
char line2[16]; 
PGM_P p; 
memcpy_P(&p, &string_table[0], sizeof(PGM_P)); 
strcpy_P(line1, p); 
memcpy_P(&p, &string_table[1], sizeof(PGM_P)); 
strcpy_P(line2, p); 

Когда я не комментирую этот код и повторно компилирую, использование памяти программы возвращается до 68%, а затем вся остальная часть программы угасает, когда я ее запускаю. Так что же это за эти строки кода, которые переписывают Program Memory?

UPDATE # 2: в строках кода выше, если я закомментируйте эти две строки:

strcpy_P(line1, p); 
strcpy_P(line2, p); 

Моя программа работает. Конечно, я все еще не имею доступа к данным, хранящимся в памяти программы. Пожалуйста, скажите мне, что происходит. Как получить данные (массив символов или, альтернативно, массив uint_8) в ОЗУ, чтобы я мог отображать экран 16x2?

+1

Когда вы говорите «хранить эти сообщения в памяти программ ROM», вы имели в виду в EEPROM? Не рекомендуется использовать EEPROM непрерывным динамическим способом, так как количество циклов записи ограничено. –

+0

в C вы не можете иметь 'const char M1_1_1 [] = {32,32,32,32,69,110,116,101,114,105,110,103};' и т. Д. В файле заголовка, это приведет к нескольким определениям единиц перевода, которые являются неопределенным поведением. Я не уверен, что PROGMEM имеет какое-то значение для этого, но при условии, что это не так (и предположим, что вы включили languages.h как минимум в 2 единицы), которые объяснят вашу проблему. –

+0

@ M.M. Я переместил весь код, который у меня был на языках .h, в основную программу [до main()] и, похоже, работает. Спасибо. –

ответ

0

В стандартном C, если у вас есть это в файле заголовка:

const char M1_1_1[] = {32,32,32,32,69,110,116,101,114,105,110,103}; 

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

Если вы можете изменить порядок кода, чтобы определения отображались только в файле .c, это может решить проблему. Другие устройства могут получить доступ к данным на extern const char M1_1_1[];.

+0

'static' помогает с одной стороны, но с другой стороны умножает печать на память.' 'Extern' для самого массива не полезен (и не будет работать), так как вам нужно знать размер массива , Либо вы экспортируете две константы, либо используете терминатор. – 0andriy

+0

@ 0andriy вы можете использовать перечисление или '# define' для размера массива, если это необходимо. Код, который я опубликовал, работает и полезен, в зависимости от требований. Вы делаете предположение, что вызывающему нужно размер, что может быть неверным. –

+0

Да, я знаю, но это больше подвержено ошибкам, так как нужно обновить два + места вместо одного. – 0andriy

Смежные вопросы