/**************************************************************************** Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT be copied by any method or incorporated into another program without the express written consent of Aerospace C.Power. This Information or any portion thereof remains the property of Aerospace C.Power. The Information contained herein is believed to be accurate and Aerospace C.Power assumes no responsibility or liability for its use in any way and conveys no license or title under any patent or copyright and makes no representation or warranty that this Information is free from patent or copyright infringement. ****************************************************************************/ /* FreeRTOS includes */ #include "FreeRTOS.h" #include "task.h" /* os shim includes */ #include "os_types.h" #include "os_event.h" /* common includes */ #include "iot_module.h" #include "iot_config.h" /* crypto module(rng) include */ #include "iot_crypto.h" #define TICK_PER_MS (configTICK_RATE_HZ / 1000) static uint64_t boot_time_ms = 0; static uint32_t last_tick = 0; static os_event_h time_event = NULL; extern int xPortCheckIfHeapAddress(void *addr); void os_utils_init() { if (time_event == NULL) { // create a event to protect boot time and last tick count time_event = os_create_event(OS_UTILS_MID, 1); } cpl_utils_init(); } uint64_t os_boot_time64() { uint64_t result = 0; uint32_t passed_tick_count = 0; uint32_t now_ticks; IOT_ASSERT(time_event); os_wait_event(time_event, MAX_TIME); // start of protection now_ticks = xTaskGetTickCount(); if (now_ticks >= last_tick) { passed_tick_count = now_ticks - last_tick; } else { passed_tick_count = ((TickType_t)(-1) - (last_tick - now_ticks)); } last_tick = now_ticks; boot_time_ms += passed_tick_count / TICK_PER_MS; result = boot_time_ms; os_set_event(time_event); // end of protection return result; } uint32_t os_boot_time32() { uint32_t ticks = xTaskGetTickCount(); return ticks / TICK_PER_MS; } uint32_t os_rand() { static uint32_t ulNextRand = 0; /* Disabled for bringup stage. */ #if HW_PLATFORM > HW_PLATFORM_FPGA iot_crypto_rng_get_random((uint8_t*)&ulNextRand, sizeof(uint32_t)); #else const uint32_t ulMultiplier = 0x015a4e35UL; uint32_t ticks = xTaskGetTickCount(); uint32_t ulIncrement = ticks % 39989; if (ulNextRand == 0) { ulNextRand = (ticks + ((uint32_t)&ticks & 0xFFFF)) % 49891; } ulNextRand = (ulMultiplier * ulNextRand) + ulIncrement; #endif return(uint32_t)(ulNextRand); } uint32_t IRAM_ATTR os_check_heap_address(void *addr) { #if HW_PLATFORM == HW_PLATFORM_SIMU (void)addr; return true; #else return xPortCheckIfHeapAddress(addr) ? 1 : 0; #endif } uint32_t os_delay(uint32_t millisec) { TickType_t ticks = millisec / portTICK_PERIOD_MS; vTaskDelay(ticks ? ticks : 1); /* Minimum delay = 1 tick */ return 0; } #if (PLC_STATISTICS_ENABLE) #define CASE(x) {case x: return #x;} /* convert a mid to corresponding string */ char* iot_get_mid_str(module_id_t mid) { switch (mid) { CASE(UNKNOWN_MID) CASE(OS_TIMER_MID) CASE(OS_LOCK_MID) CASE(OS_TASK_MID) CASE(OS_UTILS_MID) CASE(CPL_UTILS_MID) CASE(IOT_PKT_MID) CASE(IOT_QUEUE_MID) CASE(IOT_IPC_MID) CASE(IOT_PLC_LIB_MID) CASE(IOT_DBGLOG_MID) CASE(IOT_COMMUNICATOR_MID) CASE(IOT_CLI_MID) CASE(IOT_APP_PING_MID) CASE(PLC_CVG_COMMON_MID) CASE(PLC_CVG_RT_MID) CASE(PLC_CVG_SEC_MID) CASE(PLC_CVG_BWM_MID) CASE(PLC_CVG_PRM_MID) CASE(PLC_CVG_NWM_MID) CASE(PLC_MAC_COMMON_MID) CASE(PLC_MAC_BEACON_MID) CASE(PLC_MAC_DATA_MID) CASE(PLC_MAC_VDEV_MID) CASE(PLC_MAC_PDEV_MID) CASE(PLC_MAC_RX_RING_MID) CASE(PLC_MAC_DESC_ENGINE_MID) CASE(PLC_MAC_ZC_MID) CASE(PLC_SIM_COMMON_MID) CASE(PLC_SIM_BEACON_MID) CASE(PLC_SIM_TX_MID) } return "Unknown_MID"; } #endif //PLC_STATISTICS_ENABLE