Igor68 0 19 марта, 2007 Опубликовано 19 марта, 2007 (изменено) · Жалоба У меня вопрос: 1) при выполнении __swi возможна ли работа простых __int ? 2) Если невозможна, то как сбросить влаг программного прерывания (__swi), не выходя из самой функции __swi, чтобы разрешить INTы во время её выполнения ? Или что можно ещё сделать. /проверять флаги __INTов нежелательно/ / __fiq не предлагать, он уже занят / (ADuC7024 и AT91SAM7S256) с уважением PARAMON ! Изменено 19 марта, 2007 пользователем Paramon Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kichkine 0 19 марта, 2007 Опубликовано 19 марта, 2007 (изменено) · Жалоба 1) при выполнении __swi возможна ли работа простых __int ? Из ARM Architecture Reference Manual, инструкция SWI: if CondidtionPassed(<cond>) then R14_svc = address of SWI instruction + 4 SPSR_svc = CPSR CPSR[5:0] = 0b010011; enter Supervisor mode CPSR[7] = 1; disable IRQ -- прерывания запрещены PC = 0x08 2) Если невозможна, то как сбросить влаг программного прерывания (__swi), не выходя из самой функции __swi, чтобы разрешить INTы во время её выполнения ? Или что можно ещё сделать. Прерывания запрещены и процессор в режиме Supervisor. Но ведь ничто не мешает нам разрешить прерывания в рег. CPSR (бит I). Изменено 19 марта, 2007 пользователем kichkine Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Igor68 0 19 марта, 2007 Опубликовано 19 марта, 2007 · Жалоба Из ARM Architecture Reference Manual, инструкция SWI: if CondidtionPassed(<cond>) then R14_svc = address of SWI instruction + 4 SPSR_svc = CPSR CPSR[5:0] = 0b010011; enter Supervisor mode CPSR[7] = 1; disable IRQ -- прерывания запрещены PC = 0x08 Прерывания запрещены и процессор в режиме Supervisor. Но ведь ничто не мешает нам разрешить прерывания в рег. CPSR (бит I). Спасибо огромное kichkine! Хорошо бы ещё незапутаться с вызовом __SWI из разных мест (приложение под ARTX) /будем смотреть и ставить флаг выполнения самого __swi/ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iShustov 0 20 марта, 2007 Опубликовано 20 марта, 2007 · Жалоба Из ARM Architecture Reference Manual, инструкция SWI: Прерывания запрещены и процессор в режиме Supervisor. Но ведь ничто не мешает нам разрешить прерывания в рег. CPSR (бит I). А как бы красиво оформить обратную ситуацию - в прерывании возникает необходимость запустить при выходе из прерывания "фоновую задачу"? Фоновой задаче назначить какой-нибудь вектор и выставлять соответствующий бит в VICSoftInt? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Igor68 0 20 марта, 2007 Опубликовано 20 марта, 2007 · Жалоба А как бы красиво оформить обратную ситуацию - в прерывании возникает необходимость запустить при выходе из прерывания "фоновую задачу"? Фоновой задаче назначить какой-нибудь вектор и выставлять соответствующий бит в VICSoftInt? Извините не понял высказывания. Мне требуется такая ситуация: __swi может быть очень длинным с ветвлением, при его выполнении итак должны работать фоновые задачи (функции). При этом должны работать таймеры!!! и другие устр-ва по прерываниям т.е __int - работает,а __fiq - работает всегда(выбор из таблицы в ШИМ). (Из супервизора НАДО выйти, но непрекращая __swi). из __swi(он у меня вектор) выходить как из обычной вызываемой ф-и. вход в __swi(он содержит набор своих векторов на каждую процедуру), из любого(даже загружаемого модуля), ну почти как в BIOS /вот было бы здорово/ С уважением PARAMON! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iShustov 0 20 марта, 2007 Опубликовано 20 марта, 2007 · Жалоба Извините не понял высказывания. С уважением PARAMON! Да это не относится к вашему вопросу, просто в тему вложенных прерываний. В упрощенном варианте - хочу из обработчика прерывания irq при выходе попадать в обработчик софтового прерывания (который разрешает вложенность прерываний) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 20 марта, 2007 Опубликовано 20 марта, 2007 · Жалоба В упрощенном варианте - хочу из обработчика прерывания irq при выходе попадать в обработчик софтового прерывания (который разрешает вложенность прерываний) #define CONTEXT_SWITCH_INT VIC_SW #define RaiseContextSwitch() \ do \ { \ VICSoftInt = (1<<CONTEXT_SWITCH_INT); \ VICIntEnable = (1<<CONTEXT_SWITCH_INT); \ } \ while (0) // set flag and enable interrupt #endif Оно? (Из супервизора НАДО выйти, но непрекращая __swi).Вы путаетесь в понятиях. Вам нужно переключить режим процессора из Supervisor в System. Как это сделать - трудно посоветовать, не зная каким компилятором вы пользуетесь. При этом можно одновременно разрешить прерывания. вход в __swi(он содержит набор своих векторов на каждую процедуру), из любого(даже загружаемого модуля), ну почти как в BIOSВ IAR это примерно так и реализовано. Ветвление по номеру swi компилятор выполняет сам. Ищите в описании компилятора по ключевому слову swiю Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
bzx 0 20 марта, 2007 Опубликовано 20 марта, 2007 · Жалоба Да это не относится к вашему вопросу, просто в тему вложенных прерываний. В упрощенном варианте - хочу из обработчика прерывания irq при выходе попадать в обработчик софтового прерывания (который разрешает вложенность прерываний) Компилятор не важен. Это делается через стек. При выходе из irq в стек заносишь указатель, на который хочешь попасть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Igor68 0 21 марта, 2007 Опубликовано 21 марта, 2007 · Жалоба #define CONTEXT_SWITCH_INT VIC_SW #define RaiseContextSwitch() \ do \ { \ VICSoftInt = (1<<CONTEXT_SWITCH_INT); \ VICIntEnable = (1<<CONTEXT_SWITCH_INT); \ } \ while (0) // set flag and enable interrupt #endif Оно? Вы путаетесь в понятиях. Вам нужно переключить режим процессора из Supervisor в System. Как это сделать - трудно посоветовать, не зная каким компилятором вы пользуетесь. При этом можно одновременно разрешить прерывания. В IAR это примерно так и реализовано. Ветвление по номеру swi компилятор выполняет сам. Ищите в описании компилятора по ключевому слову swiю (Из супервизора НАДО выйти, но непрекращая __swi). - это просто неправильная фраза, никто никуда сейчас не выходит - мы еще работаем. Извините. /работаю с Keil uVision3 V3.20a с родным комполятором/ Надо испытать под ARTX: /ARTX config/ (кусок) /*--------------------------- os_switch_tasks -------------------------------*/ void os_switch_tasks (P_TCB p_new) __swi (0) { /* Switch to next task (identified by "p_new"). Saving old and restoring */ /* new context is written in assembly (module: Swi_ARTX.s) */ /////// тут что-то типа: t_Command=os_tsk_create(Command,0); //что-то нужное /////// os_runtask->full_ctx = FALSE; os_runtask = p_new; p_new->state = RUNNING; #if (OS_ROBIN == 1) os_tsk_robin = p_new; #endif /* Tsk_Unlock */ OS_UNLOCK(); } /* end of os_switch_tasks */ //то самое нужное void Command(void) __task { .... //какой - то код } при этом не трогать никакие переключения режимов ядра. и про разрешение прерывания забыь? сработает? А как бы красиво оформить обратную ситуацию - в прерывании возникает необходимость запустить при выходе из прерывания "фоновую задачу"? -вы наверное это имели ввиду? Извините если что не так! с уважением PARAMON! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 21 марта, 2007 Опубликовано 21 марта, 2007 · Жалоба Надо испытать под ARTX: ... при этом не трогать никакие переключения режимов ядра. и про разрешение прерывания забыь? сработает? Так и не понял чего вы хотели выразить этими фразами и причем тут приведенный вами кусок кода. А как бы красиво оформить обратную ситуацию - в прерывании возникает необходимость запустить при выходе из прерывания "фоновую задачу"? -вы наверное это имели ввиду?Что я имел ввиду, то я и отцитировал:В упрощенном варианте - хочу из обработчика прерывания irq при выходе попадать в обработчик софтового прерывания (который разрешает вложенность прерываний) P.S. Давайте вы попробуете спокойно, обстоятельно, подробно (как для первокласника) и без восклицаний изложить: что вы хотите получить, что вы для этого пытаетесь (если) сделать и что не получается/не понятно. P.P.S. Старайтесь оставлять в цитатах только самое необходимое для понимания ваших ответов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Igor68 0 21 марта, 2007 Опубликовано 21 марта, 2007 · Жалоба Так и не понял чего вы хотели выразить этими фразами и причем тут приведенный вами кусок кода. Что я имел ввиду, то я и отцитировал: P.S. Давайте вы попробуете спокойно, обстоятельно, подробно (как для первокласника) и без восклицаний изложить: что вы хотите получить, что вы для этого пытаетесь (если) сделать и что не получается/не понятно. P.P.S. Старайтесь оставлять в цитатах только самое необходимое для понимания ваших ответов. требуется собрать макет устройства, пока на базе макеток: A) AT91SAM7256 (USB,COM,SD/MMC) B) ADuC7024 (ADC,PWM) с ADuC всё решено. с AT91SAM7 сделать возможным загрузку короткого кода из SD/MMC в RAM и его запуск. Проблемы: 1) работа с SD/MMS (файловая система) - решаю сейчас.(нужно компактное решение) 2) организация вызова необходимых функций из флеш AT91SAM7,запущенным в RAM кодом. При всём этом обмен между AT91 и ADuC должен быть стабильным. За основу выбран ARTX/Keil/ Буду рад советам. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 21 марта, 2007 Опубликовано 21 марта, 2007 · Жалоба Ага, теперь понятнее. 1) работа с SD/MMS (файловая система) - решаю сейчас.(нужно компактное решение)Поищите по форуму. Я искал недавно и понял что вариантов немного: EFSL, uC/FS. Я смотрел еще вот это: FAT File System Module. С виду довольно компактно, но функции нижнего уровня придется писать самому. Мне за день удалось прикрутить к AT45DB321, вроде даже заработало, но глубоко не проверял. Можете посмотреть как вариант (там есть один баг, должно быть ST_WORD(tbl+510, 0xAA55); вместо *(WORD*)(tbl+510) = 0xAA55;, автору я уже отписал). 2) организация вызова необходимых функций из флеш AT91SAM7,запущенным в RAM кодом. При всём этом обмен между AT91 и ADuC должен быть стабильным. Тут видятся два пути: первый - swi, но каждая swi-функция в самом начале должна переключать процессор обратно в system mode и разрешать прерывания, а в самом конце делать обратное переключение. Как оформляются swi в Кейле я не знаю (пользую IAR), но в документации должно быть. второй путь: зачем swi? Почему бы в фиксированной области флеш не разместить таблицу указателей на функции и вызывать функции через эту таблицу? прерывания запрещаться не будут вообще. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Igor68 0 21 марта, 2007 Опубликовано 21 марта, 2007 · Жалоба Ага, теперь понятнее. Поищите по форуму. Я искал недавно и понял что вариантов немного: EFSL, uC/FS. Я смотрел еще вот это: FAT File System Module. С виду довольно компактно, но функции нижнего уровня придется писать самому. Мне за день удалось прикрутить к AT45DB321, вроде даже заработало, но глубоко не проверял. Можете посмотреть как вариант (там есть один баг, должно быть ST_WORD(tbl+510, 0xAA55); вместо *(WORD*)(tbl+510) = 0xAA55;, автору я уже отписал). Тут видятся два пути: первый - swi, но каждая swi-функция в самом начале должна переключать процессор обратно в system mode и разрешать прерывания, а в самом конце делать обратное переключение. Как оформляются swi в Кейле я не знаю (пользую IAR), но в документации должно быть. второй путь: зачем swi? Почему бы в фиксированной области флеш не разместить таблицу указателей на функции и вызывать функции через эту таблицу? прерывания запрещаться не будут вообще. По поводу файловой системы - понятно. Сейчас уже реализую. Я был по этой ссылке. Баг на определение системных секторов? Незнал ! Большое спасибо! По поводу __swi - мне казалось удобнее и универсальнее. Код который приведён мной - НЕВЕРНЫЙ! Наткнулся на пример, правда для LPC21xx. Там есть формирование записей таблиц для этого. Пока непонятно.Вечером буду разбираться. Если это будет то,что надо - выложу, иначе последую вашему примеру! С уважением PARAMON! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 21 марта, 2007 Опубликовано 21 марта, 2007 · Жалоба Я был по этой ссылке. Баг на определение системных секторов? Незнал ! Большое спасибо!В функции mkfs. Он проявляется только на процессорах которые умеют обращаться по указателю только на выровненные адреса (ARM в частности). По поводу __swi - мне казалось удобнее и универсальнее.Но учтите, что на ветвление по номеру swi тоже расходуется время и еще неизвестно что будет быстрее - доступ через таблицу или swi. А с учетом разрешения вложенных прерываний в режиме supervisor - точно быстрее будет через таблицу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Igor68 0 22 марта, 2007 Опубликовано 22 марта, 2007 (изменено) · Жалоба В функции mkfs. Он проявляется только на процессорах которые умеют обращаться по указателю только на выровненные адреса (ARM в частности). Но учтите, что на ветвление по номеру swi тоже расходуется время и еще неизвестно что будет быстрее - доступ через таблицу или swi. А с учетом разрешения вложенных прерываний в режиме supervisor - точно быстрее будет через таблицу. вчера испытывал пример с таблицами - не вышло. получилось следующее: //пример. даже не пример а проба #include <ARTX.H> OS_TID t_Func1; // OS_TID t_Func2; // OS_TID t_Func3; unsigned int counter; int par1; int par2; void Func2 (void) __task; void Func3 (void) __task; void SWI_Handler(int set) __swi(8) //set - потом будет номером ф-ии //__swi работает короткое время, только для вызова { if(set==1) par1++; if((par1 > par2)) { t_Func2 = os_tsk_create (Func3,2); // start task 2 } else if(par1==0xFFFFFFFF) { par1=0; par2=0; }; } // void Func3(void) __task { if(par2>=par1) os_tsk_delete_self(); //удаление ф-ии "Func3" while(1) { os_itv_set(50); os_itv_wait(); }; } // * Task 1 void Func1 (void) __task { t_Func1 = os_tsk_self (); t_Func2 = os_tsk_create (Func2,2); while (1) { SWI_Handler(1); os_dly_wait (1); }; } // * Task 2 void Func2 (void) __task { while (1) { SWI_Handler(2); os_dly_wait (5); } } void init(void) __task { t_Func1=os_tsk_create(Func1,0); os_itv_set(5); os_itv_wait(); os_tsk_delete_self(); //удаление модуля инициализации "init" } void main(void) { os_sys_init(init); //инициализация модулей } через SWI_Handler(2); вызывается ф-я Func3, причём много раз. после свего исполнения каждый экземпляр удаляется. Думаю то, что мне надо. Можно с любой точки вызвать свой экземпляр. под ARTX они работают параллельно. Пока незнаю как быть с передачей параметров, без глобальных описаний??????? Спасибо вам всем огромное, особенноо вам Сергей Борщ !!! Пока я это всё непереварю, навряд ли осмелюсь задавать вопросы. С уважением PARAMON!!! Изменено 22 марта, 2007 пользователем Paramon Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться