Предположим, у меня есть три узла CAN: A, B и C. Мы знаем, что когда два узла передают одновременно, то узел, имеющий наименьший SID, будет преобладать над шиной, и другой узел должен будет отдать шину первому. узел. Что я хотел бы сделать, так это то, что узлы B и C будут непрерывно отправлять кадр CAN узлу A последовательно (например, узел B -> узел A, узел C -> узел A, узел B -> узел A). Могу ли я просто назначить более низкий SID для B, чем для C, и просто выполнить следующий фрагмент кода?
Узел Б
while(1) sendCANmsg(data, NODE_A, sizeof(data), RTR_OFF);
Узел С
while(1) sendCANmsg(data, NODE_A, sizeof(data), RTR_OFF);
Внутри sendCANmsg есть фрагмент:
TXB0CONbits.TXREQ = 1; // Request Message Transmission
while (TXB0CONbits.TXREQ); // Wait until message is sent.
Кстати, я использую PIC18F25k80 для реализации этого. Я просто подумал, что после того, как узел B отправил сообщение, когда узел C собирается отправить свое сообщение. Узел B снова выиграет арбитраж шины, что не даст узлу C возможности передачи. Поэтому я исправляю, о чем могу только подумать, это вставить небольшую задержку, например:
while(1) {
sendCANmsg(data, NODE_A, sizeof(data), RTR_OFF);
delay_us(10);
}
Или я ошибаюсь? :)
Поскольку этот метод позволяет использовать шину почти на 100%, мы предполагаем, что эти 3 узла являются единственными узлами на шине. Основываясь на вашем времени задержки 10 мкс, мы также предполагаем, что скорость шины составляет 500 кбит/с (т. е. 5 бит задержки или 1 бит меньше ожидания после арбитража между сообщениями).
Будет ли этот метод работать или нет, во многом зависит от деталей реализации вашего CAN-драйвера. Более надежным способом добиться этого было бы, чтобы узлы B и C ждали чтения сообщения друг друга перед отправкой (с узлом B, изначально передающим без ожидания). IE:
Чтобы учесть десинхронизацию, каждый период ожидания должен иметь тайм-аут, после которого узел передает независимо от того, получил ли он сообщение другого узла.
Это уравновешивает использование шины и позволяет каждому контроллеру выполнять другие задачи, ожидая сообщения (вместо того, чтобы постоянно пытаться передать в случае арбитражного проигрыша).
Обратите внимание, что это нетрадиционное использование CAN. Возможно, вам будет лучше обслуживать более простой протокол, такой как SPI (узел A должен будет опрашивать B и C, но не потребуется арбитража, и все может быть DMA и/или управляемым прерыванием).
Во-первых, у узлов нет идентификаторов, а у сообщений есть.
Это сложно, и это не то, для чего CAN был разработан. Это должно работать, если каждый узел преднамеренно немного задерживается после каждой успешной передачи. Я не помню, позволяет ли оборудование PIC 18F25K80 узнать, когда кадр фактически отправлен, но, вероятно, это так. Другому узлу нужно только короткое окно, чтобы увидеть конец кадра и начать передачу. Как только этот второй узел начнет передачу, первый все равно автоматически задержит свое сообщение до следующего конца кадра.
Однако это звучит как злоупотребление шиной CAN, и лучшим ответом может быть переосмысление общей архитектуры.
Зегара
Скотт Уиндер
Зегара
Скотт Уиндер
Зегара