Перейти к содержанию
    

Вопрос по прерываниям

У меня вопрос:

1) при выполнении __swi возможна ли работа простых __int ?

2) Если невозможна, то как сбросить влаг программного прерывания (__swi), не выходя из самой функции __swi, чтобы разрешить INTы во время её выполнения ? Или что можно ещё сделать.

/проверять флаги __INTов нежелательно/

/ __fiq не предлагать, он уже занят /

 

(ADuC7024 и AT91SAM7S256)

 

с уважением PARAMON !

Изменено пользователем Paramon

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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).

Изменено пользователем kichkine

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из 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/

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Из ARM Architecture Reference Manual, инструкция SWI:

Прерывания запрещены и процессор в режиме Supervisor. Но ведь ничто не мешает нам разрешить прерывания в рег. CPSR (бит I).

 

А как бы красиво оформить обратную ситуацию - в прерывании возникает необходимость запустить при выходе из прерывания "фоновую задачу"? Фоновой задаче назначить какой-нибудь вектор и выставлять соответствующий бит в VICSoftInt?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как бы красиво оформить обратную ситуацию - в прерывании возникает необходимость запустить при выходе из прерывания "фоновую задачу"? Фоновой задаче назначить какой-нибудь вектор и выставлять соответствующий бит в VICSoftInt?

 

 

Извините не понял высказывания.

 

Мне требуется такая ситуация:

__swi может быть очень длинным с ветвлением, при его выполнении итак должны работать фоновые задачи (функции). При этом должны работать таймеры!!! и другие устр-ва по прерываниям т.е __int - работает,а __fiq - работает всегда(выбор из таблицы в ШИМ). (Из супервизора НАДО выйти, но непрекращая __swi). из __swi(он у меня вектор) выходить как из обычной вызываемой ф-и.

вход в __swi(он содержит набор своих векторов на каждую процедуру), из любого(даже загружаемого модуля), ну почти как в BIOS

/вот было бы здорово/

 

С уважением PARAMON!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Извините не понял высказывания.

 

С уважением PARAMON!

 

Да это не относится к вашему вопросу, просто в тему вложенных прерываний.

В упрощенном варианте - хочу из обработчика прерывания irq при выходе попадать в обработчик софтового прерывания (который разрешает вложенность прерываний)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В упрощенном варианте - хочу из обработчика прерывания 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ю

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да это не относится к вашему вопросу, просто в тему вложенных прерываний.

В упрощенном варианте - хочу из обработчика прерывания irq при выходе попадать в обработчик софтового прерывания (который разрешает вложенность прерываний)

Компилятор не важен. Это делается через стек. При выходе из 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

Оно?

 

Вы путаетесь в понятиях. Вам нужно переключить режим процессора из 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!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Надо испытать под ARTX:

...

при этом не трогать никакие переключения режимов ядра.

и про разрешение прерывания забыь?

сработает?

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

 

А как бы красиво оформить обратную ситуацию - в прерывании возникает необходимость запустить при выходе из прерывания "фоновую задачу"? -вы наверное это имели ввиду?
Что я имел ввиду, то я и отцитировал:
В упрощенном варианте - хочу из обработчика прерывания irq при выходе попадать в обработчик софтового прерывания (который разрешает вложенность прерываний)

P.S. Давайте вы попробуете спокойно, обстоятельно, подробно (как для первокласника) и без восклицаний изложить: что вы хотите получить, что вы для этого пытаетесь (если) сделать и что не получается/не понятно.

 

P.P.S. Старайтесь оставлять в цитатах только самое необходимое для понимания ваших ответов.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

Что я имел ввиду, то я и отцитировал:

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/

Буду рад советам.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ага, теперь понятнее.

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? Почему бы в фиксированной области флеш не разместить таблицу указателей на функции и вызывать функции через эту таблицу? прерывания запрещаться не будут вообще.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ага, теперь понятнее.

Поищите по форуму. Я искал недавно и понял что вариантов немного: 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!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я был по этой ссылке. Баг на определение системных секторов? Незнал ! Большое спасибо!
В функции mkfs. Он проявляется только на процессорах которые умеют обращаться по указателю только на выровненные адреса (ARM в частности).

 

 

По поводу __swi - мне казалось удобнее и универсальнее.
Но учтите, что на ветвление по номеру swi тоже расходуется время и еще неизвестно что будет быстрее - доступ через таблицу или swi. А с учетом разрешения вложенных прерываний в режиме supervisor - точно быстрее будет через таблицу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В функции 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!!!

Изменено пользователем Paramon

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...