|
|
  |
Keil RTOS и микросекундные задержки. |
|
|
|
Apr 16 2015, 06:24
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(zheka @ Apr 16 2015, 09:12)  Как мне в сложившихся условиях (невозможность отключить RTOS и отсутствие специальной функции в ней) получить функцию, осуществляющую задержку на заданное число микросекунд? Если не запрещать прерывания и переключение задач, то это будет задержка "N микросекунд или больше", естественно. А решение очевидное: простой цикл ожидания с использованием одного из аппаратных таймеров. Если не злоупотреблять, то существенного общего замедления программы не будет. Кстати, в STM32F4 есть очень удобный для этих дел счётчик тактов процессора DWT_CYCCNT. Код void delay(unsigned int ticks) { unsigned int start = DWT_CYCCNT; while (DWT_CYCCNT - start < ticks); /* wait */ }
|
|
|
|
|
Apr 16 2015, 07:11
|
Гуру
     
Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164

|
Цитата Если не запрещать прерывания Цитата Какие проблемы запретить прерывания Взаимоисключающие решения))) Цитата А решение очевидное: простой цикл ожидания с использованием одного из аппаратных таймеров. Не хочется мне занимать таймер. Цитата DWT_CYCCNT. Что нужно подключить к проекту, чтобы компилятор не ругался, что не знает этого идентификатора?
|
|
|
|
|
Apr 16 2015, 07:16
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(zheka @ Apr 16 2015, 10:11)  Что нужно подключить к проекту, чтобы компилятор не ругался, что не знает этого идентификатора? Я ничего не подключаю. У меня есть вот такие дефайны: Код #define DWT_CTRL (*(uint32_t volatile*)0xE0001000) #define DWT_CYCCNT (*(uint32_t volatile*)0xE0001004) #define SCB_DEMCR (*(uint32_t volatile*)0xE000EDFC) Ну и перед использованием этого таймера делаю вот так: Код void init_cyccnt(void) { SCB_DEMCR |= 1 << 24; DWT_CYCCNT = 0; DWT_CTRL |= 1; }
|
|
|
|
|
Apr 16 2015, 18:09
|

Гуру
     
Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514

|
Цитата(zheka @ Apr 16 2015, 19:43)  Так там если только поставить галку напротив USB, сразу подключается RTX... нужно поискать usbcore, usbhw, usbdesc и usbuser для нужного камня просмотреть их, выбросить все, относящееся к RTX, сделать вызов нужных функций из прерывания вместо передачи сигнала оттуда в задачу Инициализация останется, только в ней нужно не задачи поднимать, а настроить прерывание, причем в RTX оно делается через SWI, его тоже выбросить В принципе, дел - на часа три Также можно покопать старые примеры кейла для 4.х ветки, там были без использования RTX, насколько я помню Возможно, что не сам CDC, а какой-нибудь HID или MSC, прикрутить к нему обработку CDC для точки (обычно EP0 стандартная служебная, EP1 - контрольная для CDC, там настраиваются параметры порта и прочие вещи, а весь обмен валится через EP2 bulk)
|
|
|
|
|
Apr 17 2015, 04:41
|

Гуру
     
Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514

|
Цитата(jcxz @ Apr 17 2015, 04:54)  В чём сложность заменить системный ISR Systick своим? тут тоже не так однозначно. Можно оттуда послать сигнал в задачу, но будет затрачено время на переключение, кстати, по-моему, в том же самом ISR Systick, т.е. сигнал нужно выставлять в самом начале прерывания, до обработок RTOS. UPD а можно попробовать такой финт: 1. Задействовать что-то неиспользуемое, например SPI на частоте 10 МГц 2. Настроить его на передачу 10 бит 3. Отправить одно 10-битное слово и заснуть в ожидании сигнала 4. Из прерывания SPI по окончании передачи отправить этот сигнал в задачу По идее, если приоритет у задачи будет повыше, должно получиться
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|