|
Как глобально запретить прерывания |
|
|
|
Aug 21 2006, 09:17
|
Дух погибшего транзистора
Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288
|
Столкнулся со следующей неувязкой. На время записи во флеш мне очень желательно запретить выполнение прерываний. Я даже догадался что для запрета прерываний нужно "всего лишь" установить биты I и F в регистре CPSR. Написал следующий код. Код INT_DISABLE_MASK EQU 0x000000C0
EXPORT disable_interrupts EXPORT enable_interrupts
ARM AREA FASTCODE, CODE enable_interrupts ;Çàïèñàòü 0 â áèòû I è F ðåãèñòðà CPSR, ÷òîáû çàïðåòèòü ïðåðûâàíèÿ mrs r0, cpsr mvn r1, #INT_DISABLE_MASK and r0, r0, r1 msr cpsr_c, r0 bx lr
disable_interrupts ;Çàïèñàòü 1 â áèòû I è F ðåãèñòðà CPSR, ÷òîáû çàïðåòèòü ïðåðûâàíèÿ mrs r0, cpsr orr r0, r0, #INT_DISABLE_MASK msr cpsr_c, r0 bx lr END Но с помощью отладчика обнаружил, что он не работает, то есть значение регистра cpsr не меняется. Вызаваются эти функции в свою очередь из функции находящейся в рам и помеченной с помощью #pragma arm, то есть некорректный переход из АРМ в thumb не является причиной. Начал копать в чем же дело и наткнулся на вот такое Цитата In user mode, only the condition flags of the CPSR (CPSR_f) can be changed. In other modes, the entire CPSR can be changed. То есть собственно правильно что код не работает. Отсюда вопрос как же корректно запретить - установить разрешение прерываний IRQ и FIQ? Только как-то через AIC?
Сообщение отредактировал SpiritDance - Aug 21 2006, 09:18
--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
|
|
|
|
|
Aug 21 2006, 12:05
|
Участник
Группа: Свой
Сообщений: 55
Регистрация: 25-08-05
Из: Украина, Харьков
Пользователь №: 7 954
|
Цитата(SpiritDance @ Aug 21 2006, 14:46) ...из user mode в system mode с помощью команды перейти невозможно. Поправьте если я ошибаюсь. Поправляю. Из user mode можно перейти в swi mode (инструкция swi), а из swi можно и в System, хотя swi тоже привелегированный режим
Сообщение отредактировал gmax - Aug 21 2006, 12:06
|
|
|
|
|
Aug 21 2006, 12:05
|
Гуру
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448
|
Цитата(SpiritDance @ Aug 21 2006, 15:46) Все. Процессор в систем с самого начала Только не в system, а в supervisor. Цитата(SpiritDance @ Aug 21 2006, 15:46) так понимаю что для однозадачных прошивок это даже более правильно чем user mode? Однозначно. Во многих процессорах даже доступ к периферии из user mode закрыт. Оставьте процессор в supervisor. Цитата(SpiritDance @ Aug 21 2006, 15:46) Насколько я понимаю вышеприведенную цитату из user mode в system mode с помощью команды перейти невозможно. Поправьте если я ошибаюсь. Переход возможен только через исключения - IRQ, FIQ, SWI и т.п.
|
|
|
|
|
Aug 21 2006, 12:17
|
Дух погибшего транзистора
Группа: Свой
Сообщений: 877
Регистрация: 6-09-05
Из: Москва
Пользователь №: 8 288
|
Цитата(aaarrr @ Aug 21 2006, 16:05) Только не в system, а в supervisor. Почему? В смысле почему оставлять в супервизоре? Не грамотней переключится в систем? Или тут уже все равно? klen, gmax Нет, преключатся через swi + вызывать исключение перед прошивкой флеш мне не хочется. К тому же как грамотно переключится? По идее при выходе и обработчика процессор достанет из spsr старое значение и процессор снова окажется в user mode. Запускать перешивку страницы флешь через swi? Это не то чтобы долго, это как-то криво на мой взгляд. Кстати. кто нибудь пробовал сишную функцию запихнуть в swi?
Сообщение отредактировал SpiritDance - Aug 21 2006, 12:38
--------------------
Yes, there are two paths you can go by But in the long run Theres still time to change the road youre on.
|
|
|
|
|
Aug 21 2006, 13:14
|
бессмертным стать можно тремя способами
Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912
|
Цитата(SpiritDance @ Aug 21 2006, 16:17) .. кто нибудь пробовал сишную функцию запихнуть в swi? Я делал. Инициализирую таблицу адресов системных функций. При вызове swi, которая у меня выглядит #define SysCall_0() asm volatile ("swi #0") #define SysCall_1() asm volatile ("swi #1") #define SysCall_2() asm volatile ("swi #2") #define SysCall_3() asm volatile ("swi #3") ..... в вызывающей функции например SysCall_0(); далее обработчик програмго прерывания определяет адрес системной функции и вызывает ее, даллее возвращает управление Код #include "SwiHandlers.h"
//массив адресов системных функций volatile SWIHANDLER SwiHandlers[SWI_HANDLERS]; volatile TSwiData SwiData; //----------------------------------------------- void swiHandler_0() { } //----------------------------------------------- void swiHandler_1() { // } //----------------------------------------------- void swiHandler_2() { // } //----------------------------------------------- void swiHandler_3() { // }
//----------------------------------------------- void InitSWIHandlers() { SwiHandlers[0] = swiHandler_0; SwiHandlers[1] = swiHandler_1; SwiHandlers[2] = swiHandler_2; SwiHandlers[3] = swiHandler_3; }
void Swi_Handler(void) __attribute__((interrupt("SWI"))); void Swi_Handler(void) { // вызов системной функции asm volatile ( "mov r0 , r14 ; \ sub r0 , #0x4 ; \ ldr r0 , [r0] ; \ bic r0 , #0xff000000; \ mov r1 , #0x4 ; \ mul r0 , r1 ; \ mov r1 , %0 ; \ add r0 , r1 ; \ ldr r0 , [r0] ; \ mov lr, pc ;\ bx r0" : : "r"(SwiHandlers) : "r0", "r1" ); } код
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|