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

 
 
 
Reply to this topicStart new topic
> Keil RTOS и микросекундные задержки.
zheka
сообщение Apr 16 2015, 06:12
Сообщение #1


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



Господа, есть проект в KEIL 5 под STM32F4Discovery, в котором подключена RTOS (Keil RTX). Она мне в принципе не нужна, она требуется для работы библиотеки USB_CDC, попытки отвязать ее от KEIL RTX не принесли успеха.
В Keil RTX есть только миллисекундные задержки, микросекундных - нет.
Пытался прикрутить библиотеку systick - не вышло - компилятор не дает создать свой Systick_Handler, мотивируя это тем, что таковой есть уже в HAL_CM4.C (это файл RTX)

Как мне в сложившихся условиях (невозможность отключить RTOS и отсутствие специальной функции в ней) получить функцию, осуществляющую задержку на заданное число микросекунд?
Go to the top of the page
 
+Quote Post
scifi
сообщение Apr 16 2015, 06:24
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 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 */
}
Go to the top of the page
 
+Quote Post
kan35
сообщение Apr 16 2015, 06:50
Сообщение #3


Знающий
****

Группа: Участник
Сообщений: 537
Регистрация: 22-02-06
Пользователь №: 14 594



Какие проблемы запретить прерывания в задаче и сделать задержку, потом включить прерывания. Критические секции в rtos как правило это и делают.
Go to the top of the page
 
+Quote Post
zheka
сообщение Apr 16 2015, 07:11
Сообщение #4


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



Цитата
Если не запрещать прерывания

Цитата
Какие проблемы запретить прерывания

Взаимоисключающие решения)))

Цитата
А решение очевидное: простой цикл ожидания с использованием одного из аппаратных таймеров.

Не хочется мне занимать таймер.

Цитата
DWT_CYCCNT.

Что нужно подключить к проекту, чтобы компилятор не ругался, что не знает этого идентификатора?
Go to the top of the page
 
+Quote Post
scifi
сообщение Apr 16 2015, 07:16
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 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;
}
Go to the top of the page
 
+Quote Post
zheka
сообщение Apr 16 2015, 07:23
Сообщение #6


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



ОК, просто интересно, вы этим так и ползуетесь, или где-то делаете пересчет на микро и миллисекунды?
Go to the top of the page
 
+Quote Post
scifi
сообщение Apr 16 2015, 07:26
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(zheka @ Apr 16 2015, 10:23) *
ОК, просто интересно, вы этим так и ползуетесь, или где-то делаете пересчет на микро и миллисекунды?

У меня есть дефайн #define CYCCNT_RATE 168000000. Если нужна микросекунда, то пишу delay(CYCCNT_RATE / 1000000);
Go to the top of the page
 
+Quote Post
toweroff
сообщение Apr 16 2015, 16:10
Сообщение #8


Гуру
******

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



Можно отвязать CDC от RTX
Там все замучено в ту сторону, что вертится одна задача, обслуживающая служебную информацию через EP0, а так же по задаче на каждую точку
Ничто не мешает оставить просто "дергание" нужных функций из прерывания USB
Отправлять данные можно по SOF, вполне себе рабочий вариант (то есть складывать в буфер, а по SOF проверять и если что-то есть - отправлять кусок до размера точки - 64 байта)
Go to the top of the page
 
+Quote Post
zheka
сообщение Apr 16 2015, 16:43
Сообщение #9


Гуру
******

Группа: Участник
Сообщений: 2 072
Регистрация: 14-01-06
Пользователь №: 13 164



Цитата(toweroff @ Apr 16 2015, 19:10) *
Можно отвязать CDC от RTX
Там все замучено в ту сторону, что вертится одна задача, обслуживающая служебную информацию через EP0, а так же по задаче на каждую точку
Ничто не мешает оставить просто "дергание" нужных функций из прерывания USB
Отправлять данные можно по SOF, вполне себе рабочий вариант (то есть складывать в буфер, а по SOF проверять и если что-то есть - отправлять кусок до размера точки - 64 байта)

Так там если только поставить галку напротив USB, сразу подключается RTX...
Go to the top of the page
 
+Quote Post
toweroff
сообщение Apr 16 2015, 18:09
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 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)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 17 2015, 01:54
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(zheka @ Apr 16 2015, 12:12) *
Пытался прикрутить библиотеку systick - не вышло - компилятор не дает создать свой Systick_Handler, мотивируя это тем, что таковой есть уже в HAL_CM4.C (это файл RTX)

В чём сложность заменить системный ISR Systick своим?
Go to the top of the page
 
+Quote Post
toweroff
сообщение Apr 17 2015, 04:41
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 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 по окончании передачи отправить этот сигнал в задачу

По идее, если приоритет у задачи будет повыше, должно получиться
Go to the top of the page
 
+Quote Post
jcxz
сообщение Apr 17 2015, 06:50
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Если нужны задержки на несколько микросекунд, то возможно можно просто запретить прерывания и отсчитать нужное кол-во тактов Systick просто читая регистр-счётчик Systick
(конечно с учётом переполнения при достижении величины делителя).
Go to the top of the page
 
+Quote Post
toweroff
сообщение Apr 17 2015, 07:28
Сообщение #14


Гуру
******

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



Цитата(jcxz @ Apr 17 2015, 09:50) *
Если нужны задержки на несколько микросекунд, то возможно можно просто запретить прерывания и отсчитать нужное кол-во тактов Systick просто читая регистр-счётчик Systick
(конечно с учётом переполнения при достижении величины делителя).

кстати, да
тем более, что 1мкс даже на 100МГц - это всего 100 тактов
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 22nd June 2025 - 10:38
Рейтинг@Mail.ru


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