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

jcxz

Свой
  • Постов

    13 478
  • Зарегистрирован

  • Посещение

  • Победитель дней

    34

jcxz стал победителем дня 29 июня

jcxz имел наиболее популярный контент!

Репутация

217 Очень хороший

4 Подписчика

Информация о jcxz

  • Звание
    Гуру
    Гуру
  • День рождения 01.12.1974

Контакты

  • ICQ
    Array

Информация

  • Город
    Array

Посетители профиля

28 453 просмотра профиля
  1. Зачем? У меня эти 16 адресов использовались всеми участниками CAN-сети. Типа - как параллельная шина. Самый старший адрес (базовый_CAN_ID + 15) - для передачи кадров управления (заголовки мультикадров и различные команды управления этой "шиной"). Точнее - старший адрес у каждого устройства был свой, а вот остальные 15 адресов - общие (для передачи тела данных мультикадров). Хотя наверное всё-таки = было 16 адресов для тела данных, а адреса управления - отдельно, у каждого устройства свой. У меня в сети были мастер и много слэйвов. Инициатива обмена мультикадром (на ввод или вывод) - всегда по инициативе мастера. Поэтому все слэйвы по дефолту держат свои 16 MO тела данных в режиме приёма; мастер - в режиме передачи. В прерывании выигрыша арбитража (вроде так) адреса управления мастер переключает свои 16 MO данных на приём (так как в этот момент все MO данных гарантированно уехали в шину); потом передаётся собственно кадр из MO управления. Один из слэйвов (который получил в свой адрес управления) финальный управляющий кадр; перед ответом переключает 16 MO данных на передачу; передаёт ответный мультикадр (или короткий ACK через адрес управления; если тело данных не нужно) и также в прерывании выигрыша арбитража на передачу заголовка переключает свои 16 MO данных на приём. Так нет коллизий (нет двух наборов MO данных одновременно настроенных на передачу в разных устройствах). Вобщем - такая себе полудуплексная квази-параллельная шина из 16 MO данных и одного MO управления. С одним прерыванием на передачу мультикадра и одним - на приём. Всего у нас устройств в шине планировалось - до 33 шт. Значит для всего интерфейса нужно: 16+33 шт. адресов. Вроде как не особо много. Требования по ресурсу CPU - очень низкие получились, практически незаметные на общей загрузке CPU Cortex-M4 144MHz. Только надо добавить небольшие защитные паузы перед переключением MO данных на передачу. Чтобы другая сторона гарантированно успела переключить свои на приём. Чтобы не мешали задержки входа в ISR на разных участниках обмена. ЗЫ: Глянул в исходники: всё-таки наврал - ширина шины у меня == 8 MO. Но задаётся дефайном, так что можно поменять в любой момент. #define CAN_NSLAVES 32 //макс.кол-во слэйвов #define CAN_UG_D_WIDTH 8 //кол-во MO (и адресов) используемых для отправки тела UG-кадра //Распределение адресов (11-битных) на внутренней CAN-шине. Адрес == смещению от начала ICanAddrSpace. struct ICanAddrSpace { char unuse0[16]; char obReset; //адрес сброс-сообщения (протокол обзора + UG) char unuse1[15]; char torque; //адрес рассылки задания крутящего момента char unuse2[32]; char obData; //протокол обзора. данные char obCmd; //протокол обзора. команды char obGarbage; //протокол обзора. сбор мусора char obScan[4]; //протокол обзора. сканирование серийных номеров char obInfo; //протокол обзора. информация о совместимости прошивок char unuse3[7]; char ugData[CAN_UG_D_WIDTH]; //адреса тела UG-кадра struct { char master; //адрес UG-master char slave[CAN_NSLAVES]; //адрес UG-slave } ugCtl; }; //Распределение CAN.MO. Номер MO == смещению от начала CanMoSpace. //Чем больше смещение - тем ниже приоритет при отправке на передачу. struct CanMoSpace { struct T_ug { //MO UG-протокола. Использование мастером и слэйвом: char data[CAN_UG_D_WIDTH]; //все: приём/передача тела UG-кадра char ctlRx; //все: приём заголовков char ctlTx; //все: отправка заголовков; мастер: отправка сброс-сообщений struct Observe { //MO протокола обзора. Использование MO мастером и слэйвом: char data; //мастер: отправка тела команды (свой UID); слэйв: приём тела команды (UID мастера) char cmd; //мастер: отправка заголовка команды; слэйв: приём заголовка команды char scanRx; //мастер: приём ответов от слэйва на проверку живости UID (в OBF_DELAY3); слэйв: приём RTR-запросов сканирования char scanTx; //слэйв: отправка ответов на RTR-запросы сканирования char misc; //мастер: приём информационных кадров (в OBF_SCAN0); слэйв: отправка ответов на проверки живости UID } observe; char reset; //все: приём сброс-сообщения } ug; struct T_ecan { char tele[CfgTele::STREAM_N]; //телеметрия char remote[CfgRemote::ITEM_n]; //дистанционное управление } ecan; }; ICanAddrSpace::ugCtl - как раз адреса интерфейса передачи мультикадров. CanMoSpace::data, CanMoSpace::ctlRx, CanMoSpace::ctlTx - MO этого протокола. Как видно - ресурсов шины он требует немного.
  2. Так вы же вроде свой протокол ваяете? Почему тогда для передачи мультикадров выделили только один адрес (CAN-ID)? Почему не выделить например - 16 последовательных адресов? Когда-то также пилил свой протокол поверх CAN. С передачей мультикадров. Просто выделил для него 16 последовательных адресов (CAN-ID). И передавал мультикадр так: вырезАл очередные <=8*15 байт данных (из передаваемого массива данных); пристыковывал к нему заголовок мультикадра (с необходимой инфой: индексом мультикадра в потоке, количеством кадров в мультикадре, CRC и т.п.). Затем нарезал тело мультикадра по 8 байт и передавал начиная от хвоста с нарастающим адресом: В таком случае FIFO не нужно - каждый кадр попадает в свой MO. И для отправки не нужна возможность в МК задавать порядок отправки: можно по порядку CAN-ID передавать - заголовочный CAN-ID всегда придёт последним. И прерывание нужно только одно - для заголовочного (последнего кадра); кадры тела принимаются/передаются без прерываний. Так сделал на всякий случай - хотя у меня был XMC4700 с аппаратными FIFO и множеством MO, но на всякий случай, если нужно будет подключать к шине МК с CAN-контроллером послабее.
  3. Судя по сообщениям ТС, он изобретает свой велосипед. И ему все эти канопены с их проблемами - не указ. Вот уж точно - такое есть не в каждом МК. Тем более. Не то что FIFO..... А ещё можно - часть ID под данные кадра. И тем - повысить плотность потока. Хотя степени двойки конечно уже не будет....
  4. Почему не помогает? Если в МК имеется 2+ шт. MO для приёма, то этого достаточно для двойной буферизации. И если не пропускать прерывания, то порядок приёма не будет нарушен.
  5. Тогда: не пропуская прерываний. Или вместо прерываний - DMA. Ну или действительно - выделить часть CAN-ID под индекс кадра внутри мульти-кадра.
  6. Зависит от конкретного МК и от протокола. Могу сказать как в XMC4xxx. Надо? В XMC4xxx достаточно для каждого mailbox-а указать маску адреса - какие CAN-ID в него принимать. А если все кадры - с одинаковыми CAN-ID, то можно например соединить mailbox-ы в цепочку FIFO. Которое будет заполняться по порядку. Ну и другие способы можно придумать.... например - при помощи DMA и FIFO уже в общей памяти. Хотя для XMC4700, с его 256 майлбоксами, это не нужно. Это уж не говоря о том, что можно просто тупо реагировать на каждое прерывание о приёме каждого нового кадра. И делать всё программно. А как в жизни - расскажете? У вас биты по CAN гуляют сами по себе, куда вздумается? Кроме пустых общих фраз, есть что по делу сказать?
  7. В смысле? А почему они должны приняться не в том порядке, в котором следуют по шине? Никаких роутеров, с ретрансляцией очевидно у ТС-а на шине нет.
  8. Можно выделять можно и не выделять. Так как при отправке хвостовой (или головной) кадр пакета кадров можно отправить последним. Сам делал такой протокол. Без дополнительных счётчиков.
  9. А кто мешает? Не очень понятно - что мешает отправить в нужном порядке? Приёмная сторона примет их точно в том порядке, в котором они будут передаваться по шине. Ибо - другое невозможно по определению.
  10. Ну тогда - для XMC4xxx: раздел "Transmit Acceptance Filtering". Но вкратце - нет никакой обязательной связи CAN-ID с порядком выставления на арбитраж. Порядок задаётся другими инструментами.
  11. Из исходного поста следует, что именно отправили: а не просто "положили в ящик". Почему я и попросил уточнения. Насчёт порядка отправки готовых для отправки MO, то в XMC4xxx вроде как порядок такой отправки (выхода MO на фазу TX-арбитража) вообще не зависит от CAN-ID кадра. А зависит только от положения MO в списке MO для данной ноды и поля приоритета, прописанного в свойствах MO. Нет такой гарантии. Или о чём вы тут говорите? Сам CAN описывает только фазу арбитража. А выставлять или нет на него кадр - решает CAN-контроллер МК. Решает в общем случае - никак не согласуясь с CAN-ID. Более того: CAN XMC4xxx позволяет программисту определять: участвовать ли готовому к отправке кадру в повторном TX-арбитраже, если он проиграл предыдущий арбитраж или нет? Программист может указать как действовать для каждого конкретного кадра.
  12. Если вы их уже отправили, то как они могут поменять порядок будучи уже отправленными? Странный вопрос.... Может вы всё-таки неверно сформулировали вопрос и он касается очередности выставления для участия в арбитраже для отправки на шину кадров из мэйл-боксов готовых к передаче? А не уже отправленных кадров. Порядок отправки зависит от вашего контроллера - он может отправлять как угодно, совершенно никак не связывая это с CAN-ID. Почитайте мануал на него. Для XMC4xxx например можно задать порядок отправки. И там есть несколько возможных режимов отправки. Постановка на арбитраж (для отправки) никак не связана с CAN-ID.
  13. Наверное всё-же - не в любых. IAR 7.80.4, си-файл: typedef unsigned char byte; byte PID_CODE[4]; void LongToBytes(long LG, char* BYTES, byte Index); void mm1(void); void LongToBytes(long LG, char* BYTES, byte Index) { byte i; for (i=0;i<4;i++) { BYTES[Index+i] = (*((unsigned char *)&(LG)+i)); } } void mm1(void) { LongToBytes(0x4445, PID_CODE, 0); LongToBytes(0x4445, (char *)&PID_CODE[0], 0); } результат: Warning[Pe167]: argument of type "byte *" is incompatible with parameter of type "char *" B:\TST\11.c 27 варнинг Pe167 на первую строку mm1(). Возможно вы правы. Не буду гадать - что там у автора, так как половину необходимой для понимания инфы он скрыл. Я просто говорил, что объявление функции нужно не такое, какое вы приводили. А с типом указателя byte *. Ну или добавить ещё приведение типа.
  14. При том, что неявное преобразование типа byte * -> char * компилятор автора видимо не умеет. Поэтому не может использовать имеющееся: void LongToBytes (long LG, char * BYTES, byte Index) без явного приведения типа. Имхо.
  15. Может здесь у автора также - есть халявный доступ к неограниченному количеству ионисторов? Как у автора недавней темы про "электровелосипед на ионисторах". И очень хочется их куда-нить пристроить. Не важно куда. Его ещё купить нужно. А ионисторы оне вот - в столе лежат... целой кучей... и "на халяву".
×
×
  • Создать...