реклама на сайте
подробности

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> TEventFlag.Signal_isr()
abutorin
сообщение Mar 8 2015, 21:06
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 3-09-12
Пользователь №: 73 374



Доброго времени суток.
Пробую использовать TEventFlag для оповещения основного цикла программы о завершении передачи даннных через SPI на STM32F103. В основном цикле очищаю флаг события, записываю данные в регистр, начинаю ждать событие. В обработчике прерывания взвожу флаг события методом signal_isr. Все работает, но остается одна проблема, процесс ожидающий этого события пробуждается только после следующего планирования процессов по системному таймеру, т.е. только примерно через 1мс. Мне казалось что такой задержки быть не должно. Я что-то делаю не так, или непонимаю как это должно работать. Подскажите кто чем может.
Go to the top of the page
 
+Quote Post
DmitryM
сообщение Mar 9 2015, 06:08
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840



Цитата(abutorin @ Mar 9 2015, 00:06) *
Доброго времени суток.
Пробую использовать TEventFlag для оповещения основного цикла программы о завершении передачи даннных через SPI на STM32F103. В основном цикле очищаю флаг события, записываю данные в регистр, начинаю ждать событие. В обработчике прерывания взвожу флаг события методом signal_isr. Все работает, но остается одна проблема, процесс ожидающий этого события пробуждается только после следующего планирования процессов по системному таймеру, т.е. только примерно через 1мс. Мне казалось что такой задержки быть не должно. Я что-то делаю не так, или непонимаю как это должно работать. Подскажите кто чем может.

Каким образом ожидаете событие? TEventFlag.wait()?
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 9 2015, 06:45
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(abutorin @ Mar 8 2015, 23:06) *
Подскажите кто чем может.
В обработчике прерывания создается объект класса TISRW_SS?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
abutorin
сообщение Mar 9 2015, 09:14
Сообщение #4


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 3-09-12
Пользователь №: 73 374



Цитата(Сергей Борщ @ Mar 9 2015, 09:45) *
В обработчике прерывания создается объект класса TISRW_SS?

Создается объект TISRW. Как я понял для Cortex-M3 можно использовать его.
Цитата
Каким образом ожидаете событие? TEventFlag.wait()?

Да, именно так.
Вот код:
Код
OS::TEventFlag SPIRE_Event;
uint8_t SPI_data;

OS_INTERRUPT void SPI2_IRQHandler(void)
{
    OS::TISRW TISRW_O;
    if (SPI_I2S_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
    {

        SPI_I2S_ClearITPendingBit(SPI2,SPI_I2S_IT_RXNE); //эта строка необязательна
        SPI_data = SPI_I2S_ReceiveData(SPI2);
        SPIRE_Event.signal_isr();
    }
}

int8_t ReadWrite(uint8_t data)
    {
        /* Loop while DR register in not emplty */
        while (SPI_I2S_GetFlagStatus(SPI2, SPI_I2S_FLAG_TXE) == RESET);

        /* Send byte through the SPI1 peripheral */
        SPI_I2S_SendData(SPI2, data);

        SPIRE_Event.wait();
        SPIRE_Event.clear();
        return SPI_data;
    }


Обработчик прерывания включен только для события RXNE.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 9 2015, 10:10
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(abutorin @ Mar 9 2015, 11:14) *
Создается объект TISRW. Как я понял для Cortex-M3 можно использовать его.
Все верно. Должно работать. В деструкторе этого объекта взводится запрос перывания PendSVC. После выхода из текущего прерывания должен вызваться обработчик PendSVC, в котором собственно и должна произойти перепланировка. Причем с системным тиком механизм идентичный, а симптомы один-в-один напоминают забытый TISRW.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
abutorin
сообщение Mar 9 2015, 11:49
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 40
Регистрация: 3-09-12
Пользователь №: 73 374



Цитата(Сергей Борщ @ Mar 9 2015, 13:10) *
Все верно. Должно работать. В деструкторе этого объекта взводится запрос перывания PendSVC. После выхода из текущего прерывания должен вызваться обработчик PendSVC, в котором собственно и должна произойти перепланировка. Причем с системным тиком механизм идентичный, а симптомы один-в-один напоминают забытый TISRW.


Похоже я где-то что-то напутал. Сейчас еще раз проверил, и все работает корректно. Видимо я не ту прошивку в железо залил. Спасибо за ответы.
Go to the top of the page
 
+Quote Post
SergNK
сообщение Jan 18 2017, 11:23
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991



Доброго дня!

Решил поднять тему вот таким вопросом.
Создаю ПО под Freescale M0+ с использованием scmRTOS. Четыре процесса:
CODE
typedef OS::process<OS::pr0, 512> TProc1;
typedef OS::process<OS::pr1, 512> TProc2;
typedef OS::process<OS::pr2, 512> I2C0_TASK;
typedef OS::process<OS::pr3, 1024> TBackgroundProc;

Есть прерывания:
CODE
TRTC rtc;
OS_INTERRUPT void RTC_second_Handler()
{
OS::TISRW TISRW_O;
rtc.RtcSecondIrqHandler();
OneSecondFlag.signal_isr();
}

Устанавливаю флаг в прерывании и ловлю его в процессе TProc1:
CODE
template<> OS_PROCESS void TProc1::exec()
{
for(;;)
{
OneSecondFlag.wait();
// while (!rtc.getNewSecondFlag());
led_bl.Cpl();
sleep(5);

}
}

Вылетает по HardFault. Если закомментировать OneSecondFlag.signal_isr(); то не вылетает. Ковыряюсь уже довольно долго. Накопал, что при восстановлении контекстов из критических секций происходит лишнее действие, которое затирает правильно восстановленный контекст.
Если использовать флаг rtc.getNewSecondFlag(), вызываемый из объекта, то всё ОК.
Куда копать?

Вдогонку:

Вылетает при выполнении кода:
CODE
bool OS::TEventFlag::wait(timeout_t timeout)
{
TCritSect cs;

if(Value) // if flag already signaled
{
Value = efOff; // clear flag
return true;
}
else
{
cur_proc_timeout() = timeout;

suspend(ProcessMap);

if(is_timeouted(ProcessMap))
return false; // waked up by timeout or by externals

cur_proc_timeout() = 0; <== вылетает при попытке выполнить эту инструкцию - обращение к несуществующей памяти
return true; // otherwise waked up by signal() or signal_isr()
}
}
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 18 2017, 12:04
Сообщение #8


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (SergNK @ Jan 18 2017, 13:23) *
Вылетает при выполнении кода:

Смотрим, во что выливается этот код:
CODE
Kernel.ProcessTable[Kernel.CurProcPriority]->Timeout = 0;
Давайте начнем с того, чему равен Kernel.CurProcPriority до вызова wait() и перед падением. Потом посмотрим, куда указывает ProcessTable[Kernel.CurProcPriority]. И дальше надо искать, кто портит одну из этих переменных.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SergNK
сообщение Jan 18 2017, 12:41
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991



Ща попробую

Контекст портится после suspend(ProcessMap);
Я поставил точку останова на if(is_timeouted(ProcessMap)), а там уже запорчено.
Я так понимаю: suspend останавливает процесс, а потом перепланировщик его возобновляет. И при восстановлении контекста что-то происходит.
Go to the top of the page
 
+Quote Post
SergNK
сообщение Jan 20 2017, 21:04
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991



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

Из-за большого объёма топика всё спрятал в прикреплённом файле.

Прикрепленный файл  Doc1.zip ( 1.64 мегабайт ) Кол-во скачиваний: 50
Go to the top of the page
 
+Quote Post
SergNK
сообщение Jan 22 2017, 20:39
Сообщение #11


Частый гость
**

Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991



Весь день просидел и пытался подобраться поближе к источнику проблемы. Точно не обнаружил, но у меня складывается впечатление, что происходит то, что написано в руководстве о планировщике и о нарушении целостности системы.

В связи с этим подскажите, как исследовать эту часть так, чтобы можно было в режиме реального времени обнаружить источник. Пошаговое прохождение не приводит к фатальному исходу. Можно ухитриться словить только хвост проблемы, да и то самый кончик. Я это выложил в виде скриншотов.

Когда-то код, связанный с перепланировкой, наверняка подвергался отладке, иначе в руководстве не уделяли подробному описанию проблемы, которая очень похожа на эту.
Либо как вариант использовать планировщик с прямой передачей управления.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jan 22 2017, 21:42
Сообщение #12


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Извините за банальность, но не пробовали ли вы выключить и снова включить увеличить стеки задач?
И нет ли у вас какого-нибудь ещё прерывания, которое может портить память?


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
SergNK
сообщение Jan 23 2017, 04:41
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991



Это было сделано в первую очередь. Я не новичок в осях и понимаю подводность камней. Лет 10 назад починил PicOS18. Там при определённых условиях стек Idle восстанавливался не полностью, из-за чего происходило переполнение стеков. Тяжёлая ошибка.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Jan 23 2017, 06:23
Сообщение #14


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Не обижайтесь, но раз вы этого явно не написали, кто-то должен был спросить sm.gif
Ещё банальный вопрос: укажите использованную версию оси, и используемый компилятор.


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
SergNK
сообщение Jan 23 2017, 15:46
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 139
Регистрация: 30-03-11
Из: Фаниполь (Минск)
Пользователь №: 63 991



scmRTOS v5.1
IAR 7.70
Windows 10
Go to the top of the page
 
+Quote Post

3 страниц V   1 2 3 >
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 16th April 2024 - 22:17
Рейтинг@Mail.ru


Страница сгенерированна за 0.01513 секунд с 7
ELECTRONIX ©2004-2016