galjoen 0 7 февраля, 2010 Опубликовано 7 февраля, 2010 · Жалоба они выстроили протокол над CAN-контроллером, где имеют место быть квитанции (ACK). Вопрос: а зачем это надо? Плюнули пакет в сеть, по идее механизм разрешения коллизий и технично настроенный таймаут передачи гарантирует доставку пакета в сеть, или я не прав? В сеть то гарантирует, но неизвестно есть ли в сети в данный момент нужное устройство. Вот еще вопрос про физическую топологию. Хочу в один кабель запхать и CAN, и питание. Тянуть чистую "шину" не получается, "звезда" в моем случае оптимальна. Т.е. есть плата-дистрибьютор с кучей разъемов, например, DB-9. Максимальное расстояние от дистрибьютора до узла - метра три. Вопрос - а где ставить терминаторы? Нужно проложить пару туда-сюда к каждому девайсу. Всё равно наверняка лишние пары будут. А по другому никак. Усы 3 метра - это уже перебор. Ну или по стандарту J1708 сделать. Там как раз звезда. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AlexandrY 3 7 февраля, 2010 Опубликовано 7 февраля, 2010 · Жалоба Усы 3 метра - это уже перебор. Это зависит от битовой скорости. На 50 kbit отводы по 3-и метра несогласованным кабелем вполне работают. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kitsok 0 7 февраля, 2010 Опубликовано 7 февраля, 2010 · Жалоба Стандарт лезу читать. Про ошибки опять. Правильно ли я понимаю, что в полном контроллере (хм, не уверен, что это термин из какого-то стандарта, но CAN-контроллер AT90CAN именно так зовется) передатчик будет биться за арбитраж, пока таймаут не пройдет? Т.е. в предположении, что помехи и отсутствие нужного адресата в сети у нас исключаются, однако возможны коллизии из-за одновременного выхода в эфир нескольких узлов, верно ли утверждать, что при таймауте, выбранным адекватно нагрузки на сеть, неповрежденная отправка фрейма гарантированна? И еще вопрос про RTR. Правильно ли я разумею, что это - заложенный в стандарт механизм опроса узлов, а как он (опрос и соответствующая реакция, т.е. что будет послано в ответ) будет реализован - отдано на откуп дизайнеру? P.S. Извините пожалуйста за возможно глупые вопросы, я когда USB изучал, мозг на место вставал недели две ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kitsok 0 13 февраля, 2010 Опубликовано 13 февраля, 2010 · Жалоба Добрый день! Ввязался ;) Сейчас имеет место быть стенд из двух CAN-AVR от Olimex (at90can128 на борту). Одна постоянно шлёт пакетики, другая - принимает и отправляет дебаг в RS-232, плюс отсылает пакетик регулярно. Обнаружились забавные особенности. Во-первых, пока плата была одна, и шины как таковой не было (и терминатор был только один), не работало вообще ничего - контроллер выдавал ошибку, и по таймауту передача накрывалась. Во-вторых, но это возможно софтовый глюк, приемник принимает все пакеты передатчика по два раза, примерно вот так: Rcvd: 0x153 8 8e1000000 Rcvd: 0x153 8 8e1000000 Rcvd: 0x153 8 8f1000000 Rcvd: 0x153 8 8f1000000 Ну и в третьих, если снять питание с передатчика, то приемник может совершить отсылку одного-двух пакетов, после чего ситуация повторяет обрыв линии, т.е. ошибка передачи. Вопрос: а это правильно? Терминатор-то установлен вне зависимости от питания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kitsok 0 14 февраля, 2010 Опубликовано 14 февраля, 2010 · Жалоба Всем привет опять! Бьюсь, обессилил. Со стороны передатчика - FreeRTOS и два таска: /* continuously send CAN packets ID 0x151 with max speed (approx 1000Hz) */ static void send_function2( void *x) { (void)x; static CAN_packet packet={0x151, 8, "\0\0\0\0\0\0\0\0"}; for(;; ) { can_send( &packet, 10, 10); packet.data[1]++; vTaskDelay(500); } } /* periodically send CAN packet ID 0x150 */ static void send_function( void *x) { (void)x; static CAN_packet packet; packet.id=0x150; packet.length=2; packet.data[0]=0x00; packet.data[1]=0xaa; for(;; ) { can_send( &packet, 13, 500); packet.data[0]++; vTaskDelay(1000); } } Приемник - без изменений echo & spy из Атмеловских библиотек: -0- RxCAN @ C20C: 0x00000150(Ext.), L=2, 81-AA -0- RxCAN @ 047D: 0x00000151(Ext.), L=8, 00-03-00-00-00-00-00-00 -0- RxCAN @ 4686: 0x00000150(Ext.), L=2, 82-AA -0- RxCAN @ 88FB: 0x00000151(Ext.), L=8, 00-05-00-00-00-00-00-00 -0- RxCAN @ CAFD: 0x00000150(Ext.), L=2, 83-AA -0- RxCAN @ 0D72: 0x00000151(Ext.), L=8, 00-07-00-00-00-00-00-00 -0- RxCAN @ 4F75: 0x00000150(Ext.), L=2, 84-AA -0- RxCAN @ 91EB: 0x00000151(Ext.), L=8, 00-09-00-00-00-00-00-00 -0- RxCAN @ D3EC: 0x00000150(Ext.), L=2, 85-AA -0- RxCAN @ 1663: 0x00000151(Ext.), L=8, 00-0B-00-00-00-00-00-00 Т.е. каждый второй фрейм более "частого" таска - теряется. Ошибок нет, смотрел через JTAG регистры. Вот теперь я гадаю, где теряется фрейм - на приемнике, или на передатчике. Может кто-нибудь сталкивался? Update: Вот еще глюк, это уже серьезно ИМХО: -0- RxCAN @ E373: 0x00000151(Ext.), L=8, 00-0F-00-00-00-00-00-00 -0- TxCAN @ B704: 0x00000152(Ext.), L=8, 00-0F-00-00-00-00-E3-73 -0- RxCAN @ 2579: 0x00000150(Ext.), L=2, 08-AA -0- TxCAN @ D47F: 0x00000151(Ext.), L=8, 08-AA-00-00-00-00-25-79 -0- RxCAN @ 67EB: 0x00000151(Ext.), L=8, 00-11-00-00-00-00-00-00 Отсюда видно, что пакетик в D47F есть суперпозиция пересылки пакета 2579 и D47F (08-AA и 00-10-00...). Где же гарантированная целостность? ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
syoma 1 15 февраля, 2010 Опубликовано 15 февраля, 2010 · Жалоба Про ошибки опять. Правильно ли я понимаю, что в полном контроллере (хм, не уверен, что это термин из какого-то стандарта, но CAN-контроллер AT90CAN именно так зовется) передатчик будет биться за арбитраж, пока таймаут не пройдет? Нет. Каждый передатчик когда передает одновременно слушает линию. В CANе передатчики дерутся только в момент передачи ID пакета. В этот момент если один передатчик передаст 1 в линию а другой 0, то изза доминанты 0 в линии установится 0 и первый передатчик поймет, что арбитраж потерян и переключится на прием этого самого пакета от второго передатчика, то есть пакет не будет потерян. Так обеспечивется в CAN приоритет сообщений с более низким ID. Если же уровни не совпадут уже в теле сообщения - то это уже коллизия и будет ошибка. Обычно так бывает если два контроллера шлют сообщение с одним и тем же ID. И еще вопрос про RTR. Правильно ли я разумею, что это - заложенный в стандарт механизм опроса узлов, а как он (опрос и соответствующая реакция, т.е. что будет послано в ответ) будет реализован - отдано на откуп дизайнеру? Да. В атмелах помоему даже заложена возможность автоматической отправки ответа на RTR если пакет с соответсвующим адресом уже готов. По крайней мере в CC01 02 так. Во-первых, пока плата была одна, и шины как таковой не было (и терминатор был только один), не работало вообще ничего - контроллер выдавал ошибку, и по таймауту передача накрывалась. Конечно. Читайте внимательно спецификацию CAN. В сети должно быть как минимум 2 устройства изза того, что прием каждого сообщения приемником подтверждается установкой бита ACK в соответсвующий момент передачи. Так как у вас не было второго контроллера то первый не получал ACK и передача накрывалась. Т.е. каждый второй фрейм более "частого" таска - теряется. Ошибок нет, смотрел через JTAG регистры. Вот теперь я гадаю, где теряется фрейм - на приемнике, или на передатчике. Не знаю, что у вас в can_send - проверьте там есть ли у вас поллинг окончания передачи. Может быть что запись нового сообщения в регистры происходит до окончания передачи предыдущего. А вообще лучше очередь сообщений организовать и использовать CAN_send в отдельном таске. Последний глюк похоже тоже с этим связан. Плюс, забыл, - не забывайте прерывания отключать в CAN_send - а то ваш FreeRTOS может переключиться на другой таск в самый неподходящий момент. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
cant_101 0 15 февраля, 2010 Опубликовано 15 февраля, 2010 · Жалоба Читаю документец про сеть на борту наноспутника (http://etd.sun.ac.za/handle/10019/858 ) и удивляюсь: они выстроили протокол над CAN-контроллером, где имеют место быть квитанции (ACK). Вопрос: а зачем это надо? Плюнули пакет в сеть, по идее механизм разрешения коллизий и технично настроенный таймаут передачи гарантирует доставку пакета в сеть, или я не прав? Вот еще вопрос про физическую топологию. Хочу в один кабель запхать и CAN, и питание. Тянуть чистую "шину" не получается, "звезда" в моем случае оптимальна. Т.е. есть плата-дистрибьютор с кучей разъемов, например, DB-9. Максимальное расстояние от дистрибьютора до узла - метра три. Вопрос - а где ставить терминаторы? Смотря от задачи могли скоректировать под себя протокол. Протокол избыточен очень. Часть проверок можно опустить в пользу скорости. Мне как-то нужна была скорость максимальная. так вот: мне оказалось более выгодна 7бит адресация с передачей 8 байт без подтверждения для всех узлов сразу, чем деления на группы через фильтры. Протокол позваляет прямо по CAN передавать питание: сам хотел когда-то так сделать, но реально получается весьма не выгодно по баблу. в одном кабеле можно, но лучше соблюсти стандарт: CAN пустить витой парой в экране из земли, а рядом питание. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kitsok 0 15 февраля, 2010 Опубликовано 15 февраля, 2010 · Жалоба Не знаю, что у вас в can_send - проверьте там есть ли у вас поллинг окончания передачи. Может быть что запись нового сообщения в регистры происходит до окончания передачи предыдущего. А вообще лучше очередь сообщений организовать и использовать CAN_send в отдельном таске. Последний глюк похоже тоже с этим связан. Плюс, забыл, - не забывайте прерывания отключать в CAN_send - а то ваш FreeRTOS может переключиться на другой таск в самый неподходящий момент. Мысли мои читаете, или я - Ваши ;) Втыкал ночью в код и понял, что на самом деле вообще нигде не проверяю завершение передачи. Про отдельную очередь на передачу тоже мысль родилась, вечером попробую. Про остальные моменты - понял, я как-то не учел, что передатчик сам себя слушает, но Ack не доминантит ;) Еще напоролся у атмела на некоторый TTC mode, использующий таймер CAN-контроллера. Пока не нашел, что это такое. cant спасибо за опыт, посчитал потребление конечных устройств и понял, что питание будет отдельными проводами ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kitsok 0 16 февраля, 2010 Опубликовано 16 февраля, 2010 · Жалоба Чисто полтергейст. Функция отсылки фрейма, низкоуровневая: BOOL can_tx( char mob, CAN_packet *packet) { unsigned short cnt; cli();//portENTER_CRITICAL(); /* Select page (MOB 1) */ CANPAGE = 1 << 4; /* Setup DLC and IDE */ CANCDMOB = (packet->length) | (1<<IDE); /* Setup ID */ CANIDT1=0; CANIDT2=packet->id >>13; CANIDT3=packet->id >>5; CANIDT4=packet->id <<3; /* Load data to FIFO, byte index is autoincremented */ for (cnt=0; cnt<8; ++cnt) CANMSG = packet->data[cnt]; /* Debug counter */ cnt=0; /* Start transmittion */ CANCDMOB|=(1<<CONMOB0); //enable TX FIXME!!! /* Wait until TXOK is raised */ while (!(CANSTMOB & (1<<TXOK))) {cnt++;} /* Reset TXOK by read-modify-write */ CANSTMOB &= ~(1<<TXOK); /* Reset (disable) MOB */ CANCDMOB = 0x00; /* Finita */ sei(); return (TRUE); } Единственное место, где вызывается can_tx: /* Task for CAN transmittion */ void can_tx_task(void *x) { (void)x; static unsigned portCHAR mob; static CAN_packet packet; static unsigned portCHAR cnt; static portCHAR retv=FALSE; /* Create Tx queue */ CANTxQueue = xQueueCreate( 16, sizeof( CAN_packet)); ASSERT(CANTxQueue != 0); /* Find free MOB, die if no free channel found */ /* FIXME!!! MOB #0 used by Dump queue */ cli(); for( mob=1; mob < NO_MOBS; ++mob) { if( channels[mob]==0) break; } ASSERT(mob != NO_MOBS); channels[mob]=(CAN_cbf)0xffff; sei(); /* Main loop */ while(1) { /* Receive packet to send */ xQueueReceive( CANTxQueue, &packet, portMAX_DELAY); cnt=50; retv=TRUE; while( cnt--) { retv=can_tx( mob, &packet); if( retv==TRUE) // transmission succsessful { break; } vTaskDelay(1); } } } Многозадачность - кооперативная, не вытесняющая. Если в дебаггере, с остановкой на sei() can_tx - все отлично, пакеты улетают друг за другом, все работает как задумано. Без дебаггера - 2-байтовый пакет "затирает" длинный. Но не всегда Когда счетчик в первом байте длинного пакета (не ID, а payload) достигает 0x2a, все начинает работать как задумано ;) Эффект постоянный. Что это??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kitsok 0 17 февраля, 2010 Опубликовано 17 февраля, 2010 · Жалоба Отвечу себе сам. Это - криво написанная функция приема фреймов в Атмеловском примере. Приемник не справляется и молча теряет пакеты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться