Easyelectronics.ru

Электроника для всех
Текущее время: 26 фев 2018, 00:46

Часовой пояс: UTC + 5 часов



    • JLCPCB - Платы прототипов всего за 2$ c бесплатной доставкой (при первом заказе)
    • 10 PCBs за $2 для 2 слоев, $15 для 4 слойной, $74 для 6 слойной платы.
    • Крупнейший китайский производитель прототипных плат. 290000+ клиентов & 8000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин радиодеталей.

Начать новую тему Ответить на тему  [ Сообщений: 15 ] 
Автор Сообщение
 Заголовок сообщения: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 03 май 2017, 18:40 
Заглядывает иногда

Зарегистрирован: 03 май 2017, 17:34
Сообщения: 54
Добрый день.
Я немного запутался в связке HAL CubeMX + FreeRTOS.
У меня есть STM NUCLEO-L476RG и два модуля NFR24P01L+ с доп. антеной.
Для начала сделал проект без FreeRTOS, с бесконечным циклом.
Модуль работает и на принимающей стороне, RaspberryPI c NFR24P01L+ что-то появляется.

Появилось куча датчиков по шине I2C. Решил, что нужно делать проект на FreeRTOS.
Создал двоичный семафор. Прерывание от NFR24P01L+ освобождает семафор.
Задача (task) ждет отпускания семафора и выполняет обработку флагов прерывания.

Мне надо данные с I2C датчиков отправлять через радио модуль. Создал очередь, куда кладу готовые пакеты. Возник вопрос, как правильно организовать заполнение буфера передатчика (TX FIFO). Мне видится это, как вторая задача (task), опрашивающая очередь и как-то конкурирующая за общий ресурс SPI модуль c задачей обработки событий от прерываний.

Может есть некий семафор, типа read/write lock, с приоритетом команды записи (заполнение TX FIFO) перед чтением (прерывание) ?
Боюсь получить не предсказуемое чтение и запись регистров по SPI из переключающихся задач.

Есть еще вопрос. Хочу поставить несколько I2C датчиков на одну шину.
Одна серия датчиков обрабатывается в одной задаче. Скажем, так, гироскоп, акселерометр, магнитометр, барометр. Вторая серия датчиков обрабатывается во второй задаче. Скажем, лазерные датчики дистанции. Если что, это не летательный аппарат. Есть ли в HAL CubeMX проверка на занятость ресурсов одной шины I2C при переключении задач? Или тут мне 100% нужен собственный двоичный семафор?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 03 май 2017, 22:20 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1384
Откуда: Харьков
Вот это вам поможет:
http://www.freertos.org/taskENTER_CRITI ... TICAL.html
http://www.freertos.org/a00134.html
только нужно аккуратно пользоваться. Иначе может все остановится.
А вообще всякие ОСы это больше гемор чем польза... ИМХО.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 04 май 2017, 12:51 
Заглядывает иногда

Зарегистрирован: 03 май 2017, 17:34
Сообщения: 54
Спасибо. Это немного не то. taskENTER_CRITICAL и taskEXIT_CRITICAL запрещают менеджеру задач переключаться между задачами. У меня, пока, конкуренция двух задач за право обладания одним ресурсом, SPI модулем. И еще двух задач за право обладания одним ресурсом, одной I2C шиной.
Сейчас разбираюсь с SPI радио модулем и оставил одну задачу для части датчиков по I2C. Решил добавить еще один семафор "захват модуля".
По мне, так, немного не красиво выглядит код, где подряд идут две строки
Код:
xSemaphoreTake(irqReady, portMAX_DELAY); // получили разрешение от прерывания
xSemaphoreTake(moduleReady, portMAX_DELAY); // модуль не занят
...
xSemaphoreGive(moduleReady);

Самое печальное, что сейчас в консоль отладчика летят отладочные сообщения с одинаковой скоростью, даже если я меняю параметр задержки опроса I2C датчиков с 500 до 10000 в вызове функции
Код:
vTaskDelayUntil(&time, wait / portTICKRATEMS);

И они бегут явно быстрее 10 секунд. Да, в CubeMX с таймером особо не ковырялся, при создании проекта указал модель отладочной платы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 04 май 2017, 13:57 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1384
Откуда: Харьков
Две строки подряд вполне нормально. У меня так реализована отправка в USART - один поток шлет данные из очереди, а другие в эту очередь сливают, но при этом поток еще следит чтоб DMA который шлет в USART был свободен. Вот и получается что семафор сообщает о свободе DMA а потом еще ждем очередь.
Вроде бы все красиво, но все же колеблюсь на счет того, а нужно ли оно мне в принципе :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 04 май 2017, 14:35 
Старожил
Аватара пользователя

Зарегистрирован: 26 окт 2013, 07:58
Сообщения: 1723
Экранчик сидит на SPI.
К экранчику идут обращения из нескольких потоков и прерываний.
Как с использованием DMA (сердечко анимированное) так и без.
Всё отлично разруливается средствами FreeRTOS.
https://www.youtube.com/watch?v=ldeCwaxwkpw
Ещё и 4 независимые зоны поражения отслеживаются и обрабатываются 4-мя потоками - тоже без проблем.

Если нужно сделать что то сложнее, чем помигать диодиком, без RTOS не обойтись, моё ИМХО.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 04 май 2017, 15:31 
Старожил

Зарегистрирован: 22 мар 2010, 22:54
Сообщения: 3996
во фриртос (по кр мере 10 лет назад) все эти семафоры были реализованы на очередях. почему бы не сделать задачу работы с спи модулем и не слать ей задания в очередь? она берет задание, опрашивает что просят и выдает результат. взаимодействие между прерыванием и этой задачей, ясное дело, по семафору.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 04 май 2017, 16:37 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1384
Откуда: Харьков
Да я не спорю что ОС полезная штука, но вот косяки подобные этому вводят в ступор: viewtopic.php?f=35&t=31546


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 04 май 2017, 17:07 
Заглядывает иногда

Зарегистрирован: 03 май 2017, 17:34
Сообщения: 54
Ink писал(а):
во фриртос (по кр мере 10 лет назад) все эти семафоры были реализованы на очередях. почему бы не сделать задачу работы с спи модулем и не слать ей задания в очередь? она берет задание, опрашивает что просят и выдает результат. взаимодействие между прерыванием и этой задачей, ясное дело, по семафору.

Извините, мы немного о разном говорим. Для того, чтобы переключить модуль в режим передатчика, надо
1) прочитать регистр CONFIG;
2) обнулить младший байт и записать в регистр (активировать передатчик);
3) передать данные во внутреннюю очередь FIFO;
4) дернуть лапку CE к плюсу;
5) выждать как минимум 15 мкс;
6) дернуть лапку CE к минусу.
Как видите, не легкая это задача и одной посылкой по SPI не отделаешься.
Я пользуюсь инструкцией по модулю NRF24L01+ вот от сюда http://aterlux.ru/article/nrf24l01p В данном случае я описал метод send_data.

Да, важное дополнение для понимания картины. Прерывание идет от самого радио модуля об успешной передаче данных или получении данных.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 04 май 2017, 19:54 
Старожил

Зарегистрирован: 22 мар 2010, 22:54
Сообщения: 3996
alexey-s писал(а):
Как видите, не легкая это задача и одной посылкой по SPI не отделаешься.
а кто говорил про одну посылку спи? я говорил про задания. типа, отправить пакет такой-то на адрес такой-то, принять пакет (задание отправляется с обработчика прерывания). а этот поток для спи/нрф принимает задания из очереди и выполняет алгоритмы управления модулем.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 04 май 2017, 20:38 
Старожил
Аватара пользователя

Зарегистрирован: 26 окт 2013, 07:58
Сообщения: 1723
alexey-s писал(а):
Извините, мы немного о разном говорим. Для того, чтобы переключить модуль в режим передатчика, надо
1) прочитать регистр CONFIG;
2) обнулить младший байт и записать в регистр (активировать передатчик);
3) передать данные во внутреннюю очередь FIFO;
4) дернуть лапку CE к плюсу;
5) выждать как минимум 15 мкс;
6) дернуть лапку CE к минусу.
Как видите, не легкая это задача и одной посылкой по SPI не отделаешься.
Я пользуюсь инструкцией по модулю NRF24L01+ вот от сюда http://aterlux.ru/article/nrf24l01p В данном случае я описал метод send_data.

Да, важное дополнение для понимания картины. Прерывание идет от самого радио модуля об успешной передаче данных или получении данных.


Вот она - ваша задача.
https://www.youtube.com/watch?v=xjHGfmLD1Zs
Модули обмениваются пакетами по 32 байта (пересылают друг другу), инкриминируя первый байт.
Все делается в потоке, семафор освобождается из прерывания.
Проверяется успешность отправки пакета.

Но я хочу другие модули попробовать - SI4432


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 05 май 2017, 00:21 
Старожил
Аватара пользователя

Зарегистрирован: 27 мар 2015, 04:10
Сообщения: 1384
Откуда: Харьков
Вот тут работа с NRF24L01+ и прием передача команд в USART. Это т.н. Хаб:
https://github.com/saewave/RemoteSwitch ... freertos.c

Тут работа уже самого удаленного устройства на NRF.
https://github.com/saewave/RemoteSwitch ... h-Template

Все работает как часы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 05 май 2017, 02:37 
Заглядывает иногда

Зарегистрирован: 03 май 2017, 17:34
Сообщения: 54
alexsam писал(а):
Вот тут работа с NRF24L01+ и прием передача команд в USART. Это т.н. Хаб:

Это конечно, очень здорово. Большое спасибо за примеры. Там не совсем честно. К плате подключено два радио модуля. Один в режиме передатчика, другой, в режиме приемника. Нет конкуренции за одно устройство.
У меня один модуль переключается то приемник, то передатчик. И даже как бы начинает работать под FreeRTOS..
Буду читать, почему при выключенном RPI, у меня нет прерываний с флагом MAX_RT (превышения числа попыток повторной отправки). Всегда идет прерывание TX_DS (успешная отправка). Ну, это я где-то ошибся.

И да, я, пока не решался переходить на FreeRTOS, использовал те же алгоритмы nRF24_Delay_ms и nRF24_Delay_us. Но тут они работают ни чуть не лучше vTaskDelay. Почему? Потому что система может переключиться на другую задачу. И задержка в желаемые 5 мкс может обойтись дороже задержки в один тик vTaskDelay(1). Мое мнение, это экономия на спичках.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 05 май 2017, 07:01 
Старожил
Аватара пользователя

Зарегистрирован: 26 окт 2013, 07:58
Сообщения: 1723
alexey-s писал(а):
alexsam писал(а):
Вот тут работа с NRF24L01+ и прием передача команд в USART. Это т.н. Хаб:

Это конечно, очень здорово. Большое спасибо за примеры. Там не совсем честно. К плате подключено два радио модуля. Один в режиме передатчика, другой, в режиме приемника. Нет конкуренции за одно устройство.

А-ха-ха!
Фома неверующий.
Второй - это блютус модуль, не выпаивать же мне его "для доказательства". :-)
Проект с открытыми исходниками, сами сможете убедиться.
Show nrf24.c




Show nrf24.h


Show nrf2task




Код:

#ifdef NRF24_ENABLE
void nrf24_tx_byte(void){
   NRF24L01_CE_LOW;
   nrf24_spi_writeReg(CONFIG, Bit(NRF_REGF_PWR_UP)|Bit(NRF_REGF_EN_CRC)|(0<<NRF_REGF_PRIM_RX));
   NRF24L01_CE_HIGH;
   Delay_us(15);
   NRF24L01_CE_LOW;
   Delay_us(135);
}

bool nrf24_send_byte(unsigned char value, int timeout,  unsigned char* status){//отправка байта.
//    unsigned char reg_val;
    bool result=false;
   nrf24_clr_status_reg();
   nrf24_spi_writeCmd(FLUSH_TX);
   nrf24_spi_writeReg(WR_TX_PLOAD,value);
   nrf24_tx_byte();
    if (xSemaphoreTake(xNRF24_IQR_Semaphore, (portTickType) timeout/*portMAX_DELAY*/ )== pdTRUE)//ждем событий NRF24
   {
         *status = nrf24_clr_status_reg();
          if(BitIsSet(*status, NRF_REGF_MASK_TX_DS )){//если данные успешно отправлены

             bool result = true;
          }
          else  result=false; //ошибка при передаче данных
   }
    else  result=false; //ошибка по таймауту
   //   while (GPIO_ReadInputDataBit(NRF24L01_IQR_PORT, NRF24L01_IQR_PIN) == 1);//Ждем пока байт не передан


//   nrf24_spi_writeReg(NRF_REG_STATUS,status);//сбрасываем флаги

   return (result);

}


bool nrf24_send_package(int timeout,  unsigned char* status){//отправка байта.
    bool result=false;
   nrf24_clr_status_reg();
   nrf24_spi_writeCmd(FLUSH_TX);
   nrf24_spi_writeBuf(WR_TX_PLOAD, (unsigned char *) &tx_buf[0], TX_PLOAD_WIDTH);
   nrf24_px();
    if (xSemaphoreTake(xNRF24_IQR_Semaphore, (portTickType) timeout/*portMAX_DELAY*/ )== pdTRUE)//ждем событий NRF24
   {
         *status = nrf24_clr_status_reg();
          if(BitIsSet(*status, NRF_REGF_MASK_TX_DS )){//если данные успешно отправлены

             result = true;
          }
          else  result=false; //ошибка при передаче данных
   }
    else  result=false; //ошибка по таймауту
   return (result);

}



void nrf24_to_rx_mode(void){
     nrf24_clr_status_reg();
   nrf24_spi_writeCmd(FLUSH_RX);
   nrf24_spi_writeReg(CONFIG, Bit(NRF_REGF_PWR_UP)|Bit(NRF_REGF_EN_CRC)|Bit(NRF_REGF_PRIM_RX));
   nrf24_spi_writeReg(NRF_REG_RX_PW_P0,1);//будем получать 1 байт
   NRF24L01_CE_HIGH;
   Delay_us(135);
    //режим према RX
}




void inline nrf24_IQR_callback(void){
   static portBASE_TYPE xHigherPriorityTaskWoken;
   xHigherPriorityTaskWoken = pdFALSE;
   xSemaphoreGiveFromISR( xNRF24_IQR_Semaphore, &xHigherPriorityTaskWoken);

}




Грязновато конечно (в таком виде не собирался выкладывать - чисто проверить работоспособность модулей и дальность связи) и мешанина из нескольких либ (дублирование), но работает.

Дальностью разочарован, хочу другие модули попробовать.

Цитата:
И да, я, пока не решался переходить на FreeRTOS, использовал те же алгоритмы nRF24_Delay_ms и nRF24_Delay_us. Но тут они работают ни чуть не лучше vTaskDelay. Почему? Потому что система может переключиться на другую задачу. И задержка в желаемые 5 мкс может обойтись дороже задержки в один тик vTaskDelay(1). Мое мнение, это экономия на спичках.


У меня задачи переключаются 300 раз в секунду, поэтому минимальный интервал, который могу задать средствами FreeRTOS - 1/300 секунды.
Есть ограничения, согласен, но сами функции задержки отрабатывают чётко.


Последний раз редактировалось Pingvin 05 май 2017, 07:40, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 05 май 2017, 07:35 
Старожил
Аватара пользователя

Зарегистрирован: 26 окт 2013, 07:58
Сообщения: 1723
Но учтите, что есть грабли с настройкой приоритетов прерываний, из которых идёт вызов функций FromIsr.
Настраивать надо и саму FreeRTOS и приоритеты прерываний правильно.
Наступал на эти грабли.
Как делать - поищите, тут обсуждалось.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: FreeRTOS и борьба за одну шину данных (датчик)
СообщениеДобавлено: 05 май 2017, 13:27 
Заглядывает иногда

Зарегистрирован: 03 май 2017, 17:34
Сообщения: 54
Pingvin писал(а):
Дальностью разочарован, хочу другие модули попробовать.

Я покупал модули на Ali с антенной. Long Range E01-ML01DP5 Ebyte 20dBm 2100 м SPI NRF24L01 + PA + МШУ 2.4 ГГц. На Youtube смотрел видео, где мужик проверял дальность работы разных модулей. Оттуда и узнал, что есть с большой дальностью. Сам, пока, не проверял. Максимум, дома, через 4 стены (2 несущие) и дальностью в 7м, без ошибок в течении полу часа.

Спасибо за код. Обязательно посмотрю. Для меня, это самоделка. Так, что буду вечером разбираться.


Извините, мне очень хочется покритиковать ваш метод NRF24task. Я как раз хотел избежать вашей ошибки.
И так, если прерывания нет, переключаем модуль в режим передатчика и отправляем пакет. После отправки переключаем в режим приемника.
Всё, вроде работает.
И так, допустим, что система не переключилась и продолжает работать цикл этой задачи. Через очень короткое время, возвращаемся к переключению в режим передатчика. Процессор работает с частотами в десятки или сотни МГц. Это довольно быстро. Хорошо, если радио модуль успеет что-то схватить данные из радио эфира.

По этой причине, я создаю очередь для заполнения данными передатчика. Задача следит за появлением передаваемых данных и при освобождении модуля, переводит его в режим передатчика. Вторая задача следит за прерыванием. Если пришло прерывание от передатчика, проверяем заполнение буфера передатчика. Есть данные, передаем данные. Нет данных, переключаемся в режим приемника.

Описанный алгоритм будет работать эффективнее, так как задачи управления радио модулем будут простаивать в ожидании данных. Ваш алгоритм старается завалить радио эфир.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 15 ] 

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB