zheka 1 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Господа, есть проект в KEIL 5 под STM32F4Discovery, в котором подключена RTOS (Keil RTX). Она мне в принципе не нужна, она требуется для работы библиотеки USB_CDC, попытки отвязать ее от KEIL RTX не принесли успеха. В Keil RTX есть только миллисекундные задержки, микросекундных - нет. Пытался прикрутить библиотеку systick - не вышло - компилятор не дает создать свой Systick_Handler, мотивируя это тем, что таковой есть уже в HAL_CM4.C (это файл RTX) Как мне в сложившихся условиях (невозможность отключить RTOS и отсутствие специальной функции в ней) получить функцию, осуществляющую задержку на заданное число микросекунд? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Как мне в сложившихся условиях (невозможность отключить RTOS и отсутствие специальной функции в ней) получить функцию, осуществляющую задержку на заданное число микросекунд? Если не запрещать прерывания и переключение задач, то это будет задержка "N микросекунд или больше", естественно. А решение очевидное: простой цикл ожидания с использованием одного из аппаратных таймеров. Если не злоупотреблять, то существенного общего замедления программы не будет. Кстати, в STM32F4 есть очень удобный для этих дел счётчик тактов процессора DWT_CYCCNT. void delay(unsigned int ticks) { unsigned int start = DWT_CYCCNT; while (DWT_CYCCNT - start < ticks); /* wait */ } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
kan35 7 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Какие проблемы запретить прерывания в задаче и сделать задержку, потом включить прерывания. Критические секции в rtos как правило это и делают. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Если не запрещать прерывания Какие проблемы запретить прерывания Взаимоисключающие решения))) А решение очевидное: простой цикл ожидания с использованием одного из аппаратных таймеров. Не хочется мне занимать таймер. DWT_CYCCNT. Что нужно подключить к проекту, чтобы компилятор не ругался, что не знает этого идентификатора? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Что нужно подключить к проекту, чтобы компилятор не ругался, что не знает этого идентификатора? Я ничего не подключаю. У меня есть вот такие дефайны: #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; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба ОК, просто интересно, вы этим так и ползуетесь, или где-то делаете пересчет на микро и миллисекунды? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба ОК, просто интересно, вы этим так и ползуетесь, или где-то делаете пересчет на микро и миллисекунды? У меня есть дефайн #define CYCCNT_RATE 168000000. Если нужна микросекунда, то пишу delay(CYCCNT_RATE / 1000000); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Можно отвязать CDC от RTX Там все замучено в ту сторону, что вертится одна задача, обслуживающая служебную информацию через EP0, а так же по задаче на каждую точку Ничто не мешает оставить просто "дергание" нужных функций из прерывания USB Отправлять данные можно по SOF, вполне себе рабочий вариант (то есть складывать в буфер, а по SOF проверять и если что-то есть - отправлять кусок до размера точки - 64 байта) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zheka 1 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Можно отвязать CDC от RTX Там все замучено в ту сторону, что вертится одна задача, обслуживающая служебную информацию через EP0, а так же по задаче на каждую точку Ничто не мешает оставить просто "дергание" нужных функций из прерывания USB Отправлять данные можно по SOF, вполне себе рабочий вариант (то есть складывать в буфер, а по SOF проверять и если что-то есть - отправлять кусок до размера точки - 64 байта) Так там если только поставить галку напротив USB, сразу подключается RTX... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 0 16 апреля, 2015 Опубликовано 16 апреля, 2015 · Жалоба Так там если только поставить галку напротив USB, сразу подключается RTX... нужно поискать usbcore, usbhw, usbdesc и usbuser для нужного камня просмотреть их, выбросить все, относящееся к RTX, сделать вызов нужных функций из прерывания вместо передачи сигнала оттуда в задачу Инициализация останется, только в ней нужно не задачи поднимать, а настроить прерывание, причем в RTX оно делается через SWI, его тоже выбросить В принципе, дел - на часа три Также можно покопать старые примеры кейла для 4.х ветки, там были без использования RTX, насколько я помню Возможно, что не сам CDC, а какой-нибудь HID или MSC, прикрутить к нему обработку CDC для точки (обычно EP0 стандартная служебная, EP1 - контрольная для CDC, там настраиваются параметры порта и прочие вещи, а весь обмен валится через EP2 bulk) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 17 апреля, 2015 Опубликовано 17 апреля, 2015 · Жалоба Пытался прикрутить библиотеку systick - не вышло - компилятор не дает создать свой Systick_Handler, мотивируя это тем, что таковой есть уже в HAL_CM4.C (это файл RTX) В чём сложность заменить системный ISR Systick своим? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 0 17 апреля, 2015 Опубликовано 17 апреля, 2015 · Жалоба В чём сложность заменить системный ISR Systick своим? тут тоже не так однозначно. Можно оттуда послать сигнал в задачу, но будет затрачено время на переключение, кстати, по-моему, в том же самом ISR Systick, т.е. сигнал нужно выставлять в самом начале прерывания, до обработок RTOS. UPD а можно попробовать такой финт: 1. Задействовать что-то неиспользуемое, например SPI на частоте 10 МГц 2. Настроить его на передачу 10 бит 3. Отправить одно 10-битное слово и заснуть в ожидании сигнала 4. Из прерывания SPI по окончании передачи отправить этот сигнал в задачу По идее, если приоритет у задачи будет повыше, должно получиться Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 17 апреля, 2015 Опубликовано 17 апреля, 2015 · Жалоба Если нужны задержки на несколько микросекунд, то возможно можно просто запретить прерывания и отсчитать нужное кол-во тактов Systick просто читая регистр-счётчик Systick (конечно с учётом переполнения при достижении величины делителя). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
toweroff 0 17 апреля, 2015 Опубликовано 17 апреля, 2015 · Жалоба Если нужны задержки на несколько микросекунд, то возможно можно просто запретить прерывания и отсчитать нужное кол-во тактов Systick просто читая регистр-счётчик Systick (конечно с учётом переполнения при достижении величины делителя). кстати, да тем более, что 1мкс даже на 100МГц - это всего 100 тактов Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться