Dimmy 0 21 августа, 2007 Опубликовано 21 августа, 2007 · Жалоба Господа! Помогите разобраться. С АРМ - в начале пути. Происходят непонятки с прерываниями. Используемое оборудование: IAR 4.41 + H-JTAG V0.4.4 + Wiggler В качестве основы приложения взял пример AT91SAM7X-Getting Started. Происходит слелующее. При отработке кода cstartup.s79 в момент инициализации стека для режима SUPERVISOR на последней строчке (mov r13, r0) программа "улетает" на default-обработчик прерывания IRQ, где, соответственно, и остается. #define TOP_OF_MEMORY (AT91C_ISRAM + AT91C_ISRAM_SIZE) #define IRQ_STACK_SIZE (3*8*4) ; 3 words to be saved per interrupt priority level #define ARM_MODE_IRQ 0x12 #define ARM_MODE_SVC 0x13 #define I_BIT 0x80 #define F_BIT 0x40 ..... ;- Retrieve end of RAM address EXTERN lowlevel_init ldr r13,=TOP_OF_MEMORY ;- Temporary stack in internal RAM for Low Level Init execution ldr r0,=lowlevel_init mov lr, pc bx r0 ;- Branch on C function (with interworking) ;------------------------------------------------------------------------------ ;- Setup the stack for each mode ;------------------------------------------------------------------------------ ldr r0, =TOP_OF_MEMORY ;- Set up Interrupt Mode and set IRQ Mode Stack msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT mov r13, r0 ; Init stack IRQ sub r0, r0, #IRQ_STACK_SIZE msr CPSR_c, #ARM_MODE_SVC | F_BIT mov r13, r0 вот код процедуры lowlevel_init: void lowlevel_init(void){ unsigned char i = 0; // EFC Init AT91C_BASE_MC->MC_FMR = AT91C_MC_FWS_1FWS; // 1 Wait State to work at 48MHz // Init PMC Step 1. Enable Main Oscillator AT91C_BASE_PMC->PMC_MOR = (((AT91C_CKGR_OSCOUNT & (0x40 << 8)) | AT91C_CKGR_MOSCEN)); // Wait Main Oscillator stabilization while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)); // Init PMC Step 2. AT91C_BASE_PMC->PMC_PLLR = AT91C_CKGR_USBDIV_1 | AT91C_CKGR_OUT_0 | (16 << 8) | (AT91C_CKGR_MUL & (72 << 16)) | (AT91C_CKGR_DIV & 14); // Wait for PLL stabilization while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCK)); // Wait until the master clock is established for the case we already // turn on the PLL while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); // Init PMC Step 3. AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK_2; // Wait until the master clock is established while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLL_CLK; // Wait until the master clock is established while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); //инициализация AIC AT91C_BASE_AIC->AIC_SVR[0] = (int) default_fiq_handler; for (i = 1; i < 31; i++) { AT91C_BASE_AIC->AIC_SVR[i] = (int) default_irq_handler; } AT91C_BASE_AIC->AIC_SPU = (unsigned int) default_spurious_handler; // Perform 8 IT acknoledge (write any value in EOICR) for (i = 0; i < 8; i++) { AT91C_BASE_AIC->AIC_EOICR = 0; } // Enable the Debug mode AT91C_BASE_AIC->AIC_DCR = AT91C_AIC_DCR_PROT; // Disable Watchdog AT91C_BASE_WDTC->WDTC_WDMR = AT91C_WDTC_WDDIS; } В симуляторе все работает нормально. Перед выполнением команды [mov r13, r0] состояние AIC в дебаггере в режиме СИМУЛЯТОА следующее: AIC_SVR = 0x00000315 AIC_SPU = 0x00000305 AIC_DCR = 0x00000001 остальные - 0x00000000 Перед выполнением команды [mov r13, r0] состояние AIC в дебаггере в режиме RDI + H-JTAG следующее: AIC_SVR = 0x00000315 AIR_IVR = 0x00000325 AIR_FVR = 0x00000305 AIR_IPR = 0x00000002 AIR_IMR = 0x00000006 AIR_CISR = 0x00000002 AIC_SPU = 0x00000305 AIC_DCR = 0x00000001 НО: 1. При отключенном wiggler'е при пересбросе питания система работает нормально! О чем сужу по поведению светодиодов. 2. Один раз из 100 в дебаггере все-таки добираюсь до точки main Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexBoy 0 21 августа, 2007 Опубликовано 21 августа, 2007 · Жалоба 1. Стек желательно инициализировать до вызова lowlevel_init 2. Выключайте все прерывания: msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT И включайте после входа в main 3. При инициализации контроллера прерываний перед строкой: // Perform 8 IT acknoledge (write any value in EOICR) добавить: AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFFUL; AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFFUL; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dimmy 0 21 августа, 2007 Опубликовано 21 августа, 2007 · Жалоба 1. Стек желательно инициализировать до вызова lowlevel_init Ну, стек (временный) здесь инициализируется в [ldr r13,=TOP_OF_MEMORY] 2. Выключайте все прерывания: msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT И включайте после входа в main Это делать пытался. А вот РЕАЛЬНО ПОМОГЛО третье!!!: 3. При инициализации контроллера прерываний перед строкой: // Perform 8 IT acknoledge (write any value in EOICR) добавить: AT91C_BASE_AIC->AIC_IDCR = 0xFFFFFFFFUL; AT91C_BASE_AIC->AIC_ICCR = 0xFFFFFFFFUL; Спасибо! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 24 ноября, 2008 Опубликовано 24 ноября, 2008 (изменено) · Жалоба Всем добрый день! Решил поднять тему ибо прерывания достали уже :( Используется следующее оборудование: отладочная плата SAM7-P64, IAR 4.30A, Wiggler. Трабла в следующем: Сначала пытался написать свою програмку с прерыванием от таймера, но в режиме эмулятора (в RAM) они не срабатывают :(. Сначала долго парился по нужным векторам 0х18 и 0х1с записать ldr pc, [pc, #-0xf20] ; IRQ но потом таки получилось. Все равно не заходит в прерывание. Хотя все везде разрешено и в таймере самом и в AIC. В процессе работы сам таймер считает как-то хаотично. Выполняеш команды пошагово (STEP ITNO) , по идее таймер должен икриментировать свое значение на 1, а на самом деле там лабуда всякая после каждого такта вылетает. Причем после одного такого нажатия выставляется флаг в регистре AIC_IPR (регистр задержанных, отложенных прерываний). ППЦ просто. отрубил этот таймер и запустил с разрешением прерываний PIT (периодический интервальный таймер). Такая же хрень, но зато счет идет нормально, после каждого нажатия - инкремент. Прерывания разрешены, вектора прописаны, А когда счет доходит до того момента, когда должно сработать прерывание, то: Выставляется бит прерывания PITS Вместо того чтобы пойти на обработку прерывания, выставляется опять таки соответствующий флаг в AIC_IPR. Доходит до смешного, что я разрешаю прерывания ВСЕМ и всему в AIC, все вектора в регистрах AIC_SVR устанавливаю на одну программу обработчика прерываний, и плин, НИФИГА ! Запустил прогу - пример по прерываниям от атмеля, что лежит в "корне" IAR. Так там один раз всего увидел, как кристалл вышел на обработку прерывания от таймеров, да и то млин не как положено начал обработку (с самого начала подпрограммы), а с самого конца - фактически с последней строчки в этой подпрограмме. Более я ни разу не добился ни в пошаговом, ни в каком режиме выхода в прерывания. И комп перезагружал, и плату отладочную. Нифига. :( Зашить в ФЛЭШ пока не получается посредством Яра :( Незнаю какие настройки правильно выставить. Может во флэше будет все работать нормально ? Или это таки глюки вигглера и он не работает в прерываниях? Люди какой-то J-tag 4.0 совместно с вигглером юзают, может его надо, но кто это и с чем его едят? ЧТО ДЕЛАТЬ! ХЕЛП! у меня уже все сроки горят, а я до сих пор с прерываниями мучаюсь! :( Блин! Всю периферию акромя USB уже опробовал, а прерывания как не могу, так и не получается :( Поможите начинающему! Люди добрые! Изменено 24 ноября, 2008 пользователем Vinterman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 24 ноября, 2008 Опубликовано 24 ноября, 2008 · Жалоба Выхода два: 1. Не отлаживать прерывания под эмуляторм (ИМХО, лучший вариант) 2. Прочитать в мануале на AIC, как именно это делать правильно Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dron_Gus 2 24 ноября, 2008 Опубликовано 24 ноября, 2008 · Жалоба 3. ходя по шагам Вы не попадете в прерывание. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 24 ноября, 2008 Опубликовано 24 ноября, 2008 · Жалоба Выхода два: 1. Не отлаживать прерывания под эмуляторм (ИМХО, лучший вариант) 2. Прочитать в мануале на AIC, как именно это делать правильно 1)Не отлаживать в эмуляторе - плохо :( Не всегда видно ошибку, а когда эмулятор в железе делает все пошагово, то она всегда вылазиет. Да и тотальный контроль на первых парах не помешает. Отказаться сложно. 2) Прочитал, все по букварю, все как надо. Буду пробовать в флэш залить програмулинку. Похоже выбора узнать правду нет :) Вечером попробую. Завтра отпишусь ответом :) 3. ходя по шагам Вы не попадете в прерывание. В том то и дело что ни в пошаговом режиме ни в режиме запуска программы на постоянку, в режиме отладки через Jtag, ни в одно прерывание я более так и не попал, причем у "яровского" примера такая же канитель:( Ладно, пойду пробовать решать траблу. Попробую так же чере H-Jtag поработать, может он лучшее Wiggler-а? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 119 24 ноября, 2008 Опубликовано 24 ноября, 2008 · Жалоба В том то и дело что ни в пошаговом режиме ни в режиме запуска программы на постоянку, в режиме отладки через Jtag, ни в одно прерывание я более так и не попал, 1) Нажатие иконки "сброс" приводит к сбросу ядра, а не периферии (контроллер прерываний тоже периферия). Поэтому надо его "привести в чувство" записью в AIC_EOICR либо в программе после инициализации, либо при помощи макроса execUserReset() отладчика IAR. 2)Чтение некоторых из регистров периферии (даже отладчиком) приводит к изменению их значений и нарушению нормального функционирования программы. В контроллере прерываний это касается AIC_IVR. Поэтому если у вас открыто окно с регистрами периферии, то будут подобные чудеса. Уберите AIC_IVR из .ddf, если хотите наблюдать остальные регистры. 3) Когда вы исполняете программу пошагово, отладчик тормозит только ядро. Периферия продолжает работать. Поэтому вы и наблюдаете "случайные" значения в регистрах таймеров. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Dron_Gus 2 24 ноября, 2008 Опубликовано 24 ноября, 2008 · Жалоба Еще блок AIC имеет специальный режим отладки. Тогда чтение регистра AIC_IVR не влияет на функционирование. AT91C_BASE_AIC->AIC_DCR = AT91C_AIC_DCR_PROT; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 25 ноября, 2008 Опубликовано 25 ноября, 2008 · Жалоба 1) Нажатие иконки "сброс" приводит к сбросу ядра, а не периферии (контроллер прерываний тоже периферия). Поэтому надо его "привести в чувство" записью в AIC_EOICR либо в программе после инициализации, либо при помощи макроса execUserReset() отладчика IAR. Ок. - попробую 2)Чтение некоторых из регистров периферии (даже отладчиком) приводит к изменению их значений и нарушению нормального функционирования программы. В контроллере прерываний это касается AIC_IVR. Поэтому если у вас открыто окно с регистрами периферии, то будут подобные чудеса. Уберите AIC_IVR из .ddf, если хотите наблюдать остальные регистры. Блин, не отладчик, а конструктор какой-то. 3) Когда вы исполняете программу пошагово, отладчик тормозит только ядро. Периферия продолжает работать. Поэтому вы и наблюдаете "случайные" значения в регистрах таймеров. Вкрадывались такие подозрения, теперь все подтвердилось. А тактирование PIT тогда идет совместно с ядром. Тогда внимание вопрос! :) Нафига спрашивается тогда нужен ТАКОЙ внутрисхемный отладчик? Который ни прерывания нормально обработать не может из-за того что меняет регистры, ни млин таймер отладить немогёт :( А с остальной периферией такая же песня? Или там отладка нормальная? Я имею в виду USB и работу по прерываниям других протоколов? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 25 ноября, 2008 Опубликовано 25 ноября, 2008 · Жалоба Еще вопрос, где есть ветка про то как загрузить через USB с помощью самбы флэш память контроллера. Только чтоб новичку было все понятно :) ?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 26 ноября, 2008 Опубликовано 26 ноября, 2008 (изменено) · Жалоба Эньдя.... Ну и система отладки .... ППЦ! :) ЗАПУСТИЛ !!!! УРАААА!!!! Я таки запустил прерывания ! И IAR-овские и свои! :) Трабла была в том, что действительно нельзя смотреть регистр AIC_IVR... ЖЕСТЬ! Естественно в предыдущие свои попытки я никуда без него деться не мог.... Ну и запись в регистр конца прерывания AIC_EOICR оказалось так же необходимой, без нее прерывания тоже не работали. Запись в AIC_EOICR поставил сразу после всех инициализаций, перед началом основного тела программы. Обнаружились следующие глюки, по которым надо разобраться. нужон ХЕЛП! :) В моей программе отладчик входит в прерывания только в том случае, если я смотрю регистры того устройства, от которого жду прерывание. Т.е. если у меня запущен таймер, то когда кликаеш кнопку запуска программы "в постоянку"(запамятовал как она обзывается) в прерывание программа заходит всего один раз, а далее выполняется основное тело программы, даже если я ставлю курсор в обработчик прерывания и нажимаю кнопку запуска "выполнить до текущей позиции курсора", то контроллер в прерывания даже не заходит. А вот если я при этом просматриваю регистры таймера и делаю все те же операции, то в прерывания МК заходит. Пошагово все отрабатывается вроде нормально. В самом обработчике прерываний у меня прога меняет состояние светодиода- горит/негорит. И вот даже если я запускаю, просматривая при этом регистры таймера, то светодиод не моргает. Но когда останавливаю/запускаю программу, то состояние светодиода меняется в момент очередного запуска только. Тобиш программа получается заходит в прерывание всего один раз после того как я нажал на кнопку "запуска программы". В Главном примере от яра такой баг отстутствует. Там я тоже дописал прогу, чтобы при заходе в прерывание менялось состояние светодиода. В основном теле программы так же стоит код - меняющий состояние другого светодиода. И вот тут то все в точности до наоборот. Запускаеш программу (но тут уже не важно смотрю я регистр таймера или не смотрю) - мигает светодиод "прерываний", а основной программы моргнет раза 3-4 и остановится. Пошагово когда смотриш работу, то видно, что только программа вышла из прерывания и сразу же заходит в него обратно. (Хотя до этого же основное тело программы выполнялось параллельно с прерываниями). Правда один раз случилось чудо и программа заработала нормально после энного программного резета из окна дебугера, т.е. мигали и светодиод основной программы и светодиод прерывания. В чем может быть баг? В случае моей программы я использую чутка модифицированный асмовский файл cstartup того же примера яра, только lowinit процедуру я "убил" и вынес ее в другой-отдельный файл инициализации, где так же проходит инициализация нужной мне периферии. В обработчике прерываний между моим и яровским примером имеется следующее отличие в начале : AT91PS_TC TC_pt = AT91C_BASE_TC0; unsigned int dummy; //* Acknowledge interrupt status dummy = TC_pt->TC_SR; //* Suppress warning variable "dummy" was set but never used dummy = dummy; count_timer0_interrupt++; - что они этим хотели сделать ? Но в защиту програмки яра надо сказать, что я припоминаю, что у меня там 2 таймера работают. МОжет это они друг другу толком работать не дают.? Хотя с другой стороны время обработки прерываний много меньше, чем время вызова этих прерываний.... А вообще всем огромное спасибо за то что помогаете новичку !!!! :a14: :beer: Пробовал отладку и в РАМ и во ФЛЭШ и там и там отлаживается везде все одинаково :( Как теперь мне загрузить програмку в контроллер, чтобы она выполнялась на отладочной плате сразу после включения питания, автономно, не зависимо от дебугера ? А то у меня этот фокус так и не вышел. Подскажите правильные настройки для кристалла AT91SAM7S64 в IAR для Wiggler, чтобы во флэш залить для выполнения автономно.... Пробовал как советовал Сергей: 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 файла был выбран at91SAM7S64_NoRemap.xcl - стандартный яра а макросовый - SAM7.mac, так же стандартный от яра. Может там чего поменять так же необходимо? Или те настройки что я сделал - это только для дебуга во флэше? Но не автономная работа контроллера ? еще раз повторюсь - отладочная плата SAM7-P64 Изменено 26 ноября, 2008 пользователем Vinterman Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 26 ноября, 2008 Опубликовано 26 ноября, 2008 · Жалоба - что они этим хотели сделать ? Прочитать TC_SR для сброса флага прерывания. Судя по тому, что программа у Вас продолжает выполняться, а прерывание срабатывает один раз, настроено оно на срабатывание по фронту, что может подкинуть еще грабли в будущем. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vinterman 0 26 ноября, 2008 Опубликовано 26 ноября, 2008 · Жалоба Прочитать TC_SR для сброса флага прерывания. Судя по тому, что программа у Вас продолжает выполняться, а прерывание срабатывает один раз, настроено оно на срабатывание по фронту, что может подкинуть еще грабли в будущем. Гм. А чтоб от остальной периферии не получать "таких сюрпризов" - так же необходимо читать их регистры состояний, чтобы сбросить флаги прерываний? По поводу срабатывания прерывания по фронту - а разве это важно для внутренней периферии? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 26 ноября, 2008 Опубликовано 26 ноября, 2008 · Жалоба Гм. А чтоб от остальной периферии не получать "таких сюрпризов" - так же необходимо читать их регистры состояний, чтобы сбросить флаги прерываний? Чтобы не получать сюрпризов, прежде всего нужно читать документацию на соответствующий модуль :) Сброс может быть организован по-разному, в зависимости от модуля. По поводу срабатывания прерывания по фронту - а разве это важно для внутренней периферии? Важно, естественно: так Вы рискуете пропустить событие. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться