1 /* 2 * Copyright (c) 2017 Oticon A/S 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #include <stdbool.h> 8 #include "zephyr/types.h" 9 #include "fake_timer.h" 10 #include "time_machine.h" 11 #include <arch/posix/posix_soc_if.h> 12 #include <posix_board_if.h> 13 #include <posix_soc.h> 14 15 /** 16 * Replacement to the kernel k_busy_wait() 17 * Will block this thread (and therefore the whole Zephyr) during usec_to_wait 18 * 19 * Note that interrupts may be received in the meanwhile and that therefore this 20 * thread may lose context. 21 * Therefore the wait time may be considerably longer. 22 * 23 * All this function ensures is that it will return after usec_to_wait or later. 24 */ arch_busy_wait(uint32_t usec_to_wait)25void arch_busy_wait(uint32_t usec_to_wait) 26 { 27 bs_time_t time_end = tm_get_hw_time() + usec_to_wait; 28 29 while (tm_get_hw_time() < time_end) { 30 /* 31 * There may be wakes due to other interrupts or nested calls to 32 * k_busy_wait in interrupt handlers 33 */ 34 fake_timer_wake_in_time(time_end); 35 posix_halt_cpu(); 36 } 37 } 38 39 /** 40 * Will block this thread (and therefore the whole Zephyr) during usec_to_waste 41 * 42 * Very similar to arch_busy_wait(), but if an interrupt or context switch 43 * occurs this function will continue waiting after, ensuring that 44 * usec_to_waste are spent in this context, irrespectively of how much more 45 * time would be spent on interrupt handling or possible switched-in tasks. 46 * 47 * Can be used to emulate code execution time. 48 */ posix_cpu_hold(uint32_t usec_to_waste)49void posix_cpu_hold(uint32_t usec_to_waste) 50 { 51 bs_time_t time_start; 52 int64_t to_wait = usec_to_waste; 53 54 while (to_wait > 0) { 55 /* 56 * There may be wakes due to other interrupts or nested calls to 57 * cpu_hold in interrupt handlers 58 */ 59 time_start = tm_get_hw_time(); 60 fake_timer_wake_in_time(time_start + to_wait); 61 posix_change_cpu_state_and_wait(true); 62 to_wait -= tm_get_hw_time() - time_start; 63 64 posix_irq_handler(); 65 } 66 } 67