Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: AVR+FREERTOS+RS485
Форум разработчиков электроники ELECTRONIX.ru > Cистемный уровень проектирования > Операционные системы > FreeRTOS
Volldemar
Тупик, прошу помощи, это мой первый опыт с фриртосой.
Значит так, всё крутится в мега1284. Делаю пересылку между юсартами, с первого принимаю, на второй передаю, со второго принима, н апервый передаю. RS485 на втором. Пока было без драйверов 485 (ADM485) две FT232 на два порта юсба в комп, всё бегало без проблем, а вот с драйвером - беда, беда, печалька... Симптом: по юсарт1 принимаю байты, на юсарт2 выдаю, ну и запущено две терминальные проги на компе, теряются байты, передаю 20, принимаю 17...20.
вот мои обработчики прерываний:
Код
ISR( USART1_UDRE_vect )
{
    uint8_t cChar;
    signed portBASE_TYPE cTaskWoken;

    if( xQueueReceiveFromISR( xCharsForTx[1], &cChar, &cTaskWoken ) == pdTRUE )
    {
        RS485_tx;
        UDR1 = cChar;
    }
    else
    {
        vInterruptOff(1); // запрещение прерывания UDRE1
    }
}

Код
ISR( USART1_TX_vect )
{
    RS485_rx;
}

где косяк? подскажите плиз...
Volldemar
Код
inline portBASE_TYPE xSerialPutChar485( uint8_t uiUSARTport_num, unsigned portBASE_TYPE cOutChar, portTickType xBlockTime )
{
    uint8_t uiReturn;

    if( xQueueSendToBack( xCharsForTx[ uiUSARTport_num ], &cOutChar, xBlockTime ) == pdTRUE )
        {
            uiReturn = pdTRUE;
            vInterruptOn(uiUSARTport_num); //разрешение прерывания UDRE1
            return uiReturn;
        }
    else
        {
            uiReturn = pdFAIL;
            return uiReturn;
        }
}
Volldemar
Может я что то не так делаю? поздскажите, кто имел опыт с RS485 в фриртосе?
Задача, делающая перенаправление вот:
Код
static void prvUSARTEchoTask1( void *pvParameters )
{
    uint8_t cChar;

    ( void ) pvParameters;

    for(;; )
        {
            if (xSerialGetChar( mainUSART1, &cChar, portMAX_DELAY ) == pdTRUE)

            xSerialPutChar( mainUSART0, cChar, xNoBlock );
        }
    }
juvf
Цитата(Volldemar @ Apr 4 2012, 19:26) *
Симптом: по юсарт1 принимаю байты, на юсарт2 выдаю, ну и запущено две терминальные проги на компе, теряются байты, передаю 20, принимаю 17...20.

Не совсем понятно как комп отправляет/получает в/из RS485? Наверно есть преобразователь типа USB<->RS485? Проверьте, чтоб был отключен ..... программный контроль (follow control чтоли), иначе некоторые байты будут приняты за управляющие, например 0х11.

Не понятно, что за команда
Код
RS485_tx;
Это макрос какой-то?

Не понятно, а где управление ADM-кой? Ей на ноги надо выставлять RE и DE. Как минимум ногой DE дёргать. А чтоб эха не было ещё и RE нужно управлять.

ps При использовании в компе преобразователя USB<->COM некоторые проги на компе глючат с виртуальными компортами. У меня было подобное, терялись байты. (с чипами ftdi проблем не было, а вот с др были). Я для отладки таких вещей использую вместо говнотерминалок COM Port Toolkit

pps Да и программа как-то написана..... в таск1 вызов xSerialPutChar(), а ниже определение xSerialPutChar485(). Наверно это одно и тоже.
код функции xSerialPutChar485() - жесть. наверно это не вся функция и лишнее выкинуто. Но если это вся, то я бы определил её так
Код
inline portBASE_TYPE xSerialPutChar485( uint8_t uiUSARTport_num, unsigned portBASE_TYPE cOutChar, portTickType xBlockTime )
{
    if( xQueueSendToBack( xCharsForTx[ uiUSARTport_num ], &cOutChar, xBlockTime ) == pdTRUE )
    {
        vInterruptOn(uiUSARTport_num); //разрешение прерывания UDRE1
        return pdTRUE;
    }
    else
        return pdFAIL;
}
Volldemar
В компе, на двух юсбах висят FT232, на одной из них ADM485, вторая подключена к RXD/TXD меги.
Макросы:
Код
RS485_tx;
RS485_rx;

как раз управляют адм-кой (выводы RE и DE содинены вместе и подключены к свободному выводу меги), которая установлена на моей плате.
Пользуюсь терминалкой - QT_comport, так как указанная вами "COM Port Toolkit" почему то выдаёт ошибку при запуске, когда запущено два толкита.
juvf
Цитата(Volldemar @ Apr 13 2012, 12:09) *
В компе, на двух юсбах висят FT232, на одной из них ADM485, вторая подключена к RXD/TXD меги.

эээ...... тоже не совсем понятно.... получается путь такой:

РС - FT232R(USB-UART) -(три провода, TTL уровни)- ADM485 -(2 провода, уровни rs485)- ADM485 -(TTL уровни)- ATMega -
-(TTL уровни)- FT232R(UART-USB) - РС

Если так, то адм-кой возле атмеги управление макросами RS485_tx и RS485_rx. А кто управляет адм-кой возле компа?
Volldemar
Цитата(juvf @ Apr 13 2012, 09:59) *
эээ...... тоже не совсем понятно.... получается путь такой:

РС - FT232R(USB-UART) -(три провода, TTL уровни)- ADM485 -(2 провода, уровни rs485)- ADM485 -(TTL уровни)- ATMega -
-(TTL уровни)- FT232R(UART-USB) - РС

Если так, то адм-кой возле атмеги управление макросами RS485_tx и RS485_rx. А кто управляет адм-кой возле компа?

Путь сигнала:
РС USB1 - FT232R(USB-UART) - USART0 ATmega - USART1 ATmega ADM485 - ADM485 - FT232R - РС USB0
адм-кой возле компа рулит FT232R схема: http://bsvi.ru/perexodnik-usb-rs485/
juvf
Цитата
FT232. Оказывается, у нее есть ножка которая переключается в момент фактической передачи. Работает это на отлично
Не знал про это. *WRITE*

Ну если без адм-ок, с атмегой и ртосом всё работает на ура, то может косяк не в ртос? а как будут работать терминалки по пути:

РС USB1 - FT232R(USB-UART) - ADM485 - ADM485 - FT232R - РС USB0

Хотя в таком пути адм-кой, которой управляла атмега, некому управлять. можно у неё ноги DE и RE припаять к 0 или к 1. И проверить только в одну сторону. Может ртос с атмегой не причем, может косяк где-то в преобразователях?
Volldemar
Цитата(juvf @ Apr 13 2012, 12:02) *
Не знал про это. *WRITE*

Ну если без адм-ок, с атмегой и ртосом всё работает на ура, то может косяк не в ртос? а как будут работать терминалки по пути:

РС USB1 - FT232R(USB-UART) - ADM485 - ADM485 - FT232R - РС USB0

Хотя в таком пути адм-кой, которой управляла атмега, некому управлять. можно у неё ноги DE и RE припаять к 0 или к 1. И проверить только в одну сторону. Может ртос с атмегой не причем, может косяк где-то в преобразователях?

Уверен, что дело не в преобразователях, так как потери идут только по:
-> USART1 ATmega ADM485 - ADM485 - FT232R - РС USB0 ->
если:
-> РС USB0 FT232R - ADM485 - ADM485 - USART1 ATmega ->
то всё ходит без потерь...
да и осцилографом глядел форму сигнала на управляющей ноге меги, которая дрвгает и переключает адм-ку, там явно видны "провалы", и количество провалов соответствует количеству потеряных байт. Значит где то в алгоритме баг...

В варианте вот такого обработчика прерывания:
Код
ISR( USART1_TX_vect )
{
//        RS485_rx;
}
потери байтов нет.
В этом случает драйвер rs485 всегда включен на передачу.
unkier
а осцилом или логическим анализатором глянуть где именно пропадают байты ?
Volldemar
Цитата(unkier @ Apr 28 2012, 10:40) *
а осцилом или логическим анализатором глянуть где именно пропадают байты ?

Глядел осцилом, каждый раз, пропадает случайный байт (байты), повторяемости нет.
unkier
мигнуть светодиодом из обработчика прерывания ? и встать щупами на лампочки.
Lotor
Цитата(Volldemar @ Apr 4 2012, 17:26) *
Код
ISR( USART1_UDRE_vect )
{
    uint8_t cChar;
    signed portBASE_TYPE cTaskWoken;

    if( xQueueReceiveFromISR( xCharsForTx[1], &cChar, &cTaskWoken ) == pdTRUE )
    {
        RS485_tx;
        UDR1 = cChar;
    }
    else
    {
        vInterruptOff(1); // запрещение прерывания UDRE1
    }
}

Код
ISR( USART1_TX_vect )
{
    RS485_rx;
}

где косяк? подскажите плиз...

Я могу ошибаться, но смотрите, приоритет USART1_UDRE_vect выше чем USART1_TX_vect. И т.к. последнее разрешено всегда, то оно может вклиниться в неподходящий момент. Вот и потеря данных. Вообщем, самое простое - это переписать для начала код, чтобы использовалось одно прерывание USART1_TX_vect. Если потери исчезнут - то будете знать, где копать.
Volldemar
Цитата(Lotor @ Apr 28 2012, 14:47) *
Я могу ошибаться, но смотрите, приоритет USART1_UDRE_vect выше чем USART1_TX_vect. И т.к. последнее разрешено всегда, то оно может вклиниться в неподходящий момент. Вот и потеря данных. Вообщем, самое простое - это переписать для начала код, чтобы использовалось одно прерывание USART1_TX_vect. Если потери исчезнут - то будете знать, где копать.

Не особо понял на счёт применения только одного прерывания USART1_TX_vect. Проблема ещё актуальна, не победил sad.gif
Lotor
Цитата(Volldemar @ May 4 2012, 15:40) *
Не особо понял на счёт применения только одного прерывания USART1_TX_vect. sad.gif

Я предлагаю вам для поиска проблемы для начала использовать только это прерывание - переводите rs485 на передачу, в самом прерывании выгребаете очередь, когда она будет пуста переводить rs485 на прием. Есть вероятность, что в такой реализации потери исчезнут.
Volldemar
Проблему решил. Не знаю на сколько правильно, но работает.
Смысл в следующем. В задаче "эхо" <prvUSARTEchoTask1> делаю анализ периодического таймера, длительность таймера пятикратное время приёма одного байта на заданной скорости, если таймер запущен - сбрасываю, если не запущен - запускаю. Функция таймера запускает прерывание УДРЕ на передачу байтов из очереди. если буду предложения, замечания - жду sm.gif
bumborashik
Цитата(Volldemar @ May 8 2012, 17:48) *
Проблему решил. Не знаю на сколько правильно, но работает.
Смысл в следующем. В задаче "эхо" <prvUSARTEchoTask1> делаю анализ периодического таймера, длительность таймера пятикратное время приёма одного байта на заданной скорости, если таймер запущен - сбрасываю, если не запущен - запускаю. Функция таймера запускает прерывание УДРЕ на передачу байтов из очереди. если буду предложения, замечания - жду sm.gif

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