error.c File Reference

This module provides error reporting capabilities to other modules. More...

Go to the source code of this file.

Functions

BOARD_ID error_get_board (void)
 Returns the BOARD_ID for this project's board.
int error_get_frequency (void)
 Returns the frequency of the active/current error.
ERROR_ID error_get_id (void)
 Returns the ERROR_ID for the current error.
int error_get_info (void)
 Gets the info of the active error.
int error_get_time (void)
 Gets the time from the active error.
void error_init (VOID_VOID_F transmit_function, INT_VOID_F timestamp_function, BOARD_ID board_id)
 Initializes the error modules.
void error_occurred (ERROR_ID error_code)
 Alerts the error module that an error has occurred.
void error_occurred_fiq (ERROR_ID error_code)
 Alerts the error module that an error has occurred.
void error_occurred_irq (ERROR_ID error_code)
 Alerts the error module that an error has occurred.
static volatile ERROR_INFOerror_pop (volatile ERROR_BUFFER *buffer)
 Pops the oldest error from the ring buffer.
static void error_push (volatile ERROR_BUFFER *buffer, volatile ERROR_INFO new_error)
 Pushes the error onto a ring buffer.
void error_send_next (void)
 Uses a transmit function to send out the next error.
void error_update (void)
 This function iterates through and updates the list of errors that have occurred, putting the error data into ERROR_INFO structs.

Variables

static volatile ERROR_INFOer_active
 The oldest error ready to be sent out.
static BOARD_ID er_board_id
 The BOARD_ID for this project's specific board.
static volatile ERROR_BUFFER er_buffer
 The ring buffer for holding errors that have occurred.
MUTEX er_fiq_mutex
static volatile unsigned int er_flags [er_length]
 The array holding the error flags.
static INT_VOID_F er_get_timestamp = intvoid
 A function that returns the current timestamp.
MUTEX er_irq_mutex
static int er_is_init = 0
 Whether or not this module has been initialized yet.
static const int er_length = ((int)(ERROR_LAST_ID)/32)+1
 The length of the array needed to hold all of the error flags.
MUTEX er_mutex
static VOID_VOID_F er_transmit = voidvoid
 The transmit function that will access the active error and transmit or display its info.

Detailed Description

This module provides error reporting capabilities to other modules.

During operation, errors that occur will set flags. Calls to error_update will iterate through the flags and create ERROR_INFO structs for any errors that have occurred and add them to a buffer. Finally, calls to error_send_next will use the transmit function passed to the module at initialization to transmit or display the oldest error.

Note:
All public functions are now protected if the user does not call error_init first. The functions will either do nothing, or will return 0.
Author:
Nicolas Williamson
Date:
Summer 2009

Definition in file error.c.


Function Documentation

BOARD_ID error_get_board ( void   ) 

Returns the BOARD_ID for this project's board.

Returns:
The board this project is for.

Definition at line 261 of file error.c.

References er_board_id.

00262 {
00263   return er_board_id;
00264 }

int error_get_frequency ( void   ) 

Returns the frequency of the active/current error.

Returns:
The frequency - number of times the error has occurred since it was last transmitted.

Definition at line 283 of file error.c.

References er_is_init, and ERROR_INFO::frequency.

00284 {
00285   if (er_is_init){ //make sure error module has been initialized first
00286     return er_active->frequency;
00287   } else {
00288     return 0;
00289   }
00290 }

ERROR_ID error_get_id ( void   ) 

Returns the ERROR_ID for the current error.

Returns:
The error id of the active/current error.

Definition at line 270 of file error.c.

References er_is_init, and ERROR_INFO::error_id.

00271 {
00272   if (er_is_init){ //make sure error module has been initialized first
00273     return (ERROR_ID)er_active->error_id;
00274   } else {
00275     return ERROR_DEFAULT;
00276   }
00277 }

int error_get_info ( void   ) 

Gets the info of the active error.

The format for the int returned is:

  • Bits 0:15 (16 bits) = error_id
  • Bits 16:21 (6 bits) = board_id
  • Bits 22:31 (10 bits) = frequency (number of times the error has occurred since it was last transmitted
    Returns:
    The info of the current error, including id and frequency

Definition at line 247 of file error.c.

References er_board_id, er_is_init, ERROR_INFO::error_id, and ERROR_INFO::frequency.

00248 {
00249   if (er_is_init){ //make sure error module has been initialized first
00250     long int info = (er_active->error_id & 0xFFFF) | ((er_board_id & 0x3F) << 16) | ((er_active->frequency & 0x3FF) << 22);
00251     return info;
00252   } else {
00253     return 0;
00254   }
00255 }

int error_get_time ( void   ) 

Gets the time from the active error.

Returns:
The time the error occurred

Definition at line 231 of file error.c.

References er_is_init, and ERROR_INFO::time_occurred.

00232 {
00233   if (er_is_init){ //make sure error module has been initialized first
00234     return (int)(er_active->time_occurred); 
00235   } else {
00236     return 0;
00237   }
00238 }

void error_init ( VOID_VOID_F  transmit_function,
INT_VOID_F  timestamp_function,
BOARD_ID  board_id 
)

Initializes the error modules.

Call this from software setup before any other error module functions.

Parameters:
transmit_function A voidvoid function that will be called to report the next error over CAN or otherwise.
timestamp_function A function which returns the current timestamp, usually asched_get_timestamp.
board_id The BOARD_ID for this project's board.

Definition at line 41 of file error.c.

References ERROR_BUFFER::empty, er_board_id, er_get_timestamp, er_is_init, er_transmit, ERROR_BUFFER::first, ERROR_BUFFER::next, and ERROR_BUFFER::overflows.

00042 {
00043   er_buffer.first = 0;
00044   er_buffer.next = 0;
00045   er_buffer.overflows = 0;
00046   er_buffer.empty = 1;
00047   er_transmit = transmit_function;
00048   er_get_timestamp = timestamp_function;
00049   er_board_id = board_id;
00050   er_is_init = 1;
00051 }

void error_occurred ( ERROR_ID  error_code  ) 

Alerts the error module that an error has occurred.

This function will be called by other modules whenever something bad or unexpected happens.

Parameters:
error_code The ID of the error that occurred, of type ERROR_ID

Definition at line 60 of file error.c.

References er_is_init, mutex_check(), mutex_lock(), and mutex_unlock().

Referenced by adci_convert_all(), adci_efilter_add(), adcx_add_config(), adcx_convert_all(), adcx_read_buffer(), adcx_write(), ae_get_pos(), ae_init_encoder(), ae_isr(), ae_read(), asched_tick(), button_pushed(), floatvoid(), intvoid(), lcd_push(), ls_get_state(), ls_init_switch(), mc_get_thermal_limiter(), mc_is_running(), mc_pid_current(), mc_set_pwm(), mc_set_target_current_fixed(), mc_turnoff(), mc_turnon(), msimu_isr(), msimu_send_all(), qec_get_abs_pos(), qec_get_velocity(), qec_update(), rcx_get_chan(), rcx_update(), voidint(), and voidvoid().

00061 {
00062   volatile int index, bit;
00063   if (er_is_init){//make sure error module has been initialized first
00064     volatile int index, bit;
00065     if (!mutex_check(&er_mutex)){
00066       mutex_lock(&er_mutex);
00067       index = (int)(error_code) / 32;
00068       bit = (int)(error_code) % 32;
00069       er_flags[index] |= (1<<bit);
00070    //   mcu_led_red_blink(100);
00071       mutex_unlock(&er_mutex);
00072     } else {
00073     }
00074   }
00075 }

void error_occurred_fiq ( ERROR_ID  error_code  ) 

Alerts the error module that an error has occurred.

This function will be called by other modules whenever something bad or unexpected happens during an FIQ (Fast Interrupt Request).

Parameters:
error_code The ID of the error that occurred, of type ERROR_ID

Definition at line 106 of file error.c.

References er_is_init, mutex_check(), mutex_lock(), and mutex_unlock().

00107 {
00108   volatile int index, bit;
00109   if (er_is_init){ //make sure error module has been initialized first
00110     if (!mutex_check(&er_fiq_mutex)){
00111       mutex_lock(&er_fiq_mutex);
00112       index = (int)(error_code) / 32;
00113       bit = (int)(error_code) % 32;
00114       er_flags[index] |= (1<<bit);
00115    //   mcu_led_red_blink(100);
00116       mutex_unlock(&er_fiq_mutex);
00117     } else {
00118     }
00119   }
00120 }

void error_occurred_irq ( ERROR_ID  error_code  ) 

Alerts the error module that an error has occurred.

This function will be called by other modules whenever something bad or unexpected happens during an IRQ (Interrupt Request).

Parameters:
error_code The ID of the error that occurred, of type ERROR_ID

Definition at line 84 of file error.c.

References er_is_init, mutex_check(), mutex_lock(), and mutex_unlock().

00085 {
00086   volatile int index, bit;
00087   if (er_is_init){//make sure error module has been initialized first
00088     if (!mutex_check(&er_irq_mutex)){
00089       mutex_lock(&er_irq_mutex);
00090       index = (int)(error_code) / 32;
00091       bit = (int)(error_code) % 32;
00092       er_flags[index] |= (1<<bit);
00093    //   mcu_led_red_blink(100);
00094       mutex_unlock(&er_irq_mutex);
00095     } else {
00096     }
00097   }
00098 }

static volatile ERROR_INFO* error_pop ( volatile ERROR_BUFFER buffer  )  [static, private]

Pops the oldest error from the ring buffer.

Parameters:
buffer A pointer to the ring buffer
Returns:
A pointer to the oldest error information

Definition at line 209 of file error.c.

References ERROR_BUFFER::empty, ERROR_BUFFER::errors, ERROR_BUFFER::first, ERROR_BUFFER::next, and ERROR_BUFFER::overflows.

Referenced by error_send_next().

00210 {
00211   volatile ERROR_INFO* err = 0;
00212   if (!buffer->empty){
00213     err = &(buffer->errors[buffer->first]);
00214     if (buffer->first + 1 >= ERR_BUF_SIZE){
00215       buffer->first = 0;
00216     } else {
00217       buffer->first++;
00218     }
00219     buffer->overflows = 0;    
00220     if (buffer->first == buffer->next){
00221       buffer->empty = 1;
00222     }
00223   } 
00224   return err;
00225 }

static void error_push ( volatile ERROR_BUFFER buffer,
volatile ERROR_INFO  new_error 
) [static, private]

Pushes the error onto a ring buffer.

Parameters:
buffer A pointer to the ring buffer
new_error The new error that is being pushed onto the ring buffer

Definition at line 182 of file error.c.

References ERROR_BUFFER::empty, ERROR_BUFFER::errors, ERROR_BUFFER::first, ERROR_BUFFER::next, and ERROR_BUFFER::overflows.

Referenced by error_update().

00183 { 
00184   // ****** CHECK FOR OVERFLOW ******
00185   if ((buffer->next == buffer->first) && !(buffer->empty)){ //the front has caught up to the tail!! it's eating itself!! nooooo
00186     buffer->overflows++;
00187     if (buffer->first + 1 >= ERR_BUF_SIZE){
00188       buffer->first = 0;
00189     } else {
00190       buffer->first++;
00191     }
00192   }
00193   // ****** ADD NEW DATA ****** 
00194   buffer->errors[buffer->next] = new_error;
00195   if (buffer->next + 1 >= ERR_BUF_SIZE){
00196     buffer->next = 0;
00197   } else {
00198     buffer->next++;
00199   }
00200   buffer->empty = 0; //buffer now has stuff in it
00201 }

void error_send_next ( void   ) 

Uses a transmit function to send out the next error.

This function sets up the next error to be transmitted, then uses the error_transmit function that was passed at initialization to error_init. The transmit function should use the error_get_time and error_get_info to fill up whatever communications packets or to display whatever information it needs.

Definition at line 299 of file error.c.

References ERROR_BUFFER::empty, er_is_init, er_transmit, and error_pop().

00300 {
00301   if (er_is_init){ //make sure error module has been initialized first
00302     if (!er_buffer.empty){
00303       er_active = error_pop(&er_buffer);
00304       if (er_active != 0){
00305         er_transmit();
00306       }
00307     }
00308   }
00309 }

void error_update ( void   ) 

This function iterates through and updates the list of errors that have occurred, putting the error data into ERROR_INFO structs.

Note:
error_update should be called with every tick of the scheduler.

Definition at line 127 of file error.c.

References ERROR_BUFFER::empty, er_get_timestamp, er_is_init, er_length, ERROR_INFO::error_id, error_push(), ERROR_BUFFER::errors, ERROR_BUFFER::first, ERROR_INFO::frequency, ERROR_BUFFER::next, and ERROR_INFO::time_occurred.

00127                        {
00128   int chunk, bit;
00129   int index;
00130   int found = 0;
00131   ERROR_ID error_code;
00132   volatile ERROR_BUFFER* buf;
00133   volatile ERROR_INFO new_error; 
00134   
00135   if (er_is_init){ //make sure error module has been initialized first
00136     for (chunk = 0; chunk < er_length; chunk++){
00137       if (er_flags[chunk]){
00138         for (bit = 0; bit < 32; bit++){
00139           if (er_flags[chunk] & (1<<bit)){
00140             error_code = (ERROR_ID)(bit + (32 * chunk));
00141             
00142             buf = &er_buffer;
00143             
00144             // ********* CHECK IF ERROR ALREADY OCCURRED ***********
00145             if (!(buf->empty)){ //only traverse if the buffer has stuff in it
00146               index = buf->first;
00147               while (index != buf->next) { //traverse the buf of errors to see if this error has already been generated
00148                 if (buf->errors[index].error_id == error_code) { //we've had this error before since the last time we sent info
00149                   buf->errors[index].frequency++; //if it has, increase the frequency
00150                   found = 1;
00151                   break;
00152                 }
00153                 if (index + 1 >= ERR_BUF_SIZE){
00154                   index = 0;
00155                 } else {
00156                   index++;
00157                 }
00158               }
00159             }
00160             
00161             // ********** ADD NEW ERROR TO BUFFER *********
00162             if (!found) { //we haven't seen this error before, add it to the ring buffer
00163               new_error.error_id = error_code;
00164               new_error.frequency = 1;
00165               new_error.time_occurred = er_get_timestamp(); //will hold actual value when sent out; this is just the initial time
00166               error_push(buf, new_error); //will new_error be out of scope here and be meaningless? TOMMY HELP!!
00167             } 
00168           }
00169         }
00170         er_flags[chunk] = 0;
00171       }  
00172     } 
00173   } 
00174 }


Variable Documentation

volatile ERROR_INFO* er_active [static]

The oldest error ready to be sent out.

Its data can be accessed using error_get_time and error_get_info

Definition at line 27 of file error.c.

BOARD_ID er_board_id [static]

The BOARD_ID for this project's specific board.

Definition at line 30 of file error.c.

Referenced by error_get_board(), error_get_info(), and error_init().

volatile unsigned int er_flags[er_length] [static]

The array holding the error flags.

Every error has one flag which takes up a bit within this array of ints

Definition at line 33 of file error.c.

int er_is_init = 0 [static]

Whether or not this module has been initialized yet.

0 = no, 1 = yes.

Definition at line 31 of file error.c.

Referenced by error_get_frequency(), error_get_id(), error_get_info(), error_get_time(), error_init(), error_occurred(), error_occurred_fiq(), error_occurred_irq(), error_send_next(), and error_update().

Generated on Tue Jun 29 16:36:15 2010 by  doxygen 1.6.3