Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
/******************************************************************************
* Copyright (c) 2006 Altera Corporation, San Jose, California, USA. *
* All rights reserved. All use of this software and documentation is *
* subject to the License Agreement located at the end of this file below. *
******************************************************************************* *
* Date - October 24, 2006 *
* Module - alt_error_handler.c *
* *
******************************************************************************/
/*
* The following functions are MicroC/OS-II system call, network stack system
* call, and Simple Socket Server Application call error handlers that perform
* error handling appropriate for development. If the error_code is not 0,
* an error has occurred, and task scheduling is turned off while the error is
* processed. Depending on the severity level, as determined by the value
* set for FAULT_LEVEL (NONE, TASK, or SYSTEM), either control is returned to
* the task, the task is deleted, or the system scheduler is suspended,
* respectively.
*
* In a deployed embedded system, errors must be
* handled according to the data storage and communications capabilities of an
* embedded hardware platform. For example, a JTAG UART requires a host PC to
* receive the JTAG UART printf command, and a serial UART requires a device
* at the end of the cable to display the output. Development PCs and
* terminals normally do not exist in a deployed embedded system, so other
* means of logging the error must be used.
*
* The manner in which errors are resolved also changes in deployed embedded
* systems. While developing, it is desireable to have the system halt task
* activity and report an error message so that the developer can study the
* context in which the error occurred. The scheduler is locked so that the
* developer can read the error message written to standard out (or stderr),
* without having the message garbled by having messages from other tasks
* interleaved on the output device, or scrolled out of view by other task
* console output.
*
* In a live deployed system, it is desireable not to disable the scheduler.
* To minimize task latency, the scheduler should not be locked while the error
* is processed. Worst case, the embedded system hardware should be power-
* cycled, so that it can recover on its own. Some intelligent checking in the
* error handler can take a less severe error recovery method, such as deleting
* and restarting only the errant task, or by freeing up resources required by
* the errant task so that it may continue. In addition, errors should be
* logged to some form of persistent data storage in a deployed embedded system
* so that a log of activity is available
* to the engineer who may have to resolve a critical failure in the field.
*
* The purpose of this development error handler is to simply alert a developer
* that a task has encountered a problem by writing error details to standard
* output, so that a developer can study the cause of the error.
*
* A MicroC/OS-II system call passes an output value or sets a return value
* with some status other than "OK". The network stack will set errno in some
* cases. The implementation of MicroC/OS-II, network stack, and SSS
* application error handlers take the following actions based on the fault
* status:
*
* Fault Status Action
* ------------ ------
* TASK Terminates the task
* SYSTEM Halts the scheduler, enters an endless loop
* NONE Returns control to the application task
*
* In a deployed embedded systems application, there should be some attempt made
* to recover from errors where possible, by recreating task which caused the
* error in the case of a TASK fault level, or resetting the entire application,
* if necessary due to a SYSTEM fault level. In addition, if any means exist,
* the error should be logged, such as to a local persistent memory store, or
* to an external data collection device. Some embedded applications even send
* errors out over the internet for handling by a central facility. This error
* handling function to invoke should be chosen based on whether errors are the
* result of the application only, or invocation of the network stack or
* MicroC/OS-II system call.
*
* Additional extensions can be made to the use of EXPANDED_DIAGNOSIS
* value for error_code. This feature could also be used to control the flow
* that is taken from different errors occurring at different locations in the
* application code. For example, instead of using the expanded_diagnosis_ptr
* as a string to be printed, as it is used below, the expanded_diagnosis_ptr
* could point to a different function to be invoked, or it could point to a
* structure which contains several items for analysis, including multiple
* function pointers to be invoked based on other structure elements which
* indicate the state of the application at the time of the failure. This
* extensibility capability for a variety of overloaded uses is the reason
* for declaration of the expanded_diagnosis_ptr as void *.
*/
/*
* Include files:
*
* <stdio.h>: Contains C "{fp,p}rintf()" functions.
* includes.h: This is the default MicroC/OS-II include file.
* alt_error_handler.h: Altera Error Handler suite of development
* error handling functions.
*/
#include <stdio.h>
#include <errno.h>
#include "includes.h"
#include "alt_error_handler.h"
#include "stdlib.h"
void alt_uCOSIIErrorHandler(INT8U error_code, void *expanded_diagnosis_ptr)
{
FAULT_LEVEL fault_level;
if(error_code == OS_NO_ERR)
{
return;
}
fault_level = SYSTEM;
OSSchedLock(); /* Disable Task Switching but still service other IRQs */
switch (error_code)
{
case OS_PRIO_EXIST:
fprintf(stderr, "Attempted to assign task priority aready in use.\n");
break;
case OS_PRIO_INVALID:
fprintf(stderr, "Specified task priority higher than allowed max.\n");
fprintf(stderr, "Task can't be assigned a priority higher than %d\n",
OS_LOWEST_PRIO);
break;
case OS_NO_MORE_TCB:
fprintf(stderr, "Task Control Blocks have been exhausted\n");
fprintf(stderr, "Current max number of tasks is %d\n",OS_MAX_TASKS);
break;
case OS_MBOX_FULL:
fault_level = NONE;
fprintf(stderr, "Attempted Post to Mailbox already holding message\n");
break;
case OS_ERR_EVENT_TYPE:
fault_level = TASK;
fprintf(stderr,
"Attempted to access a resource with no match for the required data type.\n");
break;
case OS_ERR_PEVENT_NULL:
fprintf(stderr, "Attempting to access a resource pointing to NULL\n");
break;
case OS_ERR_POST_NULL_PTR:
fault_level = TASK;
fprintf(stderr, "Attempted to Post a NULL to a resource. \n");
break;
case OS_TIMEOUT:
fault_level = NONE;
fprintf(stderr, "Resource not received in specified time\n");
break;
case OS_ERR_PEND_ISR:
fprintf(stderr, "Attempting to pend for a resource in an ISR\n");
break;
case OS_TASK_DEL_IDLE:
fprintf(stderr, "Attempted to delete the IDLE task\n");
break;
case OS_TASK_DEL_ERR:
fault_level = NONE;
fprintf(stderr, "Attempted to delete a task that does not exist\n");
break;
case OS_TASK_DEL_ISR:
fprintf(stderr, "Attempted to delete a task from an ISR\n");
break;
case OS_Q_FULL:
fault_level = NONE;
fprintf(stderr, "Attempted to post to a full message queue\n");
break;
case OS_ERR_NOT_MUTEX_OWNER:
fault_level = TASK;
fprintf(stderr, "Attempted to post a mutex not owned by the task\n");
break;
case EXPANDED_DIAGNOSIS_CODE:
fault_level = SYSTEM;
printf(
"\n[MicroC/OS-II]: See STDERR for expanded diagnosis translation.");
fprintf(stderr, "\n[MicroC/OS-II]: Expanded Diagnosis: %s.",
(char *)expanded_diagnosis_ptr);
break;
default:
printf("\n[MicroC/OS-II]: (Not a MicroC/OS-II error) See STDERR.\n");
fprintf(stderr, "\n[MicroC/OS-II]:");
fprintf(stderr, "\nError_code %d.\n", error_code);
perror("\n[MicroC/OS-II]: (Not a MicroC/OS-II error), ERRNO: ");
break;
}
/* Process the error based on the fault level, reenable scheduler if appropriate. */
switch (fault_level) {
case TASK:
/* Error can be isolated by killing the task */
printf("\n[MicroC/OS-II]: See STDERR (FAULT_LEVEL is TASK).");
fprintf(stderr, "\n[MicroC/OS-II]: FAULT_LEVEL is TASK");
fprintf(stderr, "\n[MicroC/OS-II]: Task is being deleted.\n");
OSSchedUnlock(); /* Reenable Task Switching */
OSTaskDel(OS_PRIO_SELF);
/* Reinvoke uCOSII error handler in case task deletion fails, in
* which case fault_level for this secondary error will be SYSTEM. */
alt_uCOSIIErrorHandler(error_code, 0);
break;
case SYSTEM:
/* Total System Failure, Restart Required */
printf("\n[MicroC/OS-II]: See STDERR (FAULT_LEVEL is SYSTEM).");
fprintf(stderr, "\n[MicroC/OS-II]: FAULT_LEVEL is SYSTEM");
fprintf(stderr, "\n[MicroC/OS-II]: FATAL Error, Restart required.");
fprintf(stderr, "\n[MicroC/OS-II]: Locking scheduler - endless loop.\n");
while(1); /* Since scheduler is locked,loop halts all task activity.*/
break;
case NONE:
fprintf(stderr, "\n[MicroC/OS-II]: FAULT_LEVEL is NONE");
fprintf(stderr, "\n[MicroC/OS-II]: Informational error only, control");
fprintf(stderr,
"returned to task to complete processing at application level.\n");
OSSchedUnlock(); /* Reenable Task Switching */
return;
break;
default:
printf("\n[MicroC/OS-II]: See STDERR (FAULT_LEVEL is Unknown).\n");
fprintf(stderr, "\n[MicroC/OS-II]: FAULT_LEVEL is unknown!?!\n");
}
while(1); /* Correct Program Flow never gets here. */
}
void alt_NetworkErrorHandler(INT8U error_code, void *expanded_diagnosis_ptr)
{
FAULT_LEVEL fault_level;
if(error_code == OS_NO_ERR)
{
return;
}
fault_level = SYSTEM;
OSSchedLock(); /* Disable Task Switching but still service other IRQs */
if (error_code == EXPANDED_DIAGNOSIS_CODE)
{
fault_level = SYSTEM;
printf("\n[Network]: See STDERR for expanded diagnosis translation.");
fprintf(stderr, "\n[Network]: %s", (char *)expanded_diagnosis_ptr);
/* Check errno also in case it has been set. */
perror("\n[Network]: ERRNO: ");
}
else
{
fault_level = TASK;
printf("\n[Network]: See STDERR.\n");
fprintf(stderr, "\n[Network]: Error_code %d!\n", error_code);
perror("\n[Network]: ERRNO: ");
}
/* Process error based on fault level, reenable scheduler if appropriate. */
switch (fault_level)
{
case TASK:
/* Error can be isolated by killing the task */
printf("\n[Network]: See STDERR (FAULT_LEVEL is TASK).");
fprintf(stderr, "\n[Network]: FAULT_LEVEL is TASK");
fprintf(stderr, "\n[Network]: Task is being deleted.\n");
OSSchedUnlock(); /* Reenable Task Switching */
OSTaskDel(OS_PRIO_SELF);
/* Reinvoke uCOSII error handler in case task deletion fails, in
* which case fault_level for this secondary error will be SYSTEM. */
alt_uCOSIIErrorHandler(error_code, 0);
break;
case SYSTEM:
/* Total System Failure, Restart Required */
printf("\n[Network]: See STDERR (FAULT_LEVEL is SYSTEM).");
fprintf(stderr, "\n[Network]: FAULT_LEVEL is SYSTEM.");
fprintf(stderr, "\n[Network]: FATAL Error, Restart required.");
fprintf(stderr, "\n[Network]: Locking scheduler - endless loop.\n");
while(1); /* Since scheduler is locked, loop halts all task activity.*/
break;
case NONE:
fprintf(stderr, "\n[Network]: FAULT_LEVEL is NONE.");
fprintf(stderr, "\n[Network]: Informational "
"error only, control returned");
fprintf(stderr,
"to task to complete processing at the application level.\n");
OSSchedUnlock(); /* Reenable Task Switching */
return;
break;
default:
printf("\n[Network]: See STDERR (FAULT_LEVEL is unknown).\n");
fprintf(stderr, "\n[Network] FAULT_LEVEL is unknown !?!\n");
}
while(1); /* Correct Program Flow never gets here. */
}
void alt_NTPErrorHandler(INT8U error_code,
void *expanded_diagnosis_ptr)
{
FAULT_LEVEL fault_level;
if (error_code == OS_NO_ERR)
{
return;
}
fault_level = (error_code == OS_NO_ERR) ? NONE : SYSTEM;
OSSchedLock(); /* Disable Task Switching but still service other IRQs */
switch (error_code)
{
case EXPANDED_DIAGNOSIS_CODE:
fault_level = SYSTEM;
printf("\n[NTP]: See STDERR for expanded diagnosis translation.");
fprintf(stderr, "\n[NTP]: %s", (char *)expanded_diagnosis_ptr);
fprintf(stderr, "\n[NTP]: Error_code %d!\n", error_code);
break;
case OS_Q_FULL:
fault_level = NONE;
fprintf(stderr,"\n[NTP]: Attempted to post to a full message queue.");
break;
default:
fault_level = SYSTEM;
printf("\n[NTP]: See STDERR.\n");
fprintf(stderr, "\n[NTP]: Error_code %d!", error_code);
perror("\n[NTP]: ERRNO: ");
}
printf("[Program Error]: See STDERR\n");
switch (error_code) {
case OS_PRIO_EXIST:
fprintf(stderr, "Attempted to assign a task priority that is aready in use.\n");
break;
case OS_PRIO_INVALID:
fprintf(stderr, "Specified a task priority higher than the allowed maximum.\n");
fprintf(stderr, "Task can not be assigned a priority higher than %d\n",OS_LOWEST_PRIO);
break;
case OS_NO_MORE_TCB:
fprintf(stderr, "Task Control Blocks have been exhausted\n");
fprintf(stderr, "The current max number of task is %d\n",OS_MAX_TASKS);
break;
case OS_MBOX_FULL:
fprintf(stderr, "Attempted a Post to a Mailbox that already contains a message\n");
break;
case OS_ERR_EVENT_TYPE:
fprintf(stderr, "Attempted to access a resource that doesn't match the required data type\n");
break;
case OS_ERR_PEVENT_NULL:
fprintf(stderr, "Attempting access a resource that is pointing to NULL\n");
break;
case OS_ERR_POST_NULL_PTR:
fprintf(stderr, "Attempted to Post a NULL to a resource. \n");
break;
case OS_TIMEOUT:
fprintf(stderr, "Resource not received in specified time\n");
break;
case OS_ERR_PEND_ISR:
fprintf(stderr, "Attempting to pending for a resource in an ISR\n");
break;
case OS_TASK_DEL_IDLE:
fprintf(stderr, "Attempted to delete the IDLE task\n");
break;
case OS_TASK_DEL_ERR:
fprintf(stderr, "Attempted to delete a task that does not exist\n");
break;
case OS_TASK_DEL_ISR:
fprintf(stderr, "Attempted to delete a task from an ISR\n");
break;
case OS_Q_FULL:
fprintf(stderr, "Attempted to post to a full message queue\n");
break;
case OS_ERR_NOT_MUTEX_OWNER:
fprintf(stderr, "Attempted to post a mutex that is not owned by the task\n");
break;
default:
fprintf(stderr, "Unknown Error\n");
break;
}
fprintf(stderr, "Program is terminating.\n");
exit(0);
/* Process the error based on the fault level,
* reenable scheduler if appropriate. */
// switch (fault_level)
// {
// case TASK:
/* Error can be isolated by killing the task */
//printf("\n[NTP]: See STDERR (FAULT_LEVEL is TASK).");
//fprintf(stderr, "\n[NTP]: FAULT_LEVEL is TASK");
//fprintf(stderr, "\n[NTP]: Task is being deleted.\n");
//OSSchedUnlock(); /* Reenable Task Switching */
//OSTaskDel(OS_PRIO_SELF);
/* Invoke uCOSII error handler in case task deletion fails, in
* which case fault_level for this secondary error will be SYSTEM. */
//alt_uCOSIIErrorHandler(error_code, 0);
//break;
//case SYSTEM:
/* Total System Failure, Restart Required */
//printf("\n[NTP]: See STDERR (FAULT_LEVEL is SYSTEM).");
//fprintf(stderr, "\n[NTP]: FAULT_LEVEL is SYSTEM.");
//fprintf(stderr, "\n[NTP]: FATAL Error, Restart required.");
//fprintf(stderr, "\n[NTP]: Locking scheduler - endless loop.\n");
//while(1); /* Since scheduler is locked, loop halts all task activity.*/
//break;
//case NONE:
//fprintf(stderr, "\n[NTP] FAULT_LEVEL is NONE.");
//fprintf(stderr,
//"\n[NTP] Informational error only, control returned to task to ");
//fprintf(stderr,
//"complete processing at the application level.\n");
//OSSchedUnlock(); /* Reenable Task Switching */
//return;
//break;
//default:
//printf("\n[NTP]: See STDERR (FAULT_LEVEL is Unknown).\n");
//fprintf(stderr, "\n[NTP] FAULT_LEVEL is unknown!?!\n");
//}
//while(1); /* Correct Program Flow never gets here. */
}
/* The following task is called regularly to determine if some potential system
* integrity issues have occurred during a MicroC/OS-II system call. If something
* has occurred, the scheduling is turned off and the error handler is called.
*/
void alt_ucosii_check_return_code(INT8U return_code)
{
if(return_code != OS_NO_ERR)
{
OSSchedLock(); /* Disable Task Switching but still service other IRQs */
alt_uCOSIIErrorHandler(EXPANDED_DIAGNOSIS_CODE,"[MicroC/OS-II] - Check return code error");
OSSchedUnlock(); /* Enable Task Switching */
}
}
/******************************************************************************
* *
* License Agreement *
* *
* Copyright (c) 2006 Altera Corporation, San Jose, California, USA. *
* All rights reserved. *
* *
* Permission is hereby granted, free of charge, to any person obtaining a *
* copy of this software and associated documentation files (the "Software"), *
* to deal in the Software without restriction, including without limitation *
* the rights to use, copy, modify, merge, publish, distribute, sublicense, *
* and/or sell copies of the Software, and to permit persons to whom the *
* Software is furnished to do so, subject to the following conditions: *
* *
* The above copyright notice and this permission notice shall be included in *
* all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, *
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE *
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER *
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING *
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER *
* DEALINGS IN THE SOFTWARE. *
* *
* This agreement shall be governed in all respects by the laws of the State *
* of California and by the laws of the United States of America. *
* Altera does not recommend, suggest or require that this reference design *
* file be used in conjunction or combination with any other product. *
******************************************************************************/
d0f74983cThis file is pinned to the selected release. Download the original to open it in your design tool.