Canbus ID filter and mask

Canbus ID filter and mask 

CANBUS is a two-wire, half-duplex, bus based LAN system that is ‘collision free’.

Data is BROADCAST onto the bus -THERE IS NO SUCH THNG AS A POINT TO POINT CONNECTION as with data LANs.

All nodes receive all broadcast data and decide whether or not that data is relevant.

A CANBUS B frame consists of a four byte header (containing a 29-bit identifier), followed by up to 8 data bytes.

A receiving node would examine the identifier to decide if it was relevant (e.g. waiting for a frame with ID 00001567 which contains data to switch on or off a motor).

It could do this via software (using a C if or case statement); in practice the Canbus interface contains firmware to carry out this task

using the acceptance filter and mask value to filter out unwanted messages.

The filter mask is used to determine which bits in the identifier of the received frame are compared with the filter

  • If a mask bit is set to a zero, the corresponding ID bit will automatically be accepted, regardless of the value of the filter bit.

  • If a mask bit is set to a one, the corresponding ID bit will be compare with the value of the filter bit;
    if they match it is accepted otherwise the frame is rejected.
     

  • 0
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的基于CAN总线的STM32F103固件升级程序的代码示例,你可以根据实际情况进行修改: ``` #include "stm32f10x.h" #include "stm32f10x_flash.h" #include "stm32f10x_can.h" #define FLASH_PAGE_SIZE ((uint16_t)0x400) #define APP_ADDR ((uint32_t)0x08004000) #define APP_SIZE ((uint32_t)0x0001C000) #define BOOTLOADER_ADDR ((uint32_t)0x08000000) #define BOOTLOADER_SIZE ((uint32_t)0x00004000) #define CRC32_POLY ((uint32_t)0xEDB88320) uint32_t crc32(uint32_t crc, const uint8_t *buf, uint32_t len) { crc = ~crc; while (len--) { crc ^= *buf++; for (int i = 0; i < 8; i++) crc = crc & 1 ? (crc >> 1) ^ CRC32_POLY : crc >> 1; } return ~crc; } void flash_erase(uint32_t addr) { FLASH_Unlock(); FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); FLASH_ErasePage(addr); FLASH_Lock(); } void flash_write(uint32_t addr, const uint8_t *buf, uint32_t len) { FLASH_Unlock(); FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_PGERR | FLASH_FLAG_WRPRTERR); for (uint32_t i = 0; i < len; i += 4) { uint32_t data = buf[i] | (buf[i+1] << 8) | (buf[i+2] << 16) | (buf[i+3] << 24); FLASH_ProgramWord(addr + i, data); } FLASH_Lock(); } void bootloader_upgrade(uint8_t *buf, uint32_t len) { if (len < 8) return; uint32_t crc = crc32(0, buf, len - 4); if (crc != ((uint32_t)buf[len-4] | ((uint32_t)buf[len-3] << 8) | ((uint32_t)buf[len-2] << 16) | ((uint32_t)buf[len-1] << 24))) return; uint32_t addr = APP_ADDR; if (buf[0] == 0x12 && buf[1] == 0x34) { // check magic number uint32_t size = ((uint32_t)buf[2] << 24) | ((uint32_t)buf[3] << 16) | ((uint32_t)buf[4] << 8) | buf[5]; if (size <= APP_SIZE) { flash_erase(addr); flash_write(addr, buf + 8, size); crc = crc32(0, (uint8_t *)addr, size); flash_write(addr + size, (uint8_t *)&crc, 4); } } else if (buf[0] == 0x56 && buf[1] == 0x78) { // check magic number flash_erase(BOOTLOADER_ADDR); flash_write(BOOTLOADER_ADDR, buf + 8, BOOTLOADER_SIZE); } } int main() { RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_Init(GPIOA, &GPIO_InitStructure); CAN_InitTypeDef CAN_InitStructure; CAN_StructInit(&CAN_InitStructure); CAN_InitStructure.CAN_TTCM = DISABLE; CAN_InitStructure.CAN_ABOM = DISABLE; CAN_InitStructure.CAN_AWUM = DISABLE; CAN_InitStructure.CAN_NART = ENABLE; CAN_InitStructure.CAN_RFLM = DISABLE; CAN_InitStructure.CAN_TXFP = DISABLE; CAN_InitStructure.CAN_Mode = CAN_Mode_Normal; CAN_InitStructure.CAN_SJW = CAN_SJW_1tq; CAN_InitStructure.CAN_BS1 = CAN_BS1_9tq; CAN_InitStructure.CAN_BS2 = CAN_BS2_4tq; CAN_InitStructure.CAN_Prescaler = 4; CAN_Init(CAN1, &CAN_InitStructure); CAN_FilterInitTypeDef CAN_FilterInitStructure; CAN_FilterInitStructure.CAN_FilterNumber = 0; CAN_FilterInitStructure.CAN_FilterMode = CAN_FilterMode_IdMask; CAN_FilterInitStructure.CAN_FilterScale = CAN_FilterScale_32bit; CAN_FilterInitStructure.CAN_FilterIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdHigh = 0x0000; CAN_FilterInitStructure.CAN_FilterMaskIdLow = 0x0000; CAN_FilterInitStructure.CAN_FilterFIFOAssignment = CAN_Filter_FIFO0; CAN_FilterInitStructure.CAN_FilterActivation = ENABLE; CAN_FilterInit(&CAN_FilterInitStructure); uint8_t buf[256]; uint32_t len = 0; while (1) { if (CAN_MessagePending(CAN1, CAN_FIFO0) > 0) { CanRxMsg msg; CAN_Receive(CAN1, CAN_FIFO0, &msg); if (msg.IDE == CAN_Id_Standard && msg.RTR == CAN_RTR_Data && msg.DLC <= 8) { for (int i = 0; i < msg.DLC; i++) buf[len++] = msg.Data[i]; if (msg.DLC < 8) { bootloader_upgrade(buf, len); len = 0; } } } } } ``` 这段代码实现了一个基本的CAN总线固件升级程序,它监听CAN总线上的数据,当收到完整的固件升级包时,将新的固件写入FLASH中。需要注意的是,这段代码并没有进行完整性和安全性的检查,如果你需要更加安全可靠的固件升级方案,需要进行更多的优化和改进。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值