Error Handling

Nano-RK uses the convention that system calls return -1 upon error and 1 upon success.

NRK_OK     1
NRK_ERROR  -1

_nrk_errno_set

void _nrk_errno_set( NRK_ERRNO error_code )

Parameters: NRK_ERRNO error code to set
Return Values: none

This function should be used by user defined system calls to set an error number.

nrk_errno_get

uint8_t nrk_errno_get( )

Parameters: none
Return Values: uint8_t error code last set for current task

Once a function returns failure (-1), this function can be used to get a more descriptive error code.

Kernel-Errors

Kernel errors are triggered when various OS services fail. There are various flags in nrk_cfg.h that govern how the system responds to errors:

  • NRK_REPORT_ERRORS
    • Print error messages. Usually this should be disabled in final deployments.
  • NRK_HALT_ON_ERROR
    • Halt execution and print a single error message
  • NRK_HALT_AND_LOOP_ON_ERROR
    • Halt execution and prints error in a loop
  • NRK_LOG_ERROR
    • Not yet implemented. Will store error log to MMC card.
  • NRK_WATCHDOG
    • Enable the watchdog timer in case a kernel service hangs during a deployment
  • NRK_REBOOT_ON_ERROR
    • This must be used with the watchdog timer to reboot the system on errors
1// NRK_REPORT_ERRORS will cause the kernel to print out information about
2// missed deadlines or reserve violations
3#define NRK_REPORT_ERRORS
1// NRK_HALT_ON_ERRORS will cause the kernel to freeze on errors so that
2// it is easier to see debugging messages.
3#define NRK_HALT_ON_ERROR
1// NRK_HALT_AND_LOOP_ON_ERRORS will cause the kernel to freeze on errors but continue
2// to print the panic message in a loop so that the node can be plugged into a terminal
3// in order to indentify the problem.
4#define NRK_HALT_AND_LOOP_ON_ERROR
1// Add these two #define statements to ignore certain typical errors.
2// This is useful if NRK_HALT_ON_ERROR is defined, but for example you
3// are connected to a programmer which will use external reset at startup
4#define IGNORE_BROWN_OUT_ERROR
5#define IGNORE_EXT_RST_ERROR

*NRK ERROR( task_id ): ERROR_MESSAGE

task_id is the ID of the task that caused the error. 0 means the kernel had an internal error.

  • "Task Stack Overflow"
    • The canary value in the identified task was over written. Try making the task stack size larger.
  • "Reserve Error in Scheduler"
  • "Task Reserve Violated"
    • Increase the reservation for the task, or disable a task reserve by setting it to 0
  • "Scheduler Missed Wakeup"
    • See Timer Overflow
  • "Duplicated Task ID"
    • There is a problem with the way the tasks are being configured
  • "Unexpected Restart"
    • This usually happens when the program counter jumps to 0 due to a memory problem.
    • Reset sources like brown-out, watchdog timer and external interrupt will have more specific errors
  • "Idle or Kernel Stack Overflow"
  • "Extra Task started, is nrk_cfg.h ok?"
    • Most likely NRK_MAX_TASKS in nrk_cfg.h needs to be larger
  • "Low Voltage"
  • "Bad Startup"
    • This occurs when the kernel checks the Power-on reset flag (PORF) at startup and sees that it was not set. This indicates that the node restarted somehow without a proper reset. Bad memory operations like dereferencing a null pointer can cause jumps to address 0. Normally if the POR flag is set at startup the kernel will clear it immediately.
  • "Unhandled Interrupt Vector"
    • An interrupt mask was set that should not have been.
    • The code executed passed the end of a task (no while() loop inside task etc)
  • "Timer Overflow"
    • This is likely a problem in the kernel. It can happen if the fuses get cleared such that the ASYNC clock is now operating differently. It can also happen if NRK_SLEEP_WAKEUP_TIME in nrk_platform_time.h is set too low. NRK_SLEEP_WAKEUP_TIME is the max number of ms required for the processor to wake from deep sleep.
  • "Device Driver Error"
  • "Failed to create Signal"
  • "Failed to create Semaphore"
    • An internal OS related operation failed to create a semaphore. This is probably because NRK_MAX_RESOURCE_CNT needs to be increased for some functionality the application is trying to use.
  • "Kernel function not implemented"
  • "Brown Out Detected"
    • This alerts you that a reboot was caused by the CPU brown out detector (BOD)
  • "External Reset"
    • This alerts you that an external reset cause the CPU to restart.
    • This can be caused by the programmer board. See IGNORE_EXT_RST_ERROR #define above to disable
  • "Watchdog Restart"
    • This indicates that the hardware watchdog timer expired
  • "SW Watchdog Restart"
    • This indicates that a software watchdog timer expired
  • "UNKOWN"

Error Code #defines

#define NRK_UNKOWN                      0
#define NRK_STACK_OVERFLOW              1
#define NRK_RESERVE_ERROR               2
#define NRK_RESERVE_VIOLATED            3
#define NRK_WAKEUP_MISSED               4
#define NRK_DUP_TASK_ID                 5
#define NRK_BAD_STARTUP                 6
#define NRK_EXTRA_TASK                  7
#define NRK_STACK_SMASH                 8
#define NRK_LOW_VOLTAGE                 9
#define NRK_SEG_FAULT                   10      
#define NRK_TIMER_OVERFLOW              11      
#define NRK_DEVICE_DRIVER               12      
#define NRK_UNIMPLEMENTED               13      
#define NRK_SIGNAL_CREATE_ERROR         14
#define NRK_SEMAPHORE_CREATE_ERROR      15
#define NRK_WATCHDOG_ERROR              16
#define NRK_STACK_TOO_SMALL             17
#define NRK_INVALID_STACK_POINTER       18
#define NRK_BOD_ERROR                   19
#define NRK_EXT_RST_ERROR               20
#define NRK_SW_WATCHDOG_ERROR           21
#define NRK_NUM_ERRORS                  22     

nrk_kernel_error_add

void nrk_kernel_error( Kernel_Panic_ID, uint8_t task_ID )

Parameters: Kernel_Panic_ID is a #define kernel panic id
Parameters: uint8_t task_ID is the PID of the offending task
Return Values: none

This function is called from within kernel code to post kernel panics. This can be used by applications in cases of a hoplessly fatal error (this should rarely be the case though).

1nrk_kernel_error_add( NRK_SIGNAL_CREATE_ERROR ,nrk_cur_task_TCB->task_ID);

Kernel-Watchdog-Timer

For final deployments, you may wish to enable extra protection against the system halting by using a watchdog timer. After including NRK_WATCHDOG in the nrk_cfg.h file, the system watchdog timer will be enabled at bootup and set each time the Nano-RK scheduler executes. Under normal operation, application tasks will be bounded by their reservations. If a part of the OS fails to exit within 8 seconds, the system will reboot. Upon restart, a watchdog kernel panic is triggered. When NRK_HALT_ON_ERROR or NRK_HALT_AND_LOOP_ON_ERROR is enabled, the watchdog timer is disabled upon an error so as to not interfere with the normal error printing operation.

1// Enable the watchdog as a protective measure
2// This will only activate if the scheduler fails.
3#define NRK_WATCHDOG

Software-Watchdog-Timer

The software watchdog timer allows individual watchdog timers of different periods for unique tasks. If a task gets stuck in a loop that sleeps, then the hardware watchdog timer will not trigger since the kernel still runs. In cases like this, software watchdog timers provide an extra level of coverage to detect these error cases.

1// Enable software watchdog timer
2#define NRK_SW_WDT
3// Set the number of watchdog timers you wish to create
4#define NRK_MAX_SW_WDT 3

nrk_sw_wdt_init

int8_t nrk_sw_wdt_init(uint8_t id, nrk_time_t period, void *func)

Parameters: uint8_t id, nrk_time_t *period, void *func()
Return Values: NRK_OK upon success and NRK_ERROR on failure

This function sets the period for software watchdog timer id. If a task does not call nrk_sw_wdt_update() for the timer within the specified period the node call the function set by func(). If 'func' is set to NULL, the node will simply reboot.

 1nrk_time_t t;
 2int8_t v;
 3t.secs=15;
 4t.nano_secs=0;
 5// Setup software watchdog timer 0 to expire every 15 seconds and reboot
 6v=nrk_sw_wdt_init(0, &t, NULL);
 7
 8nrk_sw_wdt_start(0);
 9while(1)
10   {
11   nrk_sw_wdt_update(0);
12   nrk_wait_until_next_period();
13   }

nrk_sw_wdt_start

int8_t nrk_sw_wdt_start(uint8_t id)

Parameters: uint8_t id
Return Values: NRK_OK upon success and NRK_ERROR on failure

This function starts id software watchdog timer.

nrk_sw_wdt_stop

int8_t nrk_sw_wdt_stop(uint8_t id)

Parameters: uint8_t id
Return Values: NRK_OK upon success and NRK_ERROR on failure

This function stops id software watchdog timer.

nrk_sw_wdt_update

int8_t nrk_sw_wdt_update(uint8_t id)

Parameters: uint8_t id
Return Values: NRK_OK upon success and NRK_ERROR on failure

This function updates the software watchdog timer. Call this faster than the watchdog period to keep the timer running.

Prev: Contents Next: Time Management Top