|
|
  |
scmRtos для медных чайников |
|
|
|
Dec 11 2015, 09:43
|

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

|
Цитата(dxp @ Dec 11 2015, 13:10)  std::vector<int> my_vector; my_vector тоже находится в пространстве имён std. Так? Переменная my_vector - нет. Функция my_vector::size() - да. Вот ещё ссылка в тему.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Dec 11 2015, 12:04
|

Гуру
     
Группа: Свой
Сообщений: 2 429
Регистрация: 30-11-05
Из: Ижевск
Пользователь №: 11 606

|
Цитата Т.е. подозреваете банальный (и подлый) memory overwrite при пересылке данных? Так и оказалось. При инициализации DMA указал количество элементов как sizeof(adc_buf), а adc_buf состоит из 12 элементов 2 байтовых. В итоге sizeof(adc_buf) возвращало вдвое больше чем я хотел передать и данные писались поверх других переменных. Уже не первый раз на этом попадаюсь
|
|
|
|
|
Apr 16 2016, 17:36
|

Частый гость
 
Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811

|
Опять туплю. На сей раз процессор STM32F103, компилятор GCC, версия scmRTOS 5, если это имеет значение. Прерывание: Код OS::channel<uint8_t, 32> UsartRxChannel; .... extern "C" void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { uint8_t c; c = USART1->DR; if (UsartRxChannel.get_free_size()>0) UsartRxChannel.push(c); } } Как только доходит первый раз до UsartRxChannel.push( c ) - все улетает неведомо куда и прерывания больше не случаются. При использовании TEventFlag signal_isr() никаких странностей не наблюдается, но делать свой буфер, когда есть channel как-то не кошерно  . Не подскажете, что я делаю не так?
|
|
|
|
|
Apr 16 2016, 18:48
|

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

|
Цитата(varvar @ Apr 16 2016, 22:36)  Не подскажете, что я делаю не так? При использовании сервисов оси в прерываниях обязательно нужно объявлять в обработчике прерывания переменную типа OS::TISRW: Код extern "C" void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) { OS::TISRW ISR; ... Она обеспечивает перепланировку при выходе из зоны видимости.
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Apr 16 2016, 19:15
|

Частый гость
 
Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811

|
Цитата(AHTOXA @ Apr 16 2016, 21:48)  При использовании сервисов оси в прерываниях обязательно нужно объявлять в обработчике прерывания переменную типа OS::TISRW: Она обеспечивает перепланировку при выходе из зоны видимости. Спасибо огромное - похоже, у меня склероз крепчает - ведь в старых проектах у меня она везде есть!
|
|
|
|
|
Apr 17 2016, 09:12
|

Частый гость
 
Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811

|
Цитата(AHTOXA @ Apr 16 2016, 22:57)  Насколько я могу сейчас сообразить, это не должно приводить к зависанию. Что-то не выходит каменный цветок - вроде как заработало, через несколько десятков секунд опять виснет. Пока оставил следующее решение - работает без вопросов: CODE struct sFifo { uint8_t buf[128]; uint8_t tail; uint8_t head; uint8_t MsgSize; }; sFifo usartRXfifo; OS::TEventFlag GpsFlag; extern "C" void USART1_IRQHandler(void) { OS::TISRW ISR; auto status = USART1->SR; auto data = USART1->DR; if (status & USART_FLAG_RXNE) { if((usartRXfifo.head-usartRXfifo.tail)!=128) { usartRXfifo.buf[usartRXfifo.head & 0x7F]=data; usartRXfifo.head++; } if (data=='\r') { usartRXfifo.MsgSize = usartRXfifo.head-usartRXfifo.tail; GpsFlag.signal_isr(); } } }
Может, с другими задачами чего поделить не может - в системе еще IMU крутится и данные в CAN выплевывает.
|
|
|
|
|
Apr 17 2016, 14:45
|

Частый гость
 
Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811

|
Цитата(dxp @ Apr 17 2016, 16:51)  А уверены, что channel не переполняется? Он с большим запасом вроде как, и, кроме того, я проверяю перед записью, есть ли там место get_free_size. Короче, мистика какая-то.
|
|
|
|
|
May 12 2016, 12:26
|
Группа: Участник
Сообщений: 10
Регистрация: 28-10-10
Пользователь №: 60 480

|
Необходимо написать "мягкий" вариант критической секции, когда прерывания разрешены, но заблокирована работа планировщика, чтобы не было переключения процессов. Вопрос. В какой п/программе Оси лучше сделать блокировку планировщика?
Сообщение отредактировал Anatoly74 - May 12 2016, 13:00
|
|
|
|
|
May 12 2016, 16:57
|
Группа: Участник
Сообщений: 10
Регистрация: 28-10-10
Пользователь №: 60 480

|
Спасибо за наводку
|
|
|
|
|
Jun 10 2018, 08:27
|

Частый гость
 
Группа: Участник
Сообщений: 93
Регистрация: 5-01-05
Из: Оулу
Пользователь №: 1 811

|
Опять туплю. Пытаюсь заставить работать scmRTOS c STM32F103C8 (платка Blue Pill, операционная система должна работать поверх STM32duino) В качестве системного таймера пытаюсь использовать TIMER3: CODE // If the macro value is 0 (the default), the port uses SysTick as a system // timer. It initializes the timer and starts it. The user must make sure that // the address of the timer interrupt handler (SysTick_Handler) is in the right // place at the interrupt vector table. // If the macro value is 1, then the user has to implement (see docs for details): // 1. extern "C" void __init_system_timer(); // 2. void LOCK_SYSTEM_TIMER() / void UNLOCK_SYSTEM_TIMER(); // 3. In the interrupt handler of the custom timer, the user needs to call // OS::system_timer_isr()
#if SCMRTOS_USE_CUSTOM_TIMER == 1
static void TIM3_Event() { OS::system_timer_isr(); }
extern "C" void __init_system_timer() { RCC_BASE->APB1ENR |= RCC_APB1ENR_TIM3EN; // TIM3 // TIM3 master counter period 1 msec 48MHz main TIMER3->regs.gen->CR1 &= ~TIMER_CR1_CEN; // disabled TIMER3->regs.gen->PSC = 480 - 1; //new clock = 100kHz TIMER3->regs.gen->ARR = 100 - 1; //period = 16usec TIMER3->regs.gen->CR1 |= TIMER_CR1_DIR; //used as downcounter timer_attach_interrupt(TIMER3, TIMER_UPDATE_INTERRUPT, TIM3_Event); TIMER3->regs.gen->CR1 |= TIMER_CR1_CEN; // enable timer TIMER3->regs.gen->DIER |= TIMER_DIER_UIE; //enable interrupt }
INLINE void LOCK_SYSTEM_TIMER() { TIMER3->regs.gen->CR1 &= ~TIMER_CR1_CEN; // disable timer }
INLINE void UNLOCK_SYSTEM_TIMER() { TIMER3->regs.gen->CR1 |= TIMER_CR1_CEN; // enable timer }
#endif
после первого же вызова OS::sleep() прерывание больше не наблюдается. Что я опять делаю не так?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|