* @internal * @brief Opens the CAN device and initializes its resources. * * This function is called when `rt_device_open()` is invoked on a CAN device. * It allocates and initializes software FIFOs for reception and transmission, * sets up semaphores for the blocking send mechanism, configures the non-blocking * send buffer, and starts the periodic status timer. * * @param[in] dev A poi
| 390 | * @return `RT_EOK` on successful opening, or an error code on failure. |
| 391 | */ |
| 392 | static rt_err_t rt_can_open(struct rt_device *dev, rt_uint16_t oflag) |
| 393 | { |
| 394 | struct rt_can_device *can; |
| 395 | char tmpname[16]; |
| 396 | RT_ASSERT(dev != RT_NULL); |
| 397 | can = (struct rt_can_device *)dev; |
| 398 | |
| 399 | CAN_LOCK(can); |
| 400 | |
| 401 | /* get open flags */ |
| 402 | dev->open_flag = oflag & 0xff; |
| 403 | if (can->can_rx == RT_NULL) |
| 404 | { |
| 405 | if (oflag & RT_DEVICE_FLAG_INT_RX) |
| 406 | { |
| 407 | int i = 0; |
| 408 | struct rt_can_rx_fifo *rx_fifo; |
| 409 | |
| 410 | rx_fifo = (struct rt_can_rx_fifo *) rt_malloc(sizeof(struct rt_can_rx_fifo) + |
| 411 | can->config.msgboxsz * sizeof(struct rt_can_msg_list)); |
| 412 | RT_ASSERT(rx_fifo != RT_NULL); |
| 413 | |
| 414 | rx_fifo->buffer = (struct rt_can_msg_list *)(rx_fifo + 1); |
| 415 | rt_memset(rx_fifo->buffer, 0, can->config.msgboxsz * sizeof(struct rt_can_msg_list)); |
| 416 | rt_list_init(&rx_fifo->freelist); |
| 417 | rt_list_init(&rx_fifo->uselist); |
| 418 | rx_fifo->freenumbers = can->config.msgboxsz; |
| 419 | for (i = 0; i < can->config.msgboxsz; i++) |
| 420 | { |
| 421 | rt_list_insert_before(&rx_fifo->freelist, &rx_fifo->buffer[i].list); |
| 422 | #ifdef RT_CAN_USING_HDR |
| 423 | rt_list_init(&rx_fifo->buffer[i].hdrlist); |
| 424 | rx_fifo->buffer[i].owner = RT_NULL; |
| 425 | #endif |
| 426 | } |
| 427 | can->can_rx = rx_fifo; |
| 428 | |
| 429 | dev->open_flag |= RT_DEVICE_FLAG_INT_RX; |
| 430 | /* open can rx interrupt */ |
| 431 | can->ops->control(can, RT_DEVICE_CTRL_SET_INT, (void *)RT_DEVICE_FLAG_INT_RX); |
| 432 | } |
| 433 | } |
| 434 | |
| 435 | if (can->can_tx == RT_NULL) |
| 436 | { |
| 437 | if (oflag & RT_DEVICE_FLAG_INT_TX) |
| 438 | { |
| 439 | int i = 0; |
| 440 | struct rt_can_tx_fifo *tx_fifo; |
| 441 | |
| 442 | tx_fifo = (struct rt_can_tx_fifo *) rt_malloc(sizeof(struct rt_can_tx_fifo) + |
| 443 | can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list)); |
| 444 | RT_ASSERT(tx_fifo != RT_NULL); |
| 445 | |
| 446 | tx_fifo->buffer = (struct rt_can_sndbxinx_list *)(tx_fifo + 1); |
| 447 | rt_memset(tx_fifo->buffer, 0, |
| 448 | can->config.sndboxnumber * sizeof(struct rt_can_sndbxinx_list)); |
| 449 | rt_list_init(&tx_fifo->freelist); |
nothing calls this directly
no test coverage detected