Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: FreeRTOS + USB
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
Atlantis-
Здравствуйте!
Как правильней объединить USB (конкретно обработчик прерываний) и задачи по приему данных и обработке реквестов? надо ли всю обработку прерывания совать в задачу и потом семафором ее вызывать или можно вызывать задачу только когда пришли данные?
den_po
Зачем семафором? Для этого очереди есть.
А что в примерах не понравилось? Там есть энное количество примеров с USB.
Atlantis-
Цитата(den_po @ Aug 5 2014, 17:49) *
Зачем семафором? Для этого очереди есть.
А что в примерах не понравилось? Там есть энное количество примеров с USB.

в очередь точно...
а что за примеры? где их скачать?
den_po
http://www.freertos.org/ -> download
в дистрибутиве папка Demo
Atlantis-
Цитата(den_po @ Aug 6 2014, 09:49) *
http://www.freertos.org/ -> download
в дистрибутиве папка Demo

это я качал, но разве там есть примеры с USB? как называются?
gridinp
а что за процессор, что за USB контроллер, master or slave?
Atlantis-
Цитата(gridinp @ Aug 8 2014, 22:36) *
а что за процессор, что за USB контроллер, master or slave?

плата 32F429IDISCOVERY
Atlantis-
Еще вопрос: насколько правильно будет для обработки USB запросов (пользовательских конечно) сделать специальную задачу и вызывать ее из обработчика запросов с помощью отправки сообщения? запуск задачи будет же занимать какое то дополнительное время, насколько это будет корректно? то же самое с принимаемыми по USB данными, можно ли отсылать сообщение содержащее адрес первого элемента и кол-во данных, а в задаче уже обрабатывать?
uriy
На STM32F103 я использую семафоры:

Прерывание:
Код
void EP2_OUT_Callback(void)
{
    SetEPRxStatus(ENDP2, EP_RX_VALID);

    static portBASE_TYPE xHigherPriorityTaskWoken;
    xHigherPriorityTaskWoken = pdFALSE;
    xSemaphoreGiveFromISR(xSemaphoreUSB_EP2_OUT, &xHigherPriorityTaskWoken );
}


Задача:
Код
void prvUSB( void *pvParameters )
{
    uint8_t                answer[64];
    GPIO_InitTypeDef      GPIO_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    //Set PA11,12 as USB_DM,DP
    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11 | GPIO_Pin_12;        // set DAC1 pin as analog output
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    xSemaphoreUSB_EP2_OUT = xSemaphoreCreateBinary();

    USB_Disconnect_Config();
    Set_USBClock();
    USB_Interrupts_Config();
    USB_Init();

    while(1)
    {
        if(xSemaphoreUSB_EP2_OUT != NULL)
        {
            if( xSemaphoreTake( xSemaphoreUSB_EP2_OUT, portMAX_DELAY  ) == pdTRUE )
            {
                // в answer получаем данные с хоста
                USB_SIL_Read(EP2_OUT, answer);

                // отправляем данные на хост
                USB_SIL_Write(EP1_IN, answer, 64);
                SetEPTxValid(ENDP1);
            }
        }
    }
}
Atlantis-
а обработка USB-запросов аналогичным образом?
uriy
Нет. В задаче у меня обрабатывается только поступление данных в эндпойнт.
Все остальное обрабаывается внутри прерываний.
Atlantis-
Цитата(uriy @ Jun 11 2015, 11:12) *
Нет. В задаче у меня обрабатывается только поступление данных в эндпойнт.
Все остальное обрабаывается внутри прерываний.

Вот меня интересует как раз вопрос, когда есть смысл создавать задачу, а когда выполнять действия сразу в прерывании? Есть какие то рекомендации на этот счет?
uriy
Для коротких прерываний нет смысла создавать задачу.
В задаче обработчике эндпойнта у меня, например, есть процедура записи параметров во флеш.
Делать это в прерывании слишком долго.
Atlantis-
У меня много разных USB запросов и наверно было бы правильно создать задачу для обработки запросов и из прерывания вызывать эту задачу, передавая в нее (через очередь) параметры запроса (поля и данные). Но у меня есть некоторые запросы, в которых надо отправлять данные на хост (USB запрос с данными) и тут я не понимаю, как это реализовать.
Получается, что после прихода запроса я записываю его параметры в очередь, запускается задача и все, а нужно еще в теле прерывания записать данные в буфер, чтобы они отправились на хост.
uriy
Так в примере который я приложил тоже отправляются данные на хост из задачи.
Вовсе не обязательно данные записывать в теле прерывания
Еще коммент специально по русски написал
Код
// отправляем данные на хост
                USB_SIL_Write(EP1_IN, answer, 64);
                SetEPTxValid(ENDP1);
Atlantis-
В STM-овских библиотеках сделано так: когда приходит USB запрос (неважно с данными или без) вызывается функция
Код
static int8_t CDC_Control_HS  (uint8_t cmd, uint16_t index, uint16_t value, uint8_t* pbuf, uint16_t length)
{

}


Если запрос с данными от хоста, то надо прочитать по адресу pbuf, а если надо отправить на хост - записать по адресу pbuf, очевидно до выхода из функции. Если я сделаю очередь, которая вызывает задачу, то задача запуститься уже после выхода из функции CDC_Control_HS
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.