os.c (3275B)
1 #include "os.h" 2 #include "app/packet.h" 3 #include "libopencm3/stm32/iwdg.h" 4 #include "shared/flash-io.h" 5 #include "shared/drv-usart-dma.h" 6 7 volatile uint16_t osDoggyRegister = OS_DOGGY_RESET_VALUE; 8 9 TaskHandle_t os_create_task(const OS_TaskAttr_t attr, TaskHandle_t handle) { 10 xTaskCreate(attr.function, attr.name, attr.stackSize, attr.parameters, attr.priority, &handle); 11 return handle; 12 } 13 14 QueueHandle_t os_create_queue(const OS_QueueAttr_t attr, QueueHandle_t handle) { 15 handle = xQueueCreateStatic(attr.length, attr.itemSize, attr.pxStorageBuf, attr.pxQueueBuf); 16 return handle; 17 } 18 19 void os_init_rtos(void) { 20 21 packet_tx_queueHandle = os_create_queue(packet_tx_queueAttr, packet_tx_queueHandle); 22 packet_rx_taskHandle = os_create_task(packet_rx_taskAttr, packet_rx_taskHandle); 23 packet_tx_taskHandle = os_create_task(packet_tx_taskAttr, packet_tx_taskHandle); 24 25 usart_enable_idle_interrupt(gsm.port); 26 usart_disable_rx_interrupt(gsm.port); 27 28 usart_enable_idle_interrupt(dbg.port); 29 usart_disable_rx_interrupt(dbg.port); 30 31 iwdg_start(); 32 iwdg_set_period_ms(1000); 33 while (iwdg_reload_busy() || iwdg_prescaler_busy()); 34 uint8_t dummy = 0; 35 xTaskNotify(packet_tx_taskHandle, dummy, eSetValueWithOverwrite); 36 } 37 38 static uint16_t os_check_for_failure(void) { 39 // Watchdog scheme: 40 static uint16_t periodicFailCnt = 0; 41 static uint16_t classifierFailCnt = 0; 42 static uint16_t uartFailCnt = 0; 43 static uint16_t periodicFailTrigger = 0x2500; // temporary 44 static uint16_t classifierFailTrigger = 0x05; // temporary 45 static uint16_t uartFailTrigger = 0x02; // temporary 46 if ((osDoggyRegister & PERIODIC_CHAIN) == PERIODIC_CHAIN) { 47 periodicFailCnt = 0; 48 osDoggyRegister &= ~(uint16_t)PERIODIC_CHAIN; 49 } else { 50 periodicFailCnt++; 51 if (periodicFailCnt > periodicFailTrigger) { 52 return osDoggyRegister & PERIODIC_CHAIN; 53 } else osDoggyRegister &= ~(uint16_t)PERIODIC_CHAIN; 54 } 55 if ((osDoggyRegister & CLASSIFIER_CHAIN) == (CLASSIFIER_CHAIN)) { 56 classifierFailCnt = 0; 57 osDoggyRegister &= ~(uint16_t)CLASSIFIER_CHAIN; 58 } else if ((osDoggyRegister & CLASSIFIER_CHAIN) == OS_DOGGY_CLASSIFIER_Q) { 59 classifierFailCnt++; 60 if (classifierFailCnt > classifierFailTrigger) { 61 return osDoggyRegister & CLASSIFIER_CHAIN; 62 } else osDoggyRegister &= ~(uint16_t)CLASSIFIER_CHAIN; 63 } 64 if ((osDoggyRegister & UART_CHAIN) == (UART_CHAIN)) { 65 uartFailCnt = 0; 66 osDoggyRegister &= ~(uint16_t)UART_CHAIN; 67 } else if ((osDoggyRegister & UART_CHAIN) == OS_DOGGY_UART_DATA) { 68 uartFailCnt++; 69 if (uartFailCnt > uartFailTrigger) { 70 return osDoggyRegister & UART_CHAIN; 71 } else osDoggyRegister &= ~(uint16_t)UART_CHAIN; 72 } 73 return 0; 74 } 75 76 // Automatically created idle_task by FreeRTOS 77 void vApplicationIdleHook(void) { 78 for (;;) { 79 vTaskEnterCritical(); 80 uint16_t result = os_check_for_failure(); 81 if (result == 0) { 82 iwdg_reset(); 83 } else { 84 // Dump the osDoggyRegister to flash area 85 flash_io_dump_diagnostic(osDoggyRegister); 86 // Go for reboot 87 } 88 vTaskExitCritical(); 89 } 90 }