|
|
 |
Ответов
(1 - 14)
|
Sep 15 2014, 10:35
|
Участник

Группа: Участник
Сообщений: 46
Регистрация: 3-07-06
Пользователь №: 18 536

|
Задача такая. Есть внешне устройство (ПЛИС), с которым STM общается по SPI, при этом с программно формируемым CS и дополнительной линией, определяющей, устанавливаем ли адрес внутри ПЛИС или пишем/читаем из нее данные. Общения должны происходить как в обработчике таймера, так и в фоне и не не мешать друг-другу. Одна посылка SPI намного короче периода таймера. Поэтому надо просто запрещать прерывание перед каждым обращением из фона и потом разрешать. Так всегда делал в AVR. Здесь хочется что-то аналогичное.
|
|
|
|
|
Sep 15 2014, 11:57
|
Участник

Группа: Участник
Сообщений: 46
Регистрация: 3-07-06
Пользователь №: 18 536

|
Что за менеджер? Что-нибудь связанное с RTOS? Не пользуюсь, не знаю как. У меня stand-alone приложение.
|
|
|
|
|
Sep 15 2014, 12:16
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(Sidoroff @ Sep 15 2014, 15:57)  Что за менеджер? Что-нибудь связанное с RTOS? Не пользуюсь, не знаю как. У меня stand-alone приложение. Конечно без RTOS. Можно сделать простой кольцевой буфер. Функции push() - для помещения элемента в очередь, pop() - для извлечения. Элементом очереди будет структура, содержащая данные и указатель на callback-функцию. При вызове push() выделяется новый элемент в очереди. В него помещается структура. Если SPI свободен, то отправляем данные из данного элемента очереди. Если ведется передача, то в обработчике окончания передачи вызывать указанную calback-функцию, извлекать следующий элемент из очереди и отправлять его по SPI. Или совсем просто: В Systick устанавливать флаг, а в фоне сбрасывать и передавать, те данные, которые нужно было отправить в Systick.
|
|
|
|
|
Sep 16 2014, 10:04
|
Участник

Группа: Участник
Сообщений: 46
Регистрация: 3-07-06
Пользователь №: 18 536

|
Последовал первому совету: использовал обычный таймер. Все работает, прерывания не теряет.
//Инициализация RCC->APB1ENR |= RCC_APB1ENR_TIM2EN; TIM2->PSC = 0; TIM2->ARR = SystemCoreClock/2/TIMER_FREQ - 1; // TIMER_FREQ = 10000 (10kHz) TIM2->DIER |= TIM_DIER_UIE; TIM2->CR1 |= TIM_CR1_CEN; NVIC_EnableIRQ(TIM2_IRQn); // в первый раз разрешим прерывания
// В фоновой программе запрещаю перед обменом и разрешаю после обмена так же NVIC_DisableIRQ(TIM2_IRQn); .. SPI-обмен NVIC_EnableIRQ(TIM2_IRQn);
// Обработчик extern "C" void TIM2_IRQHandler(void) { TIM2->SR &= ~TIM_SR_UIF; // без этого виснет, содрал просто .. тело }
Всем спасибо.
|
|
|
|
|
Sep 16 2014, 13:11
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(Sidoroff @ Sep 16 2014, 14:04)  Последовал первому совету: использовал обычный таймер. Все работает, прерывания не теряет. Т.к. у обычных прерываний есть pending-бит в NVIC. Типа, отложенные прерывания - идеально для вас. Цитата(Sidoroff @ Sep 16 2014, 14:04)  TIM2->SR &= ~TIM_SR_UIF; // без этого виснет, содрал просто Лучше так: Код TIM2->SR = ~TIM_SR_UIF; Почему? Много раз обсуждалось тут: чтобы сбросить только UIF.
|
|
|
|
|
Sep 18 2014, 11:26
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(adnega @ Sep 16 2014, 22:35)  Предлагал. Но для доступа к очереди все равно придется городить критические секции (запрещать прерывания). Во-первых: очереди возможно и не нужны. Если доступ к службе делать с блокировкой (задачи), до достаточно для каждой задачи иметь флаг и задаче ждать на этом флаге снятия его ISR-ом. ISR знает все флаги. Во-вторых: очереди легко строятся без всяких критических секций, если писатель (в очередь) только один (задача или ISR) и читатель - только один. Так даже можно очереди синхронизации между ядрами CPU строить, где невозможно сделать критическую секцию другому ядру. Цитата(adnega @ Sep 16 2014, 22:35)  То, что было нужно ТС - это отложенные прерывания. Но я бы подумал над архитектурой. Cortex-M это не AVR))) Возможности богаче. Да, у ТС естественно детский, АВР-ский подход. Думаю он ещё не скоро вырастет из детских штанишек
|
|
|
|
|
Sep 18 2014, 12:05
|
Гуру
     
Группа: Свой
Сообщений: 2 724
Регистрация: 14-05-07
Из: Ярославль, Россия
Пользователь №: 27 702

|
Цитата(jcxz @ Sep 18 2014, 15:26)  Во-первых: очереди возможно и не нужны. Если доступ к службе делать с блокировкой (задачи), до достаточно для каждой задачи иметь флаг и задаче ждать на этом флаге снятия его ISR-ом. ISR знает все флаги. Deadlock: в фоне сделали блокировку, в Systick ждем освобождения. Цитата(jcxz @ Sep 18 2014, 15:26)  Во-вторых: очереди легко строятся без всяких критических секций, если писатель (в очередь) только один (задача или ISR) и читатель - только один. Сам так пользуюсь. Но к сожалению, писателей у ТС два(
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|