Easyelectronics.ru

Электроника для всех
Текущее время: 18 ноя 2018, 23:52

Часовой пояс: UTC + 5 часов



    • JLCPCB - Прототипы 10 PCBs всего за 2$ (100*100mm, 2-layer)
    • Как мы делаем платы, смотрите на YouTube
    • Крупнейшая китайская фабрика прототипов. 300000+ заказчиков и 10000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин комплектующих.

Начать новую тему Ответить на тему  [ Сообщений: 21 ] 
Автор Сообщение
 Заголовок сообщения: Atmega8 не хватает оперативы
СообщениеДобавлено: 31 дек 2017, 02:10 
Заглядывает иногда

Зарегистрирован: 30 июл 2017, 22:45
Сообщения: 56
Добрый день. Не могу записать большой массив 512байт во флэш, он все время занимает половину ОЗУ.

Подскажите пожалуйста, что я делаю не так.

Пишу под AVR в Eclipse.
Используется связь через RS-485 , есть CRC.

Для рассчета CRC использую таблицы:

Код:
uint16_t crc16(uint8_t *adr_buffer, uint32_t byte_cnt)
{

    static const unsigned char auchCRCHi[]=
    {
        0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
        0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
        0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
        0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
        0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
        0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
        0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
        0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
        0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
        0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
        0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
        0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
        0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
        0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
        0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,
        0x00,0xC1,0x81,0x40,0x01,0xC0,0x80,0x41,0x01,0xC0,0x80,0x41,0x00,0xC1,0x81,0x40,
    };
    /*Table of CRC values for low–order byte*/
    static const char auchCRCLo[]=
    {
        0x00,0xC0,0xC1,0x01,0xC3,0x03,0x02,0xC2,0xC6,0x06,0x07,0xC7,0x05,0xC5,0xC4,0x04,
        0xCC,0x0C,0x0D,0xCD,0x0F,0xCF,0xCE,0x0E,0x0A,0xCA,0xCB,0x0B,0xC9,0x09,0x08,0xC8,
        0xD8,0x18,0x19,0xD9,0x1B,0xDB,0xDA,0x1A,0x1E,0xDE,0xDF,0x1F,0xDD,0x1D,0x1C,0xDC,
        0x14,0xD4,0xD5,0x15,0xD7,0x17,0x16,0xD6,0xD2,0x12,0x13,0xD3,0x11,0xD1,0xD0,0x10,
        0xF0,0x30,0x31,0xF1,0x33,0xF3,0xF2,0x32,0x36,0xF6,0xF7,0x37,0xF5,0x35,0x34,0xF4,
        0x3C,0xFC,0xFD,0x3D,0xFF,0x3F,0x3E,0xFE,0xFA,0x3A,0x3B,0xFB,0x39,0xF9,0xF8,0x38,
        0x28,0xE8,0xE9,0x29,0xEB,0x2B,0x2A,0xEA,0xEE,0x2E,0x2F,0xEF,0x2D,0xED,0xEC,0x2C,
        0xE4,0x24,0x25,0xE5,0x27,0xE7,0xE6,0x26,0x22,0xE2,0xE3,0x23,0xE1,0x21,0x20,0xE0,
        0xA0,0x60,0x61,0xA1,0x63,0xA3,0xA2,0x62,0x66,0xA6,0xA7,0x67,0xA5,0x65,0x64,0xA4,
        0x6C,0xAC,0xAD,0x6D,0xAF,0x6F,0x6E,0xAE,0xAA,0x6A,0x6B,0xAB,0x69,0xA9,0xA8,0x68,
        0x78,0xB8,0xB9,0x79,0xBB,0x7B,0x7A,0xBA,0xBE,0x7E,0x7F,0xBF,0x7D,0xBD,0xBC,0x7C,
        0xB4,0x74,0x75,0xB5,0x77,0xB7,0xB6,0x76,0x72,0xB2,0xB3,0x73,0xB1,0x71,0x70,0xB0,
        0x50,0x90,0x91,0x51,0x93,0x53,0x52,0x92,0x96,0x56,0x57,0x97,0x55,0x95,0x94,0x54,
        0x9C,0x5C,0x5D,0x9D,0x5F,0x9F,0x9E,0x5E,0x5A,0x9A,0x9B,0x5B,0x99,0x59,0x58,0x98,
        0x88,0x48,0x49,0x89,0x4B,0x8B,0x8A,0x4A,0x4E,0x8E,0x8F,0x4F,0x8D,0x4D,0x4C,0x8C,
        0x44,0x84,0x85,0x45,0x87,0x47,0x46,0x86,0x82,0x42,0x43,0x83,0x41,0x81,0x80,0x40,
    };
    /////////////////////////////////////////////////////////////

    // переменные для расчета CRC16 -?*:?????
    unsigned char uchCRCHi = 0xFF;
    unsigned char uchCRCLo = 0xFF;
    unsigned uIndex;

    /* CRC Generation Function */
    while( byte_cnt--) /* pass through message buffer */
    {
        uIndex = uchCRCHi ^ *adr_buffer++; /* calculate the CRC */
        uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];
        uchCRCLo = auchCRCLo[uIndex];
    }
    return (uchCRCHi << 8 | uchCRCLo);
}



Все отлично работает! только озу в атмеге8 всего килобайт. И вот эти таблицы, хоть и const, хранятся все равно в ОЗУ.
То есть отжирают половину по дефолту. Это очень плохо для меня.
Пробовал выносить их из фукции в глобальные переменные, все равно занимают озу.
Есть другой массив, который знакогенератор для дисплея. Его данные тоже пихаются в озу, хоть и const.
Подскажите, кто знает, что я делаю не так. И как записать их во флэш, если это возможно.


___________________________________________

UPDATE:

Вроде бы нашел решение.
Оказывается даже const копируются после старта в озу.
Что бы этого не делать, прописываем #include "avr/pgmspace.h" и добавляем атрибут перед типом данных __ATTR_PROGMEM__ , тогда копирование в озу не происходит.

Что бы их считывать из флеша, нужно тоже юзать команду
Код:
byte = pgm_read_byte(&(mydata[i][j]));


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 31 дек 2017, 13:52 
Старожил

Зарегистрирован: 20 мар 2013, 11:27
Сообщения: 5150
решение зависит от компилятора, а не от редактора
у вас судя по всему avr-gcc
рекомендую почитать документацию на библиотеку для avr-gcc, первоисточник http://www.nongnu.org/avr-libc/

там все подробно описано в том числе про хранение данных во флэш

вместо использования атрибутов удобнее применять макрос PROGMEM:

Код:
uint8_t data[] PROGMEM = { .... };


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 31 дек 2017, 14:50 
Старожил
Аватара пользователя

Зарегистрирован: 18 фев 2014, 11:27
Сообщения: 212
как то так:
Код:
#include <avr/pgmspace.h>
////////
const unsigned char mass[] PROGMEM = {};
//////чтение
temp = pgm_read_byte(&mass[x]);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 01 янв 2018, 13:59 
Старожил
Аватара пользователя

Зарегистрирован: 17 апр 2010, 08:38
Сообщения: 4858
Откуда: Усинск, республика Коми
Все переменные хранятся в ОЗУ. Константа это то, что не изменяется в процессе выполнения программы. И никакого указания где ее хранить из этого не следует. Переменная - значит ОЗУ.

_________________
хаос это непознанный порядок


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 01 янв 2018, 15:35 
Старожил

Зарегистрирован: 20 мар 2013, 11:27
Сообщения: 5150
BigLeha писал(а):
Все переменные хранятся в ОЗУ. Константа это то, что не изменяется в процессе выполнения программы. И никакого указания где ее хранить из этого не следует. Переменная - значит ОЗУ.

для AVR это так, а вот в общем случае утверждение неверное
для примера с STM8/STM32 достаточно указать const, чтобы данные разместились полностью во флэш и не потребляли оперативку
с AVR фигня в том, что для разных типов памяти разное адресное пространство, а значит и разные машинные инструкции по доступу
даже если бы компилятор так разместил данные только во флэш:
Код:
const char data[] = { 0, 1, 2, 3 };

то этот код бы работал неверно:
Код:
char c = data[1];


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 01 янв 2018, 17:04 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 1431
Откуда: Китай, Пекин
а зачем выбрана такая несбалансированная реализация CRC16?
эта версия хороша ТОЛЬКО для десктопа

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

Код:
static const uint16_t tab[16] = {0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 45419, 49548, 53677, 57806, 61935};

inline static uint16_t crc16(uint8_t data, uint16_t crc)
{
   crc = tab[(crc >> 12 ^ data >> 4) & 0x0F] ^ crc << 4;
   return tab[(crc >> 12 ^ data & 0x0F) & 0x0F] ^ crc << 4;
}


можешь не сомневаться он проверен мною "боями" и на многих платформах.
версию на С#, java ,если надо, найдешь рядом.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 02 янв 2018, 10:01 
Старожил
Аватара пользователя

Зарегистрирован: 17 апр 2010, 08:38
Сообщения: 4858
Откуда: Усинск, республика Коми
axill писал(а):
BigLeha писал(а):
Все переменные хранятся в ОЗУ. Константа это то, что не изменяется в процессе выполнения программы. И никакого указания где ее хранить из этого не следует. Переменная - значит ОЗУ.

для AVR это так, а вот в общем случае утверждение неверное
для примера с STM8/STM32 достаточно указать const, чтобы данные разместились полностью во флэш и не потребляли оперативку

Так по названию темы видно, что речь совсем не об STM

_________________
хаос это непознанный порядок


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 05 янв 2018, 06:40 
Старожил

Зарегистрирован: 18 июл 2016, 21:17
Сообщения: 746
axill писал(а):
BigLeha писал(а):
Все переменные хранятся в ОЗУ. Константа это то, что не изменяется в процессе выполнения программы. И никакого указания где ее хранить из этого не следует. Переменная - значит ОЗУ.

для AVR это так, а вот в общем случае утверждение неверное
для примера с STM8/STM32 достаточно указать const, чтобы данные разместились полностью во флэш и не потребляли оперативку
с AVR фигня в том, что для разных типов памяти разное адресное пространство, а значит и разные машинные инструкции по доступу
даже если бы компилятор так разместил данные только во флэш:
Код:
const char data[] = { 0, 1, 2, 3 };

то этот код бы работал неверно:
Код:
char c = data[1];

В иаре и для арм и для авр достаточно вместо const написать flash и этот код продолжит работать верно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 05 янв 2018, 11:36 
Старожил

Зарегистрирован: 20 мар 2013, 11:27
Сообщения: 5150
В Iar да, подобное есть и в codevision и microc
Но у товарища gcc


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 05 янв 2018, 12:33 
Старожил

Зарегистрирован: 26 авг 2014, 10:34
Сообщения: 735
в GCC AVR давно можно __flash применять, типа так:
const __flash int array[] = { 3, 5, 7, 11, 13, 17, 19 };
http://gcc.gnu.org/onlinedocs/gcc/Named ... paces.html


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 05 янв 2018, 20:54 
Старожил

Зарегистрирован: 20 мар 2013, 11:27
Сообщения: 5150
oleg110592 Круто
Прлучается по этому атрибуту компилятор должен правильный асемблер для доступа вставить
А если такой параметр надо передать в функцию? В статье не увидел такого примера
Можно ли описать что то вида?

Код:
void print_flash(__flash char* r);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 05 янв 2018, 22:12 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 1431
Откуда: Китай, Пекин
axill писал(а):
[/code]


кстати ваш вариант crc8 у меня тоже был перед глазами, но он практически не применим.
8 бит - слишком ненадежно.

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

хотя 32 бита это конечно, уже совсем перебор.

поэтому рекомендую переключиться на 16 бит.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 05 янв 2018, 22:26 
Старожил

Зарегистрирован: 26 авг 2014, 10:34
Сообщения: 735
axill писал(а):
Можно ли описать что то вида?
Код:
void print_flash(__flash char* r);

Функции для ввода строки по USART из флеша и оперативки соответственно:
Код:
void UsartPutsP(const char __flash * str)
{
        char c;
        while(c = *str++)
        {
                UsartWriteByte( c );
        }
}

void UsartPuts(const char * str)
{
        char c;
        while(c = *str++)
        {
                UsartWriteByte( c );
        }
}

http://we.easyelectronics.ru/Soft/avr-s ... ateli.html


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 06 янв 2018, 17:46 
Старожил

Зарегистрирован: 20 мар 2013, 11:27
Сообщения: 5150
cheblin crc8 не мое, невнимательно смотрели, там все написано


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 07 янв 2018, 09:06 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 1431
Откуда: Китай, Пекин
axill писал(а):
cheblin crc8 не мое, невнимательно смотрели, там все написано

я всё внимательно смотрел и всё видел. я не совсем точно выразился.
репозитория то ваша? никакой другой реализации CRC в ней нет.

проблема не в качестве самой CRC8. она вероятно правильно написана и даже работает.
только бессмысленна и опасна тем, что создает иллюзию функционала.

только её наличие, вместо CRC16 странновато, на мой вкус.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 07 янв 2018, 10:36 
Старожил

Зарегистрирован: 20 мар 2013, 11:27
Сообщения: 5150
нет никакой иллюзии
crс8 это crc8 со всеми своими плюсами и минусами
в репозитории еще много чего нет, в разработке


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 25 мар 2018, 15:18 
Заглядывает иногда

Зарегистрирован: 30 июл 2017, 22:45
Сообщения: 56
cheblin писал(а):
а зачем выбрана такая несбалансированная реализация CRC16?
эта версия хороша ТОЛЬКО для десктопа

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

Код:
static const uint16_t tab[16] = {0, 4129, 8258, 12387, 16516, 20645, 24774, 28903, 33032, 37161, 41290, 45419, 49548, 53677, 57806, 61935};

inline static uint16_t crc16(uint8_t data, uint16_t crc)
{
   crc = tab[(crc >> 12 ^ data >> 4) & 0x0F] ^ crc << 4;
   return tab[(crc >> 12 ^ data & 0x0F) & 0x0F] ^ crc << 4;
}


можешь не сомневаться он проверен мною "боями" и на многих платформах.
версию на С#, java ,если надо, найдешь рядом.


Спасибо большое за код! а не могли бы вы пояснить его преимущества на МК по сравнению с моим табличным ? Будет быстрее работать ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 25 мар 2018, 15:38 
Старожил
Аватара пользователя

Зарегистрирован: 11 апр 2016, 18:04
Сообщения: 1431
Откуда: Китай, Пекин
Ramzez писал(а):
Спасибо большое за код! а не могли бы вы пояснить его преимущества на МК по сравнению с моим табличным ? Будет быстрее работать ?


во первых он влезет в вашу ограниченную память.... дальше можно не продолжать.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 26 мар 2018, 00:48 
Заглядывает иногда

Зарегистрирован: 30 июл 2017, 22:45
Сообщения: 56
cheblin писал(а):
Ramzez писал(а):
Спасибо большое за код! а не могли бы вы пояснить его преимущества на МК по сравнению с моим табличным ? Будет быстрее работать ?


во первых он влезет в вашу ограниченную память.... дальше можно не продолжать.


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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 26 мар 2018, 15:08 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 851
BigLeha писал(а):
Константа это то, что не изменяется в процессе выполнения программы.
не совсем так.
const гарантирует только то, что сама эта программа не будет пытаться изменить (явным образом) эту переменную (т.е. компилятор будет следить за этим и выдавать ошибку, если что). Но это не значит, что её содержимое не может измениться по какой-то другой причине.
В описании стандарта C (ISO/IEC 9899:TC3) даже такой пример есть:
Цитата:
EXAMPLE 1 An object declared

extern const volatile int real_time_clock;

may be modifiable by hardware, but cannot be assigned to, incremented, or decremented.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Atmega8 не хватает оперативы
СообщениеДобавлено: 27 окт 2018, 21:55 
Старожил

Зарегистрирован: 16 окт 2013, 01:27
Сообщения: 662
Подниму тему:
cheblin
Можете пояснить как правильно пользоваться этим
Show "алгоритмом"

Пытаюсь его использовать для рассчета MODBUS RTU CRC16 (полином 8005 вроде) но контрольная сумма на выходе не совпадает.

Отправляю из программы Modpoll
0x05 0x10 0x00 0x0A 0x00 0x03 0x06 0x00 0x00 0x32 0xff 0x03 0x11 0x36 0x50

рассчет контрольной суммы в процедуре веду с первого байта посылки 0x05 и до последнего байта информации 0x11.
По сути выкинув из расчета только 2 последних байта контрольной суммы 0x36 0x50 .
У меня в процедуре которую вы предложили (учитывая что при входе в функцию переменная crc=0x00) на выходе получается контрольная сумма 0xD3 0xAE
Что я делаю не правильно ?

P\S с Modbus RTU до этого дел не имел, без контрольной суммы все норм работает.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 21 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: demiurg1978


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB