Progmem и C++

Тема в разделе "Микроконтроллеры AVR", создана пользователем alexxx86, 2 дек 2014.

  1. alexxx86

    alexxx86 Гик

    Здравствуйте!
    Подскажите пожалуйста, работает ли атрибут PROGMEM в C+?
    Просто столкнулся с одной проблемкой, есть код на C в нем есть структура с атрибутом PROGMEM. Появилась необходимость перенести эту структуру в код на C++, но по итогу этот атрибут ни чего не дают.
    Причем если взять tiny 13, залить в ниё код на C то структура размещается во flash как и положено а если этот же код скомпилировать как C++ то PROGMEM ни чего не даёт.
    Но самое интересное дальше, если этот же код, залить уже в atmega328 как С то структура тоже размещается во flash, а если как C++ компиляции даже не проходит, появляются ошибки.
     
  2. Unixon

    Unixon Оракул Модератор

    А что он должен давать на архитектуре, где он лишен всякого смысла?
    Ну сделайте
    Код (Text):

    #define PROGMEM
     
    в начале программы и он уберется из кода
     
  3. alexxx86

    alexxx86 Гик

    Често признаюсь, я совсем не понял вашего ответа.
     
  4. Unixon

    Unixon Оракул Модератор

    Где и чем вы пытаетесь скомпилировать код для AVR ?
     
  5. alexxx86

    alexxx86 Гик

    Atmel studio 6
     
  6. Unixon

    Unixon Оракул Модератор

    А, теперь понятно. Мне поначалу показалось, что вы хотели портировать AVR-ный код на ПК.
    Какого рода ошибки возникают? Покажите вывод компилятора.
     
  7. Unixon

    Unixon Оракул Модератор

  8. alexxx86

    alexxx86 Гик

    Спасибо надо будет проверить. О результатах сообщу)
     
  9. alexxx86

    alexxx86 Гик

    Почему такая запись не катит в C++?
    Ошибки при компиляции:
    Error 1 anonymous type with no linkage used to declare function 'void read_byte(radio_command*)' with linkage [-fpermissive]
    Error 2 'typedef const struct<anonymous> radio_command' does not refer to the unqualified type, so it is not used for linkage [-fpermissive]

    Код (Text):
    #include <avr/io.h>
    #include <avr/pgmspace.h>


    typedef struct
    {
        uint8_t command[16];
        uint8_t length;
    } PROGMEM const radio_command;

    radio_command TAPE_power_on        = {{0x88, 0x12}, 1};
    radio_command TAPE_cassette_present = {{0x8B, 0x90, 0x40, 0x0C, 0x30}, 2};
    radio_command TAPE_stopped          = {{0x89, 0x0C, 0xE0}, 3};
    radio_command TAPE_playing          = {{0x89, 0x41, 0x50}, 4};
    radio_command TAPE_playback        = {{0x8B, 0x90, 0x40, 0x01, 0x00}, 1};
    radio_command TAPE_random_playback  = {{0x8B, 0x90, 0x60, 0x01, 0xE0}, 2};
    radio_command TAPE_repeat_playback  = {{0x8B, 0x90, 0x50, 0x01, 0xF0}, 3};
    radio_command TAPE_seeking          = {{0x89, 0x51, 0x60}, 4};
    radio_command TAPE_fast_rewind      = {{0x8B, 0x93, 0x40, 0x11, 0xE0}, 4};
    radio_command TAPE_fast_fastforward = {{0x8B, 0x92, 0x40, 0x11, 0xD0}, 4};



    void read_byte(radio_command *_comm)
    {
        uint8_t _byte = pgm_read_byte(&_comm->length);
        DDRB|=(1<<_byte);
    }

    int main(void)
    {
        read_byte(&TAPE_power_on);
        read_byte(&TAPE_cassette_present);
        read_byte(&TAPE_stopped);
        read_byte(&TAPE_playback);
    }
     
  10. Unixon

    Unixon Оракул Модератор

    1) PROGMEM относится к переменной, а не к типу, т.е. вместе с typedef не катит.
    2) PROGMEM используется с ограниченным количеством стандартных типов; Возможно, это расширяемо доопределением функций pgm_read_...().
     
  11. alexxx86

    alexxx86 Гик

    Первый пункт относится только C++? На C этот код компилируется нормально.
     
  12. Unixon

    Unixon Оракул Модератор

    Здесь разницы между C/C++ не должно быть.
     
  13. alexxx86

    alexxx86 Гик

    На C код компилируется нормально без ошибок и варингов. А вон на C++ получатеться ошибки!
    Но всё таки на C++ запихать структуру во влеш у меня получилось)))
    Код (Text):
    struct radio_command
    {
    т-ра та та))
    };

    radio_command const TAPE_playing PROGMEM = {т-ра тата};
     
  14. alexxx86

    alexxx86 Гик

    Короче я совсем запутался, но такая конструкция на C++ тоже работает
    Код (Text):
    typedef struct
    {
        uint8_t command[16];
        uint8_t length;
    } PROGMEM radio_command;

    const radio_command TAPE_power_on        = {{0x88, 0x12}, 1};
     
  15. Unixon

    Unixon Оракул Модератор

    Попробуйте для сравнения этот же код собрать avr-gcc.
     
  16. alexxx86

    alexxx86 Гик

    Так им и собрано. В Atmel studio он же встроен.
     
  17. Unixon

    Unixon Оракул Модератор

    Студией не пользуюсь. Думал, что там у Атмела свой велосипед стоит.
     
  18. Unixon

    Unixon Оракул Модератор

    Суть в том, что атрибут PROGMEM применяется к переменным, а не к типам. Если компилятор пропускает его в неожиданных местах и не показывает ошибку, это еще не значит, что он скомпилирует именно то, что вы думаете, что он должен скомпилировать.
     
  19. alexxx86

    alexxx86 Гик

    Как время появится попробую проверить это, так сказать на железе.