📄 rt_agent.c
字号:
}
status = send_msg_raw(&msg, format); // Send message
/* Don't send errors for term data in blocking mode */
#if RTA_TERM_W_BLOCKING
if (type != RTA_CMD_TERM_DATA) {
#endif
if (status) { // Send an error message
// Configure the buffer overrun message
msg.header.split.type = RTA_CMD_ERROR;
msg.header.split.length = status;
send_msg_raw(&msg, MSG_FORMAT_SHORT); // Send message
}
#if RTA_TERM_W_BLOCKING
}
#endif
}
else {
status = RTA_ERR_NOT_INIT;
}
return (status);
}
/*
* Send RTX Kernel task switch information to the host via Real-Time Agent
* Parameters: tsk: pointer to task entry point
* time: system time
* Return Value: RTA_STATUS (0 = OK)
*/
void RTA_Task_Mon (unsigned int time, unsigned int tcount, unsigned int tsk) {
unsigned int msg[3];
//if (rta.rtx_mon) {
msg[0] = time;
msg[1] = tcount;
msg[2] = tsk;
RTA_Msg (RTA_CMD_RTX_TASK_SWITCH, &msg[0], 3);
//}
}
/*==============================================================================
RTA Receive Functions
==============================================================================*/
/*
* Handle a read/write address from the host
* Parameters: rx_word: received address word
* Return Value: None
*/
static void main_addr(unsigned int rx_word) {
rta.rw_addr = rx_word;
rta.state = RTA_STATE_COMMAND;
}
/*
* Handle a mem read from the host
* Parameters: length: length of data to read in words
* Return Value: None
*/
static void main_mem_rd_32(unsigned int length){
// Return the data that was requested to read
RTA_Msg(RTA_CMD_MEM_READ_32,
(unsigned int *)rta.rw_addr,
length);
}
/*
* Handle a 8-bit mem write from the host
* Parameters: data: data to write
* Return Value: None
*/
static void main_mem_wr_8(unsigned int data) {
unsigned int byte = 0;
// Write data (8-bit)
while ((rta.rw_addr < rta.w_end_addr) && (byte < 32)) {
*((unsigned char *)rta.rw_addr) = (data >> byte) & 0x000000FF;
rta.rw_addr += sizeof(unsigned char);
byte+=8;
}
// Switch back to command mode when write finished
if (rta.rw_addr >= rta.w_end_addr) {
rta.state = RTA_STATE_COMMAND;
}
}
/*
* Handle a 16-bit mem write from the host
* Parameters: data: data to write
* Return Value: None
*/
static void main_mem_wr_16(unsigned int data) {
unsigned int halfword = 0;
// Write data (16-bit)
while ((rta.rw_addr < rta.w_end_addr) && (halfword < 32)) {
*((unsigned short *)rta.rw_addr) = (data >> halfword) & 0x0000FFFF;
rta.rw_addr += sizeof(unsigned short);
halfword+=16;
}
// Switch back to command mode when write finished
if (rta.rw_addr >= rta.w_end_addr) {
rta.state = RTA_STATE_COMMAND;
}
}
/*
* Handle a 32-bit mem write from the host
* Parameters: data: data to write
* Return Value: None
*/
static void main_mem_wr_32(unsigned int data) {
// Write data (32-bit)
*((unsigned int *)rta.rw_addr) = data;
rta.rw_addr += sizeof(unsigned int);
// Switch back to command mode when write finished
if (rta.rw_addr >= rta.w_end_addr) {
rta.state = RTA_STATE_COMMAND;
}
}
/*
* Handle commands from the host
* Parameters: rx_word: command word received
* val: Data
* Return Value: None
*/
static void main_cmd(unsigned int rx_word) {
unsigned int iTemp;
/* Could check sequence number and magic number here, but
do not because of the processing time cost */
switch (rx_word >> 24) { // Message type
case RTA_CMD_SYNC:
if (rx_word == RTA_SYNC_WORD) {
RTA_SYNC();
}
else {
RTA_RESET();
}
break;
case RTA_CMD_GET_VERSION:
iTemp = RTA_VERSION;
RTA_Msg(RTA_CMD_GET_VERSION, &iTemp, RTA_SHORT_MSG);
break;
case RTA_CMD_TERM_DATA:
#if (RTA_TERM_SUPPORT)
// Pass term data to term in buffer
term_in.data[RTA_TERM_IN_MASK & term_in.wr_idx++] = rx_word & 0x000000FF;
#endif
break;
case RTA_CMD_SET_ADDRESS:
rta.state = RTA_STATE_ADDRESS;
break;
case RTA_CMD_MEM_READ_32:
main_mem_rd_32(rx_word & 0x000000FF);
break;
/* Special mode messages */
case RTA_CMD_MEM_WRITE_8:
rta.w_end_addr = rta.rw_addr + ((rx_word & 0x000000FF));
rta.state = RTA_STATE_MEM_WRITE_8;
break;
case RTA_CMD_MEM_WRITE_16:
rta.w_end_addr = rta.rw_addr + ((rx_word & 0x000000FF) << 1);
rta.state = RTA_STATE_MEM_WRITE_16;
break;
case RTA_CMD_MEM_WRITE_32:
rta.w_end_addr = rta.rw_addr + ((rx_word & 0x000000FF) << 2);
rta.state = RTA_STATE_MEM_WRITE_32;
break;
/* RTX monitoring messages */
case RTA_CMD_RTX_MON_START:
rta.rtx_mon = 1;
break;
case RTA_CMD_RTX_MON_STOP:
rta.rtx_mon = 0;
break;
default:
RTA_RESET();
}
}
/*
* RTA Receive word (interrupt context)
* Parameters: None
* Return Value: None
*/
#if (RTA_EXPORT_IRQS)
void RTA_rx_word_ext (void)
#else
__irq void RTA_rx_word (void)
#endif
{
unsigned int rx_word;
RX_IRQ_ACK(); // Acknowledge Interrupt
RX_WORD(); // Read word from hardware
state_funcs[rta.state](rx_word); // Call state machine
}
/*==============================================================================
RTA Transmit Functions
==============================================================================*/
/*
* Write data to the RTA output buffer
* Parameters: data: data word to write
* Return Value: None
*/
static __forceinline void RTA_out_write(unsigned int data) {
rta.out.data[RTA_OUT_MASK & rta.out.wr_idx++] = data;
}
/*
* Read memory for the data out buffer. This must be a
* function call as it needs to be written in
* ASM so that register locations are predicatable
* for the Data Abort handler as is may cause a data abort
* Parameters: addrData: address to read
* Return Value: Data read
*/
__asm unsigned int __RTA_rd_adr (unsigned int *addrData) {
LDR R0,[R0,#0] ; Load the data at addrData
BX LR ; Return
}
__asm unsigned int DAbt_Handler (void) {
LDR R0,=RTA_NO_MEM_FLAG ; Move No_Mem_Flag into R0
SUBS PC,LR,#4 ; Return past the data abort instruction
}
/*
* Send a message to the host
* Parameters: msg: pointer to the message
* //format: format of the message (LONG or SHORT)
* Message format is now determined by a NULL data pointer
* Return Value: RTA_STATUS (0 = OK)
*/
static RTA_STATUS send_msg_raw (RTA_msg_t *msg, MSG_FORMAT format) {
RTA_STATUS retVal = RTA_OK;
unsigned int type = msg->header.split.type;
const unsigned int *data = msg->data; // Local pointer to the data
unsigned int length = msg->header.split.length;
unsigned int temp;
TX_IRQ_DISABLE(); // Disable RTA Tx Interrupt
// Special case for sync (and reset) messages
if ((type == RTA_CMD_UNKNOWN) || (type == RTA_CMD_SYNC)) {
// Have to reset the states and buffer pointers in SWI so it is safe
rta.state = RTA_STATE_COMMAND;
rta.out.rd_idx = rta.out.wr_idx; /* = 0; */ // Set buffer empty condition
rta.tx_seq_no = RTA_INITIAL_SEQ_NO; // Reset sequence number
}
/* Check there is enough buffer for the message, otherwise discard it
Note: We leave at least RTA_MAX_MSG_LEN in the buffer at all times
for req/rsp messages from the host */
temp = (format == MSG_FORMAT_SHORT) ? 1 : length; // Message length
if (!(type & DVA_REQ_RSP_BIT)) {
temp += (RTA_MAX_MSG_LEN/4); // Buffer reserved for req/rsp messages
if (type == RTA_CMD_ERROR) { // Buffer reserved for error messages
temp--;
}
}
if ( ((rta.out.rd_idx - rta.out.wr_idx - 1) & RTA_OUT_MASK) < // Buffer free
temp) {
TX_IRQ_ENABLE();
return (RTA_ERR_BUF_OVERRUN);
}
// First put the sequence number into the header
msg->header.split.seq_no = (unsigned int)rta.tx_seq_no++;
// Now write header to the buffer (or short message)
RTA_out_write(msg->header.raw);
// Write the long message
if (format == MSG_FORMAT_LONG) {
// temp isused for checksum
temp = msg->header.raw;
for (; length>0; length--) {
/* type reused as temp data store */
type = __RTA_rd_adr((unsigned int *)data++);
temp += type;
RTA_out_write(type);
}
RTA_out_write(temp);
}
TX_IRQ_ENABLE(); // Enable RTA Tx Interrupt
return (retVal);
}
/*
* RTA Transmit word (interrupt context)
* Parameters: None
* Return Value: None
*/
#if (RTA_EXPORT_IRQS)
void RTA_tx_word_ext (void)
#else
__irq void RTA_tx_word (void)
#endif
{
unsigned int tx_word;
TX_IRQ_ACK(); // Acknowledge Interrupt
if (rta.out.rd_idx == rta.out.wr_idx) { // Check for buffer empty
TX_IRQ_DISABLE(); // Disable RTA Tx Interrupt
}
else { // Write data if buffer not empty
// Write word to the RTA
tx_word = rta.out.data[RTA_OUT_MASK & rta.out.rd_idx++];
TX_WORD(); // Write word to hardware
}
}
/*
* RTA Default Interrupt
* Parameters: None
* Return Value: None
*/
static __irq void RTA_def_irq (void) {
DEF_IRQ_ACK();
}
/*==============================================================================
RTA Terminal Emulator Functions
==============================================================================*/
#if (RTA_TERM_SUPPORT)
/*
* Check is there is a character available in the terminal emulator buffer
* Parameters: None
* Return Value: Number of characters in buffer
*/
unsigned int RTA_TermIsKey (void) {
return ((term_in.wr_idx - term_in.rd_idx) & RTA_TERM_IN_MASK);
}
/*
* Get a character from the terminal. This function blocks until a
* character is available
* Parameters: None
* Return Value: Character read from terminal
*/
unsigned int RTA_TermGetChar (void) {
int ch;
while (term_in.rd_idx == term_in.wr_idx); // Block waiting for character
ch = term_in.data[RTA_TERM_IN_MASK & term_in.rd_idx++]; // Read char from buffer
#if (RTA_TERM_ECHO)
RTA_TermPutChar(ch); // Echo the character back to the serial window
#endif
return (ch);
}
/*
* Write a character to the terminal
* Parameters: ch: Character to write to the terminal
* Return Value: Character written to the terminal
*/
unsigned int RTA_TermPutChar (unsigned int ch) {
#if (RTA_TERM_W_BLOCKING)
RTA_STATUS status;
do {
status = RTA_Msg(RTA_CMD_TERM_DATA, &ch, RTA_SHORT_MSG);
} while (status == RTA_ERR_BUF_OVERRUN);
#else
RTA_Msg(RTA_CMD_TERM_DATA, &ch, RTA_SHORT_MSG);
#endif
return (ch);
}
#else /* if RTA_TERM_SUPPORT */
unsigned int RTA_TermIsKey (void) {
return(0);
}
unsigned int RTA_TermGetChar (void) {
return (0);
}
unsigned int RTA_TermPutChar (unsigned int ch) {
return (0);
}
#endif /* else RTA_TERM_SUPPORT */
#else /* if RTA_ENABLED */
/*==============================================================================
DISABLED (STUBBED) CODE SECTION
==============================================================================*/
RTA_STATUS RTA_Init (void) {
return (RTA_ERR_DISABLED);
}
RTA_STATUS RTA_Msg (unsigned int type, unsigned int *data, unsigned int length) {
return (RTA_ERR_DISABLED);
}
unsigned int RTA_TermIsKey (void) {
return(0);
}
unsigned int RTA_TermGetChar (void) {
return (0);
}
unsigned int RTA_TermPutChar (unsigned int ch) {
return (0);
}
__asm unsigned int DAbt_Handler (void) {
B DAbt_Handler ; Loop forever
}
#endif /* else RTA_ENABLED */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -