/* GPIO / PWM / 时钟三路 sim 的行为约定。 */ #include "sim_hal.h" #include "unity.h" void setUp(void) { sim_hal_reset(); } void tearDown(void) {} /* ---- GPIO ---- */ static void test_output_write_and_readback(void) { TEST_ASSERT_EQUAL_INT(HAL_OK, hal_gpio_config(5, HAL_GPIO_OUTPUT)); TEST_ASSERT_EQUAL_INT(0, sim_gpio_level(5)); /* 配完默认低 */ TEST_ASSERT_EQUAL_INT(HAL_OK, hal_gpio_write(5, 1)); TEST_ASSERT_EQUAL_INT(1, sim_gpio_level(5)); int level = -1; TEST_ASSERT_EQUAL_INT(HAL_OK, hal_gpio_read(5, &level)); TEST_ASSERT_EQUAL_INT(1, level); } /* 「把输入脚当输出写」在板子上是静默无效的,最难查 —— sim 里必须报错。 */ static void test_write_to_input_pin_is_error(void) { TEST_ASSERT_EQUAL_INT(HAL_OK, hal_gpio_config(6, HAL_GPIO_INPUT)); TEST_ASSERT_EQUAL_INT(HAL_ERR_ARG, hal_gpio_write(6, 1)); TEST_ASSERT_EQUAL_INT(HAL_ERR_ARG, hal_gpio_write(7, 1)); /* 压根没配过 */ TEST_ASSERT_EQUAL_INT(HAL_ERR_ARG, hal_gpio_config(SIM_GPIO_PINS, HAL_GPIO_OUTPUT)); } /* 五路 FLT/PG 是开漏 + 上拉:没有故障时必须读回 1,不能默认 0。 */ static void test_pullup_input_idles_high(void) { TEST_ASSERT_EQUAL_INT(HAL_OK, hal_gpio_config(8, HAL_GPIO_INPUT_PULLUP)); int level = -1; TEST_ASSERT_EQUAL_INT(HAL_OK, hal_gpio_read(8, &level)); TEST_ASSERT_EQUAL_INT(1, level); sim_gpio_drive(8, 0); /* 器件报故障,把脚拉低 */ TEST_ASSERT_EQUAL_INT(HAL_OK, hal_gpio_read(8, &level)); TEST_ASSERT_EQUAL_INT(0, level); } /* 写计数是给 A5「改 CH1 不动 CH2~5」那条断言准备的。 */ static void test_write_counter_is_per_pin(void) { TEST_ASSERT_EQUAL_INT(HAL_OK, hal_gpio_config(10, HAL_GPIO_OUTPUT)); TEST_ASSERT_EQUAL_INT(HAL_OK, hal_gpio_config(11, HAL_GPIO_OUTPUT)); hal_gpio_write(10, 1); hal_gpio_write(10, 0); TEST_ASSERT_EQUAL_UINT32(2, sim_gpio_writes(10)); TEST_ASSERT_EQUAL_UINT32(0, sim_gpio_writes(11)); } /* ---- PWM ---- */ static void test_pwm_config_and_duty(void) { TEST_ASSERT_EQUAL_INT(HAL_ERR_ARG, hal_pwm_set_permille(0, 500)); /* 没配就用 */ TEST_ASSERT_EQUAL_INT(HAL_OK, hal_pwm_config(0, 21, 25000)); /* 风扇 25 kHz */ TEST_ASSERT_EQUAL_INT(21, sim_pwm_pin(0)); TEST_ASSERT_EQUAL_UINT32(25000, sim_pwm_freq(0)); TEST_ASSERT_EQUAL_INT(0, sim_pwm_permille(0)); /* 配完默认停转 */ TEST_ASSERT_EQUAL_INT(HAL_OK, hal_pwm_set_permille(0, 400)); uint16_t d = 0; TEST_ASSERT_EQUAL_INT(HAL_OK, hal_pwm_get_permille(0, &d)); TEST_ASSERT_EQUAL_UINT16(400, d); TEST_ASSERT_EQUAL_INT(HAL_ERR_ARG, hal_pwm_set_permille(0, 1001)); /* 千分比上限 */ TEST_ASSERT_EQUAL_INT(HAL_ERR_ARG, hal_pwm_config(HAL_PWM_CH_MAX, 21, 25000)); TEST_ASSERT_EQUAL_INT(HAL_ERR_ARG, hal_pwm_config(1, 21, 0)); } /* ---- 时钟 ---- */ static void test_virtual_clock_advances_only_on_demand(void) { TEST_ASSERT_EQUAL_UINT64(0, hal_time_now_us()); hal_time_delay_ms(17); /* A9 的上电时序就是这个量级 */ TEST_ASSERT_EQUAL_UINT32(17, hal_time_now_ms()); TEST_ASSERT_EQUAL_UINT32(1, sim_time_delay_calls()); sim_time_advance_us(500); TEST_ASSERT_EQUAL_UINT64(17500, hal_time_now_us()); TEST_ASSERT_EQUAL_UINT32(17, hal_time_now_ms()); /* 不满 1 ms 不进位 */ } /* 49.7 天回绕:农场是长稳运行的,这一条迟早会被踩到。 */ static void test_elapsed_survives_wraparound(void) { sim_time_set_us(0xFFFFFFF0ull * 1000ull); uint32_t t0 = hal_time_now_ms(); sim_time_advance_ms(32); /* 跨过 32 位回绕点 */ TEST_ASSERT_TRUE(hal_time_now_ms() < t0); TEST_ASSERT_EQUAL_UINT32(32, hal_time_elapsed_ms(t0)); } int main(void) { UNITY_BEGIN(); RUN_TEST(test_output_write_and_readback); RUN_TEST(test_write_to_input_pin_is_error); RUN_TEST(test_pullup_input_idles_high); RUN_TEST(test_write_counter_is_per_pin); RUN_TEST(test_pwm_config_and_duty); RUN_TEST(test_virtual_clock_advances_only_on_demand); RUN_TEST(test_elapsed_survives_wraparound); return UNITY_END(); }