Jump to content

    

Сергей Борщ

Модераторы
  • Content Count

    9331
  • Joined

Posts posted by Сергей Борщ


  1. Однозначно первый вариант. Второй и третий ломаются элементарно - пишется прошивка которая тупо сливает по любому доступному интерфейсу содержимое "неизменной" части прошивки.

    Интересный вопрос - по какому интерфейсу вы запишите прошивку в SAM7S с установленым битом Security ?

    По тому же самому по которому заливается "штатная" прошивка.

    Учитывая что апдейтер прошивки внутри девайса будет использовать любой алгоритм однонаправленого шифрования ?
    Теперь я не понял вопроса. В раскритикованных втором и третьем вариантах прошивка не шифруется. Именно это и позволяет подсунуть любую прошивку. Шифруется она в одобренном первом варианте.
  2. Я там документации что то не нашел. Насколько сильно изменилась ОС, можно ли пользоваться документацией к версии 2 (хотя бы на первое время)?
    Документация в процессе написания. Переработки весьма основательные, в основном в организации файлов ОС. Дока от второй версии подходит, разве что отдельные части кода могут оказаться не в том файле в котором были во второй версии.
  3. Засада, очевидно, еще и в том, что в той библиотечке, которую мне выдали, везде один только keepout :(
    ну так библиотека ведь не догма. можно и подправить. В зависимости от количества элементов - либо в pattern editor либо экспорт библиотеки в текстовый файл, редактирование текстовым редактором, импорт. Потом Utils->Forse update
  4. Только вопрос в том насколько верно что Low ESR должен быть высоким и малого диаметра хз Очень часто так - например есть конденсаторы от разной бу техники
    Еще один способ "интуитивного" определения Low ESR - если он стоял на выходе импульсного преобразователя или импульсного источника питания до дросселя (сразу после диода), то с вероятностью 90% он Low ESR. Если он проработал в такой цепи 2 года и не сдох - то с вероятность 99.99%. После дросселя - если отличается по типу от того, что перед дросселем - скорее всего обычный.
  5. а сам чип к тому же преспокойно работает от 5V.
    Работать-то он работает, но вот на шине питания скорее всего кроме процессора висят и другие 3в микросхемы, которые от 5в если не сгорят, то с большой долей вероятности деградируют. Так что питание лучше не завышать.
  6. Переход из загрузчика в тело программы: JMPCODE(0x0000);

     

    В теле программы возврат векторов:

    /* Разрешение изменения векторов прерываний */

    /* Перемещение векторов ив загрузочного сектора флэш-памяти */

    MCUCR = 0x01; // MCUCR |= (1<<IVCE);

    MCUCR = 0x00; // MCUCR |= (1<<IVSEL);

    Такой подход имеет один недостаток - "основная" программа должна знать, что работает совместно с загрузчиком. Если же обратное переключение таблицы мы перенесем в загрузчик, то единственой особенностью "основной" программы останется огнраничение по размеру:

      __disable_interrupt();
      MCUCR = 0x01; // MCUCR |= (1<<IVCE);
      MCUCR = 0x00; // MCUCR |= (1<<IVSEL);
      (void (*)())0x0000();

  7. А то получается что у 5В I2C устройства уровень единицы 0.7*5В = 3.5 В

    MSP может и не выдержать с его логической 1 в 1.5-1.9В.

    Уровень логической единицы определяется только лишь потенциалом к которому подключены подтягивающие резисторы. Хватит ли этого уровня для распознания 1 вашим пятивольтовым АЦП - надо смотреть в даташите. Если хватит, то никакого дополнительного согласования не нужно.
  8. Пока я нашел , что можно функцию описать как __swi void f(void) но опять вопрос - компилер сам поставит переход по нужному адресу этого прерывания, или нужно руками все описывать?
    А вот про это довольно подробно расписано в документации на компилятор, раздел Software interrupt, и оттуда по ссылкам на описание __swi и #pragma swi_number. Такой функции можно передавать параметры, она может возвращать значения.
  9. Наверно надо обратить внимание на правильную размерность указателя на функцию когда делается кастинг перед сложением .
    Можно подключить stdint.h, там объявлен тип uintptr_t - беззнаковое целое в которое точно уместится указатель, и использовать этот тип. Но только для чего-нибудь полезного, а не для решения исходной задачи :-)
  10. 1. Как работать с прерываниями? Достаточно описать ф-цию __irq __arm void f(void) , при выходе из которой надо сбросить регистр EIOCR, или необходимо делать еще какое-то описание по адресу 0х18?, ну и соотв настроить AIC.

    (В случае со стартапом - я объявляю функцию прерывания просто void, без __irq __arm, так как в стартапе есть асм код, который делает все сам)

    тут есть два подхода (точнее, считая и Ваш с Cstartupом, три):

    1) на место вектора исключения при помощи асм-файла ставится команда безусловного перехода по адресу AIC_IVR:

            CODE32
            COMMON  INTVEC:CODE:ROOT
            org     0x00000018
            LDR     PC, AT91C_AIC_IVR
            END

    в С вы объявляете каждый обработчик с атрибутами __arm __irq. Это заставляет компилятор генерить отдельный пролог/эпилог для каждого обработчика, что конечно требует дополнительной памяти кода, но позволяет компилятору сгенерить пролог/эпилог максимально эффективно под конкретный обработчик (сохранять только нужные регистры), а вам индивидуально разрешать в отдельных обработчиках вложенные прерывания:

    __irq __arm void IRQ_Handler1() {
    
        .............
    
        AT91C_BASE_AIC->AIC_EOICR = 0;
    }
    
    __irq __arm __nested void IRQ_Handler2() {
    
        .............
    
        AT91C_BASE_AIC->AIC_EOICR = 0;
    }

    2) Делается одна функция-обработчик в которой делается сохранение/восстановление регистров и из этой функции вызываются обработчики, которые представляют из себя обычные функции. Функция-обработчик "подвешивается" на вектор исключения стандартными средствами компилятора:

    #pragma vector = 0x0000018
    __irq __arm void IRQ_Switch() {
        (void (*)(void))(AT91C_BASE_AIC->AT91C_AIC_IVR)();
        AT91C_BASE_AIC->AIC_EOICR = 0;
    }
    
    
    void Handler1() {
        ...........
    }
    void Handler2() {
        ...........
    }

    3) Ваш третий метод по сути тот же второй только на асме. Он получается чуть эффективнее чем вариант 2 на С, но мне больше всего нравится первый вариант.

    2. В вашем описании нет выбора библиотеки, но при создании нового проекта во вкладке

    Project -> Options -> General Options -> Library configuration по умолчанию стоит Normal. Это можно оставить , или нужно поменять?

    Все, что не описано можно оставить как есть. Менять нужно лишь в том случае, если вы четко понимаете что вы меняете и что вам это действительно нужно менять.

    3. Как описывать обработчики исключений - data abort, и др?
    Учитывая, что спец. ключевых слов в описании компилятора (во всяком случае в версии 4.30) нет, то судя по всему только на асме. Ну в крайнем случае пролог/эпилог на асме и вызов основного обработчика, который уже на С. Откровенно говоря, кроме "ловушек"- зацикливания пока ничего не требовалось на этих векторах.

     

     

    Спасибо, более-менее все работает, даже получилось создать проект без использования runtime библиотек, т.е. добавил весь необходимый минимальный код в проект. Буду теперь разбираться по шагам.

     

    Всем большое спасибо.

    Библиотеку все же желательно подключить. Из нее берется CStartup(если нет своего в проекте), из нее же берутся некоторые функции которые вы явно не вызываете (например у AVR конструкция switch при определенных условиях использует библиотечные функции, сдвиги на несколько битов). Что используется в ARM навскидку не скажу, но можно при помощи xlib распечатать список модулей библиотеки и поразмышлять над их названием. Нет смысла не подключать библиотеку. У IAR замечательный линкер, и ни одного лишнего (неиспользуемого) байта из библиотеки в проект не попадет.
  11. Соорудил вот такой код:
    А зачем вы делаете принудительное приведение указателя к типу int? Во-первых это требует лишней писанины, во-вторых ограничиваете указатель размером int (непереносимость), но главное - вы подавляете возможность компилятора отлавливать ошибки несоответствия типов:

    void func00(void)
    {
        printf("func00\r\n");
    }
    
    void func01(void)
    {
        printf("func01\r\n");
    }
    
    typedef void (*pfunc_t)(void);
    
    pfunc_t __flash ptrs[2] = {func00, func01};
    
    void test(void)
    {
        ptrs[0]();
        ptrs[1]();
    }

  12. Ну, обычно об этом должен помнить компилятор.

    Ну вообще-то при создании проекта, об этом должен сказать программист.

    Если я правильно понимаю, программист при создании проекта говорит в каком режиме компилировать функции по умолчанию. При этом остается возможность жестко указать - эту функцию в thumb, а эту - в Arm. Компилятор (а не программист) должен думать и помнить о том, что при вызове функции foo2 из foo1 надо переключать режим, а при вызове foo3 из foo1 - не надо.
  13. Здравствуйте.

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

    1) Запускаем IAR, создаем новый workspace или используем текущий.

     

    2) Project->Create new project, выбираем C -> main или C++ -> main по вкусу, жмем ОК, указываем имя проекта.

     

    3) Идем Project -> Options -> General Options

    3.1)вкладка Target

    --- Ставим крыжик на Device, выбираем в списке тип процессора. Это заставит IAR правильно указывать компилятору/ассемблеру архитектуру (ARM7TDMI, ARM9E и т.д.), правильно выбрать библиотеку, указать симулятору подходящий файл описания sfr (.ddf).

    --- Выбираем Processor Mode Arm Или Thumb

     

    4) Project -> Options -> С/С++ Compiler

    4.1)вкладка Language

    --- В разделе Language галочка уже стоит где надо в зависимости от того, что мы выбрали в п.2. Можно переставиь ее на Automatic(extension based).

    4.2)вкладка Optimization

    --- Для начала оставляем Size Low или Size none, позволит легко отлаживаться. По мере возрастания опыта можно будет увеличить до максимума.

    4.3)вкладка List

    --- ставим галочку Output list file

    --- Ставим галочку Assembler mnemonics

     

    5) Project -> Options -> Assembler

    5.1) Вкладка List

    --- ставим галочку Output list file

     

    6) Project -> Options -> Linker

    6.1) Вкладка Output

    --- Если делаем проект для RAM оставляем все как есть, если для Flash - ставим галочку Allow C-SPY-specific output file и на вкладке Extra output ставим галочки Generate Extra output file и выбираем Output Format -> simple-code

    6.2) Вкладка List

    --- ставим галочку Generate linker listing

    6.3) Вкладка Config

    Копируем из папки примеров компилятора в папку проекта подходящий .xcl

    --- Link command file ставим галочку Override default, указываем $PROJ_DIR$\файл.xcl

    7) Project -> Options -> Debugger

    7.1) Вкладка Setup

    --- Выбираем Driver (Simulator/J-Link/Macraigor и т.д.)

    Копируем из папки примеров .mac в папку проекта

    --- Ставим галочку Use Macro File, указываем $PROJ_DIR$\файл.mac

    7.2) Если отлаживаемся в Flash: Вкладка Download

    --- Если отлаживаемся в Flash, ставим галочки Verify download, Use flash loader(s)

    --- Жмем Edit, в появившейся форме New..., в появившемся окне настроек ничего не трогая жмем OK., Жмем ОК в форме выбора загрузчиков.

    8) Если используем Wiggler, Project -> Options -> Macraigor

    --- Выбираем Wiggler в списке OCD interface device.

     

    Остальное можно не трогать.

     

    9) File->Save all.

     

    Собственно все. Проект создан. На всякий случай прикладываю .xcl и .mac для AT91SAM7. В .xcl надо правильно указать макс. адреса ОЗУ и флеши для конкретного кристалла - сейчас там указан минимум который есть в любом SAM7.

    xcl_mac.zip

  14. Компилятор ничего предоставлять не должен. При вызове Thumb-функции из режима ARM линкер подставляет вызов своего veneer-кода, который и осуществляет корректное переключение режима.
    Ну хорошо, может сойдемся на связке компилятор-линкер? У кого из них больше работы - детали реализации. В любом случае не программист.

    А на попытку описать функцию как обработчик прерывания в thumb ругатья должен таки компилятор. Как следствие ошибка отлавливается в процессе компиляции а не после запуска.

    Не будет - ничто не мешает писать обработчик в режиме Thumb, просто нужно помнить, что переход на вектор осуществяется в режиме ARM.

    В любом случае код, "принимающий" управление на векторе исключения должен быть arm. Дальше конечно - что пожелаете. Тут плавно переходим к первому абзацу :-)

    Ну что им сложно было сделать аппаратное наложение маски?????

    Эх, PIC'и вспоминаются :)

    Вот-вот :-(
  15. Неплохо помнить о переключении ARM/THUMB

    Ну, обычно об этом должен помнить компилятор.

    Обычно об этом должен помнить линкер. И автор программы, когда дело доходит до прерываний.

    Линкер-то да, но компилятор должен предоставить возможность выбрать либо универсальный переход (BX) если смена режима, либо более короткий и быстрый BL если смены нет. А на попытку описать функцию как обработчик прерывания в thumb ругатья должен таки компилятор. Как следствие ошибка отлавливается в процессе компиляции а не после запуска.

     

    Помнить о продвинутом контроллере прервываний (VIC/AIC etc.).

    Точнее об его полном отсутствии в ADuC и необходимости вручную накладывать маску на флаги при опознавании источника прерываний.

    Сколько производителей, столько и мнений :)

    Это точно. Но: 1) В исходном посте ечь шла про ADuC и 2) Ну что им сложно было сделать аппаратное наложение маски?????

     

    Компилятор сам помнит какой регистр периферии 8 бит а какой 32 или 16, и сам подставляет нужную команду (не ошибаясь).

    Компилятор знать ничего не знает ни о перифирии, ни о размерности ее регистров.

    Почему? Конечно с его точки зрения это обычные sfr, но они уже описаны, причем в описании указан размер. Ошибка в описании если и есть то после первого же вылавливания исправляется и не возникает совершенно случайно в одном из n обращений к этому sfr. В отличие от писания на ассемблере где размер sfr надо помнить программисту, а творческий простор для неправильных обращений к sfr практически не ограничен :-)

     

    Для Bird2: Им еще в ADuC удалось сделать совершенно чудовищные sfr портов ввода-вывода, поэтому во избежание дурацких недоразумений очень удобно "дерганье ног" делать сразу через макросы (спасибо Аскольду Волкову за идею). Внутри файла комментарии как использовать. Сам пользуюсь уже 6 лет.

    ascold.zip

  16. Необходимо загрузить константу в Z регистр и косвенно вызвать подпрограмму.
    Для этого не нужен inline-asm

         ((void (*)(void))0x104)();
    
         25              ((void (*)(void))0x104)();
       \   00000000   E0E4               LDI     R30, 4
       \   00000002   E0F1               LDI     R31, 1
       \   00000004   9509               ICALL

    Только не забываем, что у IAR адреса байтовые, а в Z надо грузить адрес слова, т.е. байтовый пополам.

    А с параметрами inline-asm не работает. Более того, умный оптимизатор глубоко плюет на asm. Например, такой пример:

     static void func(uint8_t param)  // параметр должен передаваться в R16, static чтобы заинлайнить
    {
         asm("STS     TestCell, R16");
    }  
    
    void main()
    {
         func(123);
    }

    Тут оптимизатор видит, что в func памаметр не используется и в main его просто не загружает в r16 перед асм-вставкой. Они так и пишут в доке - инлайн-асм можно сказать что не получился, на него "забили", поэтому пользуйте либо имеющиеся intrinsic -функции, либо пишите всю функцию на асме и прилинковывайте к проекту.

  17. Как вариант в защищаемую фузами область FLASH (максимальная бутовая) укладывается часть функций и работа с ними по фиксированным адресам. Т.е. для специально спрятанных функций заводим сегменты в xcl, замапливаем обычные, но нужные функции туда pragma location, ну и вроде должно помочь...
    Так оно прекрасно работает (сами так делаем), но как я понял автор не имеет возможности лично прошить в конечный проц эту область и защитить ее фузами.
  18. Неплохо помнить о переключении ARM/THUMB

    Ну, обычно об этом должен помнить компилятор.

    Помнить о продвинутом контроллере прервываний (VIC/AIC etc.).
    Точнее об его полном отсутствии в ADuC и необходимости вручную накладывать маску на флаги при опознавании источника прерываний.

    Подход к периферии непривычен с точки зрения человека привыкшего к 8-биткам.
    Да нет там ничего особо непривычного. Компилятор сам помнит какой регистр периферии 8 бит а какой 32 или 16, и сам подставляет нужную команду (не ошибаясь).

     

    Про ОС - вышел релиз scmRTOS 3.0beta, там есть порт под ADuC, но, к сожалению, пока только для IAR.

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

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

    Тут трудно не согласиться, хотя для С++ функии отличающиеся типом и/или количеством параметров суть есть разные функции. Так что 100% гарантии давать не должно. Правда не знаю, относится ли это к функциям с квалификатором extern "C"
  20. Например я постоянно использую свое определение extern "C" __low_level_init(), но при этом никакой дополнительный хидер в main.cpp не включаю.

    __low_level_init() не есть библиотечная функция а просто IARовский прибамбас, посему вполне логично

    для него отсутствует прототип в библиотечных хидерах и IAR выдает просто болванку в которой все в одном флаконе с хидером. Описывать-же "свои" прототипы для стандартных библиотечных функций есть безобразие.

    Прототипы = объявления, да. Но речь шла об определении = теле функции. Если по имени, параметрам и типу возвращаемого значения функция совпадает с библиотечной, то не вижу причины перед ее определением включать хидер с объявлением. Например в таком предельном случае когда под определение этой функции выделен отдельный исходный файл.
  21. Оказывается 64тый от 256 все же отличается... Хоть и стоят в одной линейке.

    В 4 раза, если сравнивать размер RAM ;) А где RAM, там и стек.

    Только причем здесь CStartup? Он пользуется размерами сегментов, а сегменты (и их размеры) определены в .xcl Никогда не было необходимости подключать к проекту Cstartup.s79 - всегда хватало библиотечного. Кто-нибудь объяснит, зачем это делается в примерах?
  22. А что производители компиляторов уже начали писать библиотечные хидеры без extern "С" :)?

    Хотя конечно если не включить готовый хидер и наплевать на вопли об отсутствии прототипа, то добиться вышеописанного можно :(

    В некоторых случаях совсем необязательно включать хидер, ибо определение функции является и объявлением. Например я постоянно использую свое определение extern "C" __low_level_init(), но при этом никакой дополнительный хидер в main.cpp не включаю.
  23. С третьего раза я понял о чем вы говорите :) , буду разбираться с компилятором
    Если файл в котором будете определять функцию компилится в режиме C++, то надо функцию объявить с extern "C", иначе она получит другое "С++ное" внутреннее имя и, соответственно, не заменит библиотечную.