📄 rtx_can.c
字号:
/*----------------------------------------------------------------------------
* R T L - C A N D r i v e r
*----------------------------------------------------------------------------
* Name: RTX_CAN.c
* Purpose: CAN Generic Layer Driver
* Rev.: V3.12
*----------------------------------------------------------------------------
* This code is part of the RealView Run-Time Library.
* Copyright (c) 2004-2007 KEIL - An ARM Company. All rights reserved.
*---------------------------------------------------------------------------*/
#include <RTL.h> /* RTX kernel functions & defines */
#include "CAN_Cfg.h" /* CAN Configuration */
#include "RTX_CAN.h" /* CAN Generic functions & defines */
#include "CAN_Hw.h" /* CAN hw specific functions & defines */
#pragma diag_suppress 550
/* Declare memory pool for CAN messages, both transmit and receive */
CAN_msgpool_declare(CAN_mpool,CAN_CTRL_MAX_NUM*(CAN_No_SendObjects+CAN_No_ReceiveObjects));
/* Declare mailbox, for CAN transmit messages */
mbx_arr_declare(MBX_tx_ctrl,CAN_CTRL_MAX_NUM,CAN_No_SendObjects);
/* Declare mailbox, for CAN receive messages */
mbx_arr_declare(MBX_rx_ctrl,CAN_CTRL_MAX_NUM,CAN_No_ReceiveObjects);
/* Semaphores used for protecting writing to CAN hardware */
OS_SEM wr_sem[CAN_CTRL_MAX_NUM];
/*----------------------------------------------------------------------------
* CAN RTX Generic Driver Functions
*----------------------------------------------------------------------------
* Functions implemented in this module:
* CAN_ERROR CAN_mem_init (void);
* CAN_ERROR CAN_setup (void)
* CAN_ERROR CAN_init (U32 ctrl, U32 baudrate)
* CAN_ERROR CAN_start (U32 ctrl)
* static CAN_ERROR CAN_push (U32 ctrl, CAN_msg *msg, U16 timeout)
* CAN_ERROR CAN_send (U32 ctrl, CAN_msg *msg, U16 timeout)
* CAN_ERROR CAN_request (U32 ctrl, CAN_msg *msg, U16 timeout)
* CAN_ERROR CAN_set (U32 ctrl, CAN_msg *msg, U16 timeout)
* static CAN_ERROR CAN_pull (U32 ctrl, CAN_msg *msg, U16 timeout)
* CAN_ERROR CAN_receive (U32 ctrl, CAN_msg *msg, U16 timeout)
* CAN_ERROR CAN_rx_object (U32 ctrl, U32 ch, U32 id, CAN_FORMAT format)
* CAN_ERROR CAN_tx_object (U32 ctrl, U32 ch, CAN_FORMAT format)
*---------------------------------------------------------------------------*/
/*--------------------------- CAN_init --------------------------------------
*
* The first time this function is called initialize the memory pool for
* CAN messages and setup CAN controllers hardware
*
* Initialize mailboxes for CAN messages and initialize CAN controller
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* baudrate: Baudrate
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_init (U32 ctrl, U32 baudrate) {
static U8 first_run_flag = 0;
CAN_ERROR error_code;
U32 ctrl0 = ctrl-1; /* Controller index 0 .. x-1 */
/* Initialize the Semaphore before the first use */
os_sem_init (wr_sem[ctrl0], 1);
/* When function is called for the first time it will initialize and setup
all of the resources that are common to CAN functionality */
if (first_run_flag == 0) {
first_run_flag = 1;
if (_init_box (CAN_mpool, sizeof(CAN_mpool), sizeof(CAN_msg)) == 1)
return CAN_MEM_POOL_INIT_ERROR;
}
os_mbx_init (MBX_tx_ctrl[ctrl0], sizeof(MBX_tx_ctrl[ctrl0]));
os_mbx_init (MBX_rx_ctrl[ctrl0], sizeof(MBX_rx_ctrl[ctrl0]));
error_code = CAN_hw_setup (ctrl);
if (error_code != CAN_OK)
return error_code;
return (CAN_hw_init (ctrl, baudrate));
}
/*--------------------------- CAN_start -------------------------------------
*
* Start CAN controller (enable it to participate on CAN network)
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_start (U32 ctrl) {
return (CAN_hw_start (ctrl));
}
/*--------------------------- CAN_push --------------------------------------
*
* Send CAN_msg if hardware is free for sending, otherwise push message to
* message queue to be sent when hardware becomes free
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer to CAN message to be sent
* timeout: Timeout value for message sending
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
static CAN_ERROR CAN_push (U32 ctrl, CAN_msg *msg, U16 timeout) {
CAN_msg *ptrmsg;
U32 ctrl0 = ctrl-1; /* Controller index 0 .. x-1 */
if (CAN_hw_tx_empty (ctrl) == CAN_OK) { /* Transmit hardware free for send */
CAN_hw_wr (ctrl, msg); /* Send message */
}
else { /* If hardware for sending is busy */
/* Write the message to send mailbox if there is room for it */
ptrmsg = _alloc_box (CAN_mpool);
if (ptrmsg != NULL) {
*ptrmsg = *msg;
/* If message hasn't been sent but timeout expired, deallocate memory */
if (os_mbx_send (MBX_tx_ctrl[ctrl0], ptrmsg, timeout) == OS_R_TMO) {
if (_free_box (CAN_mpool, ptrmsg) == 1)
return CAN_DEALLOC_MEM_ERROR;
return CAN_TIMEOUT_ERROR;
}
} else
return CAN_ALLOC_MEM_ERROR;
}
return CAN_OK;
}
/*--------------------------- CAN_send --------------------------------------
*
* Send DATA FRAME message, see CAN_push function comment
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer to CAN message to be sent
* timeout: Timeout value for message sending
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_send (U32 ctrl, CAN_msg *msg, U16 timeout) {
msg->type = DATA_FRAME;
return (CAN_push (ctrl, msg, timeout));
}
/*--------------------------- CAN_request -----------------------------------
*
* Send REMOTE FRAME message, see CAN_push function comment
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer to CAN message to be sent
* timeout: Timeout value for message sending
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_request (U32 ctrl, CAN_msg *msg, U16 timeout) {
msg->type = REMOTE_FRAME;
return (CAN_push (ctrl, msg, timeout));
}
/*--------------------------- CAN_set ---------------------------------------
*
* Set a message that will automatically be sent as an answer to REMOTE
* FRAME message
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer to CAN message to be set
* timeout: Timeout value for message to be set
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_set (U32 ctrl, CAN_msg *msg, U16 timeout) {
S32 i = timeout;
U32 result = 0;
do {
if (CAN_hw_tx_empty (ctrl) == CAN_OK) { /* Transmit hardware free */
result = CAN_hw_set (ctrl, msg); /* Set message */
os_sem_send (wr_sem[ctrl-1]); /* Return a token back to semaphore */
return CAN_OK;
}
if (timeout == 0xffff) /* Indefinite wait */
i++;
i--;
os_dly_wait (1); /* Wait 1 timer tick */
} while (i >= 0);
return CAN_TIMEOUT_ERROR; /* CAN message not set */
}
/*--------------------------- CAN_pull --------------------------------------
*
* Pull first received and unread CAN_msg from receiving message queue
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer where CAN message will be read
* timeout: Timeout value for message receiving
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
static CAN_ERROR CAN_pull (U32 ctrl, CAN_msg *msg, U16 timeout) {
CAN_msg *ptrmsg;
U32 ctrl0 = ctrl-1; /* Controller index 0 .. x-1 */
/* Wait for received message in mailbox */
if (os_mbx_wait (MBX_rx_ctrl[ctrl0], (void **)&ptrmsg, timeout) == OS_R_TMO)
return CAN_TIMEOUT_ERROR;
/* Copy received message from mailbox to address given in function parameter msg */
*msg = *ptrmsg;
/* Free box where message was kept */
if (_free_box (CAN_mpool, ptrmsg) == 1)
return CAN_DEALLOC_MEM_ERROR;
return CAN_OK;
}
/*--------------------------- CAN_receive -----------------------------------
*
* Read received message, see CAN_pull function comment
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* msg: Pointer where CAN message will be read
* timeout: Timeout value for message receiving
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_receive (U32 ctrl, CAN_msg *msg, U16 timeout) {
return (CAN_pull (ctrl, msg, timeout));
}
/*--------------------------- CAN_rx_object ---------------------------------
*
* Enable reception of messages on specified controller and channel with
* specified identifier
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* ch: Channel for the message transmission
* id: CAN message identifier
* CAN_FORMAT: Format of CAN identifier (standard or extended)
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_rx_object (U32 ctrl, U32 ch, U32 id, CAN_FORMAT format) {
return (CAN_hw_rx_object (ctrl, ch, id, format));
}
/*--------------------------- CAN_tx_object ---------------------------------
*
* Enable transmission of messages on specified controller and channel with
* specified identifier
*
* Parameter: ctrl: Index of the hardware CAN controller (1 .. x)
* ch: Channel for the message transmission
* CAN_FORMAT: Format of CAN identifier (standard or extended)
*
* Return: CAN_ERROR: Error code
*---------------------------------------------------------------------------*/
CAN_ERROR CAN_tx_object (U32 ctrl, U32 ch, CAN_FORMAT format) {
return (CAN_hw_tx_object (ctrl, ch, format));
}
/*----------------------------------------------------------------------------
* end of file
*---------------------------------------------------------------------------*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -