Logo Robotech Nancy Wiki Robotech Nancy

Côté STM32

Côté STM32, l'initialisation est très simple :

// Démarrer le périphérique CAN
HAL_CAN_Start(hcan);

// Activer le mode interruption
HAL_CAN_ActivateNotification(hcan, CAN_IT_RX_FIFO0_MSG_PENDING);

Grâce à la seconde fonction, on indique quelle interruption doit être utilisée lorsqu'un message est reçu. Ici on utilise CAN_IT_RX_FIFO0_MSG_PENDING qui permet d'exécuter HAL_CAN_RxFifo0MsgPendingCallback lorsque le FIFO0 (queue) reçoit un message.

Côté Raspberry

Les librairies standard Linux sont utilisées pour communiquer avec le bus CAN. D'abord, on ouvre un socket :

// PF = Protocol Family
socket = ::socket(PF_CAN, SOCK_RAW, CAN_RAW);

// Ouverture du socket en mode non-bloquant
fcntl(socket, F_SETFL, O_NONBLOCK);

Ensuite, on vérifie que l'interface est prête à être utilisée :

ifreq ifr{};                          // ifreq = interface request
strcpy(ifr.ifr_name, CAN_INTERFACE);  // CAN_INTERFACE = "can0" ou "vcan0"
if (::ioctl(socket, SIOCGIFFLAGS, &ifr) < 0) {
    // Impossible de récupérer les flags de l'interface
    // donc l'interface est introuvable
}

if ((ifr.ifr_flags & IFF_UP) == 0) {
    // L'interface n'est pas up
}
if (::ioctl(socket, SIOCGIFINDEX, &ifr) < 0) {
    // Impossible de récupérer l'index de l'interface
}

Maintenant que l'interface est prête, on peut la lier au socket :

sockaddr_can addr{};
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;

if (::bind(socket, (sockaddr*) &addr, sizeof(addr)) < 0) {
    // Impossible de lier l'interface au socket
}