Перейти к содержанию
    

Ошибки при обмене по протоколу CAN 2.0B в многопроцессорной системе

Все можно проверить осциллографом

Можно конечно и скопом битики сравнивать, но проще все на бумаге разложить по полочкам. ИМХО

 

Или подключить на "внутреннюю" шину USB-CAN в качестве снифера и смотреть что-же там делается на самом деле.

 

 

 

Задача устройства - регулирование исполнительного механизма в соответствии с показаниями датчиков.

Например, обьясню на одном из регулируемых параметров:

МК1 читает данные с датчика температуры, получает значение Т1 и выставляет его на шину CAN.

МК2 читает данные со второго датчика температуры, получает значение Т2, выставляет на шину.

 

Процессор МК3 получает по шине оба значения, расчитывает результирующее Трез = (Т1+Т2)/2 с частотой 100Гц.

Каждый кадр имеет так называемый "счетчик обновляемости".

в 100Гц-м цикле счетчик обновляемости каждого кадра уменьшается на 1, если кадр пришел - устанавливается в первоначальное значение. Для Т1 и Т2 счетчик равен 10. Если счетчик кадра = 0 (значит кадр "не приходил" 10 стогерцовых циклов подряд) - устройство генерирует отказ по контролю температуры.

Так в принципе и отловили баг - периодически генерировался данный отказ (редко достаточно).

Потом уже стали процерять по инкрементирующимся счетчикам.

Вы меня не поняли, я прошу отделить "мух от котлет". Вы же продолжаете все сваливать в кучу.

У меня подозрения что трудности не в CAN, а в общих алгоритмах.

Отделите CAN, у него простая функция - передать то, что ему положили в регистры.(ему же все равно что в него положили, температуру или давление, не про это речь)

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

Диагностику CAN надо отделить от диагностики остальной программы. Иначе ошибку можно искать без конца, потому что сложно выяснить что же все таки работает так, как должно. Надо постепенно отсекать те вещи из рассмотрения, которые полностью проверены и в которых вы полностью уверены.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Жаль :)

Тем не менее ничего не меняется. В шлюзе то не фрискэйл?

Мы тут ничего не выясним сейчас. Все можно проверить осциллографом - нужно передавать одинаковое сообщение, синхронизироваться от него и убедиться, что шлюз выдает подтверждение. Если да, то значит данные теряются внутри. А если нет... Тогда думать.

А так это гадания.

 

Данные теряются именно внутри:)

Отказы считают сами процессора, через шлюз выдают при тесте ТОЛЬКО счетчик ошибок (то есть сколько сам процессор насчитал пропусков). при передаче данных через шлюз эффект ошибок "удваивается" - так как в итоге две шины. Но на ошибки на шлюзе плевать - критичными являются ошибки на внутренней шине

 

 

Вы меня не поняли, я прошу отделить "мух от котлет". Вы же продолжаете все сваливать в кучу.

У меня подозрения что трудности не в CAN, а в общих алгоритмах.

Отделите CAN, у него простая функция - передать то, что ему положили в регистры.(ему же все равно что в него положили, температуру или давление, не про это речь)

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

Диагностику CAN надо отделить от диагностики остальной программы. Иначе ошибку можно искать без конца, потому что сложно выяснить что же все таки работает так, как должно. Надо постепенно отсекать те вещи из рассмотрения, которые полностью проверены и в которых вы полностью уверены.

Прошу прощения. Попробую конкретизировать на CAN'e.

Мы пришли к выводу, что ошибка при передаче через CAN (неизвестно в каком месте, при передаче, при приеме или ошибка на шине) следующим образом - выключили все остальные функции процессоров, оставив одну - передавать с частотой 100Гц инкрементирующийся счетчик с МК1 и МК2 и принимать их в МК3.

МК3 регистрирует пропуски по счетчикам.

 

Проверили алгоритм приема и передачи, логически они верны (в своей программе конечно можно искать ошибки год и не найти явную:)).

Теперь теряемся в догадках. Что это - не успевает выдать передатчик или приемник (на 1 раз за 100Гц можно успеть я думаю), коллизии на шине вроде бы исключены. На этом и завязли - какие еще причины могут быть? Конечно, просить на форуме "в каком месте в коде исправить" было бы глупо, поэтому здесь я хочу найти только направления, по которым нужно дальше двигаться в поисках причины

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Процессоры могут стартовать асинхронно, выдачу кадров осуществляют (всех, которые предназначены к выдаче с этого МК) с частотой 100 Гц. Тесты показали, что контроллер успевает выставить все данные на шину до наступления следующего цикла.

 

А частота у генераторов достаточно одинаковая ?

 

Частота по идее абсолютно одинаковая

Частота только по идее у них одинаковая :) . Плавали, знаю. Все процессоры будут плыть с разной скоростью в разные направления. Так что уповать на то, что все будут всегда попадать в нужные 100мс не стоит. На шине должен быть один синхронизатор, эталон общесистемных часов, который должен управлять временем в системе, на него должны все модули равняться.

 

 

 

МК3 регистрирует пропуски по счетчикам.

И снова не договариваете :)

Сколько пропусков на каком количестве посылок, стабильно ли это возникает?

Как регистрирует, N1 != N2 или анализируется линейность изменения каждого счётчика по-отдельности?

 

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

 

Может оказаться что вся бяда именно в том, что все синхронно только "по идее", а на деле все плывет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И снова не договариваете :)

Сколько пропусков на каком количестве посылок, стабильно ли это возникает?

Как регистрирует, N1 != N2 или анализируется линейность изменения каждого счётчика по-отдельности?

 

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

 

Может оказаться что вся бяда именно в том, что все синхронно только "по идее", а на деле все плывет.

 

Третий процессор проверяет так:

 

if (cnt1 - cnt1_old > 1) {errorMK1++;}

if (cnt2 - cnt2_old > 1) {errorMK2++;}

 

cnt1_old = cnt1;

cnt2_old = cnt2;

 

cnt1 и cnt2 - счетчики, принимаемые от МК1 и МК2.

И все это проверяется в 800 Гц (для верности воткнули на макс. частоту) цикле (в 8 раз чаще чем выдается).

Если новое значение счетчика еще не пришло - errorMK не изменится.

 

errorMK1 и errorMK2 даже приблизительно не равны друг другу. на значение счетчика 10000 (т.е. выдалось от 0 до 10000) errorMK1 может насчитать 10, а errorMK2 - 500. И наоборот.

Тенденция - счетчики растут лавинообразно - то есть могут не изменятся достаточно долго, потом резко растут, и снова "затыкаются".

Изменено пользователем Fledgling

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Третий процессор проверяет так:

 

if (cnt1 - cnt1_old > 1) {errorMK1++;}

if (cnt2 - cnt2_old > 1) {errorMK2++;}

 

cnt1_old = cnt1;

cnt2_old = cnt2;

 

cnt1 и cnt2 - счетчики, принимаемые от МК1 и МК2.

Хм, это странно, что счетчики изменяются нелинейно.

 

Надо проверять успешно ли завершается отправка из МК1 и МК2.

 

Но скорее всего ошибка в другом:

И все это проверяется в 800 Гц (для верности воткнули на макс. частоту) цикле (в 8 раз чаще чем выдается).

Если новое значение счетчика еще не пришло - errorMK не изменится.

Если ваш контроллер не использует режим FIFO то следует работать по прерыванию.

Все сообщения принимается в один приемный слот?

Фильтры каким-то образом используются?

 

Если вы работаете через один приемный слот, то данные у вас будут теряться.

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

 

Нельзя полингом работать при таких скоростях, даже если вы сделаете 1600 или 3200 Гц опроса.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Еще раз перечитал первые ваши посты. Сообщалось что пользуете буфера приема (несколько слотов настроены на прием). Но работает ли этот буферизованный прием?

Можно одним МК1 отправлять не одно, а несколько сообщений (последовательно и без паузы) в течении 100 мс и так же проверить на линейное изменение счетчика. Если будут ошибки, то буферизация не работает и в этом кроется ошибка.

 

Даже если буферизация у вас и работает, восемь слотов вы опрашиваете восемь раз за период отправки сообщений от источников, то без потерь вы будете обрабатывать только в том случае, если отправки формируются в строгой синхронизации и в 1/8 периода формирования сообщений по шине проходит не более 8 сообщений.

У вас синхронизации нет, поэтому без ошибок вы получать сообщения не сможете по определению (их количество будет увеличиваться с увеличением абонентов на шине).

 

Так что CAN не виноват, ошибочны подходы построения взаимодействий в системе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

На приеме только один слот, который буферизированный (обьект №15).

Чтение из него производится по прерыванию (у обоих контроллеров есть по прерыванию в таблице векторов).

 

Есть мнение что когда мы производим чтение из обьекта, приходит второй кадр - а обьект №15 в это время "заблокирован".

Может ли увеличение числа обьектов-приемников помочь или не стоит даже пытаться?:)

Или нужно менять весь алгоритм в целом и вводить синхронизацию?

 

Кстати пакеты все равно будут висеть на шине последовательно, даже при максимальной скорости передача одного пакета (CAN кадра) будет около 100 мкс, процессор вроде бы должен успевать обработать и считать в свой буфер содержимое кан-обьекта до поступления следующего кадра.

Изменено пользователем Fledgling

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Введение большего кол-ва приемников приведет к другим вопросам и проблемам ... проще сделать синхронизацию.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтение из него производится по прерыванию (у обоих контроллеров есть по прерыванию в таблице векторов).

Вектора то может быть и есть, а обработчики прерываний есть?

Раньше речь шла только о полинговом вычитывании с частотой в 8 раз больше, чем посылки.

 

Есть мнение что когда мы производим чтение из обьекта, приходит второй кадр - а обьект №15 в это время "заблокирован".

Может ли увеличение числа обьектов-приемников помочь или не стоит даже пытаться? :)

Или нужно менять весь алгоритм в целом и вводить синхронизацию?

Станет лучше, но полностью ошибку не исправит.

 

Синхронизацию вводить не обязательно (но с ней бы было проще), а вот с обработкой в прерывании надо видимо разобраться.

 

Кстати пакеты все равно будут висеть на шине последовательно, даже при максимальной скорости передача одного пакета (CAN кадра) будет около 100 мкс, процессор вроде бы должен успевать обработать и считать в свой буфер содержимое кан-обьекта до поступления следующего кадра.

А это как вы программу напишите, должно конечно успеть ;-)

 

PS:Я бы не использовал слово "объект", слот больше подходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Чтение из него производится по прерыванию (у обоих контроллеров есть по прерыванию в таблице векторов).

Какому прерыванию? Сколько времени занимает обработка?

 

Или нужно менять весь алгоритм в целом и вводить синхронизацию?

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

Получается, мы должны рассказывать, что у Вас происходит.

Буфер у Вас один. Из-за несинхронности наступает момент, когда кадры идут один за другим. Первый принимается, а второй нет, потому как буфер занят. А на второй кадр подтверждение дает то устройство, что передало первый кадр, поэтому второе устройство считает, что оно успешно приняло. А шлюз и не подозревает, что был еще кадр.

Даже в старом MCP2515 три буфера приема. И обрабатываются они примерно так:

 

//запись принятого фрейма(ов) в циклический буфер
void CanSpyReceiveService(void)
{    if (msg_head>=CAN_ARR_SIZE)  msg_head=0;
    if (!can_readMessage(&can_msg_array[msg_head])) return;
    else  msg_head++;
}
// чтение фрейма
uchar can_readMessage(CanMessage *msg)
{    uchar stat, res;
    
    stat = mcp2515_readStatus();
    if ( stat & MCP_STAT_RX0IF )
  {        // Msg in Buffer 0
        mcp2515_read_canMsg( _MCP_RXBUF_0, msg);
        mcp2515_modifyRegister(MCP_CANINTF, MCP_RX0IF, 0);
        res = 1;  //CAN_OK;
    }
    else if ( stat & MCP_STAT_RX1IF )
  {    // Msg in Buffer 1
        mcp2515_read_canMsg( _MCP_RXBUF_1, msg);
        mcp2515_modifyRegister(MCP_CANINTF, MCP_RX1IF, 0);
        res = 1;  //CAN_OK;
    }
    else
  {    res = 0;//CAN_NOMSG;
    }    
    return res;
}

Успехов

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вектора то может быть и есть, а обработчики прерываний есть?

Раньше речь шла только о полинговом вычитывании с частотой в 8 раз больше, чем посылки.

Конечно есть))

Обработчик прерывания считывает данные из слота в переменные в ОЗУ.

А контроль на 800Гц уже сверяет значение в этих ячейках.

Исходим из логического предположения, что кадр с одним и тем же ID приходит реже 800Гц:)

 

Станет лучше, но полностью ошибку не исправит.

Синхронизацию вводить не обязательно (но с ней бы было проще), а вот с обработкой в прерывании надо видимо разобраться.

А это как вы программу напишите, должно конечно успеть ;-)

PS:Я бы не использовал слово "объект", слот больше подходит.

Обработчик прерывания весь перерыли. Самое плохое, что писал его другой человек, тогда баги просто зевнули, человек уволился, баги остались, теперь мы с ними разбираемся:)

 

Работает он достаточно шустро, писали его на асме.

Вся обработка по оценке предварительной занимает куда меньше времени, необходимому для передачи одного кадра на шину)).

 

 

Подозрение попало также на передатчик, но мы "новички" не можем понять, то ли мы не осознаем гениальности автора процедуры передачи, то ли он накосячил. Приведу на всякий краткий алгоритм передачи:

Передача:

1) Находим свободный КАН-слот

проверяем комплементарные биты TXRQ и NEWDAT слова Message Control Register (13 и 9 биты - старшие биты TXRQ и NEWDAT) соответственно. Слово - в R2

BAND R2.13, R2.9

JNB R2.13, CAN_IS_FREE

Если нет, переходит к следующему слоту. Крутимся пока не найдем свободный (из слотов 0-7).

 

2) Начинаем обновление данных в ячейках слота, выставляем флаг "обновляем".

MOV R2, #0x5A7D ; set CPUUPD, reset MSGVAL

 

3) Устанавливаем регистры арбитража, конфигурационный регистр сообщения и копируем данные.

4) Завершаем апдейт данных и выдаем.

MOV R2, #0x66BD ; reset CPUUPD, set MSGVAL, TXRQ, NEWDAT

 

Все, передача 1 кадра завершена.

Изменено пользователем Fledgling

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какому прерыванию? Сколько времени занимает обработка?

 

Обработка прерывания по приему занимает 10-15 мкс.

В худшем случае

Изменено пользователем Fledgling

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Буфер у Вас один. Из-за несинхронности наступает момент, когда кадры идут один за другим. Первый принимается, а второй нет, потому как буфер занят. А на второй кадр подтверждение дает то устройство, что передало первый кадр, поэтому второе устройство считает, что оно успешно приняло. А шлюз и не подозревает, что был еще кадр.

Как такое возможно? Кадр передается по шине со скоростью 1МБит/сек порядка 100 мкс (примерно), а ассемблерная процедура приема успевает считать гораздо быстрее (просто посчитали количество инструкций, посмотрели сколько времени выолняется каждая, например MOV выполняется за 2 такта - 50 наносекунд). Значит до прихода следующего кадра уже точно слот №15 (приемник) освободится? или я ошибаюсь?

Изменено пользователем Fledgling

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как такое возможно? Кадр передается по шине со скоростью 1МБит/сек порядка 100 мкс (примерно), а ассемблерная процедура приема успевает считать гораздо быстрее (просто посчитали количество инструкций, посмотрели сколько времени выолняется каждая, например MOV выполняется за 2 такта - 50 наносекунд). Значит до прихода следующего кадра уже точно слот №15 (приемник) освободится? или я ошибаюсь?

 

Если вы не можете гарантировать правильность процедур, автора которых уже не отыскать, то надо исследовать процессы более наглядными вещами

1) снифер (USB-CAN) включенный на просмотр сообщений.(подключите уже шлейф от ПК на внутреннюю шину);

2) осциллограф;

3) светодиодик отображения времени выполнения процедуры.

 

Иначе гадать будете очень долго.

Тут народ простой, не экстрасенсы, сложно найти ошибку при куче неизвестных.

(про это уже твержу не первый раз)

 

Перепишите все на Си и голову не ломайте, должно успевать. А то может вы что-то просто путаете в асме. Когда заработает можно будет оптимизировать.

 

Исходим из логического предположения, что кадр с одним и тем же ID приходит реже 800Гц :)

Исходить можно, но лучше все таки все проверить ;)

Смысла не вижу в такой частоте опроса организованного "буфер".

 

Еще предположение:

Может у вас что-то не то с записью/вычитыванием из буфера при получении больше чем одного сообщения за 1/8.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...