first init

This commit is contained in:
2026-04-10 18:10:51 +08:00
commit 51e34c4679
15 changed files with 837 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
build/*

90
CMakeLists.txt Normal file
View File

@@ -0,0 +1,90 @@
cmake_minimum_required(VERSION 3.10)
project(has_project_host LANGUAGES C)
# 当前宿主工程通过 add_subdirectory(has_platform) 的方式接入平台子仓库,
# 以模拟真实项目拉取 has_platform 子仓库后的编译场景。
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
# 宿主工程选择如何集成 has_platform
# static: 链接静态库
# shared: 链接动态库
# embed : 直接把 has_platform 对象文件并入宿主目标
set(HAS_PLATFORM_LINK_MODE "static" CACHE STRING
"How the host project integrates has_platform: static, shared or embed")
set_property(CACHE HAS_PLATFORM_LINK_MODE PROPERTY STRINGS static shared embed)
if(NOT EXISTS "${CMAKE_CURRENT_LIST_DIR}/has_project/has_platform_config.h")
message(FATAL_ERROR
"Missing has_project/has_platform_config.h. "
"The host project must provide has_platform_config.h.")
endif()
# 宿主工程显式告诉 has_platform 去 has_project/ 里查找配置头,
# 这样可以模拟外部项目拉取子仓库后的真实接入方式。
set(HAS_PLATFORM_CONFIG_DIR "${CMAKE_CURRENT_LIST_DIR}/has_project" CACHE PATH
"Directory that provides has_platform_config.h for has_platform" FORCE)
# 根据宿主工程的接入方式控制 has_platform 子仓库输出何种目标。
if(HAS_PLATFORM_LINK_MODE STREQUAL "static")
set(HAS_PLATFORM_BUILD_STATIC ON CACHE BOOL "" FORCE)
set(HAS_PLATFORM_BUILD_SHARED OFF CACHE BOOL "" FORCE)
elseif(HAS_PLATFORM_LINK_MODE STREQUAL "shared")
set(HAS_PLATFORM_BUILD_STATIC OFF CACHE BOOL "" FORCE)
set(HAS_PLATFORM_BUILD_SHARED ON CACHE BOOL "" FORCE)
elseif(HAS_PLATFORM_LINK_MODE STREQUAL "embed")
set(HAS_PLATFORM_BUILD_STATIC OFF CACHE BOOL "" FORCE)
set(HAS_PLATFORM_BUILD_SHARED OFF CACHE BOOL "" FORCE)
else()
message(FATAL_ERROR
"Unsupported HAS_PLATFORM_LINK_MODE='${HAS_PLATFORM_LINK_MODE}'. "
"Expected one of: static, shared, embed")
endif()
add_subdirectory(has_platform)
# 宿主工程业务源码。保持 has_project 现有目录结构不变。
file(GLOB HOST_APP_SOURCES CONFIGURE_DEPENDS
"${CMAKE_CURRENT_LIST_DIR}/has_project/has_app/*.c"
"${CMAKE_CURRENT_LIST_DIR}/has_project/has_app/gui/*.c"
# "${CMAKE_CURRENT_LIST_DIR}/has_project/has_app/sensor/*.c"
"${CMAKE_CURRENT_LIST_DIR}/has_project/has_app/wifi/*.c"
"${CMAKE_CURRENT_LIST_DIR}/has_project/has_app/acm/*.c"
)
file(GLOB HOST_DRIVER_SOURCES CONFIGURE_DEPENDS
"${CMAKE_CURRENT_LIST_DIR}/has_project/has_driver/v851/*.c"
)
set(HOST_PROJECT_SOURCES
${HOST_APP_SOURCES}
${HOST_DRIVER_SOURCES}
)
if(HOST_PROJECT_SOURCES STREQUAL "")
message(FATAL_ERROR "No host project sources were found under has_project/")
endif()
add_executable(test ${HOST_PROJECT_SOURCES})
target_compile_features(test PRIVATE c_std_11)
# 宿主工程根据选择的模式链接或嵌入 has_platform。
if(HAS_PLATFORM_LINK_MODE STREQUAL "static")
target_link_libraries(test PRIVATE has_platform::static)
elseif(HAS_PLATFORM_LINK_MODE STREQUAL "shared")
target_link_libraries(test PRIVATE has_platform::shared)
elseif(HAS_PLATFORM_LINK_MODE STREQUAL "embed")
has_platform_embed_in_target(test)
endif()
# 将可执行文件输出到 build/ 根目录,便于脚本统一运行。
set_target_properties(test PROPERTIES
OUTPUT_NAME test
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
)
message(STATUS "HAS_PLATFORM_LINK_MODE = ${HAS_PLATFORM_LINK_MODE}")

51
build.sh Executable file
View File

@@ -0,0 +1,51 @@
#!/bin/bash
set -euo pipefail
ACTION="${1:-}"
LINK_MODE="${2:-static}"
BUILD_DIR="build"
usage() {
echo "用法:"
echo " ./build.sh all [static|shared|embed] 配置并编译整个工程"
echo " ./build.sh run 运行 build/test"
echo " ./build.sh clean 清理 build 目录"
}
check_link_mode() {
case "$1" in
static|shared|embed)
;;
*)
echo "错误: 无效的 has_platform 接入模式 '$1'"
usage
exit 1
;;
esac
}
case "${ACTION}" in
all)
check_link_mode "${LINK_MODE}"
mkdir -p "${BUILD_DIR}"
rm -rf "${BUILD_DIR:?}/"*
cmake -S . -B "${BUILD_DIR}" \
-DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DHAS_PLATFORM_LINK_MODE="${LINK_MODE}"
cmake --build "${BUILD_DIR}" -j"$(nproc)"
;;
run)
if [ ! -x "${BUILD_DIR}/test" ]; then
echo "错误: 未找到 ${BUILD_DIR}/test请先执行 ./build.sh all"
exit 1
fi
"${BUILD_DIR}/test"
;;
clean)
rm -rf "${BUILD_DIR}"
;;
*)
usage
exit 1
;;
esac

View File

@@ -0,0 +1,255 @@
/*
* has_os_806_port.c
*
* Author: zhangzhaopeng
* Version 1.0
* Created on : 2026-02-11
* 系统适配层,基于806自定义系统层接口
*/
#include <stdint.h>
#include <string.h>
#include "has_os_806_port.h"
// TODO: 信号量限制最大数量
#if defined(HAS_OS_USER_DEFINED)
#define port_printf printf
/* ------------------------------------------------ 内存分配 API ------------------------------------------------ */
void *has_malloc(unsigned int size)
{
if (size == 0) {
return NULL;
}
return test_slab_malloc(size);
}
void has_free(void *ptr)
{
if (ptr == NULL) {
return;
}
test_slab_free(ptr);
}
void *has_realloc(void *ptr, unsigned int old_size, unsigned int new_size)
{
void *new_ptr;
unsigned int copy_size;
if (new_size == 0) {
has_free(ptr);
return NULL;
}
if (ptr == NULL) {
return has_malloc(new_size);
}
new_ptr = has_malloc(new_size);
if (new_ptr == NULL) {
return NULL;
}
copy_size = (old_size < new_size) ? old_size : new_size;
if (copy_size > 0) {
memcpy(new_ptr, ptr, copy_size);
}
has_free(ptr);
return new_ptr;
}
/**
* @brief 互斥量初始化
*
* @param mutex:互斥量
* @return 0:成功 -1失败
*/
int has_mutex_init(has_mutex_t *mutex)
{
/* to be done */
/* example:xr806 */
if (OS_MutexCreate(mutex) != OS_OK) {
port_printf("create mutex err!!\n\n");
return -1;
}
return 0;
}
/**
* @brief 互斥量上锁
*
* @param mutex:互斥量
* @return 0:成功 -1失败
*/
int has_mutex_lock(has_mutex_t *mutex)
{
if (OS_MutexLock(mutex, OS_WAIT_FOREVER) != OS_OK) {
port_printf("lock mutex err!!\n\n");
return -1;
}
return 0;
}
/**
* @brief 互斥量解锁
*
* @param mutex:互斥量
* @return 0:成功 -1失败
*/
int has_mutex_unlock(has_mutex_t *mutex)
{
OS_MutexUnlock(mutex);
return 0;
}
/**
* @brief 互斥量销毁
*
* @param mutex:互斥量
* @return 0:成功 -1失败
*/
int has_mutex_deinit(has_mutex_t *mutex)
{
if (OS_MutexDelete(mutex) != OS_OK) {
port_printf("delete mutex err!!\n\n");
return -1;
}
return 0;
}
/**
* @brief 信号量初始化
*
* @param sem:信号量
* @return 0:成功 -1失败
*/
int has_sem_init(has_sem_t *sem)
{
/* to be done */
/* example:xr806 */
if (OS_SemaphoreCreate(sem, 0, UINT_MAX) != OS_OK) {
port_printf("create counting sem error!\n");
return -1;
}
return 0;
}
/**
* @brief 消息通知
*
* @param sem:信号量
* @return 0:成功 -1失败
*/
int has_sem_notify(has_sem_t *sem)
{
/* to be done */
/* example:xr806 */
if (OS_SemaphoreRelease(sem) != OS_OK) {
port_printf("notify thread err!\n");
return -1;
}
return 0;
}
/**
* @brief 等待消息
*
* @param sem:信号量
* @param ms_timeout:超时时间ms其中0消息直接返回-1一直阻塞
* @return MSG_WAIT_RET:
* WAIT_FAIL = -1, 等待失败
* WAIT_TIMEOUT = -1, 等待超时
* WAIT_MSG_COME = -1, 有新消息
*/
enum MSG_WAIT_RET has_sem_wait(has_sem_t *sem, int ms_timeout)
{
/* to be done */
/* example:xr806 */
OS_Time_t waitMS;
if (ms_timeout < 0) {
waitMS = OS_WAIT_FOREVER;
} else {
waitMS = (OS_Time_t)ms_timeout;
}
if (OS_SemaphoreWait(sem, waitMS) != OS_OK) {
// port_printf("sem take fail\n");
return WAIT_FAIL;
}
return WAIT_MSG_COME;
}
int has_sem_deinit(has_sem_t *sem)
{
if (OS_SemaphoreDelete(sem) != OS_OK) {
port_printf("delete sem err!!\n\n");
return -1;
}
return 0;
}
/* ------------------------------------------------ 线程创建API ------------------------------------------------ */
int has_task_create(const char *task_name, int priority, unsigned int stack_size,
has_taskentry pfnEntry, void *pEntryParm, OS_THREAD_ID *pthread_id)
{
(void)task_name;
(void)priority;
(void)stack_size;
(void)pfnEntry;
(void)pEntryParm;
if (pthread_id != NULL) {
*pthread_id = NULL;
}
port_printf("has_task_create is not implemented for HAS_OS_USER_DEFINED.\n");
return -1;
}
int has_task_delete(OS_THREAD_ID thread_id)
{
(void)thread_id;
port_printf("has_task_delete is not implemented for HAS_OS_USER_DEFINED.\n");
return -1;
}
uint64_t has_get_time_ms(void)
{
#if defined(OS_TicksToMSecs)
return (uint64_t)OS_TicksToMSecs(OS_GetTicks());
#else
uint64_t ticks = (uint64_t)OS_GetTicks();
#if defined(OS_HZ) && (OS_HZ > 0)
return (ticks * 1000ULL) / (uint64_t)OS_HZ;
#else
/* 兜底:若 SDK 未提供换算宏且未暴露 HZ按 tick=ms 处理 */
return ticks;
#endif
#endif
}
void has_sleep_ms(uint32_t ms)
{
/* TODO: 若 SDK 提供线程睡眠接口,可替换为 OS 级阻塞延时 */
// uint64_t start_ms;
// if (ms == 0U) {
// return;
// }
// start_ms = has_get_time_ms();
// while ((has_get_time_ms() - start_ms) < (uint64_t)ms) {
// }
}
int has_task_exit(OS_THREAD_ID task_id, uint32_t dw_cookie)
{
(void)task_id;
(void)dw_cookie;
port_printf("has_task_exit is not implemented for HAS_OS_USER_DEFINED.\n");
return -1;
}
#endif

View File

@@ -0,0 +1,76 @@
#ifndef HAS_OS_806_PROT_H
#define HAS_OS_806_PROT_H
#include "has_platform_config.h"
#if defined(HAS_OS_USER_DEFINED)
#define HAS_ENABLE_MUTEX_SEM // 支持互斥量和信号量
/* 下面示例是基于xr806移植 */
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <stdint.h>
#include "../has_wifi_slab.h"
#include "../kernel/os/os.h"
#define has_mutex_t OS_Mutex_t
#define has_sem_t OS_Semaphore_t
#define TASK_PRIORITY_SYS 0
#define TASK_PRIORITY_HIGH 1
#define TASK_PRIORITY_LOW 8
#define TASK_PRIORITY_NORMAL 4
#define TASK_PRIORITY_ABOVE_NORMAL 3
#define TASK_PRIORITY_BELOW_NORMAL 6
typedef void *OS_THREAD_ID;
typedef void *(*has_taskentry)(void *param);
#ifdef HAS_ENABLE_MUTEX_SEM
enum MSG_WAIT_RET{
WAIT_FAIL = -1, // 等待失败
WAIT_TIMEOUT, // 等待超时
WAIT_MSG_COME, // 需要处理消息
};
int has_mutex_init(has_mutex_t *mutex);
int has_mutex_lock(has_mutex_t *mutex);
int has_mutex_unlock(has_mutex_t *mutex);
int has_mutex_deinit(has_mutex_t *mutex);
int has_sem_init(has_sem_t *sem);
int has_sem_notify(has_sem_t *sem);
enum MSG_WAIT_RET has_sem_wait(has_sem_t *sem, int ms_timeout);
int has_sem_deinit(has_sem_t *sem);
#else
#define has_mutex_t
#define has_mutex_init(m)
#define has_mutex_lock(m)
#define has_mutex_unlock(m)
#define has_mutex_deinit(m)
#define has_sem_t
#define has_sem_init(s)
#define has_sem_notify(s)
#define has_sem_wait(s, t)
#define has_sem_deinit(s)
#endif
int has_task_create(const char *task_name, int priority, unsigned int stack_size,
has_taskentry pfnEntry, void *pEntryParm, OS_THREAD_ID *pthread_id);
int has_task_exit(OS_THREAD_ID task_id, uint32_t dw_cookie);
int has_task_delete(OS_THREAD_ID thread_id);
uint64_t has_get_time_ms(void);
void has_sleep_ms(uint32_t ms);
void *has_malloc(unsigned int size);
void *has_realloc(void *ptr, unsigned int old_size, unsigned int new_size);
void has_free(void *ptr);
#endif
#endif

View File

@@ -0,0 +1,123 @@
#include "has_platform.h"
static OS_THREAD_ID protocol_tid;
static OS_THREAD_ID send_test_tid;
static unsigned char *read_buffer;
#define REC_BUFFER_LEN_MAX 1024
#define PROCESS_MSG_PERIOD 3000
#define TEST_EVENT 0
#define TEST_EVENT1 1
#define TEST_EVENT2 2
static has_ptcl_handler *g_handler = NULL;
static void has_receive_from_mcu(const has_tlv_t *box)
{
printf("receive event:%d\n", box->event);
return 0;
}
static void has_receive_from_mcu_1(const has_tlv_t *box)
{
printf("receive event:%d\n", box->event);
return 0;
}
static void has_receive_from_mcu_2(const has_tlv_t *box)
{
printf("receive event:%d\n", box->event);
return 0;
}
int acm_hal_send(uint8_t *buff, uint32_t len)
{
return has_dev_write(UART, 0, buff, len);
}
void resend_callback(has_tlv_t *p_tlv, uint8_t resend_cnt)
{
printf("retry to send msg event:%d cnt:%d\n", p_tlv->event, resend_cnt);
}
void send_success_callback(has_tlv_t *p_tlv)
{
printf("event %x send successfully\n", p_tlv->event);
}
void send_fail_callback(has_tlv_t *p_tlv)
{
printf("event %x send fail\n", p_tlv->event);
}
void *protocol_task(void *param)
{
int actuall_len;
while (1)
{
/* reads */
actuall_len = has_dev_read(UART, 0, read_buffer, REC_BUFFER_LEN_MAX);
if (actuall_len > 0)
{
has_protocol_recv_process(g_handler, read_buffer, actuall_len);
}
has_sleep_ms(PROCESS_MSG_PERIOD);
}
return NULL;
}
static void msg_handle_cb(unsigned char module_id, const unsigned char *buf, unsigned int len)
{
if (has_protocol_send(g_handler, module_id, buf, 1, need_confirm) != 0) {
printf("send err module:%x\n", module_id);
}
}
void *send_test_task(void *param)
{
unsigned char data = 3;
while (1)
{
/* write */
has_msg_handle(ACM, msg_handle_cb, PROCESS_MSG_PERIOD);
/* 重发发送失败需要publish注册发送的硬件接口 */
// has_protocol_send(g_handler, TEST_EVENT2, &data, sizeof(data), need_confirm);
}
}
int example_protocol_init(void)
{
has_protocol_attr attr;
kbox_event uart_list[] =
{
{TEST_EVENT, has_receive_from_mcu},
{TEST_EVENT1, has_receive_from_mcu_1},
{TEST_EVENT2, has_receive_from_mcu_2},
};
attr.ev_list = uart_list;
attr.ev_list_sz = sizeof(uart_list) / sizeof(uart_list[0]);
attr.hal_send_cb = acm_hal_send;
attr.resend_cb = resend_callback;
attr.retry_max_cnt = 1;
attr.wait_period = 500;
attr.success_cb = send_success_callback;
attr.fail_cb = send_fail_callback;
g_handler = has_protocol_create(&attr);
if (g_handler == NULL)
{
printf("create ACM handler err!\n");
return NULL;
}
printf("module:ACM\n");
/* 创建线程 */
if (has_task_create("read_test", TASK_PRIORITY_NORMAL, 1024, protocol_task, NULL, &protocol_tid) != 0) {
printf("module:WIFI create task failed\n");
return -1;
}
if (has_task_create("send_test", TASK_PRIORITY_NORMAL, 1024, send_test_task, NULL, &send_test_tid) != 0) {
printf("module:WIFI create task failed\n");
return -1;
}
return 0;
}
HAS_DECLARE_MODULE(ACM, example_protocol_init)

View File

@@ -0,0 +1,27 @@
#include "has_platform.h"
static OS_THREAD_ID gui_tid;
void *gui_task(void *param)
{
uint8_t data[2];
data[0] = 0x5a;
data[1] = 0x5b;
while (1)
{
has_msg_publish(GUI, data, sizeof(data));
sleep(10);
}
return NULL;
}
int example_gui_init(void)
{
printf("module:GUI\n");
/* 创建线程 */
if (has_task_create("wifi", TASK_PRIORITY_NORMAL, 1024, gui_task, NULL, &gui_tid) != 0) {
printf("module:WIFI create task failed\n");
return -1;
}
return 0;
}
HAS_DECLARE_MODULE(GUI, example_gui_init)

View File

@@ -0,0 +1,45 @@
#include <stdio.h>
#include <unistd.h>
#include "has_platform.h"
int main()
{
int wakeup_source = -1;
if (has_init() != 0) {
printf("[main] has_init failed\n");
return -1;
}
/* 获取唤醒源 */
if (HAS_DRV_INIT(WAKE_UP_SRC) != 0) {
printf("[main] init WAKE_UP_SRC driver failed, fallback to default init\n");
} else if (has_dev_read(WAKE_UP_SRC, 0, &wakeup_source, sizeof(wakeup_source)) != 0) {
printf("[main] read wakeup_source failed, fallback to default init\n");
wakeup_source = -1;
}
/* 根据唤醒源初始化资源 */
switch (wakeup_source) {
case 0:
HAS_DRV_INIT(VIDEO);
HAS_DRV_INIT(UART);
HAS_APP_INIT(ACM);
HAS_APP_INIT(WIFI);
HAS_APP_INIT(GUI);
break;
default:
HAS_DRV_INIT(VIDEO);
HAS_DRV_INIT(UART);
HAS_APP_INIT(WIFI);
HAS_APP_INIT(GUI);
break;
}
while (1) {
sleep(1);
}
return 0;
}

View File

@@ -0,0 +1,43 @@
#include "has_platform.h"
void msg_handle_cb(unsigned char module_id, const unsigned char *buf, unsigned int len)
{
printf("wifi msg handle\n");
}
static OS_THREAD_ID wifi_tid;
void *wifi_task(void *param)
{
uint8_t buffer[10] = {1, 2, 8};
uint8_t data[2];
data[0] = 0x5c;
data[1] = 0x5d;
/* 操作硬件 */
if (has_dev_write(UART, 0, buffer, sizeof(buffer)) != 0) {
printf("wifi task: write uart failed\n");
}
while (1)
{
/* 发布消息 */
// has_msg_publish(WIFI, buffer, sizeof(buffer));
/* 处理接收的消息 */
has_msg_handle(WIFI, msg_handle_cb, 1000);
has_msg_publish(WIFI, data, sizeof(data));
}
return NULL;
}
int example_wifi_init(void)
{
printf("module:WIFI\n");
// has_msg_printf_subscribe(WIFI);
/* 创建线程 */
if (has_task_create("wifi", TASK_PRIORITY_NORMAL, 1024, wifi_task, NULL, &wifi_tid) != 0) {
printf("module:WIFI create task failed\n");
return -1;
}
return 0;
}
HAS_DECLARE_MODULE(WIFI, example_wifi_init)

View File

@@ -0,0 +1 @@
reserve

View File

@@ -0,0 +1 @@
reserve

View File

@@ -0,0 +1,38 @@
#include "has_platform.h"
#include <string.h>
int uart_open(int param)
{
}
int uart_close(int param)
{
printf("init uart %d\n", param);
return 0;
}
int uart_write(int param, void *buff, unsigned int len)
{
unsigned char *temp = buff;
return 0;
}
int uart_read(int param, void *buff, unsigned int len)
{
return 0;
}
int uart_ioctl(int param, void *buff, unsigned int len)
{
return 0;
}
static Device_stu_t uart_dev = {
.open = uart_open,
.close = uart_close,
.write = uart_write,
.read = uart_read,
.drv_ctl = uart_ioctl,
};
HAS_DECLARE_DRV(UART, &uart_dev)

View File

@@ -0,0 +1,16 @@
#include "has_platform.h"
int video_open(int param)
{
printf("init video %d\n", param);
return 0;
}
static Device_stu_t video_dev = {
.open = video_open,
.close = NULL,
.write = NULL,
.read = NULL,
.drv_ctl = NULL,
};
HAS_DECLARE_DRV(VIDEO, &video_dev)

View File

@@ -0,0 +1,31 @@
#include "has_platform.h"
#include <string.h>
int wakeup_src_open(int param)
{
(void)param;
return 0;
}
int wakeup_src_read(int param,void *buff,unsigned int len)
{
(void)param;
memset(buff, 0, len);
return 0;
}
int wakeup_src_write(int param,void *buff,unsigned int len)
{
(void)param;
memset(buff, 0, len);
return 0;
}
static Device_stu_t wake_up_src_dev = {
.open = wakeup_src_open,
.close = NULL,
.write = wakeup_src_write,
.read = wakeup_src_read,
.drv_ctl = NULL,
};
HAS_DECLARE_DRV(WAKE_UP_SRC, &wake_up_src_dev)

View File

@@ -0,0 +1,39 @@
#ifndef HAS_PLATFORM_CONFIG_H
#define HAS_PLATFORM_CONFIG_H
/* 1.定义模块数量 */
#define MODULE_LIST \
GUI, \
ACM, \
WIFI, \
VOICE, \
/* 2.定义硬件模块数量 */
#define DRIVER_LIST \
WAKE_UP_SRC, \
VIDEO, \
UART, \
/* 3.完成模块间的发布订阅表,格式:模块 订阅数量 订阅模块 */
#define SUBSCIBE_INFO \
{ \
{GUI, 3, {ACM, WIFI, VOICE}}, \
{WIFI, 1, {GUI}}, \
{ACM, 2, {WIFI, GUI}}, \
}
/* 如果打开代码初始化时会检查config是否写错开发时应该打开 */
#define CEHCK_CONFIG_H 1
#define HAS_OS_LINUX // Linux系统
// #define HAS_OS_freeRTOS // freeRTOS系统
// #define HAS_OS_RT_THREAD // rt-thread系统
// #define HAS_OS_NONE_OR_OSAL // 裸机或osal
// #define HAS_OS_USER_DEFINED // 自定义,806
#ifdef HAS_OS_USER_DEFINED
/* 这里包含自定义的头文件 */
#include "has_806_os_port/has_os_806_port.h"
#endif
#endif