From 64adab92381efdca8c3c74ba3675f6c25cf69ae4 Mon Sep 17 00:00:00 2001 From: impressionyang Date: Thu, 28 Aug 2025 09:54:04 +0800 Subject: [PATCH] =?UTF-8?q?feat=E2=9C=A8:=20=E5=A2=9E=E5=8A=A0sg90?= =?UTF-8?q?=E7=94=B5=E6=9C=BA=E6=96=87=E4=BB=B6=E5=92=8C=E6=9C=8D=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/APP/main_app/main_app.c | 16 ++- main/CMakeLists.txt | 12 +- main/components/sg90_servo/imp_comp_sg90.c | 73 ++++++++++ main/components/sg90_servo/imp_comp_sg90.h | 60 ++++++++ main/components/sg90_servo/iot_servo.c | 130 ++++++++++++++++++ main/components/sg90_servo/iot_servo.h | 104 ++++++++++++++ main/main_common.c | 2 +- main/main_common.h | 1 + .../switch_control_service.c | 82 +++++++++++ .../switch_control_service.h | 47 +++++++ 10 files changed, 516 insertions(+), 11 deletions(-) create mode 100644 main/components/sg90_servo/imp_comp_sg90.c create mode 100644 main/components/sg90_servo/imp_comp_sg90.h create mode 100644 main/components/sg90_servo/iot_servo.c create mode 100644 main/components/sg90_servo/iot_servo.h create mode 100644 main/services/switch_control_service/switch_control_service.c create mode 100644 main/services/switch_control_service/switch_control_service.h diff --git a/main/APP/main_app/main_app.c b/main/APP/main_app/main_app.c index f0422de..0a1fd39 100644 --- a/main/APP/main_app/main_app.c +++ b/main/APP/main_app/main_app.c @@ -38,6 +38,7 @@ #include "ext_trans_service.h" #include "display_service.h" #include "audio_service.h" +#include "switch_control_service.h" #include #include "imp_out_port.h" @@ -107,12 +108,15 @@ uint8_t _main_task_wake_up_services() xTaskCreate(imp_ext_trans_service_task, imp_main_task_table[IMP_TASK_ID_EXT_TRANS_SERVICE_TASK], 2048, NULL, 10, NULL); - xTaskCreate(imp_display_service_task, - imp_main_task_table[IMP_TASK_ID_DISP_SERVICE_TASK], 8192, NULL, - 11, NULL); - xTaskCreate(imp_audio_service_task, - imp_main_task_table[IMP_TASK_ID_AUDIO_SERVICE_TASK], 2048, NULL, - 12, NULL); + // xTaskCreate(imp_display_service_task, + // imp_main_task_table[IMP_TASK_ID_DISP_SERVICE_TASK], 8192, NULL, + // 11, NULL); + // xTaskCreate(imp_audio_service_task, + // imp_main_task_table[IMP_TASK_ID_AUDIO_SERVICE_TASK], 2048, NULL, + // 12, NULL); + xTaskCreate(imp_switch_control_service_task, + imp_main_task_table[IMP_TASK_ID_SWITCH_CONTROL_TASK], 2048, + NULL, 12, NULL); return 0; } diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index b7e1e1e..8dfbe67 100755 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -11,12 +11,14 @@ idf_component_register( "components/msq_queue" "components/imp_out_port" "services/ext_trans_service" + "services/audio_service" + "services/display_service" + "services/switch_control_service" "utilities/u8g2/src" "utilities/u8g2/port" - "services/display_service" "components/screen_pages/test_page" "components/imp_esp_i2c_master_dev_op" - "services/audio_service" + "components/sg90_servo" "components/Codec/ES8388" EXCLUDE_SRCS @@ -33,16 +35,18 @@ idf_component_register( "utilities/imp_types/" "components/msq_queue" "components/imp_out_port" - "services/ext_trans_service" "utilities/imp_util_tlv_trans_protocol/" "utilities/u8g2/src" "utilities/u8g2/port" + "services/ext_trans_service" "services/display_service" + "services/switch_control_service" + "services/audio_service" "components/screen_pages/test_page" "components/imp_esp_i2c_master_dev_op" - "services/audio_service" "components/Codec/ES8388" "components/Codec" + "components/sg90_servo" LDFRAGMENTS "utilities/letter_shell/port/esp-idf/shell.lf" diff --git a/main/components/sg90_servo/imp_comp_sg90.c b/main/components/sg90_servo/imp_comp_sg90.c new file mode 100644 index 0000000..3c88eb5 --- /dev/null +++ b/main/components/sg90_servo/imp_comp_sg90.c @@ -0,0 +1,73 @@ +/** + * @file imp_comp_sg90.c + * @author Alvin Young (impressionyang@outlook.com) + * @brief + * @version 0.1 + * @date 2025-04-14 + * + * _ _ + * (_)_ _ ___ _______ ___ ___ (_)__ ___ __ _____ ____ ___ _ + * / / ' \/ _ \/ __/ -_|_-<(_- + * Date Version Author Description + * 2025-04-14 v1.0 Alvin Young 首次创建 + * + * + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +/* Includes ------------------------------------------------------------------*/ +#include "imp_comp_sg90.h" +/* define --------------------------------------------------------------------*/ +/* typedef -------------------------------------------------------------------*/ +/* variables -----------------------------------------------------------------*/ +/* Private function(only *.c) -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +uint8_t imp_comp_sg90_init(imp_comp_sg90_t* handle, uint8_t gpio, + uint8_t pwm_ch) +{ + handle->is_init = 1; + handle->servo_pin = gpio; + handle->servo_pwm_channel = pwm_ch; + handle->speed_mode = LEDC_LOW_SPEED_MODE; + handle->servo_config.channel_number = 1; + handle->servo_config.channels.servo_pin[0] = handle->servo_pin; + handle->servo_config.channels.ch[0] = + pwm_ch > LEDC_CHANNEL_MAX ? LEDC_CHANNEL_MAX : pwm_ch; + handle->servo_config.max_angle = 180; + handle->servo_config.min_width_us = 500; + handle->servo_config.max_width_us = 2500; + handle->servo_config.freq = 50; + handle->servo_config.timer_number = LEDC_TIMER_0; + + iot_servo_init(handle->speed_mode, &handle->servo_config); + + return 0; +} + +uint8_t imp_comp_sg90_set_angle(imp_comp_sg90_t* handle, float angle) +{ + iot_servo_write_angle(handle->speed_mode, handle->servo_pwm_channel, angle); + return 0; +} + +uint8_t imp_comp_sg90_get_angle(imp_comp_sg90_t* handle, float* angle) +{ + iot_servo_read_angle(handle->speed_mode, handle->servo_pwm_channel, angle); + return 0; +} + +uint8_t imp_comp_sg90_deinit(imp_comp_sg90_t* handle) +{ + iot_servo_deinit(handle->speed_mode); + return 0; +} + +/* + * EOF + */ \ No newline at end of file diff --git a/main/components/sg90_servo/imp_comp_sg90.h b/main/components/sg90_servo/imp_comp_sg90.h new file mode 100644 index 0000000..6b9dc82 --- /dev/null +++ b/main/components/sg90_servo/imp_comp_sg90.h @@ -0,0 +1,60 @@ +/** + * @file imp_comp_sg90.h + * @author Alvin Young (impressionyang@outlook.com) + * @brief + * @version 0.1 + * @date 2025-04-14 + * + * _ _ + * (_)_ _ ___ _______ ___ ___ (_)__ ___ __ _____ ____ ___ _ + * / / ' \/ _ \/ __/ -_|_-<(_- + * Date Version Author Description + * 2025-04-14 v1.0 Alvin Young 首次创建 + * + * + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __IMP_COMP_SG90_H__ +#define __IMP_COMP_SG90_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +#include "iot_servo.h" +/* define --------------------------------------------------------------------*/ +/* typedef -------------------------------------------------------------------*/ + +typedef struct __imp_comp_sg90_t__ +{ + uint8_t is_init; + uint8_t speed_mode; + uint8_t servo_pin; + uint8_t servo_pwm_channel; + servo_config_t servo_config; +} imp_comp_sg90_t; +/* variables -----------------------------------------------------------------*/ +/* Private function(only *.c) -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +uint8_t imp_comp_sg90_init(imp_comp_sg90_t* handle, uint8_t gpio, uint8_t pwm_ch); +uint8_t imp_comp_sg90_set_angle(imp_comp_sg90_t* handle, float angle); +uint8_t imp_comp_sg90_get_angle(imp_comp_sg90_t* handle, float* angle); +uint8_t imp_comp_sg90_deinit(imp_comp_sg90_t* handle); + +#ifdef __cplusplus +} +#endif +#endif //__IMP_COMP_SG90_H__ + +/* + * EOF + */ \ No newline at end of file diff --git a/main/components/sg90_servo/iot_servo.c b/main/components/sg90_servo/iot_servo.c new file mode 100644 index 0000000..26db7dd --- /dev/null +++ b/main/components/sg90_servo/iot_servo.c @@ -0,0 +1,130 @@ +// Copyright 2020 Espressif Systems (Shanghai) Co. Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "esp_log.h" +#include "esp_err.h" +#include "driver/ledc.h" +#include "iot_servo.h" + +static const char *TAG = "servo"; + +#define SERVO_CHECK(a, str, ret_val) \ + if (!(a)) { \ + ESP_LOGE(TAG,"%s(%d): %s", __FUNCTION__, __LINE__, str); \ + return (ret_val); \ + } + +#define SERVO_LEDC_INIT_BITS LEDC_TIMER_10_BIT +#define SERVO_FREQ_MIN 50 +#define SERVO_FREQ_MAX 400 + +static uint32_t g_full_duty = 0; +static servo_config_t g_cfg[LEDC_SPEED_MODE_MAX] = {0}; + +static uint32_t calculate_duty(ledc_mode_t speed_mode, float angle) +{ + float angle_us = angle / g_cfg[speed_mode].max_angle * (g_cfg[speed_mode].max_width_us - g_cfg[speed_mode].min_width_us) + g_cfg[speed_mode].min_width_us; + ESP_LOGD(TAG, "angle us: %f", angle_us); + uint32_t duty = (uint32_t)((float)g_full_duty * (angle_us) * g_cfg[speed_mode].freq / (1000000.0f)); + return duty; +} + +static float calculate_angle(ledc_mode_t speed_mode, uint32_t duty) +{ + float angle_us = (float)duty * 1000000.0f / (float)g_full_duty / (float)g_cfg[speed_mode].freq; + angle_us -= g_cfg[speed_mode].min_width_us; + angle_us = angle_us < 0.0f ? 0.0f : angle_us; + float angle = angle_us * g_cfg[speed_mode].max_angle / (g_cfg[speed_mode].max_width_us - g_cfg[speed_mode].min_width_us); + return angle; +} + +esp_err_t iot_servo_init(ledc_mode_t speed_mode, const servo_config_t *config) +{ + esp_err_t ret; + SERVO_CHECK(NULL != config, "Pointer of config is invalid", ESP_ERR_INVALID_ARG); + SERVO_CHECK(config->channel_number > 0 && config->channel_number <= LEDC_CHANNEL_MAX, "Servo channel number out the range", ESP_ERR_INVALID_ARG); + SERVO_CHECK(config->freq <= SERVO_FREQ_MAX && config->freq >= SERVO_FREQ_MIN, "Servo pwm frequency out the range", ESP_ERR_INVALID_ARG); + uint64_t pin_mask = 0; + uint32_t ch_mask = 0; + for (size_t i = 0; i < config->channel_number; i++) { + uint64_t _pin_mask = 1ULL << config->channels.servo_pin[i]; + uint32_t _ch_mask = 1UL << config->channels.ch[i]; + SERVO_CHECK(!(pin_mask & _pin_mask), "servo gpio has a duplicate", ESP_ERR_INVALID_ARG); + SERVO_CHECK(!(ch_mask & _ch_mask), "servo channel has a duplicate", ESP_ERR_INVALID_ARG); + SERVO_CHECK(GPIO_IS_VALID_OUTPUT_GPIO(config->channels.servo_pin[i]), "servo gpio invalid", ESP_ERR_INVALID_ARG); + pin_mask |= _pin_mask; + ch_mask |= _ch_mask; + } + + ledc_timer_config_t ledc_timer = { + .clk_cfg = LEDC_AUTO_CLK, + .duty_resolution = SERVO_LEDC_INIT_BITS, // resolution of PWM duty + .freq_hz = config->freq, // frequency of PWM signal + .speed_mode = speed_mode, // timer mode + .timer_num = config->timer_number // timer index + }; + ret = ledc_timer_config(&ledc_timer); + SERVO_CHECK(ESP_OK == ret, "ledc timer configuration failed", ESP_FAIL); + for (size_t i = 0; i < config->channel_number; i++) { + ledc_channel_config_t ledc_ch = { + .intr_type = LEDC_INTR_DISABLE, + .channel = config->channels.ch[i], + .duty = calculate_duty(speed_mode, 0), + .gpio_num = config->channels.servo_pin[i], + .speed_mode = speed_mode, + .timer_sel = config->timer_number, + .hpoint = 0 + }; + ret = ledc_channel_config(&ledc_ch); + SERVO_CHECK(ESP_OK == ret, "ledc channel configuration failed", ESP_FAIL); + } + g_full_duty = (1 << SERVO_LEDC_INIT_BITS) - 1; + g_cfg[speed_mode] = *config; + + return ESP_OK; +} + +esp_err_t iot_servo_deinit(ledc_mode_t speed_mode) +{ + SERVO_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "LEDC speed mode invalid", ESP_ERR_INVALID_ARG); + for (size_t i = 0; i < g_cfg[speed_mode].channel_number; i++) { + ledc_stop(speed_mode, g_cfg[speed_mode].channels.ch[i], 0); + } + ledc_timer_rst(speed_mode, g_cfg[speed_mode].timer_number); + g_full_duty = 0; + return ESP_OK; +} + +esp_err_t iot_servo_write_angle(ledc_mode_t speed_mode, uint8_t channel, float angle) +{ + SERVO_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "LEDC speed mode invalid", ESP_ERR_INVALID_ARG); + SERVO_CHECK(channel < LEDC_CHANNEL_MAX, "LEDC channel number too large", ESP_ERR_INVALID_ARG); + SERVO_CHECK(angle >= 0.0f, "Angle can't to be negative", ESP_ERR_INVALID_ARG); + esp_err_t ret; + uint32_t duty = calculate_duty(speed_mode, angle); + ret = ledc_set_duty(speed_mode, (ledc_channel_t)channel, duty); + ret |= ledc_update_duty(speed_mode, (ledc_channel_t)channel); + SERVO_CHECK(ESP_OK == ret, "write servo angle failed", ESP_FAIL); + return ESP_OK; +} + +esp_err_t iot_servo_read_angle(ledc_mode_t speed_mode, uint8_t channel, float *angle) +{ + SERVO_CHECK(speed_mode < LEDC_SPEED_MODE_MAX, "LEDC speed mode invalid", ESP_ERR_INVALID_ARG); + SERVO_CHECK(channel < LEDC_CHANNEL_MAX, "LEDC channel number too large", ESP_ERR_INVALID_ARG); + uint32_t duty = ledc_get_duty(speed_mode, channel); + float a = calculate_angle(speed_mode, duty); + *angle = a; + return ESP_OK; +} \ No newline at end of file diff --git a/main/components/sg90_servo/iot_servo.h b/main/components/sg90_servo/iot_servo.h new file mode 100644 index 0000000..0c02a5d --- /dev/null +++ b/main/components/sg90_servo/iot_servo.h @@ -0,0 +1,104 @@ +// Copyright 2020-2021 Espressif Systems (Shanghai) Co. Ltd. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef _IOT_SERVO_H_ +#define _IOT_SERVO_H_ + +#include "esp_err.h" +#include "driver/ledc.h" +#include "driver/gpio.h" + +/** + * @brief Configuration of servo motor channel + * + */ +typedef struct { + gpio_num_t servo_pin[LEDC_CHANNEL_MAX]; /**< Pin number of pwm output */ + ledc_channel_t ch[LEDC_CHANNEL_MAX]; /**< The ledc channel which used */ +} servo_channel_t; + +/** + * @brief Configuration of servo motor + * + */ +typedef struct { + uint16_t max_angle; /**< Servo max angle */ + uint16_t min_width_us; /**< Pulse width corresponding to minimum angle, which is usually 500us */ + uint16_t max_width_us; /**< Pulse width corresponding to maximum angle, which is usually 2500us */ + uint32_t freq; /**< PWM frequency */ + ledc_timer_t timer_number; /**< Timer number of ledc */ + servo_channel_t channels; /**< Channels to use */ + uint8_t channel_number; /**< Total channel number */ +} servo_config_t; + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * @brief Initialize ledc to control the servo + * + * @param speed_mode Select the LEDC channel group with specified speed mode. Note that not all targets support high speed mode. + * @param config Pointer of servo configure struct + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + * - ESP_FAIL Configure ledc failed + */ +esp_err_t iot_servo_init(ledc_mode_t speed_mode, const servo_config_t *config); + +/** + * @brief Deinitialize ledc for servo + * + * @param speed_mode Select the LEDC channel group with specified speed mode. + * + * @return + * - ESP_OK Success + */ +esp_err_t iot_servo_deinit(ledc_mode_t speed_mode); + +/** + * @brief Set the servo motor to a certain angle + * + * @note This API is not thread-safe + * + * @param speed_mode Select the LEDC channel group with specified speed mode. + * @param channel LEDC channel, select from ledc_channel_t + * @param angle The angle to go + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t iot_servo_write_angle(ledc_mode_t speed_mode, uint8_t channel, float angle); + +/** + * @brief Read current angle of one channel + * + * @param speed_mode Select the LEDC channel group with specified speed mode. + * @param channel LEDC channel, select from ledc_channel_t + * @param angle Current angle of the channel + * + * @return + * - ESP_OK Success + * - ESP_ERR_INVALID_ARG Parameter error + */ +esp_err_t iot_servo_read_angle(ledc_mode_t speed_mode, uint8_t channel, float *angle); + +#ifdef __cplusplus +} +#endif + +#endif /* _IOT_SERVO_H_ */ \ No newline at end of file diff --git a/main/main_common.c b/main/main_common.c index c2e6bf9..ce57868 100644 --- a/main/main_common.c +++ b/main/main_common.c @@ -37,7 +37,7 @@ /// @brief 所有Task的命名集合,名字长度不能超过configMAX_TASK_NAME_LEN = 16 char* imp_main_task_table[] = { - "idle", "main_task", "ext_trans_task", "display", "audio", + "idle", "main_task", "ext_trans_task", "display", "audio", "switch_key", }; /* Private function(only *.c) -----------------------------------------------*/ diff --git a/main/main_common.h b/main/main_common.h index 86f1936..067ef7c 100644 --- a/main/main_common.h +++ b/main/main_common.h @@ -37,6 +37,7 @@ extern "C" { #define IMP_TASK_ID_EXT_TRANS_SERVICE_TASK (2) #define IMP_TASK_ID_DISP_SERVICE_TASK (3) #define IMP_TASK_ID_AUDIO_SERVICE_TASK (4) +#define IMP_TASK_ID_SWITCH_CONTROL_TASK (5) /* typedef -------------------------------------------------------------------*/ /* variables -----------------------------------------------------------------*/ diff --git a/main/services/switch_control_service/switch_control_service.c b/main/services/switch_control_service/switch_control_service.c new file mode 100644 index 0000000..ef88f70 --- /dev/null +++ b/main/services/switch_control_service/switch_control_service.c @@ -0,0 +1,82 @@ +/** + * @file switch_control_service.c + * @author Alvin Young (impressionyang@outlook.com) + * @brief + * @version 0.1 + * @date 2025-04-14 + * + * _ _ + * (_)_ _ ___ _______ ___ ___ (_)__ ___ __ _____ ____ ___ _ + * / / ' \/ _ \/ __/ -_|_-<(_- + * Date Version Author Description + * 2025-04-14 v1.0 Alvin Young 首次创建 + * + * + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +/* Includes ------------------------------------------------------------------*/ +#include "switch_control_service.h" +#include "freertos/FreeRTOS.h" +#include "freertos/task.h" +#include "imp_msg_queue.h" +#include "imp_comp_sg90.h" +#include "main_common.h" +#include "esp_log.h" +/* define --------------------------------------------------------------------*/ +/* typedef -------------------------------------------------------------------*/ +/* variables -----------------------------------------------------------------*/ +static imp_msg_queue_t* msg_q_handle = NULL; +/* Private function(only *.c) -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +void imp_switch_control_service_task(void*) +{ + msg_q_handle = imp_msg_queue_create_handle(IMP_TASK_ID_SWITCH_CONTROL_TASK); + + imp_msg_item_t msg_item = { 0 }; + uint8_t msg_read_ret = 0; + uint8_t direction = 0; + int i = 0; + float angle_ls = 0; + + imp_comp_sg90_t sg90_01_hanle = { 0 }; + uint16_t max_degree = 45; + + imp_comp_sg90_init(&sg90_01_hanle, 12, 0); + + vTaskDelay( 5000 / portTICK_PERIOD_MS); + while (1) { + if (!direction) { + for (i = 0; i <= max_degree; i++) { + // _set_angle(LEDC_LOW_SPEED_MODE, i); + imp_comp_sg90_set_angle(&sg90_01_hanle, i); + vTaskDelay(10 / portTICK_PERIOD_MS); + imp_comp_sg90_get_angle(&sg90_01_hanle, &angle_ls); + ESP_LOGI("servo", "[%d|%.2f]", i, angle_ls); + } + vTaskDelay(2000 / portTICK_PERIOD_MS); + direction = !direction; + } else { + for (i = max_degree; i >= 0; i--) { + imp_comp_sg90_set_angle(&sg90_01_hanle, i); + vTaskDelay(10 / portTICK_PERIOD_MS); + imp_comp_sg90_get_angle(&sg90_01_hanle, &angle_ls); + ESP_LOGI("servo", "[%d|%.2f]", i, angle_ls); + } + vTaskDelay(2000 / portTICK_PERIOD_MS); + direction = !direction; + } + } + + imp_comp_sg90_deinit(&sg90_01_hanle); +} + +/* + * EOF + */ \ No newline at end of file diff --git a/main/services/switch_control_service/switch_control_service.h b/main/services/switch_control_service/switch_control_service.h new file mode 100644 index 0000000..22a84bd --- /dev/null +++ b/main/services/switch_control_service/switch_control_service.h @@ -0,0 +1,47 @@ +/** + * @file switch_control_service.h + * @author Alvin Young (impressionyang@outlook.com) + * @brief + * @version 0.1 + * @date 2025-04-14 + * + * _ _ + * (_)_ _ ___ _______ ___ ___ (_)__ ___ __ _____ ____ ___ _ + * / / ' \/ _ \/ __/ -_|_-<(_- + * Date Version Author Description + * 2025-04-14 v1.0 Alvin Young 首次创建 + * + * + */ +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __SWITCH_CONTROL_SERVICE_H__ +#define __SWITCH_CONTROL_SERVICE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Includes ------------------------------------------------------------------*/ +#include +/* define --------------------------------------------------------------------*/ +/* typedef -------------------------------------------------------------------*/ +/* variables -----------------------------------------------------------------*/ +/* Private function(only *.c) -----------------------------------------------*/ +/* Exported functions --------------------------------------------------------*/ + +void imp_switch_control_service_task(void *); + +#ifdef __cplusplus +} +#endif +#endif //__SWITCH_CONTROL_SERVICE_H__ + +/* + * EOF + */ \ No newline at end of file