void nrk_kernel_error_add (uint8_t n, uint8_t task) { error_num = n; error_task = task; #ifdef NRK_LOG_ERRORS _nrk_log_error(error_num, error_task); #endif #ifdef NRK_REPORT_ERRORS nrk_error_print (); #endif /* */ #ifdef NRK_SOFT_REBOOT_ON_ERROR #ifdef NRK_WATCHDOG nrk_watchdog_disable(); #endif asm volatile("jmp 0x0000\n\t" ::); #endif #ifdef NRK_REBOOT_ON_ERROR // wait for watchdog to kick in if(n!=NRK_WATCHDOG_ERROR && n!=NRK_BOD_ERROR && n!=NRK_EXT_RST_ERROR) { nrk_watchdog_enable(); nrk_int_disable(); while(1); } #endif #ifdef NRK_HALT_ON_ERROR uint8_t t; uint8_t i; while (1) { for(i=0; i<20; i++ ) { nrk_led_set (2); nrk_led_clr (3); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); nrk_led_set (3); nrk_led_clr (2); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); } nrk_led_clr (3); nrk_led_clr (2); blink_morse_code_error( task ); blink_morse_code_error( n ); } #endif /* */ }
int8_t nrk_error_print () { int8_t t; if (error_num == 0) return 0; //nrk_led_set(RED_LED); #ifdef NRK_HALT_ON_ERROR nrk_int_disable (); #ifdef NRK_WATCHDOG nrk_watchdog_disable(); #endif #endif #ifndef NRK_REBOOT_ON_ERROR nrk_int_disable (); #endif #ifdef NRK_HALT_AND_LOOP_ON_ERROR nrk_int_disable (); #ifdef NRK_WATCHDOG nrk_watchdog_disable(); #endif while (1) { #endif nrk_kprintf (PSTR ("*NRK ERROR(")); #ifdef PRINTF printf ("%d", error_task); #endif nrk_kprintf (PSTR ("): ")); if (error_num > NRK_NUM_ERRORS) error_num = NRK_UNKOWN; switch (error_num) { case NRK_STACK_TOO_SMALL: nrk_kprintf (PSTR ("Stack was not defined as large enough!")); break; case NRK_STACK_OVERFLOW: //nrk_led_set(BLUE_LED); nrk_kprintf (PSTR ("Task Stack Overflow")); break; case NRK_INVALID_STACK_POINTER: nrk_kprintf (PSTR ("Invalid Stack Pointer")); break; case NRK_RESERVE_ERROR: //nrk_led_set(BLUE_LED); nrk_kprintf (PSTR ("Reserve Error in Scheduler")); break; case NRK_RESERVE_VIOLATED: nrk_kprintf (PSTR ("Task Reserve Violated")); break; case NRK_WAKEUP_MISSED: nrk_kprintf (PSTR ("Scheduler Missed Wakeup")); break; case NRK_DUP_TASK_ID: nrk_kprintf (PSTR ("Duplicated Task ID")); break; case NRK_BAD_STARTUP: nrk_kprintf (PSTR ("Unexpected Restart")); break; case NRK_STACK_SMASH: //nrk_led_set(GREEN_LED); nrk_kprintf (PSTR ("Idle or Kernel Stack Overflow")); break; case NRK_EXTRA_TASK: nrk_kprintf (PSTR ("Extra Task started, is nrk_cfg.h ok?")); break; case NRK_LOW_VOLTAGE: nrk_kprintf (PSTR ("Low Voltage")); break; case NRK_SEG_FAULT: nrk_kprintf (PSTR ("Unhandled Interrupt Vector")); break; case NRK_TIMER_OVERFLOW: //nrk_led_set(GREEN_LED); nrk_kprintf (PSTR ("Timer Overflow")); break; case NRK_WATCHDOG_ERROR: nrk_kprintf (PSTR ("Watchdog Restart")); break; case NRK_DEVICE_DRIVER: nrk_kprintf (PSTR ("Device Driver Error")); break; case NRK_UNIMPLEMENTED: nrk_kprintf (PSTR ("Kernel function not implemented")); break; case NRK_SIGNAL_CREATE_ERROR: nrk_kprintf (PSTR ("Failed to create Signal")); break; case NRK_SEMAPHORE_CREATE_ERROR: nrk_kprintf (PSTR ("Failed to create Semaphore")); break; default: nrk_kprintf (PSTR ("UNKOWN")); } putchar ('\r'); putchar ('\n'); #ifdef NRK_REBOOT_ON_ERROR // wait for watchdog to kick in if(error_num!=NRK_WATCHDOG_ERROR) { nrk_watchdog_enable(); nrk_int_disable(); while(1); } #endif //t=error_num; #ifdef NRK_HALT_AND_LOOP_ON_ERROR nrk_led_set (2); nrk_led_clr (3); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); nrk_led_set (3); nrk_led_clr (2); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); } #endif /* */ #ifdef NRK_HALT_ON_ERROR while (1) { nrk_led_set (2); nrk_led_clr (3); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); nrk_led_set (3); nrk_led_clr (2); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); } #endif /* */ error_num = 0; return t; }
/** * nrk_init(); * * - Init TCBlist - linked list of empty TCBs * - Init global variables * - Init event list * - Create idle task */ void nrk_init() { uint8_t i; // unsigned char *stkc; nrk_task_type IdleTask; nrk_wakeup_signal = nrk_signal_create(); if(nrk_wakeup_signal==NRK_ERROR) nrk_kernel_error_add(NRK_SIGNAL_CREATE_ERROR,0); //if((volatile)TCCR1B!=0) nrk_kernel_error_add(NRK_STACK_OVERFLOW,0); #ifndef NRK_SOFT_REBOOT_ON_ERROR i=_nrk_startup_error(); if((i&0x1)!=0) nrk_kernel_error_add(NRK_BAD_STARTUP,0); #ifndef IGNORE_EXT_RST_ERROR if((i&0x2)!=0) nrk_kernel_error_add(NRK_EXT_RST_ERROR,0); #endif #ifndef IGNORE_BROWN_OUT_ERROR if((i&0x4)!=0) nrk_kernel_error_add(NRK_BOD_ERROR,0); #endif //if((i&0x8)!=0) nrk_kernel_error_add(NRK_BAD_STARTUP,0); //if(_nrk_startup_ok()==0) nrk_kernel_error_add(NRK_BAD_STARTUP,0); #endif #ifdef NRK_STARTUP_VOLTAGE_CHECK if(nrk_voltage_status()==0) nrk_kernel_error_add(NRK_LOW_VOLTAGE,0); #endif #ifdef NRK_REBOOT_ON_ERROR #ifndef NRK_WATCHDOG while(1) { nrk_kprintf( PSTR("KERNEL CONFIG CONFLICT: NRK_REBOOT_ON_ERROR needs watchdog!\r\n") ); for (i = 0; i < 100; i++) nrk_spin_wait_us (1000); } #endif #endif #ifdef NRK_WATCHDOG if(nrk_watchdog_check()==NRK_ERROR) { nrk_watchdog_disable(); nrk_kernel_error_add(NRK_WATCHDOG_ERROR,0); } nrk_watchdog_enable(); #endif // nrk_stack_pointer_init(); /* #ifdef KERNEL_STK_ARRAY stkc = (uint16_t*)&nrk_kernel_stk[NRK_KERNEL_STACKSIZE-1]; nrk_kernel_stk[0]=STK_CANARY_VAL; nrk_kernel_stk_ptr = &nrk_kernel_stk[NRK_KERNEL_STACKSIZE-1]; #else stkc = NRK_KERNEL_STK_TOP-NRK_KERNEL_STACKSIZE; *stkc = STK_CANARY_VAL; stkc = NRK_KERNEL_STK_TOP; nrk_kernel_stk_ptr = NRK_KERNEL_STK_TOP; #endif *stkc++ = (uint16_t)((uint16_t)_nrk_timer_tick>>8); *stkc = (uint16_t)((uint16_t)_nrk_timer_tick&0xFF); */ // printf( "Init kernel_entry= %d %d\n",kernel_entry[1], kernel_entry[0] ); nrk_cur_task_prio = 0; nrk_cur_task_TCB = NULL; nrk_high_ready_TCB = NULL; nrk_high_ready_prio = 0; #ifdef NRK_STATS_TRACKER nrk_stats_reset(); #endif #ifdef NRK_MAX_RESERVES // Setup the reserve structures _nrk_reserve_init(); #endif _nrk_resource_cnt=0; //NRK_MAX_RESOURCE_CNT; for(i=0;i<NRK_MAX_RESOURCE_CNT;i++) { nrk_sem_list[i].count=-1; nrk_sem_list[i].value=-1; nrk_sem_list[i].resource_ceiling=-1; //nrk_resource_count[i]=-1; //nrk_resource_value[i]=-1; //nrk_resource_ceiling[i]=-1; } for (i= 0; i<NRK_MAX_TASKS; i++) { nrk_task_TCB[i].task_prio = TCB_EMPTY_PRIO; nrk_task_TCB[i].task_ID = -1; } // Setup a double linked list of Ready Tasks for (i=0;i<NRK_MAX_TASKS;i++) { _nrk_readyQ[i].Next = &_nrk_readyQ[i+1]; _nrk_readyQ[i+1].Prev = &_nrk_readyQ[i]; } _nrk_readyQ[0].Prev = NULL; _nrk_readyQ[NRK_MAX_TASKS].Next = NULL; _head_node = NULL; _free_node = &_nrk_readyQ[0]; nrk_task_set_entry_function( &IdleTask, nrk_idle_task); nrk_task_set_stk( &IdleTask, nrk_idle_task_stk, NRK_TASK_IDLE_STK_SIZE); nrk_idle_task_stk[0]=STK_CANARY_VAL; //IdleTask.task_ID = NRK_IDLE_TASK_ID; IdleTask.prio = 0; IdleTask.period.secs = 0; IdleTask.period.nano_secs = 0; IdleTask.cpu_reserve.secs = 0; IdleTask.cpu_reserve.nano_secs = 0; IdleTask.offset.secs = 0; IdleTask.offset.nano_secs = 0; IdleTask.FirstActivation = TRUE; IdleTask.Type = IDLE_TASK; IdleTask.SchType = PREEMPTIVE; nrk_activate_task(&IdleTask); }
void deep_sleep_button() { int i,cnt; nrk_int_disable(); nrk_eeprom_write_byte(EEPROM_SLEEP_STATE_ADDR,1); nrk_led_set(0); nrk_spin_wait_us(50000); nrk_led_clr(0); nrk_led_clr(1); nrk_led_clr(2); nrk_led_clr(3); nrk_watchdog_disable(); nrk_int_disable(); _nrk_os_timer_stop(); nrk_gpio_direction(NRK_BUTTON, NRK_PIN_INPUT); rf_power_down(); // Enable Pullup for button //PORTD = 0xff; nrk_gpio_set(NRK_BUTTON); nrk_ext_int_configure( NRK_EXT_INT_1,NRK_LEVEL_TRIGGER, &wakeup_func); EIFR=0xff; nrk_ext_int_enable( NRK_EXT_INT_1); nrk_int_enable(); DDRA=0x0; DDRB=0x0; DDRC=0x0; ASSR=0; TRXPR = 1 << SLPTR; set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_cpu(); // reboot while(1) { //printf( "awake!\r\n" ); nrk_led_clr(0); nrk_led_clr(1); nrk_led_set(1); cnt=0; for(i=0; i<100; i++ ) { //if((PIND & 0x2)==0x2)cnt++; if(nrk_gpio_get(NRK_BUTTON)==0)cnt++; nrk_spin_wait_us(10000); } printf( "cnt=%d\n",cnt ); if(cnt>=50 ) { // reboot nrk_led_clr(1); nrk_led_set(0); nrk_eeprom_write_byte(EEPROM_SLEEP_STATE_ADDR,0); nrk_spin_wait_us(50000); nrk_spin_wait_us(50000); nrk_watchdog_enable(); while(1); } nrk_led_clr(0); nrk_led_clr(1); TRXPR = 1 << SLPTR; set_sleep_mode(SLEEP_MODE_PWR_DOWN); sleep_enable(); sleep_cpu(); } }
int8_t nrk_error_print () { int8_t t=0,i=0; if (error_num == 0) return 0; #ifdef NRK_HALT_ON_ERROR nrk_int_disable (); #ifdef NRK_WATCHDOG nrk_watchdog_disable(); #endif #endif #ifndef NRK_REBOOT_ON_ERROR nrk_int_disable (); #endif #ifdef NRK_HALT_AND_LOOP_ON_ERROR nrk_int_disable (); #ifdef NRK_WATCHDOG nrk_watchdog_disable(); #endif while (1) { #endif nrk_kprintf (PSTR ("*NRK ERROR(")); printf ("%d", error_task); nrk_kprintf (PSTR ("): ")); if (error_num > NRK_NUM_ERRORS) error_num = NRK_UNKOWN; switch (error_num) { case NRK_PERIOD_OVERFLOW: nrk_kprintf (PSTR ("Task period too large. Period must be less than 61 seconds.")); break; case NRK_STACK_TOO_SMALL: nrk_kprintf (PSTR ("Stack was not defined as large enough!")); break; case NRK_STACK_OVERFLOW: nrk_kprintf (PSTR ("Task Stack Overflow")); break; case NRK_INVALID_STACK_POINTER: nrk_kprintf (PSTR ("Invalid Stack Pointer")); break; case NRK_RESERVE_ERROR: nrk_kprintf (PSTR ("Reserve Error in Scheduler")); break; case NRK_RESERVE_VIOLATED: nrk_kprintf (PSTR ("Task Reserve Violated")); break; case NRK_WAKEUP_MISSED: nrk_kprintf (PSTR ("Scheduler Missed Wakeup")); break; case NRK_DUP_TASK_ID: nrk_kprintf (PSTR ("Duplicated Task ID")); break; case NRK_BAD_STARTUP: nrk_kprintf (PSTR ("Unexpected Restart")); break; case NRK_STACK_SMASH: nrk_kprintf (PSTR ("Idle or Kernel Stack Overflow")); break; case NRK_EXTRA_TASK: nrk_kprintf (PSTR ("Extra Task started, is nrk_cfg.h ok?")); break; case NRK_LOW_VOLTAGE: nrk_kprintf (PSTR ("Low Voltage")); break; case NRK_SEG_FAULT: nrk_kprintf (PSTR ("Unhandled Interrupt Vector")); break; case NRK_TIMER_OVERFLOW: nrk_kprintf (PSTR ("Timer Overflow")); break; case NRK_SW_WATCHDOG_ERROR: nrk_kprintf (PSTR ("SW Watchdog Restart")); break; case NRK_WATCHDOG_ERROR: nrk_kprintf (PSTR ("Watchdog Restart")); break; case NRK_DEVICE_DRIVER: nrk_kprintf (PSTR ("Device Driver Error")); break; case NRK_UNIMPLEMENTED: nrk_kprintf (PSTR ("Kernel function not implemented")); break; case NRK_SIGNAL_CREATE_ERROR: nrk_kprintf (PSTR ("Failed to create Signal")); break; case NRK_SEMAPHORE_CREATE_ERROR: nrk_kprintf (PSTR ("Failed to create Semaphore")); break; case NRK_BOD_ERROR: nrk_kprintf (PSTR ("Brown Out Detect")); break; case NRK_EXT_RST_ERROR: nrk_kprintf (PSTR ("External Reset")); break; default: nrk_kprintf (PSTR ("UNKOWN")); } putchar ('\r'); putchar ('\n'); #ifdef NRK_SOFT_REBOOT_ON_ERROR #ifdef NRK_WATCHDOG nrk_watchdog_disable(); #endif GTCCR=0; ASSR=0; OCR0B=0; OCR0A=0; TCNT0=0; TCCR0B=0; TCCR0A=0; EIMSK=0; EIFR=0; PCIFR=0; OCR3B =0; OCR3A =0; TCNT3 =0; TCCR3B=0; TCCR3A=0; TIFR3=0; TIMSK3=0; OCR2B =0; OCR2A =0; TCNT2 =0; TCCR2B=0; TCCR2A=0; TCCR2A=0; TIFR2=0; TIMSK2=0; //nrk_int_disable(); /* Dalton Banks asm volatile( "ldi r28,0xFF\n\t" "out __SP_L__, r28\n\t" "ldi r29,0x21\n\t" "out __SP_H__, r29\n\t" "clr r0\n\t" "clr r1\n\t" "clr r2\n\t" "clr r3\n\t" "clr r4\n\t" "clr r5\n\t" "clr r6\n\t" "clr r7\n\t" "clr r8\n\t" "clr r9\n\t" "clr r10\n\t" "clr r11\n\t" "clr r12\n\t" "clr r13\n\t" "clr r14\n\t" "clr r15\n\t" "clr r16\n\t" "clr r17\n\t" "clr r18\n\t" "clr r19\n\t" "clr r20\n\t" "clr r21\n\t" "clr r22\n\t" "clr r23\n\t" "clr r24\n\t" "clr r25\n\t" "clr r26\n\t" "clr r27\n\t" "clr r28\n\t" "clr r29\n\t" "clr r30\n\t" "clr r31\n\t" "cli\n\t" "out __SREG__, r0\n\t" "jmp __ctors_end\n\t" ::); */ #endif #ifdef NRK_REBOOT_ON_ERROR // wait for watchdog to kick in if(error_num!=NRK_WATCHDOG_ERROR && error_num!=NRK_BOD_ERROR && error_num!=NRK_EXT_RST_ERROR) { nrk_watchdog_enable(); nrk_int_disable(); while(1); } #endif //t=error_num; #ifdef NRK_HALT_AND_LOOP_ON_ERROR for(i=0; i<20; i++ ) { nrk_led_set (2); nrk_led_clr (3); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); nrk_led_set (3); nrk_led_clr (2); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); } nrk_led_clr(2); nrk_led_clr(3); blink_morse_code_error( error_task ); pause(); nrk_led_set(2); pause(); nrk_led_clr(2); pause(); blink_morse_code_error( error_num); } #endif /* */ #ifdef NRK_HALT_ON_ERROR while (1) { for(i=0; i<20; i++ ) { nrk_led_set (2); nrk_led_clr (3); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); nrk_led_set (3); nrk_led_clr (2); for (t = 0; t < 100; t++) nrk_spin_wait_us (1000); } nrk_led_clr (3); nrk_led_clr (2); blink_morse_code_error( error_task ); pause(); nrk_led_set(2); pause(); nrk_led_clr(2); pause(); blink_morse_code_error( error_num); } #endif /* */ error_num = 0; return t; }