赞
踩
上一篇写CAN的文章用的mb-message buffer
这次来搞FIFO收发。
FLEXCAN RXFIFO
意义
先声明一下搞FIFO的意义,配置为FIFO 模式,加大了接受数据的可靠性。这个模式会占用FLEXCAN模块的MB0-MB5 这5个邮箱。 硬件会自动将这几个邮箱作为FIFO。使能FIFO之后,在中断处理完成后,还会接着进中断。如果不开启FIFO,则会覆盖数据。
配置队列过滤器
CTRL2->RFFN :过滤器元素的数量
初始化FIFO队列的时候即:
FLEXCAN_DRV_Init->FLEXCAN_EnableRxFifo(前者调用后者传参num_id_filters 即写入RFFN寄存器的值)
上边这个就是下边FLEXCAN_RX_FIFO_ID_FILTERS_8 RFFN传入0x0
typedef enum { FLEXCAN_RX_FIFO_ID_FILTERS_8 = 0x0, /*!< 8 Rx FIFO Filters. @internal gui name="8 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_16 = 0x1, /*!< 16 Rx FIFO Filters. @internal gui name="16 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_24 = 0x2, /*!< 24 Rx FIFO Filters. @internal gui name="24 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_32 = 0x3, /*!< 32 Rx FIFO Filters. @internal gui name="32 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_40 = 0x4, /*!< 40 Rx FIFO Filters. @internal gui name="40 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_48 = 0x5, /*!< 48 Rx FIFO Filters. @internal gui name="48 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_56 = 0x6, /*!< 56 Rx FIFO Filters. @internal gui name="56 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_64 = 0x7, /*!< 64 Rx FIFO Filters. @internal gui name="64 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_72 = 0x8, /*!< 72 Rx FIFO Filters. @internal gui name="72 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_80 = 0x9, /*!< 80 Rx FIFO Filters. @internal gui name="80 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_88 = 0xA, /*!< 88 Rx FIFO Filters. @internal gui name="88 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_96 = 0xB, /*!< 96 Rx FIFO Filters. @internal gui name="96 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_104 = 0xC, /*!< 104 Rx FIFO Filters. @internal gui name="104 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_112 = 0xD, /*!< 112 Rx FIFO Filters. @internal gui name="112 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_120 = 0xE, /*!< 120 Rx FIFO Filters. @internal gui name="120 Rx FIFO Filters" */ FLEXCAN_RX_FIFO_ID_FILTERS_128 = 0xF /*!< 128 Rx FIFO Filters. @internal gui name="128 Rx FIFO Filters" */ } flexcan_rx_fifo_id_filter_num_t;
下表显示了RxFIFO滤波器的结构是如何由CTRL2[RFFN]的值决定的
过滤器元素数量为8;
RxFIFO和ID过滤器表所占用的消息缓冲区 MB0-7;
可用的剩余邮箱 MB8-31;
RxFIFOID过滤表元素受Rx私有掩码的影响元素 0-7;
RxFIFOID过滤表元素受Rx全局掩码的影响元素 0。
那现在的配置是FIFO占用MB0-5,剩下的MB6, 7 会被用做filter 的设置。
MB 6-7的空间能容纳8个 filter(4Byte存储一个filter), 这样RXIMR[0…7] 也有8个mask 与之对应, 这样 Rx FIFO global mask 就没有用途。
关于MB的结构
正常到0C就完事儿了这个是FD模式的,flexcan0最大有32个这样的mb,要用多少在PE里面设置。
配置掩码与过滤表
掩码的意义:掩码不影响筛选表,而是与对应的ID位是否需要去和MB里面设定的预期ID对比!!!!!!!!
关于掩码分为全局掩码和私有掩码
全局掩码:对全局MB有效。
私有掩码:对对应的MB有效。
SDK:
①FLEXCAN_DRV_SetRxMaskType
设置掩码类型:参数为全局掩码类型与私有掩码类型。
行为:向MCR寄存器IRMQ中写1 为私有掩码。
②FLEXCAN_DRV_SetRxIndividualMask
Eg:FLEXCAN_DRV_SetRxIndividualMask(INST_CANCOM1, FLEXCAN_MSG_ID_STD, id_counter, 0xC0000000|0x7FF);
行为:向特定的通道id_counter写入掩码0xC0000000|0x7FF ID为标准帧。
关于私有掩码的分析:
私有掩码则有64个,RXIMR0 - RXIMR63,对应MB0 – MB63,是一一对应的关系,所以私有掩码和对应的MB可以放到一起配置。
检查过滤器中相应的位。 0b-过滤器中相应的位是“不在乎”
这里举个例子我也是研究半天才看懂:
例如上边的0xC0000000|0x7FF掩码参数,传参进去之后是标准帧调用FLEXCAN_SetRxIndividualStdMask设置标准帧私有掩码
实现:(base->RXIMR[msgBuffIdx]) = (stdMask << CAN_ID_STD_SHIFT) & CAN_ID_STD_MASK;
CAN_ID_STD_SHIFT 宏为18
即0xC00007FF 左移18位=0x1FFC0000;
#define CAN_ID_STD_MASK 0x1FFC0000u
相与之后还是0x1FFC0000u
这个0x1FFC0000u二进制是 00011111111111000000000000000000
正好是19-29位 标准帧全部接受check
现在我们传入掩码0xC0000000|0x7FC
RXIMR最后得到的值是0x1FF00000二进制是11111111100000000000000000000 少了1920两个bit也就是说为0,也就dont care。如果来的是0x123ID的话掩码为0x7FC能通过掩码的ID为0x123~0x126 两个bit最多是3!!!!
结合理论测试一下
这里边主要检验掩码也就是hal_mcu_can_open函数中调用
①for(i = 0; i < 8; i++)
{
conf->canbus_fifo_filter_table[i].isRemoteFrame = FALSE;
conf->canbus_fifo_filter_table[i].isExtendedFrame = FALSE;
//conf->canbus_fifo_filter_table[i].id = i + 1;
conf->canbus_fifo_filter_table[i].id = 0x111;
}
FLEXCAN_DRV_ConfigRxFifo(conf->instance, FLEXCAN_RX_FIFO_ID_FORMAT_A, conf->canbus_fifo_filter_table);
②FLEXCAN_DRV_SetRxMaskType(conf->instance, FLEXCAN_RX_MASK_INDIVIDUAL);
③for(id_counter=0;id_counter<8;id_counter++)
FLEXCAN_DRV_SetRxIndividualMask(INST_CANCOM1, FLEXCAN_MSG_ID_STD, id_counter, 0xC0000000|0x7FF);
总结一下就是 RX FIFO接收 8个过滤器,每个过滤器都过滤ID 0x111,用私有掩码配合,0不check1就check,我现在只允许0x111通过!!!
hal_uart.c
#include "../inc/hal_can.h" QueueHandle_t hw_can_queue = NULL; /* func: can gpio irq func register * prara: call back func * return: boolen */ int hal_can_pioirq_register(int (*handler)(void)) { for (int i = 0; i < TYPE_BID_COUNT; i++) { if (pio_type_handlers[i].handler == handler) { return i; } if (pio_type_handlers[i].handler == NULL) { pio_type_handlers[i].handler = handler; return i; } } return -1; } /* func: get canbus public config * prara: none * return: hal_canbus_public_t */ static hal_canbus_public_t *hal_canbus_get_public(void) { return &canbus_public_config; } /* func: get canbus config * prara: CAN_CH_E * return: hal_canbus_config_t */ static hal_canbus_config_t *hal_canbus_get_config(CAN_CH_E ch) { if (ch >= MAX_CAN_CH) { return NULL; } hal_canbus_config_t *ctx = &g_canbus_ctx[ch]; if (ctx->init_conf == NULL || ctx->state == NULL) { return NULL; } return ctx; } /* func: mcu can send api main func:give mcucan_tx_ready sem * prara: CAN_CH_E/can_msg_t * return: BOOLEAN */ BOOLEAN hal_mcu_can_send(INT8U ch, can_msg_t* msg) { hal_canbus_tx_data_t csd; hal_canbus_public_t *ctx; hal_canbus_config_t *conf; INT8U i; if (ch >= HAL_MCUCAN_SUPPPORT_MAX_CHL) { return FALSE; } conf = hal_canbus_get_config(ch); ctx = hal_canbus_get_public(); for (i = 0; i < sizeof(g_canbus_ctx) / sizeof(g_canbus_ctx[0]); i++) { if (conf->instance == ch) { if (conf->canbus_open_flag == CANBUS_STATUS_OPEN) { break; } else { return FALSE; } } } if (i == sizeof(g_canbus_ctx) / sizeof(g_canbus_ctx[0])) { return FALSE; } if (ringbuf_is_full(ctx->rb_tx)) { return FALSE; } memcpy(&csd, msg, sizeof(hal_canbus_tx_data_t) - sizeof(csd.chl)); csd.chl = ch; if (ringbuf_write(ctx->rb_tx, &csd, sizeof(hal_canbus_tx_data_t)) != sizeof(hal_canbus_tx_data_t)) { return FALSE; } xSemaphoreGive(ctx->mcucan_tx_ready); return TRUE; } /* func: mcu can send SDK api package * prara: CAN_CH_E/can_msg_t * return: BOOLEAN */ BOOLEAN hal_canbus_sdk_send(hal_canbus_tx_data_t *csd) { flexcan_data_info_t dataInfo; INT8U can_tx_status; hal_canbus_public_t *pbc; pbc = hal_canbus_get_public(); //xSemaphoreTake(pbc->tx_mutex, 100); dataInfo.data_length = csd->dlc; dataInfo.fd_enable = 0; dataInfo.msg_id_type = csd->ide; dataInfo.is_remote = csd->rtr; FLEXCAN_DRV_ConfigTxMb(csd->chl, 10, &dataInfo, csd->canid); can_tx_status = FLEXCAN_DRV_SendBlocking(csd->chl, 10, &dataInfo, csd->canid, csd->data, 20); if (can_tx_status != STATUS_SUCCESS) { extern void FLEXCAN_CompleteTransfer(uint8_t instance, uint32_t mb_idx); FLEXCAN_CompleteTransfer(csd->chl, 10); } //xSemaphoreGive(pbc->tx_mutex); if (can_tx_status != STATUS_SUCCESS) { return FALSE; } else { return TRUE; } } /* func: mcu can read API * prara: ch /can_msg_t * return: BOOLEAN */ INT8S hal_mcu_can_read(INT8U ch, can_msg_t* msg) { hal_canbus_public_t *pbc; hal_canbus_rx_data_t csd; (void)ch; if (ch >= HAL_MCUCAN_SUPPPORT_MAX_CHL) { return FALSE; } if (msg == NULL) { return -1; } pbc = hal_canbus_get_public(); taskENTER_CRITICAL(); if (ringbuf_is_empty(pbc->rb_rx)) { taskEXIT_CRITICAL(); return 0; } if (ringbuf_read(&csd, pbc->rb_rx, sizeof(hal_canbus_rx_data_t)) != sizeof(hal_canbus_rx_data_t)) { taskEXIT_CRITICAL(); return -1; } taskEXIT_CRITICAL(); if (csd.dlc > 8) { return -1; } msg->canid = csd.canid; msg->chl = csd.chl; msg->dlc = csd.dlc; memcpy(msg->data, csd.data, csd.dlc); msg->ide = CAN_ID_EXT; return 1; } /* func: mcu can irq call back func * prara: ins /event /state * return: BOOLEAN */ void hal_canbus_error_cb(uint8_t instance, flexcan_event_type_t eventType, flexcan_state_t *flexcanState) { (void)flexcanState; if (eventType == FLEXCAN_EVENT_ERROR) { for (INT8U i = 0; i < COUNTOF(hal_canbus_status_group); i++) { if (hal_canbus_status_group[i].instance == instance && hal_canbus_status_group[i].status != CANBUS_STATUS_ERROR) { hal_canbus_status_group[i].status = CANBUS_STATUS_ERROR; //xQueueSendFromISR(hw_sys_queue, (void*)&hal_canbus_status_group[i].msg_error, NULL); } } } } /* func: mcu can gpio err irq call back * prara: none * return: BOOLEAN */ static int hal_err_interrupt_cb(void) { INT32U Port_IntFlag = 0; /* read the PORT interrupt flags*/ INT8U i; for (i = 0; i < COUNTOF(hal_canbus_errpin_group); i++) { if (hal_canbus_errpin_group[i].status == CANBUS_STATUS_OPEN) { Port_IntFlag = PINS_DRV_GetPortIntFlag(hal_canbus_errpin_group[i].base); if(Port_IntFlag & (1 << hal_canbus_errpin_group[i].pinPortIdx)) { PINS_DRV_ClearPinIntFlagCmd(hal_canbus_errpin_group[i].base, hal_canbus_errpin_group[i].pinPortIdx); break; } } } if (i < COUNTOF(hal_canbus_errpin_group)) { for (i = 0; i < COUNTOF(hal_canbus_status_group); i++) { if (hal_canbus_status_group[i].instance == hal_canbus_errpin_group[i].instance && hal_canbus_status_group[i].status != CANBUS_STATUS_ERROR) { hal_canbus_status_group[i].status = CANBUS_STATUS_ERROR; //xQueueSendFromISR(hw_sys_queue, (void*)&hal_canbus_status_group[i].msg_error, NULL); } } } return TRUE; } /* func: mcu can call back * prara: instance event buffIdx flexcan_state_t * return: BOOLEAN */ static void hal_can_call_back_func(INT8U instance, flexcan_event_type_t event, INT32U buffIdx, flexcan_state_t *flexcanState) { hal_canbus_rx_data_t canbus_rx_data; BaseType_t xResult; BaseType_t xHigherPriorityTaskWoken = pdFALSE; hw_sys_task_msg_e hw_sys_msg = HW_SYS_MSG_CAN0; (void)buffIdx; (void)flexcanState; switch (event) { case FLEXCAN_EVENT_RX_COMPLETE: break; case FLEXCAN_EVENT_TX_COMPLETE: break; case FLEXCAN_EVENT_RXFIFO_COMPLETE: { FLEXCAN_DRV_RxFifo(instance, &canbus_rx_msg_data[instance]); canbus_rx_data.chl = instance; canbus_rx_data.canid = canbus_rx_msg_data[instance].msgId; canbus_rx_data.dlc = canbus_rx_msg_data[instance].dataLen; memcpy(canbus_rx_data.data, canbus_rx_msg_data[instance].data, canbus_rx_msg_data[instance].dataLen); for (INT8U i = 0; i < COUNTOF(hal_canbus_status_group); i++) { if (hal_canbus_status_group[i].instance == instance && hal_canbus_status_group[i].status != CANBUS_STATUS_OK) { hal_canbus_status_group[i].status = CANBUS_STATUS_OK; xQueueSendFromISR(hw_can_queue, (void*)&hal_canbus_status_group[i].msg_ok, NULL); } } if (instance == INST_CANCOM1) { hw_sys_msg = HW_SYS_MSG_CAN0; } if (!ringbuf_is_full(canbus_public_config.rb_rx)) { if (ringbuf_write(canbus_public_config.rb_rx, &canbus_rx_data, sizeof(hal_canbus_rx_data_t)) == sizeof(hal_canbus_rx_data_t)) { } } if (hw_can_queue != NULL) { xResult = xQueueSendFromISR(hw_can_queue, (void*)&hw_sys_msg, &xHigherPriorityTaskWoken); if(xResult != pdFAIL) { portEND_SWITCHING_ISR(xHigherPriorityTaskWoken); } } break; } case FLEXCAN_EVENT_ERROR: case FLEXCAN_EVENT_RXFIFO_OVERFLOW: { FLEXCAN_DRV_RxFifo(instance, &canbus_rx_msg_data[instance]); break; } case FLEXCAN_EVENT_RXFIFO_WARNING: case FLEXCAN_EVENT_WAKEUP_TIMEOUT: case FLEXCAN_EVENT_WAKEUP_MATCH: case FLEXCAN_EVENT_SELF_WAKEUP: case FLEXCAN_EVENT_DMA_COMPLETE: case FLEXCAN_EVENT_DMA_ERROR: break; } } /* func: mcu can tx os task * prara: instance event buffIdx flexcan_state_t * return: BOOLEAN */ static void hal_mcucan_tx_task(void* args) { (void)args; hal_canbus_public_t *pbc; hal_canbus_tx_data_t csd; BaseType_t xReturn = pdPASS; INT32S data_size = sizeof(hal_canbus_tx_data_t); pbc = hal_canbus_get_public(); for(;;) { xReturn = xSemaphoreTake(pbc->mcucan_tx_ready, 100); if (pdFALSE == xReturn) { continue; } while (!ringbuf_is_empty(pbc->rb_tx)) { if (ringbuf_read(&csd, pbc->rb_tx, data_size) == data_size) { hal_canbus_sdk_send(&csd); } } } } /* func: mcu can ringbuf init * prara: hal_canbus_public_t * return: BOOLEAN */ static BOOLEAN hal_canbus_ringbuf_init(hal_canbus_public_t *rb) { if (rb->rb_rx == NULL) { rb->rb_rx = ringbuf_malloc(HAL_MCUCAN_RX_MSG_SIZE * sizeof(hal_canbus_rx_data_t)); if (!rb->rb_rx) { return FALSE; } } if (rb->rb_tx == NULL) { rb->rb_tx = ringbuf_malloc(HAL_MCUCAN_RX_MSG_SIZE * sizeof(hal_canbus_tx_data_t)); if (!rb->rb_tx) { vPortFree(rb->rb_rx); return FALSE; } } return TRUE; } /* func: mcu can set baudrate * prara: CAN_CH_E/CAN_BAUDRATE_E * return: BOOLEAN */ BOOLEAN hal_mcucan_set_baudrate(CAN_CH_E ch, CAN_BAUDRATE_E baudrate) { INT8U i; INT16U baudrate_value; hal_canbus_config_t *conf; if (ch >= HAL_MCUCAN_SUPPPORT_MAX_CHL)//澶т簬鏈�澶ч�氶亾 { return FALSE; } conf = hal_canbus_get_config(ch); if (conf == NULL) { return FALSE; } switch (baudrate) { case CAN_10K: baudrate_value = 10; break; case CAN_20K: baudrate_value = 20; break; case CAN_50K: baudrate_value = 50; break; case CAN_100K: baudrate_value = 100; break; case CAN_125K: baudrate_value = 125; break; case CAN_250K: baudrate_value = 250; break; case CAN_500K: baudrate_value = 500; break; case CAN_800K: baudrate_value = 800; break; case CAN_1000K: baudrate_value = 1000; break; default: break; } for (i = 0; i < sizeof(g_baudrate_ctx) / sizeof(g_baudrate_ctx[0]); i++) { if (baudrate_value == g_baudrate_ctx[i].baudrate) { conf->init_conf->bitrate.phaseSeg1 = g_baudrate_ctx[i].conf->phaseSeg1; conf->init_conf->bitrate.phaseSeg2 = g_baudrate_ctx[i].conf->phaseSeg2; conf->init_conf->bitrate.preDivider = g_baudrate_ctx[i].conf->preDivider; conf->init_conf->bitrate.propSeg = g_baudrate_ctx[i].conf->propSeg; conf->init_conf->bitrate.rJumpwidth = g_baudrate_ctx[i].conf->rJumpwidth; conf->init_conf->bitrate_cbt.phaseSeg1 = g_baudrate_ctx[i].conf->phaseSeg1; conf->init_conf->bitrate_cbt.phaseSeg2 = g_baudrate_ctx[i].conf->phaseSeg2; conf->init_conf->bitrate_cbt.preDivider = g_baudrate_ctx[i].conf->preDivider; conf->init_conf->bitrate_cbt.propSeg = g_baudrate_ctx[i].conf->propSeg; conf->init_conf->bitrate_cbt.rJumpwidth = g_baudrate_ctx[i].conf->rJumpwidth; return TRUE; } } return FALSE; } /* func: mcu can set mode * prara: CAN_CH_E/HAL_CAN_CHIP_MODE_E * return: BOOLEAN */ BOOLEAN hal_mcu_can_modeset(CAN_CH_E ch, HAL_CAN_CHIP_MODE_E mode) { INT8U EN, STB; if (ch >= HAL_MCUCAN_SUPPPORT_MAX_CHL || mode >= MAX_CANBUS_MODE)//check { return FALSE; } switch(mode) { /* TJA1043 * normal mode: EN = 1, STB = 1; * Standby mode: EN = 0, STB = 0; * listen mode: EN = 0, STB = 1; * sleep mode: EN = 1, STB = 0; * TJA1042T/3 * normal mode: STB = 0; * Standby mode: STB = 1; * 娉�: TJA1042T/3鍜孴JA1043鐩稿悓妯″紡寮曡剼鐢靛钩鐩稿弽*/ case CANBUS_MODE_NORMAL: EN = 1; STB = 1; break; /* interface chip: TJA1043 */ case CANBUS_MODE_STANDBY: EN = 0; STB = 0; break; /* interface chip: TJA1043 */ case CANBUS_MODE_LISTEN: EN = 0; STB = 1; break; /* interface chip: TJA1043 */ case CANBUS_MODE_SLEEP: EN = 1; STB = 0; break; /* interface chip: TJA1043 */ default: break; } switch (ch) { case CAN_CH0: /* interface chip: TJA1043 */ PINS_DRV_WritePin(PTC, 10, EN); /* CAN1_EN */ PINS_DRV_WritePin(PTC, 9, STB); /* CAN1_STB */ break; case CAN_CH1: /* interface chip: TJA1043 */ PINS_DRV_WritePin(PTA, 11, EN); /* CAN2_EN */ PINS_DRV_WritePin(PTB, 16, STB); /* CAN2_STB */ break; case CAN_CH2: /* interface chip: TJA1042T/3 */ if (STB == 1) { PINS_DRV_WritePin(PTB, 15, 0); /* CAN2_STB */ } else { PINS_DRV_WritePin(PTB, 15, 1); /* CAN2_STB */ } break; case CAN_CH3: break; default: break; } return TRUE; } /* func: mcu can open API * prara: CAN_CH_E/can_init_cfg_t * return: BOOLEAN */ BOOLEAN hal_mcu_can_open(CAN_CH_E ch, can_init_cfg_t* init_cfg) { hal_canbus_config_t *conf; hal_canbus_public_t *pbc; INT8U i,id_counter; if (ch >= HAL_MCUCAN_SUPPPORT_MAX_CHL)//check can channel index { return FALSE; } pbc = hal_canbus_get_public(); if (hal_canbus_ringbuf_init(pbc) != TRUE)//ringbuf缂撳瓨鍒濆鍖� { return FALSE; } if(pbc->mcucan_tx_ready == NULL) { pbc->mcucan_tx_ready = xSemaphoreCreateBinary();//申请创建一个二值信号量 } conf = hal_canbus_get_config(ch); if (hal_mcucan_set_baudrate(ch, init_cfg->baudrate) != TRUE)//璁剧疆娉㈢壒鐜� { return FALSE; } if (hal_mcu_can_modeset(ch, CANBUS_MODE_NORMAL) == FALSE)//CAN妯″紡璁剧疆 { return FALSE; } conf->canbus_callback_cb = (flexcan_callback_t)hal_can_call_back_func;//鎺ユ敹鍥炶皟鍑芥暟 for (i = 0; i < COUNTOF(hal_canbus_IRQn_group); i++)//can鎬荤嚎鎺ユ敹鎬荤嚎閿欒鎬荤嚎鎺夌嚎璁剧疆浼樺厛绾� { if (hal_canbus_IRQn_group[i].instance == conf->instance) { INT_SYS_SetPriority(hal_canbus_IRQn_group[i].irq_received, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); INT_SYS_SetPriority(hal_canbus_IRQn_group[i].irq_error, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); INT_SYS_SetPriority(hal_canbus_IRQn_group[i].irq_busoff, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); } } FLEXCAN_DRV_Init(conf->instance, conf->state, conf->init_conf);//flexcan鍒濆鍖� FLEXCAN_DRV_InstallEventCallback(conf->instance, conf-> canbus_callback_cb, NULL);//鎺ユ敹鍥炶皟鍑芥暟 FLEXCAN_DRV_InstallErrorCallback(conf->instance, hal_canbus_error_cb, NULL);//err鍥炶皟鍑芥暟 if (pbc->canbus_task_handle == NULL)//os浠诲姟 { pbc->canbus_task_handle = xTaskCreate(hal_mcucan_tx_task,"canbus_task", 1024U, NULL,HAL_MCUCAN_TASK_PRIORITY,NULL); if (pbc->canbus_task_handle == NULL) { return FALSE; } } if (pbc->tx_mutex == NULL)//鐢宠鍙戦�侀攣 { pbc->tx_mutex = xSemaphoreCreateMutex(); if (pbc->tx_mutex == NULL) { return FALSE; } } for(i = 0; i < 8; i++) { conf->canbus_fifo_filter_table[i].isRemoteFrame = FALSE; conf->canbus_fifo_filter_table[i].isExtendedFrame = FALSE; //conf->canbus_fifo_filter_table[i].id = i + 1; conf->canbus_fifo_filter_table[i].id = 0x111; } FLEXCAN_DRV_ConfigRxFifo(conf->instance, FLEXCAN_RX_FIFO_ID_FORMAT_A, conf->canbus_fifo_filter_table); FLEXCAN_DRV_SetRxMaskType(conf->instance, FLEXCAN_RX_MASK_INDIVIDUAL); //FLEXCAN_DRV_SetRxFifoGlobalMask(conf->instance, FLEXCAN_MSG_ID_EXT, 0); //FLEXCAN_DRV_RxFifo(conf->instance, &canbus_rx_msg_data[conf->instance]); for(id_counter=0;id_counter<8;id_counter++) FLEXCAN_DRV_SetRxIndividualMask(INST_CANCOM1, FLEXCAN_MSG_ID_STD, id_counter, 0xC0000000|0x7FF); FLEXCAN_DRV_RxFifo(conf->instance, &canbus_rx_msg_data[conf->instance]); for (i = 0; i < COUNTOF(hal_canbus_errpin_group); i++)//err pin flag { if (hal_canbus_errpin_group[i].instance == conf->instance) { PINS_DRV_ClearPinIntFlagCmd(hal_canbus_errpin_group[i].base, hal_canbus_errpin_group[i].pinPortIdx); INT_SYS_SetPriority(hal_canbus_errpin_group[i].irqNumber, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY + 1); INT_SYS_EnableIRQ(hal_canbus_errpin_group[i].irqNumber); hal_canbus_errpin_group[i].status = CANBUS_STATUS_OPEN; } } hal_can_pioirq_register(hal_err_interrupt_cb);// conf->canbus_open_flag = CANBUS_STATUS_OPEN; return TRUE; } /* func: mcu can msg dispatcher * prara: hw_canbus_data_t * return: void */ void hal_canbus_msgs_dispatcher(hw_canbus_data_t* pcanmsg) { for (int i = 0; i < HW_CANBUS_HANDLE_MAX; i++) { if (hw_can.handlers[i]) { hw_can.handlers[i](pcanmsg); } } } /* func: mcu can msg dispatcher * prara: hw_canbus_data_t * return: void */ int hal_canbus_register(int (*hdl)(hw_canbus_data_t* pdata)) { for (int i = 0; i < HW_CANBUS_HANDLE_MAX; i++) { if (!hw_can.handlers[i] || hw_can.handlers[i] == hdl) { hw_can.handlers[i] = hdl; return APL_OK; } } return APL_FAIL; }
hardwareManage.c
我把uart部分也一起粘过来了
void hw_uart_data_handler_test(UART_CH_E ch, uint8_t* data, int len) { hal_uart_write(UART_CH_DEBUG,data,len); } void hw_can_data_handler_test(hw_canbus_data_t* pdata) { can_msg_t msg; msg.chl = pdata->ch; msg.canid = pdata->id; msg.dlc = pdata->dlc; msg.ide = CAN_ID_STD; msg.rtr = CAN_RTR_DATA; memcpy(msg.data, pdata->array, MIN(sizeof(msg.data), pdata->dlc)); hal_mcu_can_send(CAN_CH0, &msg); } void hw_uart_open(void) { uart_dcb_t hal_dcb; hal_dcb.rbuf_size = HW_UART_DBG_BUFF_SIZE; hal_dcb.tbuf_size = HW_UART_DBG_BUFF_SIZE; hal_uart_register(UART_CH_DEBUG,hw_uart_data_handler_test);//注册处理回调函数 hal_uart_open(TO_HW_UART_CH(HW_UART_CH_DEBUG), &hal_dcb); //开启配置UART } void hw_can_open(void) { can_init_cfg_t init_cfg; CAN_BAUDRATE_E canbus_baudrate; init_cfg.baudrate = CAN_250K; init_cfg.ide = CAN_ID_EXT; init_cfg.rtr = CAN_RTR_DATA; hal_canbus_register(hw_can_data_handler_test);//注册处理回调函数 hal_mcu_can_open(CAN_CH0, &init_cfg);//开启配置CAN } void vSystemHardwareHalInit(void) { uint32_t ctrl,BAUD,STAT; uint32_t TCD1,TCD2,TCD3,TCD4; hal_board_init(); hw_uart_open(); hw_can_open(); //LPUART_GetCTRL_LPUART0(&ctrl,&BAUD,&STAT); //EDMA_TCDGetData(&TCD1,&TCD2,&TCD3,&TCD4); }
main.c
void vCanDataProcessingTask(void *p) { uint8_t count = 0; can_msg_t msg; hw_canbus_data_t canmsg; hw_can_task_msg_e hw_can_task_msg; hw_can_queue = xQueueCreate(HW_SYS_TSK_QUEUE_SIZE, 1); while(1) { if (xQueueReceive(hw_can_queue, (void*)&hw_can_task_msg, 10) == pdPASS) { while (hal_mcu_can_read(CAN_CH0, &msg) > 0) { count++; memcpy(canmsg.array, msg.data, MIN(sizeof(msg.data), msg.dlc)); canmsg.ch = msg.chl; canmsg.id = msg.canid; canmsg.dlc = msg.dlc; canmsg.type = msg.ide == CAN_ID_EXT ? 1 : 0; hal_canbus_msgs_dispatcher(&canmsg); if (count > 10) { break; } } } } } int main(void) { /* Write your local variable definition here */ /*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/ #ifdef PEX_RTOS_INIT PEX_RTOS_INIT(); /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */ #endif /*** End of Processor Expert internal initialization. ***/ vSystemHardwareHalInit(); xTaskCreate( vSystemHardwareWorkTask, "SystemHardwareWorkTask", 210, 0, 1,0);//系统硬件工作任务 优先级1 xTaskCreate( vUartDataProcessingTask, "vUartDataProcessingTask", 400, 0, 2,0);//系统硬件工作任务 优先级1 xTaskCreate( vCanDataProcessingTask, "vCanDataProcessingTask", 500, 0, 2,0);//adc数据处理任务优先级1 vTaskStartScheduler(); }
来看效果!!!!!
把0x112过滤在外,现在通过修改私有掩码放开一部份ID过滤进来!!
for(id_counter=0;id_counter<8;id_counter++)
FLEXCAN_DRV_SetRxIndividualMask(INST_CANCOM1, FLEXCAN_MSG_ID_STD, id_counter, 0xC0000000|0x7FF);
把这里边的0x7FF改成0x7fC!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。