diff --git a/BUILD.gn b/BUILD.gn index af6d0ce..82a6e08 100755 --- a/BUILD.gn +++ b/BUILD.gn @@ -11,13 +11,10 @@ # See the License for the specific language governing permissions and # limitations under the License. - if (ohos_kernel_type == "liteos_m") { import("//kernel/liteos_m/liteos.gni") module_name = get_path_info(rebase_path("."), "name") module_group(module_name) { - modules = [ - "bk7235", - ] + modules = [ "bk7235" ] } } diff --git a/OAT.xml b/OAT.xml index 769feaf..814ae89 100755 --- a/OAT.xml +++ b/OAT.xml @@ -25,10 +25,16 @@ + + + + + + - + @@ -40,6 +46,16 @@ + + + + + + + + + + diff --git a/bk7235/BUILD.gn b/bk7235/BUILD.gn index 4976378..74a9df1 100755 --- a/bk7235/BUILD.gn +++ b/bk7235/BUILD.gn @@ -14,10 +14,41 @@ if (ohos_kernel_type == "liteos_m") { import("//build/lite/config/component/lite_component.gni") import("//build/lite/config/subsystem/lite_subsystem.gni") + import("//kernel/liteos_m/config.gni") import("//kernel/liteos_m/liteos.gni") + module_name = get_path_info(rebase_path("."), "name") module_group(module_name) { modules = [ "liteos_m" ] -# deps = [ "src:bk_liteos_adapter" ] + deps = [ + ":copy_libs", + ":encrypt", + ] + } + + copy("copy_libs") { + sources = [ + "liteos_m/bk_sdk_armino/components/bk_libs/bk7235_openharmony/libs/libbt.a", + "liteos_m/bk_sdk_armino/components/bk_libs/bk7235_openharmony/libs/libwifi.a", + ] + outputs = [ "$root_build_dir/libs/{{source_file_part}}" ] + } + + copy("encrypt") { + sources = [ "${device_path}/encrypt" ] + outputs = [ "$root_build_dir/encrypt" ] + } + + build_ext_component("build_7235_sdk") { + exec_path = rebase_path("${root_out_dir}") + ENCRYPT_FLAG = "0 0 0 0" + command = "rm -rf ${exec_path}/build" + command += "&& mkdir -p ${exec_path}/build" + command += "&& ${exec_path}/encrypt ${exec_path}/${liteos_name}.bin ${ENCRYPT_FLAG}" + command += "&& mv ${exec_path}/${liteos_name}_crc.bin ${exec_path}/build/all_2M.1220.bin" + deps = [ + "${device_path}:bk_sdk", + "//kernel/liteos_m:build_kernel_image", + ] } } diff --git a/bk7235/hals/communication/bluetooth/services/BUILD.gn b/bk7235/hals/communication/bluetooth/services/BUILD.gn index 3aa36cf..003b720 100755 --- a/bk7235/hals/communication/bluetooth/services/BUILD.gn +++ b/bk7235/hals/communication/bluetooth/services/BUILD.gn @@ -1,36 +1,32 @@ -# Copyright (C) 2022 Beken Corporation -# 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. -import("//build/lite/ndk/ndk.gni") -import("${board_adapter_dir}/hals/sdk_dir.gni") - -static_library("btservice") { - sources = [ - "src/ohos_bt_hal.c", - "src/ble_test.c", - ] - include_dirs = [ - ] - include_dirs = [ - "${beken_sdk_dir}/components/bk_ble/ble_v5/include", - ] - include_dirs += bk_hal_include_dirs -} - -if (ohos_kernel_type == "liteos_m") { - ndk_lib("bluetooth_ndk") { - deps = [ ":btservice" ] - - head_files = - [ "//foundation/communication/bluetooth/interfaces/innerkits/native_c/include" ] - } -} +# Copyright (C) 2022 Beken Corporation +# 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. +import("//build/lite/ndk/ndk.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") + +static_library("btservice") { + sources = [ + "src/ble_test.c", + "src/ohos_bt_hal.c", + ] + include_dirs = [] + include_dirs = [ "${beken_sdk_dir}/components/bk_ble/ble_v5/include" ] + include_dirs += bk_hal_include_dirs +} + +if (ohos_kernel_type == "liteos_m") { + ndk_lib("bluetooth_ndk") { + deps = [ ":btservice" ] + + head_files = [ "//foundation/communication/bluetooth/interfaces/innerkits/native_c/include" ] + } +} diff --git a/bk7235/hals/communication/wifi_lite/wifiaware/BUILD.gn b/bk7235/hals/communication/wifi_lite/wifiaware/BUILD.gn index ff3f409..660c810 100755 --- a/bk7235/hals/communication/wifi_lite/wifiaware/BUILD.gn +++ b/bk7235/hals/communication/wifi_lite/wifiaware/BUILD.gn @@ -15,8 +15,6 @@ import("${board_adapter_dir}/hals/sdk_dir.gni") static_library("hal_wifiaware") { sources = [ "source/hal_wifiaware.c" ] - include_dirs = [ - "//foundation/communication/wifi_aware/interfaces/kits", - ] + include_dirs = [ "//foundation/communication/wifi_aware/interfaces/kits" ] include_dirs += bk_hal_include_dirs } diff --git a/bk7235/hals/communication/wifi_lite/wifiservice/BUILD.gn b/bk7235/hals/communication/wifi_lite/wifiservice/BUILD.gn index 035d158..0196b80 100755 --- a/bk7235/hals/communication/wifi_lite/wifiservice/BUILD.gn +++ b/bk7235/hals/communication/wifi_lite/wifiservice/BUILD.gn @@ -19,11 +19,8 @@ static_library("wifiservice") { "source/wifi_device_util.c", "source/wifi_hotspot.c", ] - defines = [ - "CFG_SUPPORT_LITEOS", - ] - include_dirs = [ - ] + defines = [ "CFG_SUPPORT_LITEOS" ] + include_dirs = [] include_dirs += bk_hal_include_dirs } diff --git a/bk7235/hals/iot_hardware/wifiiot_lite/BUILD.gn b/bk7235/hals/iot_hardware/wifiiot_lite/BUILD.gn index d20b27c..7791bb1 100755 --- a/bk7235/hals/iot_hardware/wifiiot_lite/BUILD.gn +++ b/bk7235/hals/iot_hardware/wifiiot_lite/BUILD.gn @@ -1,35 +1,32 @@ -# Copyright (C) 2022 Beken Corporation -# 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. -import("//build/lite/ndk/ndk.gni") -import("${board_adapter_dir}/hals/sdk_dir.gni") - -static_library("hal_iothardware") { - sources = [ - "hal_iot_flash.c", - "hal_iot_gpio.c", - "hal_iot_i2c.c", - "hal_iot_pwm.c", - "hal_iot_uart.c", - "hal_iot_watchdog.c", - "hal_lowpower.c", - "hal_reset.c", - -# "iot_test.c", - ] - defines = [ - "CFG_SUPPORT_LITEOS", - ] - include_dirs = [ - ] - include_dirs += bk_hal_include_dirs -} +# Copyright (C) 2022 Beken Corporation +# 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. +import("//build/lite/ndk/ndk.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") + +static_library("hal_iothardware") { + sources = [ + "hal_iot_flash.c", + "hal_iot_gpio.c", + "hal_iot_i2c.c", + "hal_iot_pwm.c", + "hal_iot_uart.c", + "hal_iot_watchdog.c", + "hal_lowpower.c", + "hal_reset.c", + + # "iot_test.c", + ] + defines = [ "CFG_SUPPORT_LITEOS" ] + include_dirs = [] + include_dirs += bk_hal_include_dirs +} diff --git a/bk7235/hals/sdk_dir.gni b/bk7235/hals/sdk_dir.gni index fd0a5a8..f2fcab3 100755 --- a/bk7235/hals/sdk_dir.gni +++ b/bk7235/hals/sdk_dir.gni @@ -1,19 +1,17 @@ declare_args() { bk_hal_include_dirs = [ - "//base/iothardware/peripheral/interfaces/inner_api", - "//foundation/communication/wifi_lite/interfaces/wifiservice", - "//foundation/communication/bluetooth/interfaces/inner_api/include/c_header", - "//foundation/systemabilitymgr/samgr_lite/interfaces/kits/samgr", - "//commonlibrary/utils_lite/include", - "//commonlibrary/utils_lite/hals/file", + "//base/iothardware/peripheral/interfaces/inner_api", + "//foundation/communication/wifi_lite/interfaces/wifiservice", + "//foundation/communication/bluetooth/interfaces/inner_api/include/c_header", + "//foundation/systemabilitymgr/samgr_lite/interfaces/kits/samgr", + "//commonlibrary/utils_lite/include", + "//commonlibrary/utils_lite/hals/file", - "${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/include", - "${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/include/modules", - "${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/include/driver", - "${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/include/arch/compiler", - "${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/include/extra", - "${beken_sdk_dir}/build/openharmony/${beken_chip_type}/armino_as_lib/${beken_chip_type}/config", - "${beken_sdk_dir}/middleware/arch/riscv/include", - "${beken_sdk_dir}/components/bk_rtos/liteos_m_mst", + "${beken_sdk_dir}", + "${beken_sdk_dir}/include", + "${beken_sdk_dir}/include/driver", + "${beken_sdk_dir}/include/extra", + "${beken_sdk_dir}/middleware/arch/riscv/include", + "${beken_sdk_dir}/components/bk_rtos/liteos_m_mst", ] } diff --git a/bk7235/hals/update/BUILD.gn b/bk7235/hals/update/BUILD.gn index cf5a9fe..386390c 100755 --- a/bk7235/hals/update/BUILD.gn +++ b/bk7235/hals/update/BUILD.gn @@ -17,8 +17,8 @@ import("${board_adapter_dir}/hals/sdk_dir.gni") static_library("hal_update_static") { sources = [ "hal_hota_board.c" ] include_dirs = [ - "//base/update/ota_lite/hals", - "//base/update/ota_lite/interfaces/kits", + "//base/update/sys_installer_lite/hals", + "//base/update/sys_installer_lite/interfaces/kits", ] include_dirs += bk_hal_include_dirs } diff --git a/bk7235/hals/utils/file/BUILD.gn b/bk7235/hals/utils/file/BUILD.gn index 54959a3..c290459 100755 --- a/bk7235/hals/utils/file/BUILD.gn +++ b/bk7235/hals/utils/file/BUILD.gn @@ -11,7 +11,6 @@ # See the License for the specific language governing permissions and # limitations under the License. - import("//build/lite/config/component/lite_component.gni") import("${board_adapter_dir}/hals/sdk_dir.gni") diff --git a/bk7235/liteos_m/BUILD.gn b/bk7235/liteos_m/BUILD.gn index 7c65cef..8a35cee 100755 --- a/bk7235/liteos_m/BUILD.gn +++ b/bk7235/liteos_m/BUILD.gn @@ -14,7 +14,5 @@ import("//kernel/liteos_m/liteos.gni") module_name = get_path_info(rebase_path("."), "name") module_group(module_name) { - modules = [ -# "components", - ] + modules = [ "bk_sdk_armino" ] } diff --git a/bk7235/liteos_m/bk_sdk_armino/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/BUILD.gn new file mode 100755 index 0000000..a7bafb2 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/BUILD.gn @@ -0,0 +1,67 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("${beken_sdk_dir}/sdkconfig.gni") + +if (ohos_kernel_type == "liteos_m") { + import("//kernel/liteos_m/liteos.gni") + module_name = get_path_info(rebase_path("."), "name") + config("board_config") { + ldflags = [ + "-std=c99", + "-mstrict-align", + "-Wl,--gc-sections", + "-ffunction-sections", + "-fdata-sections", + "-D__LITEOS__", + "-DCFG_SUPPORT_LITEOS", + "-DBEKEN_PLATFORM", + "-Wno-strict-prototypes", + "-Wno-parentheses", + ] + + include_dirs = [ + ".", + "include", + ] + } + + module_group(module_name) { + modules = [] + deps = [ + "components/base64", + "components/bk_adapter", + "components/bk_ate", + "components/bk_cli", + "components/bk_event", + "components/bk_init", + "components/bk_log", + "components/bk_netif", + "components/bk_os:bk_os", + "components/bk_ps:bk_ps", + "components/bk_startup", + "components/bk_system", + "components/easy_flash", + "components/media", + "components/saradc_intf", + "components/security", + "components/temp_detect", + "components/utf8:utf8", + "middleware/arch:arch", + "middleware/boards:boards", + "middleware/driver:driver", + "middleware/soc:soc", + "projects", + ] + } +} diff --git a/bk7235/liteos_m/bk_sdk_armino/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/CMakeLists.txt deleted file mode 120000 index 13f18b7..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -tools/build_tools/build_files/CMakeLists.txt \ No newline at end of file diff --git a/bk7235/liteos_m/bk_sdk_armino/Kconfig b/bk7235/liteos_m/bk_sdk_armino/Kconfig deleted file mode 120000 index 4f4ec16..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/Kconfig +++ /dev/null @@ -1 +0,0 @@ -tools/build_tools/build_files/Kconfig \ No newline at end of file diff --git a/bk7235/liteos_m/bk_sdk_armino/Makefile b/bk7235/liteos_m/bk_sdk_armino/Makefile deleted file mode 120000 index 5cbc7ec..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/Makefile +++ /dev/null @@ -1 +0,0 @@ -tools/build_tools/build_files/Makefile \ No newline at end of file diff --git a/bk7235/liteos_m/bk_sdk_armino/components/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/BUILD.gn new file mode 100755 index 0000000..ddd9857 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/BUILD.gn @@ -0,0 +1,22 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +module_name = get_path_info(rebase_path("."), "name") +module_group(module_name) { + modules = [ + #"bk_ps", + #"bk_os", + #"bk_utf8", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/at/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/components/at/CMakeLists.txt deleted file mode 100755 index 84a1aca..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/at/CMakeLists.txt +++ /dev/null @@ -1,21 +0,0 @@ -set(incs) -set(srcs) - -if (CONFIG_AT_CMD) - list(APPEND incs - include - ) - list(APPEND srcs - "src/at_common.c" - "src/ble_at_command.c" - "src/video_at_command.c" - "src/wifi_at_command.c" - ) - if (CONFIG_BT) - list(APPEND srcs - "src/bt_at_command.c") - endif() -endif() - -armino_component_register(SRCS "${srcs}" INCLUDE_DIRS "${incs}" REQUIRES bk_ble bk_bt bk_common bk_log PRIV_REQUIRES bk_ble) -#ali_mqtt video diff --git a/bk7235/liteos_m/bk_sdk_armino/components/at/Kconfig b/bk7235/liteos_m/bk_sdk_armino/components/at/Kconfig deleted file mode 100755 index ad9ffed..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/at/Kconfig +++ /dev/null @@ -1,3 +0,0 @@ -config AT_CMD - bool "Enable AT_CMD" - default n diff --git a/bk7235/liteos_m/bk_sdk_armino/components/at/include/at_ble_common.h b/bk7235/liteos_m/bk_sdk_armino/components/at/include/at_ble_common.h deleted file mode 100755 index 0adf401..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/at/include/at_ble_common.h +++ /dev/null @@ -1,123 +0,0 @@ -/* -// Copyright (C) 2022 Beken Corporation - * 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 AT_BLE_COMMON_H_ -#define AT_BLE_COMMON_H_ -//#if (CONFIG_BLE_5_X || CONFIG_BTDM_5_2) -#include "at_common.h" - - -/// reference common_bt_defines.h -#define ADV_INTERVAL_MIN 0x0020 //(20 ms) -#define ADV_INTERVAL_MAX 0x4000 //(10.24 sec) -#define CON_INTERVAL_MIN 0x0006 //(7.5 msec) -#define CON_INTERVAL_MAX 0x0C80 //(4 sec) -/// Supervision TO (N*10ms) (chapter 2.E.7.8.12) -#define CON_SUP_TO_MIN 0x000A //(100 msec) -#define CON_SUP_TO_MAX 0x0C80 //(32 sec) -/// Scanning interval (in 625us slot) (chapter 2.E.7.8.10) -#define SCAN_INTERVAL_MIN 0x0004 //(2.5 ms) -#define SCAN_INTERVAL_MAX 0x4000 //(10.24 sec) -#define SCAN_INTERVAL_DFT 0x0010 //(10 ms) -/// Scanning window (in 625us slot) (chapter 2.E.7.8.10) -#define SCAN_WINDOW_MIN 0x0004 //(2.5 ms) -#define SCAN_WINDOW_MAX 0x4000 //(10.24 sec) -#define SCAN_WINDOW_DFT 0x0010 //(10 ms) -/// Connection latency (N*cnx evt) (chapter 2.E.7.8.12) -#define CON_LATENCY_MIN 0x0000 -#define CON_LATENCY_MAX 0x01F3 // (499) - - -#define UNKNOW_ACT_IDX 0xFFU - -#define AT_BLE_MAX_ACTV bk_ble_get_max_actv_idx_count() -#define AT_BLE_MAX_CONN bk_ble_get_max_conn_idx_count() - -// sync actv state machine, reference actv_state_t -typedef enum { - AT_ACTV_IDLE, - /////adv - AT_ACTV_ADV_CREATED, - AT_ACTV_ADV_STARTED, - ////////scan - AT_ACTV_SCAN_CREATED, - AT_ACTV_SCAN_STARTED, - - AT_ACTV_INIT_CREATED, - AT_ACTV_PER_SYNC_CREATED, - AT_ACTV_PER_SYNC_STARTED, -} at_actv_state; - -/// Initing state machine, reference app_init_state -enum at_init_state -{ - /// Iint activity does not exists - AT_INIT_STATE_IDLE = 0, - /// Creating Iint activity - AT_INIT_STATE_CREATING, - /// Iint activity created - AT_INIT_STATE_CREATED, - - /// WAIT Start Iint activity - AT_INIT_STATE_WAIT_CONNECTTING = 3, - /// Starting Iint activity - AT_INIT_STATE_CONNECTTING = 4, - /// Iint activity conected - AT_INIT_STATE_CONNECTTED = 5, - /// Stopping Iint activity - AT_INIT_STATE_STOPPING = 6, -}; - -/// Own BD address source of the device -enum gapm_own_addr -{ - /// Public or Private Static Address according to device address configuration - BLE_STATIC_ADDR, - /// Generated resolvable private random address - BLE_GEN_RSLV_ADDR, - /// Generated non-resolvable private random address - BLE_GEN_NON_RSLV_ADDR, -}; - -enum le_phy_mask -{ - /// The Host prefers to use the LE 1M transmitter/receiver PHY (possibly among others) - PHY_1MBPS_BIT = (1<<0), - PHY_1MBPS_POS = (0), - /// The Host prefers to use the LE 2M transmitter/receiver PHY (possibly among others) - PHY_2MBPS_BIT = (1<<1), - PHY_2MBPS_POS = (1), - /// The Host prefers to use the LE Coded transmitter/receiver PHY (possibly among others) - PHY_CODED_BIT = (1<<2), - PHY_CODED_POS = (2), - /// The Host prefers to use the LE Coded transmitter/receiver PHY (possibly among others) - PHY_ALL = (PHY_1MBPS_BIT | PHY_2MBPS_BIT | PHY_CODED_BIT), -}; - -enum le_coded_phy_option { - /// The host no preferred - CODED_NO_PREFEER = 0, - CODED_S2_PREFEER, - CODED_S8_PREFEER, -}; - -enum -{ - PRF_TASK_ID_BOARDING = 10, - PRF_TASK_ID_MAX, -}; - -#endif - -//#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/at/include/at_common.h b/bk7235/liteos_m/bk_sdk_armino/components/at/include/at_common.h deleted file mode 100755 index 240ed50..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/at/include/at_common.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -// Copyright (C) 2022 Beken Corporation - * 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 AT_COMMON_H_ -#define AT_COMMON_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -//#if (CONFIG_BLE_5_X || CONFIG_BTDM_5_2) -#include "modules/ble.h" -#include "modules/bt.h" -#include "ble_api_5_x.h" - -//#endif -#include - -#define MAX_BT_AT_CMD_LEN 20 -#define MAX_BLE_AT_CMD_LEN 64 -#define MAX_WIFI_AT_CMD_LEN 30 -#define MAX_VIDEO_AT_CMD_LEN 10 -#define AT_SYNC_CMD_TIMEOUT_MS 4000 - - -#define AT_CMDRSP_HEAD "CMDRSP:" -#define AT_READY_MSG "\r\nready\r\n" -#define AT_CMD_RSP_SUCCEED "CMDRSP:OK\r\n" -#define AT_CMD_RSP_ERROR "CMDRSP:ERROR\r\n" -#define AT_CMDMSG_ERROR_RSP "CMDRSP:ERROR\r\n" -#define AT_RET_CHAR '\r' -#define AT_END_CHAR '\n' - -#define AT_EVENT_HEAD "EVT:" -#define AT_EVT_WLAN_DISCONNECTED "EVT:WLAN DISCONNECTED\r\n" -#define AT_EVT_WLAN_CONNECTED "EVT:WLAN CONNECTED\r\n" -#define AT_EVT_GOT_IP "EVT:GOT-IP\r\n" - -typedef struct -{ - /** The command index*/ - const uint8_t idx; - /** The name of the at command */ - const char *name; - /** is the unsync command**/ - bool is_sync_cmd; - /** The help text associated with the command */ - const char *help; - /** The function that should be invoked for this command. */ - int (*function) (char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -}at_command_t; - -//#if (CONFIG_BLE_5_X || CONFIG_BTDM_5_2) -const at_command_t *lookup_bt_at_command(char *str1); -const at_command_t *lookup_ble_at_command(char *str1); -const at_command_t *lookup_bt_at_command(char *str1); -void at_set_data_handle(uint8_t *out, char *buff, uint8_t len); -int get_addr_from_param(bd_addr_t *bdaddr, char *input_param); -int ble_at_cmd_cnt(void); -int bt_at_cmd_cnt(void); - -extern const at_command_t ble_at_cmd_table[MAX_BLE_AT_CMD_LEN]; -extern const at_command_t bt_at_cmd_table[MAX_BT_AT_CMD_LEN]; - -//#endif -#if CONFIG_LWIP -const at_command_t *lookup_wifi_at_command(char *str1); -int wifi_at_cmd_cnt(void); -extern const at_command_t wifi_at_cmd_table[MAX_WIFI_AT_CMD_LEN]; -#endif -const at_command_t *lookup_video_at_command(char *str1); -int video_at_cmd_cnt(void); -extern const at_command_t video_at_cmd_table[MAX_VIDEO_AT_CMD_LEN]; - -#endif - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/at/src/at_common.c b/bk7235/liteos_m/bk_sdk_armino/components/at/src/at_common.c deleted file mode 100755 index 0da25a4..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/at/src/at_common.c +++ /dev/null @@ -1,178 +0,0 @@ -/* -// Copyright (C) 2022 Beken Corporation - * 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 "at_common.h" -#if CONFIG_BT -#include "bt_include.h" -#endif -//#if (CONFIG_BLE_5_X || CONFIG_BTDM_5_2) -const at_command_t *lookup_ble_at_command(char *str1) -{ - uint8_t type = bk_ble_get_controller_stack_type(); - - if(type != BK_BLE_CONTROLLER_STACK_TYPE_BLE_5_X && - type != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - os_printf("%s stack type %d not support\n", __func__, type); - return NULL; - } - - for (int i = 0; i < ble_at_cmd_cnt(); i++) - { - if (ble_at_cmd_table[i].name == NULL) { - i++; - continue; - } - - if(!os_strcmp(ble_at_cmd_table[i].name, str1)) - { - return &ble_at_cmd_table[i]; - } - } - return NULL; -} - -#if CONFIG_BT -const at_command_t *lookup_bt_at_command(char *str1) -{ - uint8_t type = bk_bt_get_controller_stack_type(); - if(type != BK_BT_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - os_printf("%s stack type %d not support\n", __func__, type); - return NULL; - } - for (int i = 0; i < bt_at_cmd_cnt(); i++) - { - if (bt_at_cmd_table[i].name == NULL) { - i++; - continue; - } - - if(!os_strcmp(bt_at_cmd_table[i].name, str1)) - { - return &bt_at_cmd_table[i]; - } - } - return NULL; -} -#endif - -#if CONFIG_LWIP -const at_command_t *lookup_wifi_at_command(char *str1) -{ - - for (int i = 0; i < wifi_at_cmd_cnt(); i++) - { - if (wifi_at_cmd_table[i].name == NULL) { - i++; - continue; - } - - if(!os_strcmp(wifi_at_cmd_table[i].name, str1)) - { - return &wifi_at_cmd_table[i]; - } - } - return NULL; -} -#endif - -void at_set_data_handle(uint8_t *out, char *buff, uint8_t len) -{ - char temp[3]; - - int i = 0, j = 0; - for (i = 0; i < len;) - { - os_memcpy(temp, buff + i, 2); - temp[2] = '\0'; - i = i + 2; - out[j++] = os_strtoul(temp, NULL, 16) & 0xFF; - } -} - -int get_addr_from_param(bd_addr_t *bdaddr, char *input_param) -{ - int err = kNoErr; - uint8_t addr_len = os_strlen(input_param); - char temp[3]; - uint8_t j = 1; - uint8_t k = 0; - - if ( addr_len != (BK_BLE_GAP_BD_ADDR_LEN * 2 + 5)) - { - err = kParamErr; - return err; - } - - for (uint8_t i = 0; i < addr_len; i++) - { - if (input_param[i] >= '0' && input_param[i] <= '9') - { - temp[k] = input_param[i]; - k += 1; - } - else if (input_param[i] >= 'a' && input_param[i] <= 'f') - { - temp[k] = input_param[i]; - k += 1; - } - else if (input_param[i] >= 'A' && input_param[i] <= 'F') - { - temp[k] = input_param[i]; - k += 1; - } - else if (input_param[i] == ':') - { - temp[k] = '\0'; - bdaddr->addr[BK_BLE_GAP_BD_ADDR_LEN - j] = os_strtoul(temp, NULL, 16) & 0xFF; - k = 0; - j++; - } - else - { - err = kParamErr; - return err; - } - - if (i == (addr_len - 1)) - { - temp[k] = '\0'; - bdaddr->addr[BK_BLE_GAP_BD_ADDR_LEN - j] = os_strtoul(temp, NULL, 16) & 0xFF; - k = 0; - } - } - - return kNoErr; -} - -//#endif - -const at_command_t *lookup_video_at_command(char *str1) -{ - for (int i = 0; i < video_at_cmd_cnt(); i++) - { - if (video_at_cmd_table[i].name == NULL) { - i++; - continue; - } - - if(!os_strcmp(video_at_cmd_table[i].name, str1)) - { - return &video_at_cmd_table[i]; - } - } - return NULL; -} - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/at/src/ble_at_command.c b/bk7235/liteos_m/bk_sdk_armino/components/at/src/ble_at_command.c deleted file mode 100755 index 474f897..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/at/src/ble_at_command.c +++ /dev/null @@ -1,5922 +0,0 @@ -/* -// Copyright (C) 2022 Beken Corporation - * 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 -#include -#include "at_common.h" -#include "modules/wifi.h" -#include - -#if CONFIG_BLE//(CONFIG_BLE_5_X || CONFIG_BTDM_5_2) -#include "at_ble_common.h" -#include "legacy_include/bluetooth_legacy_include.h" - -#ifdef CONFIG_ALI_MQTT -#include "iot_import.h" -#include "iot_export.h" -#include "iot_export_mqtt.h" -#endif - - -enum { - TEST_IDX_SVC, - TEST_IDX_CHAR_DECL, - TEST_IDX_CHAR_VALUE, - TEST_IDX_CHAR_DESC, - - TEST_IDX_CHAR_DATALEN_DECL, - TEST_IDX_CHAR_DATALEN_VALUE, - - TEST_IDX_CHAR_INTER_DECL, - TEST_IDX_CHAR_INTER_VALUE, - - TEST_IDX_NB, -}; - - -static beken_semaphore_t ble_at_cmd_sema = NULL; -ble_err_t at_cmd_status = BK_ERR_BLE_SUCCESS; -uint8 g_test_prf_task_id = 0; -uint8 g_test_noti_att_id = 0; - -//#if CONFIG_BTDM_5_2 -static beken_timer_t ble_noti_tmr; -static beken_timer_t ble_performance_tx_statistics_tmr; -static beken_timer_t ble_performance_rx_statistics_tmr; -static uint32 s_test_noti_count = 0; -//#endif -static uint16_t s_test_data_len = 20; -static uint32_t s_test_send_inter = 500; - -uint8_t s_test_conn_ind = ~0; - - -static uint8_t s_service_type = 0; - -static uint32_t s_performance_tx_bytes = 0; -static uint32_t s_performance_rx_bytes = 0; -static uint8_t s_performance_tx_enable = 0; - - -//for ethermind -static beken_timer_t s_ethermind_ble_send_test_timer; -static uint16_t s_ethermind_send_test_service_handle = 0;; -static uint16_t s_ethermind_send_char_test_handle = 0; -static uint16_t s_ethermind_send_size_handle = 0; -static uint16_t s_ethermind_send_intv_handle = 0; - - -static uint8_t s_ethermind_send_test_value = 0xa; -static uint16_t s_ethermind_send_size_value = 20; -static uint16_t s_ethermind_send_intv_value = 1000; - -static uint8_t s_ethermind_att_handle; //ATT_CON_ID - - -static uint8_t s_ethermind_service_type = 0; - -static uint32_t s_ethermind_performance_tx_bytes = 0; -static uint32_t s_ethermind_performance_rx_bytes = 0; -static uint8_t s_ethermind_auto_tx_enable = 0; - -static beken_timer_t ble_ethermind_performance_tx_statistics_tmr; -static beken_timer_t ble_ethermind_performance_rx_statistics_tmr; - - -static ATT_ATTR_HANDLE s_ethermind_nordic_write_attr_handle[8]; -static ATT_ATTR_HANDLE s_ethermind_nordic_write_notify_handle[8]; -//static ATT_HANDLE s_ethermind_nordic_att_info[8]; -static uint8_t s_ethermind_nordic_att_info[8]; -static uint8_t s_ethermind_nordic_used[8] = {0}; - -const uint8_t nus_tx_uuid[] = {0x9e,0xca,0xdc,0x24,0x0e,0xe5,0xa9,0xe0,0x93,0xf3,0xa3,0xb5,0x03,0x00,0x40,0x6e}; -const uint8_t nus_rx_uuid[] = {0x9e,0xca,0xdc,0x24,0x0e,0xe5,0xa9,0xe0,0x93,0xf3,0xa3,0xb5,0x02,0x00,0x40,0x6e}; - -static uint16_t plc_ccc_handle[10] = {0}; -static uint16_t plc_rx_handle[10] = {0}; - -static uint8_t send_value[32] = {0}; -//static ATT_HANDLE att_handle; -static ATT_ATTR_HANDLE s_read_tmp_attr_handle = 0; - - -int set_ble_name_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int get_ble_name_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_set_adv_param_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_set_adv_data_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_set_per_adv_data_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_set_scan_rsp_data_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_set_adv_enable_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_set_scan_param_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_set_scan_enable_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_create_connect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_cancel_create_connect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_disconnect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_update_conn_param_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_get_conn_state_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_get_local_addr_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_set_local_addr_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - - - - -static int ble_register_service_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_register_noti_service_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_register_performance_service_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_enable_performance_statistic_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_tx_test_enable_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_tx_test_param_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_update_mtu_2_max_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -void ble_test_service_write_handle(uint8 val, uint8 con_idx); -int ble_read_phy_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_set_phy_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_set_max_mtu_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -//#endif -int ble_delete_adv_activity_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_delete_scan_activity_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -extern int ble_boarding_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -void ble_test_noti_hdl(void *param); -static void ble_performance_tx_timer_hdl(void *param); -static void ble_performance_rx_timer_hdl(void *param); -int ble_connect_by_name_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_disconnect_by_name_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int ble_create_periodic_sync_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_start_periodic_sync_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_stop_periodic_sync_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int ble_att_write_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -static void ble_tx_test_active_timer_callback(void *param); -static void ble_ethermind_performance_tx_timer_hdl(void *param); -static void ble_ethermind_performance_rx_timer_hdl(void *param); -int ble_enable_packet_loss_ratio_test_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -#ifdef CONFIG_ALI_MQTT -int ble_mqtt_loop_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -#endif -int ble_power_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -static int ble_att_read_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -#ifdef CONFIG_ALI_MQTT -static void ble_send_data_2_mqtt(uint8 con_idx, uint16_t len, uint8 *data); -uint8_t loop_type = 0; - -enum { - LT_NONE, - LT_WIFI_ONLY, - LT_COEX, -}; -#endif - -const at_command_t ble_at_cmd_table[] = { -#ifdef CONFIG_BT - {0, "SETBLENAME", 1, "return ble name", set_ble_name_handle}, - {1, "GETBLENAME", 1, "return ble name", get_ble_name_handle}, -#else - {0, "SETBLENAME", 0, "return ble name", set_ble_name_handle}, - {1, "GETBLENAME", 0, "return ble name", get_ble_name_handle}, -#endif - {2, "SETADVPARAM", 1, "help", ble_set_adv_param_handle}, - {3, "SETADVDATA", 1, "set adv data", ble_set_adv_data_handle}, - {4, "SETPERADVDATA", 1, "set perodic adv data", ble_set_per_adv_data_handle}, - {5, "SETSCANRSPDATA", 1, "set scan response data", ble_set_scan_rsp_data_handle}, - {6, "SETADVENABLE", 1, "set adv enable(1)/disable(0)", ble_set_adv_enable_handle}, - {7, "SETSCANPARAM", 1, "set scan param", ble_set_scan_param_handle}, - {8, "SETSCANENABLE", 1, "set scan enable(1)/disable(0)", ble_set_scan_enable_handle}, - - {9, "CREATECONNECT", 1, "create connection", ble_create_connect_handle}, - {10, "CANCELCONNECT", 1, "cancel create connection", ble_cancel_create_connect_handle}, - {11, "DISCONNECT", 1, "disconnect current connection", ble_disconnect_handle}, - {12, "UPDATECONNPARAM", 1, "update connection param", ble_update_conn_param_handle}, - - {13, "GETCONNECTSTATE", 0, "get connection state", ble_get_conn_state_handle}, -#ifdef CONFIG_BT - {14, "GETLOCALADDR", 1, "get ble local address", ble_get_local_addr_handle}, -#else - {14, "GETLOCALADDR", 0, "get ble local address", ble_get_local_addr_handle}, -#endif - {15, "SETLOCALADDR", 0, "set ble local address", ble_set_local_addr_handle}, - - {16, "REGISTERSERVICE", 1, "register a service", ble_register_noti_service_handle}, - {17, "READPHY", 1, "read current tx/rx phy", ble_read_phy_handle}, - {18, "SETPHY", 1, "set current tx/rx phy", ble_set_phy_handle}, - - {19, "DELETEADV", 1, "delete adv activity", ble_delete_adv_activity_handle}, - {20, "DELETESCAN", 1, "delete scan activity", ble_delete_scan_activity_handle}, - - {21, "REGPERFORMANCESERVICE", 1, "register performance service: [data_len uuid] [interv uuid]", - ble_register_performance_service_handle}, - {22, "SETTXTESTPARAM", 0, "set tx test param: ", ble_tx_test_param_handle}, - {23, "SETTXTESTENABLE", 0, "enable tx test: <1|0>", ble_tx_test_enable_handle}, - {24, "UPDATEMTU2MAX", 1, "update mtu 2 max: ", ble_update_mtu_2_max_handle}, - //{25, "BOARDING", 0, "boarding", ble_boarding_handle}, - {26, "ENABLEPERFORMANCESTATISTIC", 1, "enable performance statistic, <1|0>", - ble_enable_performance_statistic_handle}, - {27, "SETMAXMTU", 0, "set att maximal mtu", ble_set_max_mtu_handle}, - {28, "CONNECTBYNAME", 1, "create connection by name", ble_connect_by_name_handle}, - {29, "DISCONNECTBYNAME", 1, "disconnect current connection by name", ble_disconnect_by_name_handle}, - - {30, "CREATEPERIODICSYNC", 1, "create periodic sync", ble_create_periodic_sync_handle}, - {31, "STARTPERIODICSYNC", 1, "set periodic sync start", ble_start_periodic_sync_handle}, - {32, "STOPPERIODICSYNC", 1, "set periodic sync stop", ble_stop_periodic_sync_handle}, - {33, "ATTWRITE", 1, "att write ", ble_att_write_handle}, - {34, "ENABLEPLRTEST", 0, "enable packet loss ratio test", ble_enable_packet_loss_ratio_test_handle}, -#ifdef CONFIG_ALI_MQTT - {35, "MQTTLOOPBACK", 0, "enable mqtt loopback test", ble_mqtt_loop_handle}, -#endif - {36, "POWER", 0, "power on/off", ble_power_handle}, - {37, "ATTREAD", 1, "att read ", ble_att_read_handle}, -//#endif -}; - -int ble_at_cmd_cnt(void) -{ - return sizeof(ble_at_cmd_table) / sizeof(ble_at_cmd_table[0]); -} - -void ble_at_cmd_cb(ble_cmd_t cmd, ble_cmd_param_t *param) -{ - at_cmd_status = param->status; - switch (cmd) - { - case BLE_CREATE_ADV: - case BLE_SET_ADV_DATA: - case BLE_SET_RSP_DATA: - case BLE_START_ADV: - case BLE_STOP_ADV: - case BLE_CREATE_SCAN: - case BLE_START_SCAN: - case BLE_STOP_SCAN: - case BLE_INIT_CREATE: - case BLE_INIT_START_CONN: - case BLE_INIT_STOP_CONN: - case BLE_CONN_DIS_CONN: - case BLE_CONN_UPDATE_PARAM: - case BLE_DELETE_ADV: - case BLE_DELETE_SCAN: - case BLE_CONN_READ_PHY: - case BLE_CONN_SET_PHY: - case BLE_CONN_UPDATE_MTU: - case BLE_CREATE_PERIODIC: - case BLE_START_PERIODIC: - case BLE_STOP_PERIODIC: - case BLE_DELETE_PERIODIC: - case BLE_SET_LOCAL_NAME: - case BLE_GET_LOCAL_NAME: - case BLE_READ_LOCAL_ADDR: - if (ble_at_cmd_sema != NULL) - rtos_set_semaphore( &ble_at_cmd_sema ); - break; - default: - break; - } - -} - -enum { - STATE_IDLE, - STATE_DISCOVERING, - STATE_DISCOVERED, - STATE_CONNECTINIG, - STATE_CONNECTED, - STATE_DISCONNECTINIG, -}; - -typedef struct -{ - uint8_t len; - uint8_t name[50]; -} ble_device_name_t; - -typedef struct -{ - uint8_t state; - uint8_t addr_type; - bd_addr_t bdaddr; - ble_device_name_t dev; -} ble_device_info_t; - -ble_device_info_t g_peer_dev; - -static uint8_t ble_check_device_name(uint8_t* p_buf, uint8_t data_len, ble_device_name_t* dev_name) -{ - uint8_t* p_data = p_buf; - uint8_t* p_data_end = p_buf + data_len; - uint8_t name_len = 0; - - uint8_t is_found = 0; - - while (p_data < p_data_end) - { - if (*(p_data + 1) == 0x09)//GAP_AD_TYPE_COMPLETE_NAME - { - name_len = *p_data - 1; - - if ((name_len == dev_name->len) && (!os_memcmp(dev_name->name, p_data + 2, name_len))) - { - is_found = 1; - } - break; - } - - // Go to next advertising info - p_data += (*p_data + 1); - } - - return (is_found); -} - -static uint8_t ble_get_device_name_from_adv(uint8_t* p_buf, uint8_t data_len, uint8_t* dev_name, uint8_t *in_out_len) -{ - uint8_t* p_data = p_buf; - uint8_t* p_data_end = p_buf + data_len; - - uint8_t is_found = 0; - - while (p_data < p_data_end) - { - if (*(p_data + 1) == 0x09)//GAP_AD_TYPE_COMPLETE_NAME - { - is_found = 1; - - os_memcpy(dev_name, p_data + 2, ((p_data[0] - 1 > *in_out_len) ? *in_out_len : p_data[0] - 1)); - break; - } - - // Go to next advertising info - p_data += (*p_data + 1); - } - - return (is_found); -} - -static int8_t ethermind_find_idle_info_index(uint8_t *index) -{ - for (uint8_t i = 0; i < sizeof(s_ethermind_nordic_used) / sizeof(s_ethermind_nordic_used[0]); ++i) - { - if(s_ethermind_nordic_used[i] == 0) - { - *index = i; - return 0; - } - } - - return -1; -} - -static int8_t ethermind_clean_info_by_index(uint8_t index) -{ - s_ethermind_nordic_used[index] = 0; - os_memset(s_ethermind_nordic_write_attr_handle + index, 0, sizeof(*s_ethermind_nordic_write_attr_handle)); - os_memset(s_ethermind_nordic_att_info + index, 0, sizeof(*s_ethermind_nordic_att_info)); - - return 0; -} - -static int8_t ethermind_find_index_by_info(uint8_t *index, uint8_t att_con_id) -{ - - for (uint8_t i = 0; i < sizeof(s_ethermind_nordic_used) / sizeof(s_ethermind_nordic_used[0]); ++i) - { - if(s_ethermind_nordic_used[i] && - s_ethermind_nordic_att_info[i] == att_con_id) - { - *index = i; - return 0; - } - } - - return -1; -} - -int8_t ethermind_find_index_by_att_con_id(uint8_t *index, ATT_CON_ID att_id) -{ - - for (uint8_t i = 0; i < sizeof(s_ethermind_nordic_used) / sizeof(s_ethermind_nordic_used[0]); ++i) - { - if(s_ethermind_nordic_used[i] && - s_ethermind_nordic_att_info[i] == att_id) - { - *index = i; - return 0; - } - } - - return -1; -} - -void ble_at_notice_cb(ble_notice_t notice, void *param) -{ - switch (notice) { - case BLE_5_STACK_OK: - os_printf("ble stack ok"); - break; - case BLE_5_WRITE_EVENT: { - ble_write_req_t *w_req = (ble_write_req_t *)param; - os_printf("write_cb:conn_idx:%d, prf_id:%d, att_idx:%d, len:%d, data[0]:0x%02x\r\n", - w_req->conn_idx, w_req->prf_id, w_req->att_idx, w_req->len, w_req->value[0]); -//#if (CONFIG_BTDM_5_2) - if (bk_ble_get_controller_stack_type() == BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2 - && w_req->prf_id == g_test_prf_task_id) { - switch(w_req->att_idx) - { - case TEST_IDX_CHAR_DECL: - break; - case TEST_IDX_CHAR_VALUE: - break; - case TEST_IDX_CHAR_DESC: - g_test_noti_att_id = TEST_IDX_CHAR_VALUE; - ble_test_service_write_handle(w_req->value[0], w_req->conn_idx); - break; - - case TEST_IDX_CHAR_DATALEN_DECL: - break; - case TEST_IDX_CHAR_DATALEN_VALUE: - os_memcpy(&s_test_data_len, w_req->value, sizeof(s_test_data_len)); - break; - - case TEST_IDX_CHAR_INTER_DECL: - break; - case TEST_IDX_CHAR_INTER_VALUE: - os_memcpy(&s_test_send_inter, w_req->value, sizeof(s_test_send_inter)); - break; - - default: - break; - } - } -//#endif - break; - } - case BLE_5_READ_EVENT: { - ble_read_req_t *r_req = (ble_read_req_t *)param; - os_printf("read_cb:conn_idx:%d, prf_id:%d, att_idx:%d\r\n", - r_req->conn_idx, r_req->prf_id, r_req->att_idx); - - if (r_req->prf_id == g_test_prf_task_id) { - switch(r_req->att_idx) - { - case TEST_IDX_CHAR_DECL: - break; - case TEST_IDX_CHAR_VALUE: - break; - case TEST_IDX_CHAR_DESC: - { - uint8_t value[3] = {0}; - uint32_t length = 3; - value[0] = 0x11; - value[1] = 0x22; - value[2] = 0x33; - length = 3; - bk_ble_read_response_value(length, value, r_req->prf_id, r_req->att_idx); - break; - } - case TEST_IDX_CHAR_DATALEN_DECL: - - break; - case TEST_IDX_CHAR_DATALEN_VALUE: - { - uint8_t *value = (uint8_t *)&s_test_data_len; - bk_ble_read_response_value(sizeof(s_test_data_len), value, r_req->prf_id, r_req->att_idx); - break; - } - - case TEST_IDX_CHAR_INTER_DECL: - - break; - - case TEST_IDX_CHAR_INTER_VALUE: - { - uint8_t *value = (uint8_t *)&s_test_send_inter; - bk_ble_read_response_value(sizeof(s_test_send_inter), value, r_req->prf_id, r_req->att_idx); - break; - } - - default: - break; - } - } - break; - } - case BLE_5_REPORT_ADV: - { - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - ble_recv_adv_t *r_ind = (ble_recv_adv_t *)param; - uint8_t adv_type = r_ind->evt_type & 0x03; - os_printf("r_ind:actv_idx:%d,", r_ind->actv_idx); - switch (adv_type) - { - case 0: - os_printf("evt_type:EXT_ADV,"); - break; - case 1: - os_printf("evt_type:LEG_ADV,"); - break; - case 4: - os_printf("evt_type:PER_ADV,"); - break; - default: - os_printf("evt_type:ERR_ADV,"); - break; - } - os_printf(" adv_addr_type:%d, adv_addr:%02x:%02x:%02x:%02x:%02x:%02x\r\n", - r_ind->adv_addr_type, r_ind->adv_addr[0], r_ind->adv_addr[1], r_ind->adv_addr[2], - r_ind->adv_addr[3], r_ind->adv_addr[4], r_ind->adv_addr[5]); - - if ((STATE_DISCOVERING == g_peer_dev.state) && (ble_check_device_name(r_ind->data , r_ind->data_len, &(g_peer_dev.dev)))) - { - os_printf("dev : %s is discovered\r\n",g_peer_dev.dev.name); - os_memcpy(g_peer_dev.bdaddr.addr, r_ind->adv_addr, BK_BLE_GAP_BD_ADDR_LEN); - g_peer_dev.addr_type = r_ind->adv_addr_type; - g_peer_dev.state = STATE_DISCOVERED; - if (ble_at_cmd_sema != NULL) - rtos_set_semaphore( &ble_at_cmd_sema ); - } - } - else - { - ble_adv_report_t *r_ind = (typeof(r_ind))param; - char dname[64] = {0}; - uint8_t dname_len = sizeof(dname); - - memset(&dname, 0, sizeof(dname)); - - ble_get_device_name_from_adv(r_ind->data, r_ind->data_len, (uint8_t *)dname, &dname_len); - dname[dname_len - 1] = 0; - - if(r_ind->evt_type & (1 << 4)) - { - os_printf("evt_type:LEG_ADV,"); - } - else - { - os_printf("evt_type:EXT_ADV,"); - } - - os_printf(" adv_addr_type:%d, adv_addr:%02x:%02x:%02x:%02x:%02x:%02x name %s\r\n", - r_ind->peer_address_type, - r_ind->peer_address.addr[5], - r_ind->peer_address.addr[4], - r_ind->peer_address.addr[3], - r_ind->peer_address.addr[2], - r_ind->peer_address.addr[1], - r_ind->peer_address.addr[0], - dname); - - if ((STATE_DISCOVERING == g_peer_dev.state) && (ble_check_device_name(r_ind->data , r_ind->data_len, &(g_peer_dev.dev)))) - { - os_printf("dev : %s is discovered\r\n",g_peer_dev.dev.name); - os_memcpy(g_peer_dev.bdaddr.addr, r_ind->peer_address.addr, BK_BLE_GAP_BD_ADDR_LEN); - g_peer_dev.addr_type = r_ind->peer_address_type; - g_peer_dev.state = STATE_DISCOVERED; - - if (ble_at_cmd_sema != NULL) - { - rtos_set_semaphore( &ble_at_cmd_sema ); - } - } - } - } - break; - case BLE_5_MTU_CHANGE: { - ble_mtu_change_t *m_ind = (ble_mtu_change_t *)param; - os_printf("%s m_ind:conn_idx:%d, mtu_size:%d\r\n", __func__, m_ind->conn_idx, m_ind->mtu_size); - break; - } - case BLE_5_CONNECT_EVENT: { - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - ble_conn_ind_t *c_ind = (ble_conn_ind_t *)param; - os_printf("c_ind:conn_idx:%d, addr_type:%d, peer_addr:%02x:%02x:%02x:%02x:%02x:%02x\r\n", - c_ind->conn_idx, c_ind->peer_addr_type, c_ind->peer_addr[0], c_ind->peer_addr[1], - c_ind->peer_addr[2], c_ind->peer_addr[3], c_ind->peer_addr[4], c_ind->peer_addr[5]); - s_test_conn_ind = c_ind->conn_idx; - } - else - { - ble_conn_att_t *conn_att = (typeof(conn_att))param; - os_printf("%s ethermind connected, ATT_CON_ID %d atype %d addr 0x%02X:%02X:%02X:%02X:%02X:%02X\n", __func__, - conn_att->conn_handle, conn_att->peer_addr_type, - conn_att->peer_addr[5], - conn_att->peer_addr[4], - conn_att->peer_addr[3], - conn_att->peer_addr[2], - conn_att->peer_addr[1], - conn_att->peer_addr[0] - ); - s_ethermind_att_handle = conn_att->conn_handle; - if ((STATE_CONNECTINIG == g_peer_dev.state) && (!os_memcmp(g_peer_dev.bdaddr.addr, conn_att->peer_addr, BK_BLE_GAP_BD_ADDR_LEN))) - { - g_peer_dev.state = STATE_CONNECTED; - } - } - break; - } - case BLE_5_DISCONNECT_EVENT: { - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - ble_discon_ind_t *d_ind = (ble_discon_ind_t *)param; - os_printf("d_ind:conn_idx:%d,reason:%d\r\n", d_ind->conn_idx, d_ind->reason); - s_test_conn_ind = ~0; - } - else - { - ble_conn_att_t *att_handle = (typeof(att_handle))param; - uint8_t index = 0; - os_printf("%s ethermind disconnect reason %d attid %d atype %d addr 0x%02X:%02X:%02X:%02X:%02X:%02X\n", __func__, - att_handle->event_result, - att_handle->conn_handle, att_handle->peer_addr_type, - att_handle->peer_addr[5], - att_handle->peer_addr[4], - att_handle->peer_addr[3], - att_handle->peer_addr[2], - att_handle->peer_addr[1], - att_handle->peer_addr[0] - ); - - memset(&s_ethermind_att_handle, 0, sizeof(s_ethermind_att_handle)); - - if(0 == ethermind_find_index_by_info(&index, att_handle->conn_handle)) - { - ethermind_clean_info_by_index(index); - } - } - break; - } - case BLE_5_ATT_INFO_REQ: { - ble_att_info_req_t *a_ind = (ble_att_info_req_t *)param; - os_printf("a_ind:conn_idx:%d\r\n", a_ind->conn_idx); - a_ind->length = 128; - a_ind->status = BK_ERR_BLE_SUCCESS; - break; - } - case BLE_5_CREATE_DB: { - -//#if (CONFIG_BTDM_5_2) - if(bk_ble_get_controller_stack_type() == BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - ble_create_db_t *cd_ind = (ble_create_db_t *)param; - os_printf("cd_ind:prf_id:%d, status:%d\r\n", cd_ind->prf_id, cd_ind->status); - - at_cmd_status = cd_ind->status; - if (ble_at_cmd_sema != NULL) - rtos_set_semaphore( &ble_at_cmd_sema ); - } - else - { - os_printf("%s ethermind BLE_5_CREATE_DB ok\n", __func__); - } - } -//#endif - - break; - } - case BLE_5_INIT_CONNECT_EVENT: { - ble_conn_ind_t *c_ind = (ble_conn_ind_t *)param; - os_printf("BLE_5_INIT_CONNECT_EVENT:conn_idx:%d, addr_type:%d, peer_addr:%02x:%02x:%02x:%02x:%02x:%02x\r\n", - c_ind->conn_idx, c_ind->peer_addr_type, c_ind->peer_addr[0], c_ind->peer_addr[1], - c_ind->peer_addr[2], c_ind->peer_addr[3], c_ind->peer_addr[4], c_ind->peer_addr[5]); - - if ((STATE_CONNECTINIG == g_peer_dev.state) && (!os_memcmp(g_peer_dev.bdaddr.addr, c_ind->peer_addr, BK_BLE_GAP_BD_ADDR_LEN))) - { - g_peer_dev.state = STATE_CONNECTED; - } - break; - } - case BLE_5_INIT_DISCONNECT_EVENT: { - ble_discon_ind_t *d_ind = (ble_discon_ind_t *)param; - os_printf("BLE_5_INIT_DISCONNECT_EVENT:conn_idx:%d,reason:%d\r\n", d_ind->conn_idx, d_ind->reason); - break; - } - case BLE_5_SDP_REGISTER_FAILED: - os_printf("BLE_5_SDP_REGISTER_FAILED\r\n"); - break; - case BLE_5_READ_PHY_EVENT: { - ble_read_phy_t *phy_param = (ble_read_phy_t *)param; - os_printf("BLE_5_READ_PHY_EVENT:tx_phy:0x%02x, rx_phy:0x%02x\r\n",phy_param->tx_phy, phy_param->rx_phy); - break; - } - case BLE_5_TX_DONE: - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - uint8_t con_idx = *(uint8_t *)param; - if(s_service_type && s_performance_tx_enable == 1) - { - s_performance_tx_bytes += s_test_data_len; - ble_test_noti_hdl((void *)((uint32)con_idx)); - } - } - else - { - ble_att_tx_compl_t *tx_comp = (typeof(tx_comp))param; - os_printf("%s BLE_5_TX_DONE res %d ATT_CON_ID %d ATT_ATTR_HANDLE %d\n", __func__, - tx_comp->event_result, - tx_comp->conn_handle, tx_comp->attr_handle); - - if(s_ethermind_service_type == 1 && s_ethermind_auto_tx_enable) - { -// for (uint8_t i = 0; i < a_wr_c->num_compl; ++i) -// { -// ble_tx_test_active_timer_callback(NULL); -// } - } - } - break; - - case BLE_5_CONN_UPDATA_EVENT: - { - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - ble_conn_param_t *updata_param = (ble_conn_param_t *)param; - os_printf("BLE_5_CONN_UPDATA_EVENT:conn_interval:0x%04x, con_latency:0x%04x, sup_to:0x%04x\r\n", updata_param->intv_max, - updata_param->con_latency, updata_param->sup_to); - } - else - { - ble_conn_update_param_compl_ind_t *ind = (typeof(ind))param; - os_printf("%s BLE_5_CONN_UPDATA_EVENT mac 0x%02X:%02X:%02X:%02X:%02X:%02X status 0x%X interval 0x%X lantency 0x%X tout 0x%X\n", __func__, - ind->peer_address.addr[5], - ind->peer_address.addr[4], - ind->peer_address.addr[3], - ind->peer_address.addr[2], - ind->peer_address.addr[1], - ind->peer_address.addr[0], - ind->status, ind->conn_interval, ind->conn_latency, ind->supervision_timeout); - } - break; - } - - case BLE_5_PERIODIC_SYNC_CMPL_EVENT: - os_printf("BLE_5_PERIODIC_SYNC_CMPL_EVENT \n"); - break; - - case BLE_5_RECV_NOTIFY_EVENT: - { - //ethermind - - ble_att_notify_t *tmp = (typeof(tmp))param; - - - s_ethermind_performance_rx_bytes += tmp->len; - -#ifdef CONFIG_ALI_MQTT - if (loop_type == LT_COEX) - { - os_printf("ATT_CON_ID %d data %s len %d sendto mqtt\n", - tmp->conn_handle, - tmp->data, tmp->len); - - ble_send_data_2_mqtt(tmp->conn_handle, tmp->len, tmp->data); - } - else -#endif - { - uint8_t index = 0; - if(0 == ethermind_find_index_by_info(&index, tmp->conn_handle)) - { - os_printf("%s ATT_CON_ID %d, send data to nordic len %d %s\n", __func__, - tmp->conn_handle, tmp->len, tmp->data); - - bk_ble_att_write(tmp->conn_handle, s_ethermind_nordic_write_attr_handle[index], tmp->data, tmp->len); - } - else - { - os_printf("%s cant find info ATT_CON_ID %d\n", __func__, tmp->conn_handle); - } - } - } - break; - - case BLE_5_DISCOVERY_PRIMARY_SERVICE_EVENT: - { - ble_discovery_primary_service_t *tmp = (typeof(tmp))param; - os_printf("%s BLE_5_DISCOVERY_PRIMARY_SERVICE_EVENT count %d\n", __func__, tmp->count); - for(uint8_t i = 0; i < tmp->count; i++) - { - //service's char must in this range - bk_printf("%s service uuid 0x%X start %d end %d\n", __func__, tmp->service[i].uuid.uuid_16, - tmp->service[i].range.start_handle, tmp->service[i].range.end_handle); - - } - } - break; - - case BLE_5_DISCOVERY_CHAR_EVENT: - { - ble_discovery_char_t *tmp = (typeof(tmp))param; - uint8_t index = 0; - uint8_t found = 0; - uint8_t i = 0; - - os_printf("%s BLE_5_DISCOVERY_CHAR_EVENT count %d ATT_CON_ID %d\n", __func__, tmp->count, - tmp->conn_handle); - - // - - for (i = 0; i < tmp->count; ++i) - { - //os_printf("%s type %d %p\n", __func__, tmp->character[7].uuid_type, &tmp->character[7].uuid_type); - - switch(tmp->character[i].uuid_type) - { - case ATT_16_BIT_UUID_FORMAT: - os_printf("%s char 16bit uuid 0x%04X, attr_handle %d\n", __func__, tmp->character[i].uuid.uuid_16, tmp->character[i].value_handle); - break; - - case ATT_128_BIT_UUID_FORMAT: - { - //os_printf("%s char 128bit uuid 0x%08X\n", __func__, (uint32_t *)(tmp->character[i].uuid.uuid_128.value + 11)); - - if(!os_memcmp(&tmp->character[i].uuid.uuid_128.value, nus_rx_uuid, sizeof(nus_rx_uuid))) - { - found = 1; - i = tmp->count - 1; - break; - } - } - break; - } - } - - if(!found) - { - break; - } - - - if(0 == ethermind_find_index_by_info(&index, tmp->conn_handle)) - { - os_printf("%s nordic info already exist ! att_id %d\n", __func__, tmp->conn_handle); - } - else if(0 == ethermind_find_idle_info_index(&index)) - { - } - else - { - os_printf("%s nordic info list is full !\n", __func__); - break; - } - - - for (i = 0; i < tmp->count; ++i) - { - //os_printf("%s type %d %p\n", __func__, tmp->character[7].uuid_type, &tmp->character[7].uuid_type); - - switch(tmp->character[i].uuid_type) - { - case ATT_16_BIT_UUID_FORMAT: - break; - - case ATT_128_BIT_UUID_FORMAT: - { - os_printf("%s char 128bit uuid 0x%08X attr_hdl:%d\n", __func__, (uint32_t *)(tmp->character[i].uuid.uuid_128.value + 11), tmp->character[i].value_handle); - - if(!os_memcmp(&tmp->character[i].uuid.uuid_128.value, nus_rx_uuid, sizeof(nus_rx_uuid))) - { - os_printf("%s add to nordic info list %d\n", __func__, index); - s_ethermind_nordic_used[index] = 1; - s_ethermind_nordic_write_attr_handle[index] = tmp->character[i].value_handle; - s_ethermind_nordic_att_info[index] = tmp->conn_handle; - } - else if(!os_memcmp(&tmp->character[i].uuid.uuid_128.value, nus_tx_uuid, sizeof(nus_tx_uuid))) - { - if(tmp->character[i].desc_index) - { - for (uint8_t j = 0; j < tmp->character[i].desc_index; ++j) - { - if (ATT_16_BIT_UUID_FORMAT == tmp->character[i].descriptor[j].uuid_type && GATT_CLIENT_CONFIG == tmp->character[i].descriptor[j].uuid.uuid_16) - { - s_ethermind_nordic_write_notify_handle[index] = tmp->character[i].descriptor[j].handle; -// const uint16_t noti_enable = 0x0001; -// os_printf("%s write nordic enable notify\n", __func__); -// bk_ble_att_write(&tmp->att_handle, tmp->character[i].descriptor[j].handle, (uint8_t *)¬i_enable, sizeof(noti_enable)); - } - } - } - } - } - break; - - default: - os_printf("%s unknow uuid type %d %d %p\n", __func__, tmp->character[i].uuid_type, i, &tmp->character[i].uuid_type); - break; - } - } - - - } - break; - case BLE_5_CONN_UPD_PAR_ASK: - { - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - ble_conn_update_para_ind_t *tmp = (typeof(tmp))param; - os_printf("%s BLE_5_CONN_UPD_PAR_ASK accept\n", __func__); - tmp->is_agree = 1; - } - else - { - ble_conn_update_param_ind_t *ind = (typeof(ind))param; - os_printf("%s BLE_5_CONN_UPD_PAR_ASK 0x%02X:%02X:%02X:%02X:%02X:%02X imin 0x%X imax 0x%x latency 0x%X tout 0x%X\n", __func__, - ind->peer_address.addr[5], - ind->peer_address.addr[4], - ind->peer_address.addr[3], - ind->peer_address.addr[2], - ind->peer_address.addr[1], - ind->peer_address.addr[0], - ind->conn_interval_min, ind->conn_interval_max, ind->conn_latency, ind->supervision_timeout); - -// ind->conn_interval_min++; -// ind->conn_interval_max++; - ind->is_agree = 1; - } - } - break; - case BLE_5_ATT_READ_RESPONSE: - { - ble_att_rw_t *tmp = (typeof(tmp))param; - if(!tmp->event_result) - { - os_printf("%s att_id:%d, attr_hand:0x%x, result:%d\r\n",__func__, - tmp->conn_handle, - s_read_tmp_attr_handle, - tmp->event_result - ); - os_printf("data-> "); - for(int i=0;ilen;i++) - { - os_printf("0x%x ", *tmp->data); - } - os_printf("\r\n"); - if (ble_at_cmd_sema != NULL) - rtos_set_semaphore( &ble_at_cmd_sema ); - }else - { - os_printf("%s: Recevied Error Response!!! att_id:%d, attr_hand:%d, resp code:%d",__func__, - tmp->conn_handle, - ((uint8_t *)(&(tmp->event_result)))[1], - ((uint8_t *)(&(tmp->event_result)))[0] - ); - } - } - break; - - case BLE_5_PAIRING_REQ: - { - bk_printf("BLE_5_PAIRING_REQ\r\n"); - ble_smp_ind_t *s_ind = (ble_smp_ind_t *)param; - bk_ble_sec_send_auth_mode(s_ind->conn_idx, GAP_AUTH_REQ_NO_MITM_BOND, GAP_IO_CAP_NO_INPUT_NO_OUTPUT, - GAP_SEC1_NOAUTH_PAIR_ENC, GAP_OOB_AUTH_DATA_NOT_PRESENT); - break; - } - - case BLE_5_PARING_PASSKEY_REQ: - bk_printf("BLE_5_PARING_PASSKEY_REQ\r\n"); - break; - - case BLE_5_ENCRYPT_EVENT: - bk_printf("BLE_5_ENCRYPT_EVENT\r\n"); - break; - - case BLE_5_PAIRING_SUCCEED: - bk_printf("BLE_5_PAIRING_SUCCEED\r\n"); - break; - - default: - break; - } -} - -int set_ble_name_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - //uint8_t name[] = "BK_BLE_7231n"; - uint8_t name_len = 0;/*os_strlen((const char *)name);*/ -#ifdef CONFIG_BT - uint8_t name[BK_BLE_APP_DEVICE_NAME_MAX_LEN] = {0}; -#endif - int err = kNoErr; - if (argc != 1) - { - err = kParamErr; - goto error; - } -#ifdef CONFIG_BT - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { -#endif - name_len = bk_ble_appm_set_dev_name(os_strlen(argv[0]), (uint8_t *)argv[0]); - if (name_len == 0) - { - os_printf("\nname is empty!!!\n"); - goto error; - } - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return kNoErr; -#ifdef CONFIG_BT - } - else - { - if (ble_at_cmd_table[0].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - if(os_strlen(argv[0]) < BK_BLE_APP_DEVICE_NAME_MAX_LEN) - { - os_memcpy(name, (uint8_t *)argv[0], os_strlen(argv[0])); - name_len = os_strlen(argv[0]); - } - else - { - os_memcpy(name, (uint8_t *)argv[0], BK_BLE_APP_DEVICE_NAME_MAX_LEN); - name_len = BK_BLE_APP_DEVICE_NAME_MAX_LEN; - } - bk_ble_set_local_name(name, name_len, ble_at_cmd_cb); - - if (ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if (err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } -#endif - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} - -int get_ble_name_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint8_t name[BK_BLE_APP_DEVICE_NAME_MAX_LEN] = {0}; - uint8_t name_len = 0; - int err = kNoErr; - if (argc != 0) - { - err = kParamErr; - goto error; - } -#ifdef CONFIG_BT - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { -#endif - name_len = bk_ble_appm_get_dev_name(name, BK_BLE_APP_DEVICE_NAME_MAX_LEN); - if (name_len == 0) - { - os_printf("\nname is empty!!!\n"); - goto error; - } - - sprintf(pcWriteBuffer, "%s%s", AT_CMDRSP_HEAD, name); - return kNoErr; -#ifdef CONFIG_BT - } - else - { - if (ble_at_cmd_table[0].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - bk_ble_get_local_name(ble_at_cmd_cb); - - if (ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if (err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } -#endif - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} - -//AT+BLECMD=SETADVPARAM, map, min_intval, max_intval, local_addr_type, adv_type, adv_properties, prim_phy, second_phy -int ble_set_adv_param_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - int actv_idx = 0; - ble_adv_param_t adv_param; - - if (argc != 8) - { - os_printf("\nThe count of param is wrong!\n"); - err = kParamErr; - goto error; - } - - os_memset(&adv_param, 0, sizeof(ble_adv_param_t)); - adv_param.chnl_map = os_strtoul(argv[0], NULL, 16); - if (adv_param.chnl_map > 7) - { - os_printf("\nThe first(channel_map) param is wrong!\n"); - err = kParamErr; - goto error; - } - - adv_param.adv_intv_min = os_strtoul(argv[1], NULL, 16) & 0xFFFFFF; - adv_param.adv_intv_max = os_strtoul(argv[2], NULL, 16) & 0xFFFFFF; - if ((adv_param.adv_intv_min > ADV_INTERVAL_MAX || adv_param.adv_intv_min < ADV_INTERVAL_MIN) - || (adv_param.adv_intv_max > ADV_INTERVAL_MAX || adv_param.adv_intv_max < ADV_INTERVAL_MIN) - || (adv_param.adv_intv_min > adv_param.adv_intv_max)) - { - os_printf("input param interval is error\n"); - err = kParamErr; - goto error; - } - - adv_param.own_addr_type = os_strtoul(argv[3], NULL, 16) & 0xFF; - switch (adv_param.own_addr_type) - { - case 0: - case 1: - adv_param.own_addr_type = BLE_STATIC_ADDR; - break; - case 2: - adv_param.own_addr_type = BLE_GEN_RSLV_ADDR; - break; - case 3: - adv_param.own_addr_type = BLE_GEN_NON_RSLV_ADDR; - break; - default: - os_printf("\nThe third(own_addr_type) param is wrong!\n"); - err = kParamErr; - break; - } - - if (err != kNoErr) - goto error; - - adv_param.adv_type = os_strtoul(argv[4], NULL, 16) & 0xFF; - if (adv_param.adv_type > 2) - { - os_printf("\nThe forth(adv_type) param is wrong!\n"); - err = kParamErr; - goto error; - } - adv_param.adv_prop = os_strtoul(argv[5], NULL, 16) & 0xFFFF; - adv_param.prim_phy = os_strtoul(argv[6], NULL, 16) & 0xFF; - if(!(adv_param.prim_phy == 1 || adv_param.prim_phy == 3)) - { - os_printf("input param prim_phy is error\n"); - err = kParamErr; - goto error; - } - - adv_param.second_phy = os_strtoul(argv[7], NULL, 16) & 0xFF; - if(adv_param.second_phy < 1 || adv_param.second_phy > 3) - { - os_printf("input param second_phy is error\n"); - err = kParamErr; - goto error; - } - - if (ble_at_cmd_table[2].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_ADV_CREATED); - if (actv_idx == AT_BLE_MAX_ACTV) - { - actv_idx = bk_ble_get_idle_actv_idx_handle(); - if (actv_idx == UNKNOW_ACT_IDX) - { - err = kNoResourcesErr; - goto error; - } - } - - err = bk_ble_create_advertising(actv_idx, &adv_param, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - else - { - err = bk_ble_set_advertising_params(adv_param.adv_intv_min, adv_param.adv_intv_max, adv_param.chnl_map, - adv_param.own_addr_type,adv_param.prim_phy, adv_param.second_phy, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - - if (ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if (err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -//AT+BLECMD=SETADVDATA,data,length -int ble_set_adv_data_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint8_t adv_data[31]; - uint8_t adv_len = 0; - int actv_idx = -1; - int err = kNoErr; - - if (argc != 2) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - adv_len = os_strtoul(argv[1], NULL, 16) & 0xFF; - if (adv_len > 31 || adv_len != os_strlen(argv[0]) / 2) - { - os_printf("input adv len over limited\n"); - err = kParamErr; - goto error; - } - - at_set_data_handle(adv_data, argv[0], os_strlen(argv[0])); - - if (ble_at_cmd_table[3].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_ADV_CREATED); - - if (actv_idx == AT_BLE_MAX_ACTV) - { - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_ADV_STARTED); - if (actv_idx == AT_BLE_MAX_ACTV) - { - os_printf("ble adv not set params before\n"); - err = kNoResourcesErr; - goto error; - } - } - - err = bk_ble_set_adv_data(actv_idx, adv_data, adv_len, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - else - { - err = bk_ble_set_advertising_data(adv_data, adv_len, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -//AT+BLECMD=SETPERADVDATA,data,length -int ble_set_per_adv_data_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint8_t adv_data[31]; - uint8_t adv_len = 0; - int actv_idx = -1; - int err = kNoErr; - - if (argc != 2) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - adv_len = os_strtoul(argv[1], NULL, 16) & 0xFF; - if (adv_len > 31 || adv_len != os_strlen(argv[0]) / 2) - { - os_printf("input adv len over limited\n"); - err = kParamErr; - goto error; - } - - at_set_data_handle(adv_data, argv[0], os_strlen(argv[0])); - - if (ble_at_cmd_table[4].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_ADV_CREATED); - if (actv_idx == AT_BLE_MAX_ACTV) - { - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_ADV_STARTED); - if (actv_idx == AT_BLE_MAX_ACTV) - { - os_printf("ble adv not set params before\n"); - err = kNoResourcesErr; - goto error; - } - } - - err = bk_ble_set_per_adv_data(actv_idx, adv_data, adv_len, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_set_scan_rsp_data_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint8_t scan_rsp_data[31]; - uint8_t data_len = 0; - int actv_idx = -1; - int err = kNoErr; - - if (argc != 2) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - data_len = os_strtoul(argv[1], NULL, 16) & 0xFF; - if (data_len > 31 || data_len != os_strlen(argv[0]) / 2) - { - os_printf("input adv len over limited\n"); - err = kParamErr; - goto error; - } - - at_set_data_handle(scan_rsp_data, argv[0], os_strlen(argv[0])); - - if (ble_at_cmd_table[5].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_ADV_CREATED); - if (actv_idx == AT_BLE_MAX_ACTV) - { - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_ADV_STARTED); - if (actv_idx == AT_BLE_MAX_ACTV) - { - os_printf("ble adv not set params before\n"); - err = kNoResourcesErr; - goto error; - } - } - - err = bk_ble_set_scan_rsp_data(actv_idx, scan_rsp_data, data_len, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - else - { - err = bk_ble_set_scan_response_data(data_len, scan_rsp_data, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - -} - -int ble_set_adv_enable_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int actv_idx = -1; - int enable = 0; - int err = kNoErr; - - if (argc != 1) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - if (os_strcmp(argv[0], "1") == 0) - { - enable = 1; - } - else if (os_strcmp(argv[0], "0") == 0) - { - enable = 0; - } - else - { - os_printf("the input param is error\n"); - err = kParamErr; - goto error; - } - - if (ble_at_cmd_table[6].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - - if (enable == 1) - { - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_ADV_CREATED); - } - else - { - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_ADV_STARTED); - } - - if (actv_idx == AT_BLE_MAX_ACTV) - { - os_printf("ble adv not set params before\n"); - err = kNoResourcesErr; - goto error; - } - - if (enable == 1) - { - err = bk_ble_start_advertising(actv_idx, 0, ble_at_cmd_cb); - } - else - { - err = bk_ble_stop_advertising(actv_idx, ble_at_cmd_cb); - } - - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - else - { - err = bk_ble_set_advertising_enable(enable, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_set_scan_param_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - uint8_t actv_idx = 0; - ble_scan_param_t scan_param; - - if (argc != 4) - { - os_printf("\nThe number of param is wrong!\n"); - err = kParamErr; - goto error; - } - - os_memset(&scan_param, 0, sizeof(ble_scan_param_t)); - scan_param.own_addr_type = os_strtoul(argv[0], NULL, 16) & 0xFF; - switch (scan_param.own_addr_type) - { - case 0: - case 1: - scan_param.own_addr_type = BLE_STATIC_ADDR; - break; - case 2: - scan_param.own_addr_type = BLE_GEN_RSLV_ADDR; - break; - case 3: - scan_param.own_addr_type = BLE_GEN_NON_RSLV_ADDR; - break; - default: - os_printf("\nThe fourth param is wrong!\n"); - err = kParamErr; - break; - } - - if (err != kNoErr) - goto error; - - scan_param.scan_phy = os_strtoul(argv[1], NULL, 16) & 0xFF; - if (!(scan_param.scan_phy & (PHY_1MBPS_BIT | PHY_CODED_BIT))) - { - os_printf("\nThe scan phy param is wrong!\n"); - err = kParamErr; - goto error; - } - - scan_param.scan_intv = os_strtoul(argv[2], NULL, 16) & 0xFFFF; - scan_param.scan_wd = os_strtoul(argv[3], NULL, 16) & 0xFFFF; - if (scan_param.scan_intv < SCAN_INTERVAL_MIN || scan_param.scan_intv > SCAN_INTERVAL_MAX || - scan_param.scan_wd < SCAN_WINDOW_MIN || scan_param.scan_wd > SCAN_WINDOW_MAX || - scan_param.scan_intv < scan_param.scan_wd) - { - os_printf("\nThe second/third param is wrong!\n"); - err = kParamErr; - goto error; - } - - if (ble_at_cmd_table[7].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_SCAN_CREATED); - if (actv_idx == AT_BLE_MAX_ACTV) - { - actv_idx = bk_ble_get_idle_actv_idx_handle(); - if (actv_idx == UNKNOW_ACT_IDX) - { - err = kNoResourcesErr; - goto error; - } - } - - err = bk_ble_create_scaning(actv_idx, &scan_param, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - else - { - - err = bk_ble_set_scan_parameters(scan_param.own_addr_type, 0x00, scan_param.scan_phy, scan_param.scan_intv, scan_param.scan_wd, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_set_scan_enable_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint8_t actv_idx = 0; - int enable = 0; - int err = kNoErr; - - uint8_t filt_duplicate = 0; - uint16_t duration = 0; - uint16_t period = 10; - - if (argc < 1) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - if (os_strcmp(argv[0], "1") == 0) - { - enable = 1; - } - else if (os_strcmp(argv[0], "0") == 0) - { - enable = 0; - } - else - { - os_printf("the input param is error\n"); - err = kParamErr; - goto error; - } - - if(enable) - { - if(argc == 1) - { - - } - else if (argc >= 1 + 3) - { - filt_duplicate = os_strtoul(argv[1], NULL, 16) & 0xFF; - duration = os_strtoul(argv[2], NULL, 16) & 0xFFFF; - period = os_strtoul(argv[3], NULL, 16) & 0xFFFF; - } - else - { - os_printf("the input param is error\n"); - err = kParamErr; - goto error; - } - } - - - if (ble_at_cmd_table[8].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - bk_ble_set_notice_cb(ble_at_notice_cb); - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - - if (enable == 1) - { - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_SCAN_CREATED); - } - else - { - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_SCAN_STARTED); - } - - if (actv_idx == AT_BLE_MAX_ACTV) - { - os_printf("scan actv not start before\n"); - err = kNoResourcesErr; - goto error; - } - - if (enable == 1) - { - err = bk_ble_start_scaning_ex(actv_idx, filt_duplicate, duration, period, ble_at_cmd_cb); - } - else - { - err = bk_ble_stop_scaning(actv_idx, ble_at_cmd_cb); - } - - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - else - { - err = bk_ble_set_scan_enable_extended(enable, filt_duplicate, duration, period, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_start_connect_handle(uint8_t actv_idx, uint8_t peer_addr_type, bd_addr_t *bdaddr, ble_cmd_cb_t cb) -{ - int err = kNoErr; - err = bk_ble_init_set_connect_dev_addr(actv_idx, bdaddr, peer_addr_type); - if (err != 0) - { - return err; - } - err = bk_ble_init_start_conn(actv_idx, cb); - if (err != 0) - { - return err; - } - - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err == kNoErr) - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - return kNoErr; - } - else - { - err = at_cmd_status; - } - } - } - else - err = kNotFoundErr; - - return err; -} - -int ble_create_connect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint8_t actv_idx = 0; - ble_conn_param_t conn_param; - uint8_t peer_addr_type = 0; - bd_addr_t bdaddr; - int err = kNoErr; - uint8_t central_count = 0; - - if(!bk_ble_if_support_central(¢ral_count) || central_count == 0) - { - os_printf("not support central\n"); - err = kParamErr; - goto error; - } - - - if (argc != 6) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - conn_param.intv_max = conn_param.intv_min = os_strtoul(argv[0], NULL, 16) & 0xFFFF; - conn_param.con_latency = os_strtoul(argv[1], NULL, 16) & 0xFFFF; - if (conn_param.intv_min < CON_INTERVAL_MIN || conn_param.intv_min > CON_INTERVAL_MAX - || conn_param.con_latency > CON_LATENCY_MAX) - { - err = kParamErr; - goto error; - } - - conn_param.sup_to = os_strtoul(argv[2], NULL, 16) & 0xFFFF; - if (conn_param.sup_to < CON_SUP_TO_MIN || conn_param.sup_to > CON_SUP_TO_MAX) - { - err = kParamErr; - goto error; - } - - conn_param.init_phys = os_strtoul(argv[3], NULL, 16) & 0xFF; - if (conn_param.init_phys > (PHY_1MBPS_BIT | PHY_2MBPS_BIT | PHY_CODED_BIT)) - { - err = kParamErr; - goto error; - } - - peer_addr_type = os_strtoul(argv[4], NULL, 16) & 0xFF; - if (peer_addr_type > 0x03) - { - err = kParamErr; - goto error; - } - - err = get_addr_from_param(&bdaddr, argv[5]); - if (err != kNoErr) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - if ((10 * conn_param.sup_to) < (((1 + conn_param.con_latency) * conn_param.intv_min * 5 + 1) >> 1)) - { - os_printf("input param not suitable, maybe you can set con_latency to 0\n"); - err = kParamErr; - goto error; - } - - if (ble_at_cmd_table[9].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - - /*actv_idx = bk_ble_find_master_state_idx_handle(AT_INIT_STATE_CREATED); - if (actv_idx == AT_BLE_MAX_CONN)*/ - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - /// Do not create actv - - actv_idx = bk_ble_get_idle_conn_idx_handle(); - if (actv_idx == UNKNOW_ACT_IDX) - { - err = kNoResourcesErr; - goto error; - } - - err = bk_ble_create_init(actv_idx, &conn_param, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - err = ble_start_connect_handle(actv_idx, peer_addr_type, &bdaddr, ble_at_cmd_cb); - if (err != kNoErr) - goto error; - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - /*else - { - /// have created actv, this happend in which connection have been disconnected - err = ble_start_connect_handle(actv_idx, peer_addr_type, &bdaddr, ble_at_cmd_cb); - if (err != kNoErr) - goto error; - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - }*/ - - else - { - ble_conn_param_normal_t tmp; - - tmp.conn_interval_min = conn_param.intv_min; - tmp.conn_interval_max = conn_param.intv_max; - tmp.conn_latency = conn_param.con_latency; - tmp.supervision_timeout = conn_param.sup_to; - tmp.initiating_phys = conn_param.init_phys; - - tmp.peer_address_type = peer_addr_type; - memcpy(tmp.peer_address.addr, bdaddr.addr, sizeof(bdaddr.addr)); - - err = bk_ble_create_connection(&tmp, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - - } - - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_cancel_create_connect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint8_t actv_idx = 0; - int err = kNoErr; - uint8_t central_count = 0; - - if(!bk_ble_if_support_central(¢ral_count) || central_count == 0) - { - os_printf("not support central\n"); - err = kParamErr; - goto error; - } - - if (argc != 0) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - if (ble_at_cmd_table[10].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - actv_idx = bk_ble_find_master_state_idx_handle(AT_INIT_STATE_CONNECTTING); - if (actv_idx == AT_BLE_MAX_ACTV) - { - os_printf("ble adv not set params before\n"); - err = kNoResourcesErr; - goto error; - } - - err = bk_ble_init_stop_conn(actv_idx, ble_at_cmd_cb); - } - else - { - err = bk_ble_cancel_connect(ble_at_cmd_cb); - } - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_disconnect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - bd_addr_t connect_addr; - uint8_t addr_type = 1; - - uint8_t conn_idx; - uint8_t central_count = 0; - - if(!bk_ble_if_support_central(¢ral_count) || central_count == 0) - { - os_printf("not support central\n"); - err = kParamErr; - goto error; - } - - if (argc > 2) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - err = get_addr_from_param(&connect_addr, argv[0]); - if (err != kNoErr) - { - os_printf("input addr param error\n"); - err = kParamErr; - goto error; - } - - if (argc < 2) - { - os_printf("%s warning, you need input addr type\n", __func__); - } - else - { - addr_type = os_strtoul(argv[1], NULL, 10) & 0xFF; - } - - if (ble_at_cmd_table[11].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - /// get connect_idx from connect_addr - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - conn_idx = bk_ble_find_conn_idx_from_addr(&connect_addr); - if (conn_idx == AT_BLE_MAX_CONN) - { - os_printf("ble not connection\n"); - err = kNoResourcesErr; - goto error; - } - - err = bk_ble_disconnect(conn_idx, ble_at_cmd_cb); - } - else - { - err = bk_ble_disconnect_connection(&connect_addr, addr_type, ble_at_cmd_cb); - } - - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_update_conn_param_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - bd_addr_t connect_addr; - ble_conn_param_t conn_param; - uint8_t conn_idx; - uint8_t central_count = 0; - uint8_t addr_type = 1; - - if(!bk_ble_if_support_central(¢ral_count) || central_count == 0) - { - os_printf("not support central\n"); - err = kParamErr; - goto error; - } - - if (argc > 6) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - err = get_addr_from_param(&connect_addr, argv[0]); - if (err != kNoErr) - { - os_printf("input addr param error\n"); - err = kParamErr; - goto error; - } - - conn_param.intv_min = os_strtoul(argv[1], NULL, 16) & 0xFFFF; - conn_param.intv_max = os_strtoul(argv[2], NULL, 16) & 0xFFFF; - conn_param.con_latency = os_strtoul(argv[3], NULL, 16) & 0xFFFF; - conn_param.sup_to = os_strtoul(argv[4], NULL, 16) & 0xFFFF; - - if (argc < 6) - { - os_printf("%s warning, you need input addr type\n", __func__); - } - else - { - addr_type = os_strtoul(argv[5], NULL, 10) & 0xFF; - } - - if ((conn_param.intv_min < CON_INTERVAL_MIN || conn_param.intv_min > CON_INTERVAL_MAX) || - (conn_param.intv_max < CON_INTERVAL_MIN || conn_param.intv_max > CON_INTERVAL_MAX) || - (conn_param.intv_min > conn_param.intv_max) || (conn_param.con_latency > CON_LATENCY_MAX) || - (conn_param.sup_to < CON_SUP_TO_MIN || conn_param.sup_to > CON_SUP_TO_MAX)) - { - os_printf("input update param not suitable\n"); - err = kParamErr; - goto error; - } - - if ((10 * conn_param.sup_to) < (((1 + conn_param.con_latency) * conn_param.intv_max * 5 + 1) >> 1)) - { - os_printf("input param not suitable, maybe you can set con_latency to 0\n"); - err = kParamErr; - goto error; - } - - if (ble_at_cmd_table[12].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr) - { - os_printf("rtos_init_semaphore error\n"); - goto error; - } - } - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - /// get connect_idx from connect_addr - conn_idx = bk_ble_find_conn_idx_from_addr(&connect_addr); - if (conn_idx == AT_BLE_MAX_CONN) - { - os_printf("ble not connection\n"); - err = kNoResourcesErr; - goto error; - } - err = bk_ble_update_param(conn_idx, &conn_param, ble_at_cmd_cb); - } - else - { - ble_update_conn_param_t tmp; - tmp.peer_address_type = addr_type; - - tmp.conn_interval_min = conn_param.intv_min; - tmp.conn_interval_max = conn_param.intv_max; - tmp.conn_latency = conn_param.con_latency; - tmp.supervision_timeout = conn_param.sup_to; - - memcpy(tmp.peer_address.addr, connect_addr.addr, sizeof(connect_addr.addr)); - - err = bk_ble_update_connection_params(&tmp, ble_at_cmd_cb); - } - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - { - rtos_deinit_semaphore(&ble_at_cmd_sema); - } - return err; -} - -int ble_get_conn_state_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - uint8_t conn_state = 0; - bd_addr_t peer_addr; - - if (argc != 1) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - err = get_addr_from_param(&peer_addr, argv[0]); - if (err != kNoErr) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - conn_state = bk_ble_get_connect_state(&peer_addr); - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - if (conn_state == 1) - { - sprintf(pcWriteBuffer, "%s%s\r\n", AT_CMDRSP_HEAD, "BLE_CONNECT"); - } - else - { - sprintf(pcWriteBuffer, "%s:%s\r\n", AT_CMDRSP_HEAD, "BLE_DISCONNECT"); - } - - } - else - { - if (conn_state == AT_INIT_STATE_CONNECTTED) - { - sprintf(pcWriteBuffer, "%s%s\r\n", AT_CMDRSP_HEAD, "BLE_CONNECTED"); - } - else if (conn_state == AT_INIT_STATE_IDLE) - { - sprintf(pcWriteBuffer, "%s:%s\r\n", AT_CMDRSP_HEAD, "BLE_DISCONNECT"); - } - else if (conn_state == AT_INIT_STATE_CONNECTTING) - { - sprintf(pcWriteBuffer, "%s:%s\r\n", AT_CMDRSP_HEAD, "BLE_CONNECTTING"); - } - else if (conn_state == AT_INIT_STATE_STOPPING) - { - sprintf(pcWriteBuffer, "%s:%s\r\n", AT_CMDRSP_HEAD, "BLE_DISCONNECTTING"); - } - else - { - sprintf(pcWriteBuffer, "%s:%s\r\n", AT_CMDRSP_HEAD, "BLE_DISCONNECT"); - } - } - return err; - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} - -int ble_get_local_addr_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - uint8_t local_addr[6]; - - if (argc != 0) { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - err = bk_ble_get_mac(local_addr); - if (err != kNoErr) { - os_printf("bk_ble_get_mac error\n"); - err = kParamErr; - goto error; - } - sprintf(pcWriteBuffer, "%s%s%02x:%02x:%02x:%02x:%02x:%02x\r\n", AT_CMDRSP_HEAD, "BLE_ADDR:", local_addr[5], - local_addr[4], local_addr[3], local_addr[2], local_addr[1], local_addr[0]); - return err; - } - else - { - if (ble_at_cmd_table[14].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - err = bk_ble_read_local_addr(ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} - -int ble_set_local_addr_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - // not defined - return 0; -} - -//#if (CONFIG_BTDM_5_2) - - -#define DECL_PRIMARY_SERVICE_128 {0x00,0x28,0,0,0,0,0,0,0,0,0,0,0,0,0,0} -#define DECL_CHARACTERISTIC_128 {0x03,0x28,0,0,0,0,0,0,0,0,0,0,0,0,0,0} -#define DESC_CLIENT_CHAR_CFG_128 {0x02,0x29,0,0,0,0,0,0,0,0,0,0,0,0,0,0} - - - -ble_attm_desc_t test_service_db[TEST_IDX_NB] = { - // Service Declaration - [TEST_IDX_SVC] = {DECL_PRIMARY_SERVICE_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0}, - [TEST_IDX_CHAR_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0}, - // Characteristic Value - [TEST_IDX_CHAR_VALUE] = {{0x34, 0x12, 0}, BK_BLE_PERM_SET(NTF, ENABLE), BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128}, - //Client Characteristic Configuration Descriptor - [TEST_IDX_CHAR_DESC] = {DESC_CLIENT_CHAR_CFG_128, BK_BLE_PERM_SET(RD, ENABLE) | BK_BLE_PERM_SET(WRITE_REQ, ENABLE), 0, 0}, - - //data len - [TEST_IDX_CHAR_DATALEN_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0}, - [TEST_IDX_CHAR_DATALEN_VALUE] = {{0xbc, 0x9a, 0}, BK_BLE_PERM_SET(WRITE_REQ, ENABLE) | BK_BLE_PERM_SET(RD, ENABLE), BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128}, - - //send inter - [TEST_IDX_CHAR_INTER_DECL] = {DECL_CHARACTERISTIC_128, BK_BLE_PERM_SET(RD, ENABLE), 0, 0}, - [TEST_IDX_CHAR_INTER_VALUE] = {{0xf0, 0xde, 0}, BK_BLE_PERM_SET(WRITE_REQ, ENABLE) | BK_BLE_PERM_SET(RD, ENABLE), BK_BLE_PERM_SET(RI, ENABLE) | BK_BLE_PERM_SET(UUID_LEN, UUID_16), 128}, - -}; - -int ble_update_mtu_2_max_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - int err = kNoErr; - char *msg = NULL; - - if(bk_ble_get_controller_stack_type() != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - err = kParamErr; - goto error; - } - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - uint8 conn_idx = 0; - bd_addr_t connect_addr; - - if (argc < 1) - { - os_printf("\nThe number of param is wrong!\n"); - err = kParamErr; - goto error; - } - - err = get_addr_from_param(&connect_addr, argv[0]); - if (err != kNoErr) - { - os_printf("input addr param error\r\n"); - err = kParamErr; - goto error; - } - - conn_idx = bk_ble_find_conn_idx_from_addr(&connect_addr); - if (conn_idx == AT_BLE_MAX_CONN) - { - os_printf("ble not connection\r\n"); - err = kNoResourcesErr; - goto error; - } - - - if (1)//ble_at_cmd_table[22].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if (err != kNoErr) - { - goto error; - } - } - - - bk_ble_set_notice_cb(ble_at_notice_cb); - - err = bk_ble_gatt_mtu_change(conn_idx, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - else - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if (err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - at_cmd_status = BK_ERR_BLE_SUCCESS; - goto error; - } - } - } - } - else - { - uint8_t conn_handle; - - conn_handle = os_strtoul(argv[0], NULL, 10) & 0xFF; - err = bk_ble_set_gatt_mtu(conn_handle, 517); - - if (err == 0) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - else - { - os_printf("%s set mtu err %d\n", __func__, err); - } - } - - -error: - msg = AT_CMD_RSP_ERROR; - g_test_prf_task_id = 0; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_tx_test_param_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - int err = kNoErr; - char *msg = NULL; - uint16_t len = 0; - uint32_t inter = 0; - - if(bk_ble_get_controller_stack_type() != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - err = kParamErr; - goto error; - } - - if (argc < 2) - { - os_printf("\nThe number of param is wrong!\n"); - err = kParamErr; - goto error; - } - - if(g_test_prf_task_id == 0) - { - os_printf("%s not reg profile, exit\n", __func__); - err = kParamErr; - goto error; - } - - len = os_strtoul(argv[0], NULL, 10) & 0xFFFF; - inter = os_strtoul(argv[1], NULL, 10) & 0xFFFFFFFF; - - - if(inter == 0 || len == 0) - { - os_printf("%s param err\n", __func__); - err = kParamErr; - goto error; - } - s_ethermind_send_size_value = s_test_data_len = len; - s_ethermind_send_intv_value = s_test_send_inter = inter; - os_printf("%s len %d inter %d\n", __func__, s_test_data_len, s_test_send_inter); - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - else - { - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - else - { - err = at_cmd_status; - at_cmd_status = BK_ERR_BLE_SUCCESS; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_tx_test_enable_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - int err = kNoErr; - char *msg = NULL; - uint8_t enable = 0; - uint8 con_idx = 0; - - if(bk_ble_get_controller_stack_type() != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - err = kParamErr; - goto error; - } - - if (argc < 1) - { - os_printf("\nThe number of param is wrong!\n"); - err = kParamErr; - goto error; - } - - - if(g_test_prf_task_id == 0) - { - os_printf("%s not reg profile, exit\n", __func__); - err = kParamErr; - goto error; - } - - enable = os_strtoul(argv[0], NULL, 10) & 0xFF; - con_idx = os_strtoul(argv[1], NULL, 10) & 0xFF; - os_printf("%s enable %d, con_idx %d\n", __func__, enable, con_idx); - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - ble_test_service_write_handle(enable, con_idx); - } - else - { - s_ethermind_auto_tx_enable = enable; - - if(enable) - { - if(s_ethermind_service_type == 1) - { - ble_tx_test_active_timer_callback(NULL); - } - else - { - if (!rtos_is_timer_init(&s_ethermind_ble_send_test_timer)) - { - rtos_init_timer(&s_ethermind_ble_send_test_timer, 1000, ble_tx_test_active_timer_callback, NULL); - rtos_start_timer(&s_ethermind_ble_send_test_timer); - } - } - } - else - { - if (rtos_is_timer_init(&s_ethermind_ble_send_test_timer)) - { - if (rtos_is_timer_running(&s_ethermind_ble_send_test_timer)) - { - rtos_stop_timer(&s_ethermind_ble_send_test_timer); - } - - rtos_deinit_timer(&s_ethermind_ble_send_test_timer); - } - } - - } - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - else - { - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - else - { - err = at_cmd_status; - at_cmd_status = BK_ERR_BLE_SUCCESS; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - - -static void ble_sdp_charac_callback(uint32_t type, uint8 conidx, uint16_t hdl, uint16_t len, uint8 *data) -{ - //os_printf("%s recv type %d len %d data[0] 0x%02X\n", __func__, type, len, data[0]); - s_performance_rx_bytes += len; -} - -int ble_register_noti_service_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - s_ethermind_service_type = s_service_type = 0; - - return ble_register_service_handle(pcWriteBuffer, xWriteBufferLen, argc, argv); -} - -int ble_register_performance_service_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - s_ethermind_service_type = s_service_type = 1; - - return ble_register_service_handle(pcWriteBuffer, xWriteBufferLen, argc, argv); -} - -#define PERFORMANCE_STATISTIC_TX "tx" -#define PERFORMANCE_STATISTIC_RX "rx" - -int ble_enable_performance_statistic_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - int err = kNoErr; - char *msg = NULL; - - uint8_t enable = 0; - uint8_t type = 0; - - if(bk_ble_get_controller_stack_type() != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - err = kParamErr; - goto error; - } - - if (argc < 2) - { - os_printf("\nThe number of param is wrong!\n"); - err = kParamErr; - goto error; - } - - if(strlen(argv[0]) > 3) - { - os_printf("%s param err, exit\n", __func__); - err = kParamErr; - goto error; - } - - if(!strncmp(PERFORMANCE_STATISTIC_TX, argv[0], strlen(PERFORMANCE_STATISTIC_TX))) - { - type = 1; - } - else if(!strncmp(PERFORMANCE_STATISTIC_RX, argv[0], strlen(PERFORMANCE_STATISTIC_RX))) - { - type = 2; - } - else - { - os_printf("%s param err, exit\n", __func__); - err = kParamErr; - goto error; - } - - - enable = os_strtoul(argv[1], NULL, 10) & 0xFFFFFFFF; - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - if(g_test_prf_task_id == 0) - { - os_printf("%s not reg profile, exit\n", __func__); - err = kParamErr; - goto error; - } - - if(type == 1)//tx - { - if(enable) - { - if(!rtos_is_timer_init(&ble_performance_tx_statistics_tmr)) - { - s_performance_tx_bytes = 0; - - rtos_init_timer(&ble_performance_tx_statistics_tmr, 1000, ble_performance_tx_timer_hdl, (void *)0); - rtos_start_timer(&ble_performance_tx_statistics_tmr); - } - } - else - { - if (rtos_is_timer_init(&ble_performance_tx_statistics_tmr)) - { - s_performance_tx_bytes = 0; - if (rtos_is_timer_running(&ble_performance_tx_statistics_tmr)) - rtos_stop_timer(&ble_performance_tx_statistics_tmr); - rtos_deinit_timer(&ble_performance_tx_statistics_tmr); - } - } - } - else if(type == 2)//rx - { - if(enable) - { - if(!rtos_is_timer_init(&ble_performance_rx_statistics_tmr)) - { - s_performance_rx_bytes = 0; - - rtos_init_timer(&ble_performance_rx_statistics_tmr, 1000, ble_performance_rx_timer_hdl, (void *)0); - rtos_start_timer(&ble_performance_rx_statistics_tmr); - } - } - else - { - if (rtos_is_timer_init(&ble_performance_rx_statistics_tmr)) - { - s_performance_rx_bytes = 0; - - if (rtos_is_timer_running(&ble_performance_rx_statistics_tmr)) - rtos_stop_timer(&ble_performance_rx_statistics_tmr); - rtos_deinit_timer(&ble_performance_rx_statistics_tmr); - } - } - } - } - else - { - if(type == 1)//tx - { - if(enable) - { - if(!rtos_is_timer_init(&ble_ethermind_performance_tx_statistics_tmr)) - { - s_ethermind_performance_tx_bytes = 0; - - rtos_init_timer(&ble_ethermind_performance_tx_statistics_tmr, 1000, ble_ethermind_performance_tx_timer_hdl, (void *)0); - rtos_start_timer(&ble_ethermind_performance_tx_statistics_tmr); - } - } - else - { - if (rtos_is_timer_init(&ble_ethermind_performance_tx_statistics_tmr)) - { - s_performance_tx_bytes = 0; - if (rtos_is_timer_running(&ble_ethermind_performance_tx_statistics_tmr)) - rtos_stop_timer(&ble_ethermind_performance_tx_statistics_tmr); - rtos_deinit_timer(&ble_ethermind_performance_tx_statistics_tmr); - } - } - } - else if(type == 2)//rx - { - if(enable) - { - if(!rtos_is_timer_init(&ble_ethermind_performance_rx_statistics_tmr)) - { - s_ethermind_performance_rx_bytes = 0; - - rtos_init_timer(&ble_ethermind_performance_rx_statistics_tmr, 1000, ble_ethermind_performance_rx_timer_hdl, (void *)0); - rtos_start_timer(&ble_ethermind_performance_rx_statistics_tmr); - } - } - else - { - if (rtos_is_timer_init(&ble_ethermind_performance_rx_statistics_tmr)) - { - s_ethermind_performance_rx_bytes = 0; - - if (rtos_is_timer_running(&ble_ethermind_performance_rx_statistics_tmr)) - { - rtos_stop_timer(&ble_ethermind_performance_rx_statistics_tmr); - } - - rtos_deinit_timer(&ble_ethermind_performance_rx_statistics_tmr); - } - } - } - } - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - else - { - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - else - { - err = at_cmd_status; - at_cmd_status = BK_ERR_BLE_SUCCESS; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - - - -static void ble_tx_test_active_timer_callback(void *param) -{ - API_RESULT retval = 0; - uint8_t *tmp_buff = NULL; - - tmp_buff = os_malloc(s_ethermind_send_size_value); - - if (!tmp_buff) - { - os_printf("%s alloc send failed\n", __func__); - return; - } - - os_memset(tmp_buff, 0, s_ethermind_send_size_value); - tmp_buff[0] = s_ethermind_send_test_value++; - - - retval = bk_ble_send_notify(s_ethermind_att_handle, s_ethermind_send_test_service_handle, - s_ethermind_send_char_test_handle, tmp_buff, s_ethermind_send_size_value); - - os_free(tmp_buff); - - if (retval != 0) - { - os_printf("%s notify err %d\n", __func__, retval); - } - else - { - s_ethermind_performance_tx_bytes += s_ethermind_send_size_value; - } -} - -static void ble_tx_test_passive_timer_callback(void *param) -{ - API_RESULT retval = 0; - uint8_t *tmp_buff = NULL; - GATT_DB_HANDLE *gdbh = (GATT_DB_HANDLE *)param; - uint8_t conn_handle; - - tmp_buff = os_malloc(s_ethermind_send_size_value); - - if (!tmp_buff) - { - os_printf("%s alloc send failed\n", __func__); - return; - } - - os_memset(tmp_buff, 0, s_ethermind_send_size_value); - tmp_buff[0] = s_ethermind_send_test_value++; - - retval = bk_ble_get_conn_handle_from_device_handle(&conn_handle, &(gdbh->device_id)); - - if (retval != 0) - { - return; - } - - retval = bk_ble_send_notify(conn_handle, gdbh->service_id, gdbh->char_id, - tmp_buff, s_ethermind_send_size_value); - - os_free(tmp_buff); - - if (retval != 0) - { - os_printf("%s notify err %d\n", __func__, retval); - } - else - { - s_ethermind_performance_tx_bytes += s_ethermind_send_size_value; - } - -} - -static API_RESULT ethermind_test_gatt_char_handler -( - GATT_DB_HANDLE *handle, - GATT_DB_PARAMS *params -) -{ - API_RESULT retval = 0; - uint16_t value = 0; - - static GATT_DB_HANDLE *gdbh = NULL; - - os_printf("%s device_id %d service %d char %d attr_handle %d op 0x%02X\n", __func__, - handle->device_id, handle->service_id, handle->char_id, params->handle, params->db_op); - - if (handle->service_id == s_ethermind_send_test_service_handle) - { - switch (params->db_op) - { - case GATT_DB_CHAR_PEER_CLI_CNFG_WRITE_REQ: - { - //BT_UNPACK_LE_2_BYTE (&value, params->value.val); - memcpy(&value, params->value.val, 2); - if (handle->char_id == s_ethermind_send_char_test_handle) - { - if (GATT_CLI_CNFG_NOTIFICATION == value) - { - os_printf("%s enable notify\n", __func__); - - if (!gdbh) - { - gdbh = (GATT_DB_HANDLE *)os_malloc(sizeof(*handle)); - - if (!gdbh) - { - os_printf("%s cant alloc GATT_DB_HANDLE\n", __func__); - retval = BK_FAIL; - break; - } - } - - memcpy(gdbh, handle, sizeof(*handle)); - - if(s_ethermind_service_type == 1) - { - s_ethermind_auto_tx_enable = 1; - ble_tx_test_passive_timer_callback((void *)(size_t)gdbh); - - } - else if (!rtos_is_timer_init(&s_ethermind_ble_send_test_timer)) - { - rtos_init_timer(&s_ethermind_ble_send_test_timer, 1000, ble_tx_test_passive_timer_callback, (void *)(size_t)gdbh); - rtos_start_timer(&s_ethermind_ble_send_test_timer); - } - - } - else - { - os_printf("%s disable notify\n", __func__); - s_ethermind_auto_tx_enable = 0; - - if (rtos_is_timer_init(&s_ethermind_ble_send_test_timer)) - { - if (rtos_is_timer_running(&s_ethermind_ble_send_test_timer)) - { - rtos_stop_timer(&s_ethermind_ble_send_test_timer); - } - - rtos_deinit_timer(&s_ethermind_ble_send_test_timer); - } - - if (gdbh) - { - os_free(gdbh); - gdbh = NULL; - } - } - } - else - { - retval = BK_FAIL; - } - } - break; - - case GATT_DB_CHAR_PEER_WRITE_REQ: - { - if (handle->char_id == s_ethermind_send_size_handle) - { - //BT_UNPACK_LE_2_BYTE(&value, k); - memcpy(&value, params->value.val, 2); - os_printf("%s write s_ethermind_send_size_handle %d\n", __func__, value); - } - else if (handle->char_id == s_ethermind_send_intv_handle) - { - //BT_UNPACK_LE_2_BYTE(&value, params->value.val); - memcpy(&value, params->value.val, 2); - os_printf("%s write s_ethermind_send_intv_handle %d len %d %d\n", __func__, value, params->value.len, params->value.actual_len); - } - else - { - retval = BK_FAIL; - } - } - break; - - case GATT_DB_CHAR_PEER_READ_REQ: - if (handle->char_id == s_ethermind_send_intv_handle) - { -#if 0 - //when s_ethermind_send_intv_handle buff is null - uint8_t conn_handle = 0; - const uint32_t test_resp = 0xabcdef01; - - if(0 != bk_ble_get_conn_handle_from_device_handle(&conn_handle, &handle->device_id)) - { - break; - } - - //respone here - bk_ble_gatt_read_resp(conn_handle, (uint8_t *)&test_resp, sizeof(test_resp)); - - //must return GATT_DB_DELAYED_RESPONSE - retval = GATT_DB_DELAYED_RESPONSE; -#endif - } - - break; - } - } - else - { -// retval = BK_FAIL; - } - - return retval; -} - - - -static int ble_register_service_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - int err = kNoErr; - char *msg = NULL; - uint16 my_service_uuid = 0; - uint16 my_char_uuid = 0x1234; - struct bk_ble_db_cfg ble_db_cfg; - uint8 cur_test_prf_task_id = 0; - - if(bk_ble_get_controller_stack_type() != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - err = kParamErr; - goto error; - } - - if (argc < 2) - { - os_printf("\nThe number of param is wrong!\n"); - err = kParamErr; - goto error; - } - - cur_test_prf_task_id = g_test_prf_task_id; - g_test_prf_task_id = os_strtoul(argv[0], NULL, 16) & 0xFF; - my_service_uuid = os_strtoul(argv[1], NULL, 16) & 0xFFFF; - if(argc >= 3) - { - my_char_uuid = os_strtoul(argv[2], NULL, 16) & 0xFFFF; - } - - if(argc >= 5) - { - s_test_data_len = os_strtoul(argv[3], NULL, 10) & 0xFFFF; - s_test_send_inter = os_strtoul(argv[4], NULL, 10) & 0xFFFF; - } - - os_memcpy(&(test_service_db[TEST_IDX_CHAR_VALUE].uuid[0]), &my_char_uuid, 2); - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - - os_memset(&ble_db_cfg, 0, sizeof(ble_db_cfg)); - - ble_db_cfg.att_db = (ble_attm_desc_t *)test_service_db; - ble_db_cfg.att_db_nb = TEST_IDX_NB; - ble_db_cfg.prf_task_id = g_test_prf_task_id; - ble_db_cfg.start_hdl = 0; - ble_db_cfg.svc_perm = BK_BLE_PERM_SET(SVC_UUID_LEN, UUID_16); - os_memcpy(&(ble_db_cfg.uuid[0]), &my_service_uuid, 2); - - if (1)//ble_at_cmd_table[19].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if (err != kNoErr) - { - goto error; - } - } - bk_ble_set_notice_cb(ble_at_notice_cb); - extern void register_app_sdp_charac_callback(void (*)(uint32_t type,uint8 conidx,uint16_t hdl,uint16_t len,uint8 *data)); - register_app_sdp_charac_callback(ble_sdp_charac_callback); - err = bk_ble_create_db(&ble_db_cfg); - - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - else - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if (err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - at_cmd_status = BK_ERR_BLE_SUCCESS; - goto error; - } - } - } - } - else - { - API_RESULT retval; - GATT_DB_SERVICE_INFO service_info; - uint16_t num_attr_handles; - uint16_t service_handle; - GATT_DB_UUID_TYPE char_uuid; - uint16_t perm; - uint16_t property; - ATT_VALUE char_value; - - if (ble_at_cmd_table[16].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if (err != kNoErr) - { - goto error; - } - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - - bk_printf("%s now last attr_handle %d\n", __func__, bk_ble_get_current_gatt_db_attr_handle()); - - service_info.is_primary = 1; - service_info.uuid.uuid_format = ATT_16_BIT_UUID_FORMAT; - service_info.uuid.uuid.uuid_16 = my_service_uuid; - service_info.link_req = GATT_DB_SER_SUPPORT_ANY_LINK_TYPE; - service_info.sec_req = GATT_DB_SER_NO_SECURITY_PROPERTY; - - num_attr_handles = 10; - - retval = bk_ble_gatt_db_add_service - ( - &service_info, - num_attr_handles, - &service_handle - ); - - if (0 != retval) - { - os_printf("%s: BT_gatt_db_add_service() failed. Result: 0x%04X\n", __func__, retval); - goto error; - } - else - { - bk_printf("%s service last attr_handle %d\n", __func__, bk_ble_get_current_gatt_db_attr_handle()); - /* Save GATT Service Instance for future reference */ - s_ethermind_send_test_service_handle = service_handle; - - char_uuid.uuid_format = ATT_16_BIT_UUID_FORMAT; - char_uuid.uuid.uuid_16 = my_char_uuid; - - perm = GATT_DB_PERM_READ | GATT_DB_PERM_WRITE; - property = GATT_DB_CHAR_NOTIFY_PROPERTY | GATT_DB_CHAR_READ_PROPERTY | - GATT_DB_CHAR_WRITE_PROPERTY; - - char_value.val = (uint8_t *)"";//(UCHAR *)s_ethermind_send_test_value; - char_value.len = 0;//strlen((char *)char_value.val); - char_value.actual_len = char_value.len; - - - retval = bk_ble_gatt_db_add_characteristic - ( - service_handle, - &char_uuid, - perm, - property, - &char_value, - &s_ethermind_send_char_test_handle - ); - - if (0 != retval) - { - os_printf("%s: BT_gatt_db_add_characteristic() failed. Result: 0x%04X\n", __func__, retval); - goto error; - } - else - { - bk_printf("%s first char value attr_handle %d\n", __func__, bk_ble_get_current_gatt_db_attr_handle()); - /* Add CCCD */ - GATT_DB_UUID_TYPE desc_uuid; - UINT16 perm; - ATT_VALUE desc_value; - - uint8_t cccd_value[2U] = { 0x00U, 0x00U }; - - desc_uuid.uuid_format = ATT_16_BIT_UUID_FORMAT; - desc_uuid.uuid.uuid_16 = GATT_CLIENT_CONFIG; - perm = (GATT_DB_PERM_READ | GATT_DB_PERM_WRITE); - desc_value.val = cccd_value; - desc_value.len = sizeof(cccd_value); - desc_value.actual_len = desc_value.len; - - /* Add descriptor CCCD */ - retval = bk_ble_gatt_db_add_characteristic_descriptor - ( - service_handle, - s_ethermind_send_char_test_handle, - &desc_uuid, - perm, - &desc_value - ); - } - } - - if (0 != retval) - { - os_printf("%s: add send desc failed. Result: 0x%04X\n", __func__, retval); - goto error; - } - else - { - bk_printf("%s first char desc attr_handle %d\n", __func__, bk_ble_get_current_gatt_db_attr_handle()); - char_uuid.uuid_format = ATT_16_BIT_UUID_FORMAT; - char_uuid.uuid.uuid_16 = 0x9abc; - - perm = GATT_DB_PERM_READ | GATT_DB_PERM_WRITE; - property = GATT_DB_CHAR_READ_PROPERTY | GATT_DB_CHAR_WRITE_PROPERTY; - - char_value.val = (uint8_t *)&s_ethermind_send_size_value; - char_value.len = sizeof(s_ethermind_send_size_value); - char_value.actual_len = char_value.len; - - retval = bk_ble_gatt_db_add_characteristic - ( - service_handle, - &char_uuid, - perm, - property, - &char_value, - &s_ethermind_send_size_handle - ); - } - - if (0 != retval) - { - os_printf("%s: add send size char failed. Result: 0x%04X\n", __func__, retval); - goto error; - } - else - { - bk_printf("%s second char value attr_handle %d\n", __func__, bk_ble_get_current_gatt_db_attr_handle()); - char_uuid.uuid_format = ATT_16_BIT_UUID_FORMAT; - char_uuid.uuid.uuid_16 = 0xdef0; - - perm = GATT_DB_PERM_READ | GATT_DB_PERM_WRITE; - property = GATT_DB_CHAR_READ_PROPERTY | GATT_DB_CHAR_WRITE_PROPERTY; - - char_value.val = (uint8_t *)&s_ethermind_send_intv_value; - char_value.len = sizeof(s_ethermind_send_intv_value); - char_value.actual_len = char_value.len; -#if 0 //set val len to 0 when you don't want to create buff in gatt db - char_value.val = NULL; - char_value.len = 0; - char_value.actual_len = 0; -#endif - retval = bk_ble_gatt_db_add_characteristic - ( - service_handle, - &char_uuid, - perm, - property, - &char_value, - &s_ethermind_send_intv_handle - ); - } - - if (0 != retval) - { - os_printf("%s: add send inter char failed. Result: 0x%04X\n", __func__, retval); - goto error; - } - else - { - bk_printf("%s third char value attr_handle %d\n", __func__, bk_ble_get_current_gatt_db_attr_handle()); - retval = bk_ble_gatt_db_dyn_register(); - - if (retval != 0) - { - os_printf("%s GATT Database Registration err: 0x%04X\n", __func__, retval); - goto error; - } - } - - - retval = bk_ble_gatt_db_init_pl(ethermind_test_gatt_char_handler); - - if (retval != 0) - { - os_printf("%s bk_ble_gatt_db_init_pl err: 0x%04X\n", __func__, retval); - goto error; - } - - err = 0; - - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - - - - -error: - msg = AT_CMD_RSP_ERROR; - g_test_prf_task_id = cur_test_prf_task_id; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - - -void ble_test_noti_hdl(void *param) -{ - uint8 *write_buffer; - uint8 con_idx = (uint32)param; - - ble_err_t ret = BK_ERR_BLE_SUCCESS; - write_buffer = (uint8_t *)os_malloc(s_test_data_len); - - if(!write_buffer) - { - os_printf("%s alloc err\n", __func__); - return; - } - - os_memset(write_buffer, 0, s_test_data_len); - os_memcpy(write_buffer, &s_test_noti_count, sizeof(s_test_noti_count)); - s_test_noti_count++; - - ret = bk_ble_send_noti_value(con_idx, s_test_data_len, write_buffer, g_test_prf_task_id, TEST_IDX_CHAR_VALUE); - if(ret != BK_ERR_BLE_SUCCESS) - { - os_printf("%s ret err %d\n", __func__, ret); - } - - os_free(write_buffer); -} - -static void ble_performance_tx_timer_hdl(void *param) -{ - uint32_t tmp = s_performance_tx_bytes; - s_performance_tx_bytes = 0; - - os_printf("%s current tx %d bytes/sec\n", __func__, tmp); -} - -static void ble_performance_rx_timer_hdl(void *param) -{ - uint32_t tmp = s_performance_rx_bytes; - s_performance_rx_bytes = 0; - - os_printf("%s current rx %d bytes/sec\n", __func__, tmp); -} - -static void ble_ethermind_performance_tx_timer_hdl(void *param) -{ - uint32_t tmp = s_ethermind_performance_tx_bytes; - s_ethermind_performance_tx_bytes = 0; - - os_printf("%s current tx %d bytes/sec\n", __func__, tmp); -} - -static void ble_ethermind_performance_rx_timer_hdl(void *param) -{ - uint32_t tmp = s_ethermind_performance_rx_bytes; - s_ethermind_performance_rx_bytes = 0; - - os_printf("%s current rx %d bytes/sec\n", __func__, tmp); -} - - -void ble_test_service_write_handle(uint8 val, uint8 con_idx) -{ - if (val) - { - if(s_service_type) - { - if(!s_performance_tx_enable) - { - s_performance_tx_enable = 1; - ble_test_noti_hdl((void *)((uint32)con_idx)); - } - - } - else if (!rtos_is_timer_init(&ble_noti_tmr)) - { - s_test_noti_count = 0; - rtos_init_timer(&ble_noti_tmr, s_test_send_inter, ble_test_noti_hdl, (void *)((uint32)con_idx)); - rtos_start_timer(&ble_noti_tmr); - } - } - else - { - s_performance_tx_enable = 0; - if (rtos_is_timer_init(&ble_noti_tmr)) - { - if (rtos_is_timer_running(&ble_noti_tmr)) - rtos_stop_timer(&ble_noti_tmr); - rtos_deinit_timer(&ble_noti_tmr); - } - } -} - -int ble_read_phy_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - bd_addr_t connect_addr; - uint8_t conn_idx = 0; - uint8_t addr_type = 1; - - if(bk_ble_get_controller_stack_type() != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - err = kParamErr; - goto error; - } - - if (argc > 2) { - os_printf("input param error\r\n"); - err = kParamErr; - goto error; - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - err = get_addr_from_param(&connect_addr, argv[0]); - if (err != kNoErr) - { - os_printf("input addr param error\r\n"); - err = kParamErr; - goto error; - } - - if (argc < 2) - { - os_printf("%s warning, you need input addr type\n", __func__); - } - else - { - addr_type = os_strtoul(argv[1], NULL, 10) & 0xFF; - } - - if (ble_at_cmd_table[17].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - /// get connect_idx from connect_addr - conn_idx = bk_ble_find_conn_idx_from_addr(&connect_addr); - if (conn_idx == AT_BLE_MAX_CONN) - { - os_printf("ble not connection\r\n"); - err = kNoResourcesErr; - goto error; - } - - err = bk_ble_read_phy(conn_idx, ble_at_cmd_cb); - } - else - { - err = bk_ble_hci_read_phy(&connect_addr, addr_type, ble_at_cmd_cb); - } - - if (err != kNoErr) - { - os_printf("read connect tx/rx phy failed\r\n"); - goto error; - } - - if(ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - os_printf("get sema fail\r\n"); - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - goto error; - } - } - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_set_phy_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - bd_addr_t connect_addr; - uint8_t conn_idx = 0; - ble_set_phy_t le_set_phy; - uint8_t addr_type = 1; - - if(bk_ble_get_controller_stack_type() != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - err = kParamErr; - goto error; - } - - if (argc > 5) { - os_printf("input param error\r\n"); - err = kParamErr; - goto error; - } - - if (ble_at_cmd_table[18].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - err = get_addr_from_param(&connect_addr, argv[0]); - if (err != kNoErr) - { - os_printf("input addr param error\r\n"); - err = kParamErr; - goto error; - } - - le_set_phy.tx_phy = os_strtoul(argv[1], NULL, 10) & 0xFF; - le_set_phy.rx_phy = os_strtoul(argv[2], NULL, 10) & 0xFF; - le_set_phy.phy_opt = os_strtoul(argv[3], NULL, 10) & 0xFF; - switch (le_set_phy.phy_opt) { - case 0: - le_set_phy.phy_opt = CODED_NO_PREFEER; - break; - case 1: - le_set_phy.phy_opt = CODED_S2_PREFEER; - break; - case 2: - le_set_phy.phy_opt = CODED_S8_PREFEER; - break; - default: - os_printf("input phy_opt param error\r\n"); - err = kParamErr; - goto error; - } - - if (argc < 5) - { - os_printf("%s warning, you need input addr type\n", __func__); - } - else - { - addr_type = os_strtoul(argv[4], NULL, 10) & 0xFF; - } - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - /// get connect_idx from connect_addr - conn_idx = bk_ble_find_conn_idx_from_addr(&connect_addr); - if (conn_idx == AT_BLE_MAX_CONN) - { - os_printf("ble not connection\r\n"); - err = kNoResourcesErr; - goto error; - } - - err = bk_ble_set_phy(conn_idx, &le_set_phy, ble_at_cmd_cb); - } - else - { - err = bk_ble_hci_set_phy(&connect_addr, addr_type, &le_set_phy, ble_at_cmd_cb); - } - if (err != kNoErr) - { - os_printf("set connect tx/rx phy failed\r\n"); - goto error; - } - - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - os_printf("get sema fail\r\n"); - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } else { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} -//#endif - -int ble_set_max_mtu_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - uint16_t att_max_mtu = 0; - - if(bk_ble_get_controller_stack_type() != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - err = kParamErr; - goto error; - } - - if (argc != 1) { - os_printf("input param error\r\n"); - err = kParamErr; - goto error; - } - - if (ble_at_cmd_table[26].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - att_max_mtu = os_strtoul(argv[0], NULL, 10) & 0xFF; - - err = bk_ble_set_max_mtu(att_max_mtu); - if (err != kNoErr) { - os_printf("set att maximal MTU failed\r\n"); - goto error; - } - - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - os_printf("get sema fail\r\n"); - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } else { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - - -int ble_delete_adv_activity_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - int actv_idx = 0; - - if (ble_at_cmd_table[19].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_ADV_CREATED); - if (actv_idx == AT_BLE_MAX_ACTV) - { - os_printf("\n adv activity has not been created!\n"); - err = kNotFoundErr; - goto error; - } - - err = bk_ble_delete_advertising(actv_idx, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_delete_scan_activity_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - int actv_idx = 0; - - if (ble_at_cmd_table[20].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_SCAN_CREATED); - if (actv_idx == AT_BLE_MAX_ACTV) - { - os_printf("\n scan activity has not been created!\n"); - err = kNotFoundErr; - goto error; - } - - err = bk_ble_delete_scaning(actv_idx, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_connect_by_name_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint8_t actv_idx = 0; - ble_conn_param_t conn_param; - int err = kNoErr; - uint8_t central_count = 0; - - if(!bk_ble_if_support_central(¢ral_count) || central_count == 0) - { - os_printf("not support central\n"); - err = kParamErr; - goto error; - } - - - if (argc != 5) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - conn_param.intv_min = os_strtoul(argv[0], NULL, 16) & 0xFFFF; - conn_param.con_latency = os_strtoul(argv[1], NULL, 16) & 0xFFFF; - if (conn_param.intv_min < CON_INTERVAL_MIN || conn_param.intv_min > CON_INTERVAL_MAX - || conn_param.con_latency > CON_LATENCY_MAX) - { - err = kParamErr; - goto error; - } - conn_param.intv_max = conn_param.intv_min; - - conn_param.sup_to = os_strtoul(argv[2], NULL, 16) & 0xFFFF; - if (conn_param.sup_to < CON_SUP_TO_MIN || conn_param.sup_to > CON_SUP_TO_MAX) - { - err = kParamErr; - goto error; - } - - conn_param.init_phys = os_strtoul(argv[3], NULL, 16) & 0xFF; - if (conn_param.init_phys > (PHY_1MBPS_BIT | PHY_2MBPS_BIT | PHY_CODED_BIT)) - { - err = kParamErr; - goto error; - } - - os_memset(&g_peer_dev, 0, sizeof(g_peer_dev)); - - g_peer_dev.dev.len = os_strlen(argv[4]); - os_memcpy(g_peer_dev.dev.name, argv[4], g_peer_dev.dev.len); - os_printf("%s %s\r\n", __func__, g_peer_dev.dev.name); - g_peer_dev.state = STATE_DISCOVERING; - - if (err != kNoErr) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - if ((10 * conn_param.sup_to) < (((1 + conn_param.con_latency) * conn_param.intv_min * 5 + 1) >> 1)) - { - os_printf("input param not suitable, maybe you can set con_latency to 0\n"); - err = kParamErr; - goto error; - } - - if (ble_at_cmd_table[28].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - if (ble_at_cmd_sema != NULL) - { - err = rtos_get_semaphore(&ble_at_cmd_sema, 10000); - if(err != kNoErr) { - goto error; - } else { - if (g_peer_dev.state == STATE_DISCOVERED) - { - g_peer_dev.state = STATE_CONNECTINIG; - } - else - { - err = BK_ERR_BLE_FAIL; - goto error; - } - } - } - /*actv_idx = bk_ble_find_master_state_idx_handle(AT_INIT_STATE_CREATED); - if (actv_idx == AT_BLE_MAX_CONN)*/ - { - /// Do not create actv - actv_idx = bk_ble_get_idle_conn_idx_handle(); - if (actv_idx == UNKNOW_ACT_IDX) - { - err = kNoResourcesErr; - goto error; - } - - err = bk_ble_create_init(actv_idx, &conn_param, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - err = ble_start_connect_handle(actv_idx, g_peer_dev.addr_type, &(g_peer_dev.bdaddr), ble_at_cmd_cb); - if (err != kNoErr) - goto error; - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - /* else - { - /// have created actv, this happend in which connection have been disconnected - err = ble_start_connect_handle(actv_idx, g_peer_dev.addr_type, &(g_peer_dev.bdaddr), ble_at_cmd_cb); - if (err != kNoErr) - goto error; - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - */ - }else - { - ble_scan_param_t scan_param; - scan_param.own_addr_type = BLE_STATIC_ADDR; - scan_param.scan_phy = PHY_1MBPS_BIT; - scan_param.scan_intv = 0x64; - scan_param.scan_wd = 0x1e; - - uint8_t filt_duplicate = 0; - uint16_t duration = 0; - uint16_t period = 10; - - - if(ble_at_cmd_sema != NULL) - { - err = bk_ble_set_scan_parameters(scan_param.own_addr_type, 0x00, scan_param.scan_phy, scan_param.scan_intv, scan_param.scan_wd, ble_at_cmd_cb); - os_printf("%s set scan param\r\n", __func__); - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - err = bk_ble_set_scan_enable_extended(1, filt_duplicate, duration, period, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - - if(err != kNoErr) - { - goto error; - } - os_printf("%s start scan\r\n", __func__); - - rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - - if(g_peer_dev.state == STATE_DISCOVERED) - { - bk_ble_set_scan_enable_extended(0, filt_duplicate, duration, period, ble_at_cmd_cb); - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - os_printf("%s stop scan\r\n", __func__); - - ble_conn_param_normal_t tmp; - - tmp.conn_interval_min = conn_param.intv_min; - tmp.conn_interval_max = conn_param.intv_max; - tmp.conn_latency = conn_param.con_latency; - tmp.supervision_timeout = conn_param.sup_to; - tmp.initiating_phys = conn_param.init_phys; - - tmp.peer_address_type = g_peer_dev.addr_type; - os_memcpy(tmp.peer_address.addr, &(g_peer_dev.bdaddr.addr[0]), BK_BLE_GAP_BD_ADDR_LEN); - os_printf("%s start conn, peer addr: %x %x %x %x %x %x\r\n", __func__, tmp.peer_address.addr[0], tmp.peer_address.addr[1], - tmp.peer_address.addr[2],tmp.peer_address.addr[3],tmp.peer_address.addr[4],tmp.peer_address.addr[5]); - g_peer_dev.state = STATE_CONNECTINIG; - - err = bk_ble_create_connection(&tmp, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) - { - goto error; - } - else - { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - goto error; - } - } - }else - { - os_printf("%s SCAN Timeout %d\r\n", __func__, g_peer_dev.state); - bk_ble_set_scan_enable_extended(0, filt_duplicate, duration, period, ble_at_cmd_cb); - goto error; - } - } - - } - -error: - msg = AT_CMD_RSP_ERROR; - g_peer_dev.state = STATE_IDLE; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_disconnect_by_name_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - uint8_t conn_idx; - uint8_t central_count = 0; - ble_device_name_t dev; - - if(!bk_ble_if_support_central(¢ral_count) || central_count == 0) - { - os_printf("not support central\n"); - err = kParamErr; - goto error; - } - - if (argc != 1) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - os_memset(&dev, 0, sizeof(dev)); - - dev.len = os_strlen(argv[0]); - os_memcpy(dev.name, argv[0], dev.len); - - if (!((STATE_CONNECTED == g_peer_dev.state) && (dev.len == g_peer_dev.dev.len) && (!os_memcmp(g_peer_dev.dev.name, dev.name, dev.len)))) - { - err = kParamErr; - goto error; - } - - if (ble_at_cmd_table[29].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - /// get connect_idx from connect_addr - conn_idx = bk_ble_find_conn_idx_from_addr(&g_peer_dev.bdaddr); - if (conn_idx == AT_BLE_MAX_CONN) - { - os_printf("ble not connection\n"); - err = kNoResourcesErr; - goto error; - } - - g_peer_dev.state = STATE_DISCONNECTINIG; - - err = bk_ble_disconnect(conn_idx, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - }else - { - g_peer_dev.state = STATE_DISCONNECTINIG; - err = bk_ble_disconnect_connection(&g_peer_dev.bdaddr, g_peer_dev.addr_type, ble_at_cmd_cb); - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - - - -int ble_create_periodic_sync_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - uint8_t actv_idx = 0; - - if (ble_at_cmd_table[30].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_PER_SYNC_CREATED); - if (actv_idx == AT_BLE_MAX_ACTV) - { - actv_idx = bk_ble_get_idle_actv_idx_handle(); - if (actv_idx == UNKNOW_ACT_IDX) - { - err = kNoResourcesErr; - goto error; - } - } - - err = bk_ble_create_periodic_sync(actv_idx, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -int ble_start_periodic_sync_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint8_t actv_idx = 0; - - int err = kNoErr; - - ble_periodic_param_t periodic_param; - - if (argc < 7) - { - os_printf("\nThe number of param is wrong!\n"); - err = kParamErr; - goto error; - } - - os_memset(&periodic_param, 0, sizeof(periodic_param)); - - periodic_param.report_disable = os_strtoul(argv[0], NULL, 16) & 0xFF; - periodic_param.adv_sid = os_strtoul(argv[1], NULL, 16) & 0xFF; - - err = get_addr_from_param(&periodic_param.adv_addr, argv[2]); - if (err != kNoErr) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - periodic_param.adv_addr_type = os_strtoul(argv[3], NULL, 16) & 0xFF; - periodic_param.skip = os_strtoul(argv[4], NULL, 16) & 0xFF; - periodic_param.sync_to = os_strtoul(argv[5], NULL, 16) & 0xFF; - periodic_param.cte_type = os_strtoul(argv[6], NULL, 16) & 0xFF; - - - - if (1) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - bk_ble_set_notice_cb(ble_at_notice_cb); - - - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_PER_SYNC_CREATED); - - - if (actv_idx == AT_BLE_MAX_ACTV) - { - os_printf("periodic not create before\n"); - err = kNoResourcesErr; - goto error; - } - - err = bk_ble_start_periodic_sync(actv_idx, &periodic_param, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - - -int ble_stop_periodic_sync_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint8_t actv_idx = 0; - - int err = kNoErr; - - bd_addr_t addr; - - if (argc < 1) - { - os_printf("\nThe number of param is wrong!\n"); - err = kParamErr; - goto error; - } - - err = get_addr_from_param(&addr, argv[0]); - if (err != kNoErr) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - if (1) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - - actv_idx = bk_ble_find_actv_state_idx_handle(AT_ACTV_PER_SYNC_STARTED); - - if (actv_idx == AT_BLE_MAX_ACTV) - { - os_printf("periodic not start before\n"); - err = kNoResourcesErr; - goto error; - } - - err = bk_ble_stop_periodic_sync(actv_idx, ble_at_cmd_cb); - - if (err != BK_ERR_BLE_SUCCESS) - goto error; - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - - -#if 0 -void s_ble_update_param_callback(MASTER_COMMON_TYPE type, uint8 conidx, void *param) -{ - switch(type) - { - case MST_TYPE_UPP_ASK: - { - struct mst_comm_updata_para *tmp = (typeof(tmp))param; - os_printf("%s MST_TYPE_UPP_ASK accept\n", __func__); - tmp->is_agree = 0; - } - break; - - default: - break; - } -} - -int ble_update_param_reply_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = AT_CMD_RSP_SUCCEED; - - int err = kNoErr; -#if 0 - uint8_t con_idx = 0; - uint8_t accept = 0; - - if(bk_ble_get_controller_stack_type() != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - err = kParamErr; - goto error; - } - - if (argc != 2) { - os_printf("input param error\r\n"); - err = kParamErr; - goto error; - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - - bk_ble_register_app_sdp_common_callback(s_ble_update_param_callback); - - con_idx = os_strtoul(argv[0], NULL, 10) & 0xFF; - accept = os_strtoul(argv[0], NULL, 10) & 0xFF; - - //err = ble_param_update_reply(con_idx, accept); - if (err != kNoErr) { - os_printf("set update param reply failed\r\n"); - msg = AT_CMD_RSP_ERROR; - goto error; - } - - - -error: -#endif - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} -#endif - -int ble_att_write_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - - char tmp_buf[3] = {0}; - // int scanf_ret = 0; - uint8_t data_count = 0; - int8_t i = 0; - - uint8_t conn_handle = 0; - ATT_ATTR_HANDLE attr_handle = 0; - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - err = kParamErr; - goto error; - } - - if (argc < 3) - { - os_printf("\nThe number of param is wrong!\n"); - err = kParamErr; - goto error; - } - - //att_handle.device_id = os_strtoul(argv[0], NULL, 10) & 0xFF; - conn_handle = os_strtoul(argv[0], NULL, 10) & 0xFF; - attr_handle = os_strtoul(argv[1], NULL, 10) & 0xFFFF; - - if(strlen(argv[2]) > sizeof(send_value) * 2) - { - os_printf("\nThe number of data is wrong!\n"); - err = kParamErr; - goto error; - } - - for (i = strlen(argv[2]) - 2, data_count = 0; i >= 0; i -= 2, data_count++) - { - os_memset(tmp_buf, 0, sizeof(tmp_buf)); - os_memcpy(tmp_buf, argv[2] + i, 2); - - send_value[data_count] = os_strtoul(tmp_buf, NULL, 10) & 0xFF; - } - os_printf("%s %d %d %d\n", __func__, conn_handle, attr_handle, data_count); - - err = bk_ble_att_write(conn_handle, attr_handle, send_value, data_count); - - if (err != BK_ERR_BLE_SUCCESS) - { - goto error; - } - else - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -static int ble_att_read_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - int err = kNoErr; - char *msg = NULL; - ATT_HANDLE att_handle; - - if(bk_ble_get_host_stack_type() != BK_BLE_HOST_STACK_TYPE_ETHERMIND) - { - err = kParamErr; - goto error; - } - - if (argc < 3) - { - os_printf("\nThe number of param is wrong!\n"); - err = kParamErr; - goto error; - } - - //uint8_t conn_handle = 0; - - att_handle.device_id = os_strtoul(argv[0], NULL, 10) & 0xFF; - att_handle.att_id = os_strtoul(argv[1], NULL, 10) & 0xFF; - s_read_tmp_attr_handle = os_strtoul(argv[2], NULL, 10) & 0xFFFF; -// os_printf("%s %d %d %d\n", __func__, att_handle.device_id, att_handle.att_id, attr_handle); - - if (ble_at_cmd_table[37].is_sync_cmd) - { - err = rtos_init_semaphore(&ble_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - bk_ble_set_notice_cb(ble_at_notice_cb); - - bk_ble_att_read(att_handle.att_id, s_read_tmp_attr_handle); - - if(ble_at_cmd_sema != NULL) { - err = rtos_get_semaphore(&ble_at_cmd_sema, AT_SYNC_CMD_TIMEOUT_MS); - if(err != kNoErr) { - goto error; - } else { - if (at_cmd_status == BK_ERR_BLE_SUCCESS) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - rtos_deinit_semaphore(&ble_at_cmd_sema); - return 0; - } - else - { - err = at_cmd_status; - goto error; - } - } - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (ble_at_cmd_sema != NULL) - rtos_deinit_semaphore(&ble_at_cmd_sema); - return err; -} - -static void ble_plr_sdp_comm_callback(MASTER_COMMON_TYPE type,uint8 conidx,void *param) -{ - if (MST_TYPE_ATT_UUID == type) - { - struct ble_sdp_char_inf *char_inf = (struct ble_sdp_char_inf*)param; - - if ((!os_memcmp(char_inf->uuid, nus_tx_uuid, 16)) && (conidx < AT_BLE_MAX_CONN)) - { - plc_ccc_handle[conidx] = char_inf->val_hdl + 1; - } - - if ((!os_memcmp(char_inf->uuid, nus_rx_uuid, 16)) && (conidx < AT_BLE_MAX_CONN)) - { - plc_rx_handle[conidx] = char_inf->val_hdl; - } - } - - if (MST_TYPE_SDP_END == type) - { - bk_ble_gatt_mtu_change(conidx, NULL); - } - - if(type == MST_TYPE_UPP_ASK) - { - struct mst_comm_updata_para *tmp = (typeof(tmp))param; - os_printf("%s MST_TYPE_UPP_ASK accept\n", __func__); - tmp->is_agree = 1; - } - -} - -static void ble_plr_sdp_charac_callback(CHAR_TYPE type,uint8 conidx,uint16_t hdl,uint16_t len,uint8 *data) -{ - if (CHARAC_NOTIFY == type) - { - //os_printf("con %d , len : %d, recv data %s\n", conidx, len, data); - //bk_ble_gatt_write_value(conidx, plc_rx_handle[conidx], len, data); -#ifdef CONFIG_ALI_MQTT - if (loop_type == LT_COEX) - { - ble_send_data_2_mqtt(conidx, len, data); - } - else - { - bk_ble_gatt_write_value(conidx, plc_rx_handle[conidx], len, data); - } -#else - bk_ble_gatt_write_value(conidx, plc_rx_handle[conidx], len, data); -#endif - - } - else if (CHARAC_WRITE_DONE == type) - { - //os_printf("con %d\n", conidx); - } -} - -int ble_enable_packet_loss_ratio_test_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - int err = kNoErr; - char *msg = NULL; - uint8_t cmd = 0; - - if(bk_ble_get_controller_stack_type() != BK_BLE_CONTROLLER_STACK_TYPE_BTDM_5_2) - { - err = kParamErr; - goto error; - } - - if (argc < 1) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - cmd = os_strtoul(argv[0], NULL, 10) & 0xFF; - - if (cmd == 0) - { - if(BK_BLE_HOST_STACK_TYPE_ETHERMIND != bk_ble_get_host_stack_type()) - { - for (uint8_t j = 0; j < AT_BLE_MAX_CONN; j++) - { - if (plc_ccc_handle[j]) - { - bk_ble_gatt_write_ccc(j, plc_ccc_handle[j], 0x00); - } - else - { - os_printf("the %dth conn is not connected\n", j); - } - } - } - else - { - const uint16_t noti_enable = 0; - for(uint8_t i = 0; i < sizeof(s_ethermind_nordic_att_info) / sizeof(s_ethermind_nordic_att_info[0]); i++) - { - if(s_ethermind_nordic_used[i]) - { - bk_ble_att_write(s_ethermind_nordic_att_info[i], s_ethermind_nordic_write_notify_handle[i], (uint8_t *)¬i_enable, sizeof(noti_enable)); - } - - } - } - } - else if (cmd == 1) - { - if(BK_BLE_HOST_STACK_TYPE_ETHERMIND != bk_ble_get_host_stack_type()) - { - os_memset(plc_ccc_handle, 0, sizeof(plc_ccc_handle)); - os_memset(plc_rx_handle, 0, sizeof(plc_ccc_handle)); - bk_ble_register_app_sdp_common_callback(ble_plr_sdp_comm_callback); - bk_ble_register_app_sdp_charac_callback(ble_plr_sdp_charac_callback); - } - } - else if(cmd == 2) - { - if (argc < 4) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - uint16_t data_cnt = os_strtoul(argv[1], NULL, 10) & 0xFFFF; - uint32_t interval = os_strtoul(argv[2], NULL, 10); - uint16_t data_len = os_strtoul(argv[3], NULL, 10) & 0xFFFF; - uint8_t cmd[10] = {0x5a,0xa5,0,0}; - os_memcpy(&cmd[2], &data_cnt, sizeof(data_cnt)); - os_memcpy(&cmd[4], &interval, sizeof(interval)); - os_memcpy(&cmd[8], &data_len, sizeof(data_len)); - if(BK_BLE_HOST_STACK_TYPE_ETHERMIND != bk_ble_get_host_stack_type()) - { - for (uint8_t j =0;jmsg; - - switch (msg->event_type) { - case IOTX_MQTT_EVENT_UNDEF: - os_printf("undefined event occur.\n"); - break; - - case IOTX_MQTT_EVENT_DISCONNECT: - os_printf("MQTT disconnect.\n"); - break; - - case IOTX_MQTT_EVENT_RECONNECT: - os_printf("MQTT reconnect.\n"); - break; - - case IOTX_MQTT_EVENT_SUBCRIBE_SUCCESS: - os_printf("subscribe success, packet-id=%u.\n", (unsigned int)packet_id); - break; - - case IOTX_MQTT_EVENT_SUBCRIBE_TIMEOUT: - os_printf("subscribe wait ack timeout, packet-id=%u.\n", (unsigned int)packet_id); - break; - - case IOTX_MQTT_EVENT_SUBCRIBE_NACK: - os_printf("subscribe nack, packet-id=%u.\n", (unsigned int)packet_id); - break; - - case IOTX_MQTT_EVENT_UNSUBCRIBE_SUCCESS: - os_printf("unsubscribe success, packet-id=%u.\n", (unsigned int)packet_id); - break; - - case IOTX_MQTT_EVENT_UNSUBCRIBE_TIMEOUT: - os_printf("unsubscribe timeout, packet-id=%u.\n", (unsigned int)packet_id); - break; - - case IOTX_MQTT_EVENT_UNSUBCRIBE_NACK: - os_printf("unsubscribe nack, packet-id=%u.\n", (unsigned int)packet_id); - break; - - case IOTX_MQTT_EVENT_PUBLISH_SUCCESS: - os_printf("publish success, packet-id=%u.\n", (unsigned int)packet_id); - break; - - case IOTX_MQTT_EVENT_PUBLISH_TIMEOUT: - os_printf("publish timeout, packet-id=%u.\n", (unsigned int)packet_id); - break; - - case IOTX_MQTT_EVENT_PUBLISH_NACK: - os_printf("publish nack, packet-id=%u.\n", (unsigned int)packet_id); - break; - - case IOTX_MQTT_EVENT_PUBLISH_RECVEIVED: -#if 0 - iotx_mqtt_topic_info_pt topic_info = (iotx_mqtt_topic_info_pt)msg->msg; - os_printf("topic message arrived but without any related handle:\n"); - os_printf(" topic=%.*s,\n", - topic_info->topic_len, - topic_info->ptopic); - os_printf(" topic_msg=%.*s.\n", - topic_info->payload_len, - topic_info->payload); -#endif - break; - - default: - os_printf("Should NOT arrive here.\n"); - break; - } -} - -#define REQ_TIMEOUT_MS (5000) -#define TRX_BUF_SIZE (7*1024) - -void *ble_mqtt_open(const char *host_name, const char *username, - const char *password) -{ - iotx_conn_info_pt pconn_info; - iotx_mqtt_param_t mqtt_params; - - if (ble_mqtt_loop_tx_buffer == NULL) - { - ble_mqtt_loop_tx_buffer = (char *)os_malloc(TRX_BUF_SIZE); - - if (ble_mqtt_loop_tx_buffer == NULL) - { - os_printf("not enough memory for ble_mqtt_loop_tx_buffer\n"); - goto error; - } - } - - if (ble_mqtt_loop_rx_buffer == NULL) - { - ble_mqtt_loop_rx_buffer = (char *)os_malloc(TRX_BUF_SIZE); - - if (ble_mqtt_loop_rx_buffer == NULL) - { - os_printf("not enough memory for ble_mqtt_loop_rx_buffer\n"); - goto error; - } - } - - /* Device AUTH */ - if (0 != IOT_SetupConnInfo(PRODUCT_KEY, DEVICE_NAME, DEVICE_SECRET, (void **)&pconn_info)) { - os_printf("AUTH request failed!\n"); - goto error; - } - - os_snprintf(pconn_info->host_name, sizeof(pconn_info->host_name)-1, "%s", host_name); - os_snprintf(pconn_info->username, sizeof(pconn_info->username)-1, "%s", username); - os_snprintf(pconn_info->password, sizeof(pconn_info->password)-1, "%s", password); - - /* Initialize MQTT parameter */ - memset(&mqtt_params, 0x0, sizeof(mqtt_params)); - - mqtt_params.port = pconn_info->port; - mqtt_params.host = pconn_info->host_name; - mqtt_params.client_id = pconn_info->client_id; - mqtt_params.username = pconn_info->username; - mqtt_params.password = pconn_info->password; - mqtt_params.pub_key = pconn_info->pub_key; - - mqtt_params.request_timeout_ms = REQ_TIMEOUT_MS; - mqtt_params.clean_session = 0; - mqtt_params.keepalive_interval_ms = 60000; - mqtt_params.pread_buf = ble_mqtt_loop_rx_buffer; - mqtt_params.read_buf_size = TRX_BUF_SIZE; - mqtt_params.pwrite_buf = ble_mqtt_loop_tx_buffer; - mqtt_params.write_buf_size = TRX_BUF_SIZE; - - mqtt_params.handle_event.h_fp = ble_mqtt_loop_event_handle; - mqtt_params.handle_event.pcontext = NULL; - - - /* Construct a MQTT client with specify parameter */ - return IOT_MQTT_Construct(&mqtt_params); - - -error: - - if (ble_mqtt_loop_rx_buffer) - { - os_free(ble_mqtt_loop_rx_buffer); - ble_mqtt_loop_rx_buffer = NULL; - } - - if (ble_mqtt_loop_tx_buffer) - { - os_free(ble_mqtt_loop_tx_buffer); - ble_mqtt_loop_tx_buffer = NULL; - } - - return NULL; -} - -enum -{ - COEX_DEMO_MSG_NULL = 0, - COEX_DEMO_MSG_TX = 0, -}; - -typedef struct -{ - uint8_t type; - uint16_t len; - char *data; -} coex_demo_msg_t; - -beken_queue_t coex_demo_msg_que = NULL; -beken_thread_t coex_demo_thread_handle = NULL; -#define COEX_DEMO_MSG_COUNT (30) - -static void ble_send_data_2_mqtt(uint8 con_idx, uint16_t len, uint8 *data) -{ - coex_demo_msg_t demo_msg; - char msg_pub[350] = {0}; - int rc = -1; - - os_memset(&demo_msg, 0x0, sizeof(coex_demo_msg_t)); - //os_memset(msg_pub, 0, sizeof(msg_pub)); - if (coex_demo_msg_que == NULL) - return; - - /* Generate topic message */ - int msg_len = snprintf(msg_pub, sizeof(msg_pub), "{\"link_id\":\"%d\", \"rev_len\":\"%d\", \"rev_data\":\"", con_idx, len); - if (msg_len < 0) { - os_printf("Error occur! Exit program.\n"); - } - - //os_printf("%s len %d msg_len1 %d %p %s\n", __func__, len, msg_len, &msg_len, msg_pub); - os_memcpy(&msg_pub[msg_len], data, len); - msg_len += len; - - msg_pub[msg_len++] = '"'; - msg_pub[msg_len++] = '}'; - - //os_printf("total msg_len = %d\n",msg_len); - - demo_msg.data = (char *) os_malloc(msg_len); - if (demo_msg.data == NULL) - { - os_printf("%s, malloc failed\r\n", __func__); - return; - } - - os_memcpy(demo_msg.data, msg_pub, msg_len); - demo_msg.type = COEX_DEMO_MSG_TX; - demo_msg.len = msg_len; - - rc = rtos_push_to_queue(&coex_demo_msg_que, &demo_msg, BEKEN_NO_WAIT); - if(kNoErr != rc) - { - os_printf("%s, send queue failed\r\n",__func__); - if (demo_msg.data) - { - os_free(demo_msg.data); - } - } -} - -static void ble_mqtt_loop_recv_handle(void *pcontext, void *pclient, iotx_mqtt_event_msg_pt msg) -{ - //iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt) msg->msg; - if (loop_type == LT_WIFI_ONLY) - { - os_printf("ble mqtt loop recv %d\n", loop_sr_index++); - } - else if (loop_type == LT_COEX) - { - iotx_mqtt_topic_info_pt ptopic_info = (iotx_mqtt_topic_info_pt) msg->msg; - uint16_t vaild_len = 0; - uint8_t con_idx = 0; - uint8_t *data = NULL; - char *pos = NULL; - - pos = os_strstr(ptopic_info->payload, "link_id"); - if (pos) - { - con_idx = atoi(pos + os_strlen("link_id") + 3); - } - - pos = os_strstr(ptopic_info->payload, "rev_len"); - if (pos) - { - vaild_len = atoi(pos + os_strlen("rev_len") + 3); - } - - //os_printf("ble mqtt recv payload_len %d, vaild_len %d, con_idx %d\n", ptopic_info->payload_len, vaild_len, con_idx); - - if (ptopic_info->payload_len > vaild_len) - { - pos = os_strstr(ptopic_info->payload, "rev_data"); - if (pos) - { - data = (uint8_t *)pos + os_strlen("rev_data") + 3; - //os_printf("recv data[0] %c\n", data[0]); - if(BK_BLE_HOST_STACK_TYPE_ETHERMIND != bk_ble_get_host_stack_type()) - { - bk_ble_gatt_write_value(con_idx, plc_rx_handle[con_idx], vaild_len, data); - } - else - { - uint8_t index = 0; - if(0 == ethermind_find_index_by_att_con_id(&index, con_idx)) - { - os_printf("%s ATT_CON_ID %d, send data to nordic %s\n", __func__, - s_ethermind_nordic_att_info[index], - data); - - - bk_ble_att_write(s_ethermind_nordic_att_info[index], s_ethermind_nordic_write_attr_handle[index], data, vaild_len); - } - else - { - os_printf("%s cant find att_id %d\n", __func__, con_idx); - } - } - - } - } - - } -} - -#if CONFIG_ARCH_RISCV -extern u64 riscv_get_mtimer(void); -#endif -void coex_demo_main(void *arg) -{ -#if CONFIG_ARCH_RISCV - uint64_t current_delay_max = 0; - uint8_t packet_sent_count = 0; -#endif - while (1) { - bk_err_t err; - coex_demo_msg_t msg; - - err = rtos_pop_from_queue(&coex_demo_msg_que, &msg, BEKEN_WAIT_FOREVER); - if (kNoErr == err) - { - switch (msg.type) { - case COEX_DEMO_MSG_TX: - { - int rc = -1; - iotx_mqtt_topic_info_t topic_msg; -#if CONFIG_ARCH_RISCV - uint64_t current_time_begin,current_time_end, current_delay = 0; -#endif - /* Initialize topic information */ - os_memset(&topic_msg, 0x0, sizeof(iotx_mqtt_topic_info_t)); - - topic_msg.qos = IOTX_MQTT_QOS0; - topic_msg.retain = 0; - topic_msg.dup = 0; - topic_msg.payload = (void *)msg.data; - topic_msg.payload_len = msg.len; -#if CONFIG_ARCH_RISCV - //bk_gpio_pull_up(GPIO_2); - current_time_begin = riscv_get_mtimer(); -#endif - rc = IOT_MQTT_Publish(ble_mqtt_loop_client, loop_topic_ci, &topic_msg); - if (rc < 0) - { - os_printf("error occur when publish.\n"); - } - else - { - //os_printf("packet-id=%u, publish topic msg=%s.\n", (uint32_t)rc, msg.data); - } - os_free(msg.data); -#if CONFIG_ARCH_RISCV - current_time_end = riscv_get_mtimer(); - current_delay = current_time_end - current_time_begin; - - if (current_delay > current_delay_max) - { - current_delay_max = current_delay; - } - packet_sent_count++; - if (packet_sent_count >= 10) - { - os_printf("mqtt pulish max delay %ld us.\n",(u32)(current_delay_max/26)); - packet_sent_count = 0; - current_delay_max = 0; - } -#endif - //bk_gpio_pull_down(GPIO_2); - } - break; - default: - break; - } - } - } - - rtos_deinit_queue(&coex_demo_msg_que); - coex_demo_msg_que = NULL; - coex_demo_thread_handle = NULL; - rtos_delete_thread(NULL); -} - -int coex_demo_task_init(void) -{ - bk_err_t ret = BK_OK; - if ((!coex_demo_thread_handle) && (!coex_demo_msg_que)) - { - ret = rtos_init_queue(&coex_demo_msg_que, - "coex_demo_msg_que", - sizeof(coex_demo_msg_t), - COEX_DEMO_MSG_COUNT); - if (ret != kNoErr) { - os_printf("coex demo msg queue failed \r\n"); - return BK_FAIL; - } - - ret = rtos_create_thread(&coex_demo_thread_handle, - BEKEN_DEFAULT_WORKER_PRIORITY, - "coex_demo", - (beken_thread_function_t)coex_demo_main, - 4096, - (beken_thread_arg_t)0); - if (ret != kNoErr) { - os_printf("coex demo task fail \r\n"); - rtos_deinit_queue(&coex_demo_msg_que); - coex_demo_msg_que = NULL; - coex_demo_thread_handle = NULL; - } - - return kNoErr; - } - else - { - return kInProgressErr; - } -} - -int ble_mqtt_loop_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - int err = kNoErr, i; - char *msg = NULL; - - for (i = 0; i < argc; i++) - { - os_printf("arg[%d]: %s\n", i, argv[i]); - } - - if (loop_topic_ci == NULL) - { - loop_topic_ci = os_malloc(25); - os_memset(loop_topic_ci, 0, 25); - } - - if (loop_topic_sr == NULL) - { - loop_topic_sr = os_malloc(25); - os_memset(loop_topic_sr, 0, 25); - } - - - if (!strcmp(argv[0], "connect")) - { - ble_mqtt_loop_client = ble_mqtt_open(argv[1], argv[2], argv[3]); - - if (ble_mqtt_loop_client == NULL) - { - os_printf("MQTT connect failed\n"); - goto error; - } - else - { - os_printf("MQTT connect success\n"); - } - } - - if (!strcmp(argv[0], "wifi")) - { - if (ble_mqtt_loop_client == NULL) - { - os_printf("MQTT client was not init\n"); - goto error; - } - - if (mqtt_loop_timer == NULL) - { - mqtt_loop_timer = (beken_timer_t*)os_malloc(sizeof(beken_timer_t)); - } - - uint8_t sta_mac[6]; - bk_wifi_sta_get_mac((uint8_t *)sta_mac); - sta_mac[5] += 1; - - snprintf(loop_topic_sr, 25, "/ble/lpsr/%02x%02x%02x", sta_mac[3], sta_mac[4], sta_mac[5]); - snprintf(loop_topic_ci, 25, "/ble/lpci/%02x%02x%02x", sta_mac[3], sta_mac[4], sta_mac[5]); - - loop_interval = os_strtoul(argv[1], NULL, 10) & 0xFFFF; - loop_count = os_strtoul(argv[2], NULL, 10) & 0xFFFF; - loop_type = LT_WIFI_ONLY; - - loop_sr_index = 0; - loop_ci_index = 0; - - os_printf("WIFI only test, interval: %u, count: %u\n", loop_interval, loop_count); - os_printf("topic: %s:%s\n", loop_topic_sr, loop_topic_ci); - - if (IOT_MQTT_Subscribe(ble_mqtt_loop_client, loop_topic_sr, IOTX_MQTT_QOS0, ble_mqtt_loop_recv_handle, NULL) < 0) { - - os_printf("IOT_MQTT_Subscribe() TOPIC_CMD failed\n"); - } - - - if (!rtos_is_timer_init(mqtt_loop_timer)) - { - rtos_init_timer(mqtt_loop_timer, loop_interval, mqtt_loop_timer_callback, NULL); - rtos_start_timer(mqtt_loop_timer); - } - } - - if (!strcmp(argv[0], "stop")) - { - if (loop_topic_sr != NULL && ble_mqtt_loop_client != NULL) - { - IOT_MQTT_Unsubscribe(ble_mqtt_loop_client, loop_topic_sr); - os_printf("UnSubscribe\n"); - } - - if (mqtt_loop_timer != NULL) - { - rtos_stop_timer(mqtt_loop_timer); - os_free(mqtt_loop_timer); - mqtt_loop_timer = NULL; - } - - } - - if (!os_strcmp(argv[0], "coex")) - { - if (ble_mqtt_loop_client == NULL) - { - os_printf("MQTT client was not init\n"); - goto error; - } - - loop_type = LT_COEX; - - uint8_t sta_mac[6]; - bk_wifi_sta_get_mac((uint8_t *)sta_mac); - sta_mac[5] += 1; - - snprintf(loop_topic_sr, 25, "/ble/lpsr/%02x%02x%02x", sta_mac[3], sta_mac[4], sta_mac[5]); - snprintf(loop_topic_ci, 25, "/ble/lpci/%02x%02x%02x", sta_mac[3], sta_mac[4], sta_mac[5]); - - loop_sr_index = 0; - loop_ci_index = 0; - - os_printf("topic: %s:%s", loop_topic_sr, loop_topic_ci); - - if (IOT_MQTT_Subscribe(ble_mqtt_loop_client, loop_topic_sr, IOTX_MQTT_QOS0, ble_mqtt_loop_recv_handle, NULL) < 0) - { - os_printf("IOT_MQTT_Subscribe() TOPIC_CMD failed\n"); - } - - coex_demo_task_init(); - } - - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} -#endif - -int ble_power_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - int err = kNoErr; - char *msg = NULL; - - if (argc < 1) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - if (os_strcmp(argv[0], "1") == 0) - { - bk_ble_init(); - } - else if (os_strcmp(argv[0], "0") == 0) - { - bk_ble_deinit(); - } - - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} - -#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/at/src/bt_at_command.c b/bk7235/liteos_m/bk_sdk_armino/components/at/src/bt_at_command.c deleted file mode 100755 index e1130d6..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/at/src/bt_at_command.c +++ /dev/null @@ -1,539 +0,0 @@ -/* -// Copyright (C) 2022 Beken Corporation - * 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 -#include -#include "at_common.h" -#include -#include "modules/bt.h" -#include "modules/bt_types.h" -#include "ethermind_export/bt_defines.h" - -#if CONFIG_BT -#include "bt_include.h" -#endif - -#define INQUIRY_LAP 0x9e8B33U -#define INQUIRY_LEN 0x0A - -#define CONNECTION_PACKET_TYPE 0xcc18 -#define CONNECTION_PAGE_SCAN_REPETITIOIN_MODE 0x01 -#define CONNECTION_CLOCK_OFFSET 0x00 - -#define DISCONNECT_REASON 0x16 - -#define SPP_HANDLE_INVALID 0xFFU -#define PRINT_FUNC os_printf("%s \n", __func__) -#define SPP_ENABLE_DATA_CNF_LOG - -#define BT_DEVICE_ADDR_ONLY_FRMT_SPECIFIER\ - "ADDR: %02X:%02X:%02X:%02X:%02X:%02X" -#define BT_DEVICE_ADDR_ONLY_SPACED_FRMT_SPECIFIER\ - "ADDR: %02X %02X %02X %02X %02X %02X" -#define BT_DEVICE_ADDR_ONLY_PRINT_STR(ref)\ - (ref)[0U],(ref)[1U],(ref)[2U],(ref)[3U],(ref)[4U],(ref)[5U] -#define BT_DEVICE_ADDR_FRMT_SPECIFIER\ - "ADDR: %02X:%02X:%02X:%02X:%02X:%02X, TYPE: %02X" -#define BT_DEVICE_ADDR_SPACED_FRMT_SPECIFIER\ - "ADDR: %02X %02X %02X %02X %02X %02X, TYPE: %02X" -#define BT_IGNORE_UNUSED_PARAM(v) (void)(v) - -typedef enum{ - STATE_DISCONNECT, - STATE_CONNECTED, - STATE_PROFILE_DISCONNECT, - STATE_PROFILE_CONNECTED, -}connect_state_s; - - -typedef struct{ - uint16_t conn_handle; - uint8_t conn_state; - bd_addr_t peer_addr; - uint8_t spp_init; - SPP_HANDLE spp_handle; - uint32_t spp_record_handle; - uint8_t local_server_channel; - uint8_t peer_server_channel; -}spp_env_s; - -static bt_err_t at_cmd_status = BK_ERR_BT_SUCCESS; - -static beken_semaphore_t bt_at_cmd_sema = NULL; - -static uint16_t conn_handle = 0xff; -static spp_env_s spp_env; -static API_RESULT bt_spp_event_notify_cb - ( - /* IN */ SPP_HANDLE spp_handle, - /* IN */ SPP_EVENTS spp_event, - /* IN */ API_RESULT status, - /* IN */ void * data, - /* IN */ UINT16 data_length - ); -static int bt_start_inquiry_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -static int bt_create_connection_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -static int bt_disconnect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -static int bt_spp_connect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -static void bt_at_event_cb(bt_event_t event, void *param) -{ - switch (event) - { - case BT_EVENT_INQUIRY_RESULT: - { - uint8_t *addr = (uint8_t *)param; - os_printf("BT Inquiryed addr: %x %x %x %x %x %x \r\n",*(addr+5), *(addr+4), *(addr+3), *(addr+2),*(addr+1),*(addr)); - } - break; - case BT_EVENT_DISCONNECT: - spp_env.conn_state = STATE_DISCONNECT; - os_printf("BT Disconnected!!! \r\n"); - break; - default: - break; - } -} - -static void bt_at_cmd_cb(bt_cmd_t cmd, bt_cmd_param_t *param) -{ - at_cmd_status = param->status; - switch (cmd) - { - case BT_CMD_CREATE_CONNECT: - if(param->status == BK_ERR_BT_SUCCESS) - { - conn_handle = *((uint16_t *)(param->param)); - } - break; - case BT_CMD_DISCONNECT: - if(conn_handle == spp_env.conn_handle) - { - os_memset(&spp_env, 0, sizeof(spp_env_s)); - } - conn_handle = 0xff; - break; - case BT_CMD_SDP: - if(at_cmd_status) - { - spp_env.peer_server_channel = *((uint8_t *)param->param); - } - break; - default: - break; - } - if (bt_at_cmd_sema != NULL) - rtos_set_semaphore( &bt_at_cmd_sema ); -} - -const at_command_t bt_at_cmd_table[] = { - {0, "INQUIRY", 0, "start inquiry", bt_start_inquiry_handle}, - {1, "CONNECT", 0, "create connection", bt_create_connection_handle}, - {2, "DISCONNECT", 0, "disconnect", bt_disconnect_handle}, - - {3, "SPP_CONNECT", 1, "spp connect", bt_spp_connect_handle}, -}; -API_RESULT bt_spp_event_notify_cb - ( - /* IN */ SPP_HANDLE spp_handle, - /* IN */ SPP_EVENTS spp_event, - /* IN */ API_RESULT status, - /* IN */ void * data, - /* IN */ UINT16 data_length - ) -{ -#ifdef SPP_ENABLE_DATA_CNF_LOG - UINT32 index; -#endif /* SPP_ENABLE_DATA_CNF_LOG */ - UCHAR * l_data; - l_data = (UCHAR*)( data ); -#if 0 - os_printf("\n"\ - "SPP HANDLE : %u\n"\ - "EVENT : %d\n"\ - "RESULT : 0x%04X\n", - (unsigned int) spp_handle, spp_event, status); - if (API_SUCCESS != status) - { - os_printf("\nSPP Command failure\n"); - return API_FAILURE; - } -#endif /* 0 */ - switch(spp_event) - { - case SPP_CONNECT_CNF: - os_printf("SPP_CONNECT_CNF -> 0x%04X\n", status); - os_printf("SPP Instance Connected : %u\n",(unsigned int) spp_handle); - os_printf("Remote device " BT_DEVICE_ADDR_ONLY_FRMT_SPECIFIER " \n", - BT_DEVICE_ADDR_ONLY_PRINT_STR (l_data)); - if (0x00 == status) - { -#ifdef SPP_VCOM_INTERFACE - appl_vcom_handle = vcom_connect_pl(spp_port, spp_baud, spp_flow, spp_read_cb); -#endif /* SPP_VCOM_INTERFACE */ - if (bt_at_cmd_sema != NULL) - rtos_set_semaphore( &bt_at_cmd_sema ); - } - break; - case SPP_CONNECT_IND: - os_printf("SPP_CONNECT_IND -> 0x%04X\n", status); - os_printf("SPP Instance Connected : %u\n",(unsigned int) spp_handle); - os_printf("Remote device " BT_DEVICE_ADDR_ONLY_FRMT_SPECIFIER " \n", - BT_DEVICE_ADDR_ONLY_PRINT_STR (l_data)); - - /* Set the global handle */ - /* g_spp_handle = spp_handle; */ - -#ifdef SPP_VCOM_INTERFACE - appl_vcom_handle = vcom_connect_pl(spp_port, spp_baud, spp_flow, spp_read_cb); -#endif /* SPP_VCOM_INTERFACE */ - break; - case SPP_DISCONNECT_CNF: - os_printf("SPP_DISCONNECT_CNF -> Disconnection Successful\n"); - os_printf("Remote device " BT_DEVICE_ADDR_ONLY_FRMT_SPECIFIER " \n", - BT_DEVICE_ADDR_ONLY_PRINT_STR (l_data)); -#ifdef SPP_VCOM_INTERFACE - if (0x00 == status) - { - vcom_disconnect_pl(appl_vcom_handle); - } - spp_env.conn_state = STATE_PROFILE_DISCONNECT; -#endif /* SPP_VCOM_INTERFACE */ - break; - case SPP_DISCONNECT_IND: - os_printf("SPP_DISCONNECT_IND -> Disconnection Successful\n"); - os_printf("Remote device " BT_DEVICE_ADDR_ONLY_FRMT_SPECIFIER " \n", - BT_DEVICE_ADDR_ONLY_PRINT_STR (l_data)); -#ifdef SPP_VCOM_INTERFACE - vcom_disconnect_pl(appl_vcom_handle); -#endif /* SPP_VCOM_INTERFACE */ - break; - case SPP_STOP_CNF: - os_printf("SPP_STOP_CNF -> Stop Successful\n"); - break; - case SPP_SEND_CNF: - { - #if 0 - UCHAR * buffer; - API_RESULT retval; - #endif -#ifdef SPP_ENABLE_DATA_CNF_LOG - os_printf("Received spp send cnf\n"); - os_printf(" spp handle = %d\n", spp_handle); - os_printf(" Buffer = %p\n", l_data); - os_printf(" Actual Data Length = %d\n", data_length); -#else /* RFCOMM_ENABLE_DATA_WRITE_CNF_LOG */ - os_printf(". "); -#endif /* RFCOMM_ENABLE_DATA_WRITE_CNF_LOG */ - if (0x00 != status) - { - os_printf ("*** 0x%04X\n", status); - } - os_free(data); - #if 0 - appl_count++; - if (appl_count == appl_loop) - { - os_printf("\n*** SPP Write for %d times has completed!!!\n", appl_loop); - break; - } - buffer = (UCHAR *)BT_alloc_mem(appl_nbytes); - if (NULL == buffer) - { - os_printf("*** Buffer Allocation FAILED. !!\n"); - break; - } - if (2U > appl_nbytes) - { - BT_mem_set(buffer, appl_count, appl_nbytes); - } - else - { - BT_PACK_BE_2_BYTE_VAL(buffer, appl_count); - BT_mem_set((&buffer[2U]), appl_count, (appl_nbytes - 2U)); - } -#ifdef SPP_ENABLE_DATA_CNF_LOG - os_printf("Allocated Buffer = %p\n", buffer); - os_printf("Initiating [%d]th spp Write ... ", appl_count); -#endif /* RFCOMM_ENABLE_DATA_WRITE_CNF_LOG */ - retval = BT_spp_send - ( - g_spp_handle, - buffer, - appl_nbytes - ); - if (API_SUCCESS != retval) - { - os_printf("** FAILED ** !! Reason Code = 0x%04x\n", retval); - BT_free_mem(buffer); - } - else - { -#ifdef SPP_ENABLE_DATA_CNF_LOG - os_printf("Succeeded !!\n"); - os_printf("Wait for Write Complete.\n"); -#endif /* RFCOMM_ENABLE_DATA_WRITE_CNF_LOG */ - } - #endif - } - break; - case SPP_RECVD_DATA_IND: -#ifdef SPP_FILE_OPERATION - if (0U != spp_recv_file_operation) - { - UINT16 written; - if (NULL != spp_recv_fp) - { - (BT_IGNORE_RETURN_VALUE) BT_fops_file_write(l_data, data_length, spp_recv_fp, &written); - } - os_printf(". "); - } - else -#endif /* SPP_FILE_OPERATION */ - { -#ifdef SPP_ENABLE_DATA_CNF_LOG - os_printf("SPP_RECVD_DATA_IND -> Data received successfully\n"); - os_printf("\n----------------CHAR DUMP-----------------------\n"); - for (index = 0U; index < data_length; index++) - { - os_printf("%c ", l_data[index]); - } - os_printf("\n------------------------------------------------\n"); - os_printf("\n----------------HEX DUMP------------------------\n"); - for (index = 0U; index < data_length; index++) - { - os_printf("%02X ", l_data[index]); - } - os_printf("\n------------------------------------------------\n"); -#else /* SPP_ENABLE_DATA_CNF_LOG */ - os_printf("."); -#endif /* SPP_ENABLE_DATA_CNF_LOG */ - } -#ifdef SPP_VCOM_INTERFACE - vcom_write_pl(appl_vcom_handle, l_data, data_length); -#endif /* SPP_VCOM_INTERFACE */ - break; - default: - os_printf("\nUnknown command type\n"); - break; - } /* switch */ - BT_IGNORE_UNUSED_PARAM(spp_handle); - return 0x00; -} - -int bt_at_cmd_cnt(void) -{ - return sizeof(bt_at_cmd_table) / sizeof(bt_at_cmd_table[0]); -} - -static int bt_start_inquiry_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - PRINT_FUNC; - char *msg; - int err = kNoErr; - if (bt_at_cmd_table[0].is_sync_cmd) - { - err = rtos_init_semaphore(&bt_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - if(bk_bt_get_host_stack_type() == BK_BT_HOST_STACK_TYPE_ETHERMIND) - { - bk_bt_set_event_callback(bt_at_event_cb); - err = bk_bt_inquiry(INQUIRY_LAP, INQUIRY_LEN, 0, bt_at_cmd_cb); - if(!err) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (bt_at_cmd_sema != NULL) - rtos_deinit_semaphore(&bt_at_cmd_sema); - return err; - }else - { - goto error; - } - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (bt_at_cmd_sema != NULL) - rtos_deinit_semaphore(&bt_at_cmd_sema); - return err; -} - -static int bt_create_connection_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - PRINT_FUNC; - char *msg; - int err = kNoErr; - if (bt_at_cmd_table[1].is_sync_cmd) - { - err = rtos_init_semaphore(&bt_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - if(bk_bt_get_host_stack_type() == BK_BT_HOST_STACK_TYPE_ETHERMIND) - { - bk_bt_set_event_callback(bt_at_event_cb); - bd_addr_t addr; - uint8_t allow_role_switch = 0; - err = get_addr_from_param(&addr, argv[0]); - if(err) goto error; - - allow_role_switch = os_strtoul(argv[1], NULL, 16) & 0xFF; - err = bk_bt_connect(&(addr.addr[0]), - CONNECTION_PACKET_TYPE, - CONNECTION_PAGE_SCAN_REPETITIOIN_MODE, - 0, - CONNECTION_CLOCK_OFFSET, - allow_role_switch, - bt_at_cmd_cb); - if(!err) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (bt_at_cmd_sema != NULL) - rtos_deinit_semaphore(&bt_at_cmd_sema); - return err; - }else - { - goto error; - } - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (bt_at_cmd_sema != NULL) - rtos_deinit_semaphore(&bt_at_cmd_sema); - return err; -} - -static int bt_disconnect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - PRINT_FUNC; - char *msg; - int err = kNoErr; - if (bt_at_cmd_table[2].is_sync_cmd) - { - err = rtos_init_semaphore(&bt_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - - if(bk_bt_get_host_stack_type() == BK_BT_HOST_STACK_TYPE_ETHERMIND) - { - bk_bt_set_event_callback(bt_at_event_cb); - bd_addr_t addr; - err = get_addr_from_param(&addr, argv[0]); - if(err) goto error; - - err = bk_bt_disconnect(&(addr.addr[0]), DISCONNECT_REASON, bt_at_cmd_cb); - if(!err) - { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (bt_at_cmd_sema != NULL) - rtos_deinit_semaphore(&bt_at_cmd_sema); - return err; - }else - { - goto error; - } - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (bt_at_cmd_sema != NULL) - rtos_deinit_semaphore(&bt_at_cmd_sema); - return err; -} - -static int bt_spp_connect_handle(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - PRINT_FUNC; - char *msg; - int err = kNoErr; - if (bt_at_cmd_table[3].is_sync_cmd) - { - err = rtos_init_semaphore(&bt_at_cmd_sema, 1); - if(err != kNoErr){ - goto error; - } - } - if(bk_bt_get_host_stack_type() == BK_BT_HOST_STACK_TYPE_ETHERMIND) - { - bk_bt_set_event_callback(bt_at_event_cb); - err = get_addr_from_param(&spp_env.peer_addr, argv[0]); - if(err) goto error; - if(!spp_env.spp_init) - { - bk_bt_spp_init(bt_spp_event_notify_cb); - spp_env.spp_handle = SPP_HANDLE_INVALID; - bk_bt_spp_start((uint32_t *)&spp_env.spp_handle, &spp_env.local_server_channel, &spp_env.spp_record_handle); - spp_env.spp_init = 1; - } - if(spp_env.conn_state != STATE_DISCONNECT) - { - os_printf("With remote device is connected, please disconnect first \r\n"); - goto error; - } - bk_bt_connect(&(spp_env.peer_addr.addr[0]), - CONNECTION_PACKET_TYPE, - CONNECTION_PAGE_SCAN_REPETITIOIN_MODE, - 0, - CONNECTION_CLOCK_OFFSET, - 1, - bt_at_cmd_cb); - if(bt_at_cmd_sema == NULL) goto error; - err = rtos_get_semaphore(&bt_at_cmd_sema, 12*1000); - if(err != kNoErr) goto error; - if(at_cmd_status == 0x00) - { - spp_env.conn_state = STATE_CONNECTED; - spp_env.conn_handle = conn_handle; - } - bk_bt_sdp(spp_env.conn_handle, &(spp_env.peer_addr.addr[0]), bt_at_cmd_cb); - err = rtos_get_semaphore(&bt_at_cmd_sema, 60*1000); - if(err != kNoErr) goto error; - if(!at_cmd_status) goto error; - - bk_bt_spp_connect(&(spp_env.peer_addr.addr[0]), spp_env.peer_server_channel, (uint32_t)spp_env.spp_handle, bt_at_cmd_cb); - err = rtos_get_semaphore(&bt_at_cmd_sema, 60*1000); - if(!err) - { - spp_env.conn_state = STATE_PROFILE_CONNECTED; - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - if (bt_at_cmd_sema != NULL) - rtos_deinit_semaphore(&bt_at_cmd_sema); - return err; - }else - { - goto error; - } - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - os_memset(&spp_env, 0, sizeof(spp_env_s)); - if (bt_at_cmd_sema != NULL) - rtos_deinit_semaphore(&bt_at_cmd_sema); - return err; -} - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/at/src/video_at_command.c b/bk7235/liteos_m/bk_sdk_armino/components/at/src/video_at_command.c deleted file mode 100755 index 3949f47..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/at/src/video_at_command.c +++ /dev/null @@ -1,350 +0,0 @@ -/* -// Copyright (C) 2022 Beken Corporation - * 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 "at_common.h" -#include -#include -#include -#include -#include -#include - -extern void delay(int num);//TODO fix me - - -#if CONFIG_PSRAM -int video_read_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int video_disable_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int test_psram(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -#endif - -#if CONFIG_CAMERA -int video_set_yuv_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -int video_close_yuv_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -#endif //CONFIG_CAMERA -const at_command_t video_at_cmd_table[] = { -#if CONFIG_PSRAM - {0, "READPSRAM", 0, "psram", video_read_psram_handler}, - {1, "DEINITPSRAM", 0, "deinit psram", video_disable_psram_handler}, - {2, "TEST", 0, "psram", test_psram}, -#endif -#if CONFIG_CAMERA - {3, "SETYUV", 0, "set jpeg/yuv mode and to psram", video_set_yuv_psram_handler}, - {4, "CLOSEYUV", 0, "close jpeg", video_close_yuv_psram_handler}, -#endif -}; - -int video_at_cmd_cnt(void) -{ - return sizeof(video_at_cmd_table) / sizeof(video_at_cmd_table[0]); -} - - -#if CONFIG_PSRAM -int video_read_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - uint8_t i = 0; - - uint32_t psram = 0x60000000; - if (argc != 0) { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - err = bk_psram_init(); - if (err != kNoErr) { - os_printf("psram init error\n"); - err = kParamErr; - goto error; - } - - os_memset((uint32_t *)psram, 0, 32); - - for (i = 0; i < 8; i++) { - *((uint32 *)psram + i * 4) = i; - } - - os_printf("data:\n"); - for (i = 0; i < 8; i++) { - os_printf("%d ", *((uint32_t *)psram + i * 4)); - } - os_printf("\n"); - - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return kNoErr; - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} - -int test_psram(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - uint32_t psram = 0x60000000; - uint8_t i = 0; - for (i = 0; i < 32; i++) { - *((uint32 *)psram + i * 4) = i * 2; - } - - os_printf("data:\n"); - for (i = 0; i < 32; i++) { - os_printf("%d ", *((uint32_t *)psram + i * 4)); - } - os_printf("\n"); - - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return kNoErr; -} - -int video_disable_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - - if (argc != 0) { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - err = bk_psram_deinit(); - if (err != kNoErr) { - os_printf("psram deinit error\n"); - err = kParamErr; - goto error; - } - - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return kNoErr; - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} -#endif // CONFIG_PSRAM - -#if CONFIG_CAMERA -static void end_of_jpeg_frame(jpeg_unit_t id, void *param) -{ - //os_printf("%s, %d\n", __func__, __LINE__); -} - -static void end_of_yuv_frame(jpeg_unit_t id, void *param) -{ - //os_printf("%s, %d\n", __func__, __LINE__); -} - -int video_set_yuv_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - uint8_t yuv_mode = 0; - jpeg_config_t jpeg_config = {0}; - i2c_config_t i2c_config = {0}; - uint32_t camera_config = 0; - uint32_t camera_dev = 0; - uint32_t ppi = 0; - - if (argc != 5) { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - yuv_mode = os_strtoul(argv[0], NULL, 16) & 0xFF; - if (yuv_mode > 1) { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - -#if (!CONFIG_PSRAM) - if (yuv_mode == 1) { - os_printf("NOT have psram, jpeg encode not support yuv mode"); - err = kParamErr; - goto error; - } -#endif - -#if (CONFIG_PSRAM) - err = bk_psram_init(); - if (err != kNoErr) { - os_printf("psram init error\n"); - err = kParamErr; - goto error; - } -#endif - -#if CONFIG_SYSTEM_CTRL - err = bk_jpeg_enc_driver_init(); - if (err != kNoErr) { - os_printf("video init error\n"); - err = kParamErr; - goto error; - } -#endif - - camera_dev = os_strtoul(argv[1], NULL, 10); - ppi = os_strtoul(argv[2], NULL, 10); - camera_config = (ppi << 16) | os_strtoul(argv[3], NULL, 10); - jpeg_config.yuv_mode = yuv_mode; - - switch (ppi) { - case 240: - jpeg_config.x_pixel = X_PIXEL_320; - jpeg_config.y_pixel = Y_PIXEL_240; - ppi = QVGA_320_240; - break; - case 272: - jpeg_config.x_pixel = X_PIXEL_480; - jpeg_config.y_pixel = Y_PIXEL_272; - ppi = VGA_480_272; - break; - case 480: - jpeg_config.x_pixel = X_PIXEL_640; - jpeg_config.y_pixel = Y_PIXEL_480; - ppi = VGA_640_480; - break; - case 600: - jpeg_config.x_pixel = X_PIXEL_800; - jpeg_config.y_pixel = Y_PIXEL_600; - ppi = VGA_800_600; - break; - case 720: - jpeg_config.x_pixel = X_PIXEL_1280; - jpeg_config.y_pixel = Y_PIXEL_720; - ppi = VGA_1280_720; - break; - default: - os_printf("input pixel param error\n"); - err = kParamErr; - goto error; - } - - if (ppi == VGA_1280_720) { - jpeg_config.sys_clk_div = 3; - jpeg_config.mclk_div = 0; - }else { - jpeg_config.sys_clk_div = 4; - jpeg_config.mclk_div = 0; - } - - err = bk_jpeg_enc_dvp_init(&jpeg_config); - if (err != kNoErr) { - os_printf("jpeg init error\n"); - err = kParamErr; - goto error; - } - - bk_jpeg_enc_register_isr(END_OF_FRAME, end_of_jpeg_frame, NULL); - bk_jpeg_enc_register_isr(END_OF_YUV, end_of_yuv_frame, NULL); - - i2c_config.baud_rate = os_strtoul(argv[4], NULL, 10) & 0xFFFFFFFF;//100000;// 400k - i2c_config.addr_mode = 0; - err = bk_i2c_init(CONFIG_CAMERA_I2C_ID, &i2c_config); - if (err != kNoErr) { - os_printf("i2c init error\n"); - err = kParamErr; - goto error; - } - - //err = bk_camera_set_ppi_fps(ppi, fps); - err = bk_camera_set_param(camera_dev, camera_config); - if (err != kNoErr) { - os_printf("set camera ppi and fps error\n"); - err = kParamErr; - goto error; - } - - bk_camera_sensor_config(); - os_printf("camera init ok\n"); - - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - - return kNoErr; - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} - -int video_close_yuv_psram_handler(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - - err = bk_jpeg_enc_dvp_deinit(); - if (err != kNoErr) { - os_printf("jpeg deinit error\n"); - err = kParamErr; - goto error; - } - os_printf("jpeg deinit ok!\n"); - - err = bk_i2c_deinit(CONFIG_CAMERA_I2C_ID); - if (err != kNoErr) { - os_printf("i2c deinit error\n"); - err = kParamErr; - goto error; - } - os_printf("I2c deinit ok!\n"); - -#if CONFIG_SYSTEM_CTRL - err = bk_jpeg_enc_driver_deinit(); - if (err != kNoErr) { - os_printf("video deinit error\n"); - err = kParamErr; - goto error; - } - os_printf("video deinit ok!\n"); -#endif - -#if CONFIG_PSRAM - delay(2000); - err = bk_psram_deinit(); - if (err != kNoErr) { - os_printf("psram deinit error\n"); - err = kParamErr; - goto error; - } - os_printf("psram deinit ok!\n"); -#endif - - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return kNoErr; - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} -#endif // CONFIG_CAMERA - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/at/src/wifi_at_command.c b/bk7235/liteos_m/bk_sdk_armino/components/at/src/wifi_at_command.c deleted file mode 100755 index 5fa1855..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/at/src/wifi_at_command.c +++ /dev/null @@ -1,350 +0,0 @@ -/* -// Copyright (C) 2022 Beken Corporation - * 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 "at_common.h" -#include -#include -#include "bk_wifi_wrapper.h" -#if CONFIG_LWIP -#include "net.h" -#if CONFIG_HARMONY_LWIP -#include "ping.h" -#else -#include "lwip/ping.h" -#endif - -#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] -#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x " -int at_wifi_scan_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int at_wifi_staconn_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int at_wifi_stadisconn_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int at_wifi_ap_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int at_wifi_stop_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int at_wifi_state_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); -int at_wifi_ping_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); - -const at_command_t wifi_at_cmd_table[] = { - {0, "SCAN", 1, "scan ssid...", at_wifi_scan_cmd}, - {1, "STACONNECT", 1, "sta connect ap", at_wifi_staconn_cmd}, - // {2, "STADISCONNECT", 0, "sta disconnect ap", at_wifi_stadisconn_cmd}, - {3, "APSTART", 0, "start ap", at_wifi_ap_cmd}, - {4, "STOP", 0, "disable sta/ap", at_wifi_stop_cmd}, - {5, "STATE", 0, "get wifi state", at_wifi_state_cmd}, - {6, "PING", 0, "wifi ping", at_wifi_ping_cmd} -}; - -int wifi_at_cmd_cnt(void) -{ - return sizeof(wifi_at_cmd_table) / sizeof(wifi_at_cmd_table[0]); -} - -int at_wifi_scan_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - - if (argc == 0) { - demo_scan_app_init(); - } else if (argc == 1){ - uint8_t *ap_ssid; - - ap_ssid = (uint8_t *)argv[0]; - demo_scan_adv_app_init(ap_ssid); - } - else { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - - if (err == kNoErr) { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} - -#include "conv_utf8_pub.h" -int at_wifi_staconn_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - char *ssid = NULL; - char *password = ""; - - if ((argc < 1) || (argc > 4)) { - os_printf("invalid argc number\n"); - err = kParamErr; - goto error; - } - - if (argc >= 1) - ssid = argv[0]; - - if (argc >= 2) - password = argv[1]; - -#if 0 //TODO support BSSID/Channel configuration - if (argc >= 3) - bssid = argv[2]; - - if (argc >= 4) - channel = argv[3]; -#endif - - char *oob_ssid_tp = ssid; -#if CONFIG_USE_CONV_UTF8 - oob_ssid_tp = (char *)conv_utf8((uint8_t *)ssid); -#endif - - if (oob_ssid_tp) { - demo_sta_app_init((char *)oob_ssid_tp, password); -#if CONFIG_USE_CONV_UTF8 - os_free(oob_ssid_tp); -#endif - } else { - os_printf("not buf for utf8\r\n"); - } - - if (err == kNoErr) { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} -/* -int at_wifi_stadisconn_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - if (argc != 0) - { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - err = bk_wifi_sta_disconnect(); - if (err == kNoErr) { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} -*/ -int at_wifi_ap_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - char *ap_ssid = NULL; - char *ap_key = ""; - char *ap_channel = NULL; - - if (argc == 1) - ap_ssid = argv[0]; - else if (argc == 2) { - ap_ssid = argv[0]; - ap_key = argv[1]; - } - else if (argc == 3) { - ap_ssid = argv[0]; - ap_key = argv[1]; - ap_channel = argv[2]; - } - else { - os_printf("input param error\n"); - err = kParamErr; - goto error; - } - if (ap_ssid) - demo_softap_app_init(ap_ssid, ap_key, ap_channel); - - if (err == kNoErr) { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} - -int at_wifi_stop_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - - if (argc == 1) { - if (os_strcmp(argv[0], "STA") == 0) - err = bk_wifi_sta_stop(); - else if (os_strcmp(argv[0], "AP") == 0) - err = bk_wifi_ap_stop(); - else { - os_printf("unknown WiFi interface\n"); - err = kParamErr; - goto error; - } - } else { - os_printf("bad parameters\r\n"); - err = kParamErr; - goto error; - } - - if (err == kNoErr) { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} - -int at_wifi_state_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ - char *msg = NULL; - int err = kNoErr; - - if (argc == 0) { - err = demo_state_app_init(); - if (err == kNoErr) { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - else { - os_printf("get link status fail!\n"); - err = kGeneralErr; - goto error; - } - } - else if (argc == 1) { - wifi_link_status_t link_status = {0}; - //wifi_ap_config_t ap_info = {0}; - char ssid[33] = {0}; - if (sta_ip_is_start()) { - os_memset(&link_status, 0x0, sizeof(link_status)); - err = bk_wifi_sta_get_link_status(&link_status); - if(err != kNoErr) { - os_printf("get link status fail!\n"); - err = kGeneralErr; - goto error; - } - os_memcpy(ssid, link_status.ssid, 32); - if (os_strcmp(argv[0], "RSSI") == 0) { - os_printf("sta:rssi=%d\n", link_status.rssi); - } - else if (os_strcmp(argv[0], "CHANNEL") == 0) { - os_printf("sta:channel=%d\n", link_status.channel); - } - else if (os_strcmp(argv[0], "SNR") == 0) { - os_printf("pending\n"); - } - else if (os_strcmp(argv[0], "BSSID") == 0) { - os_printf("sta:bssid=" MACSTR "\n", MAC2STR(link_status.bssid)); - } - else if (os_strcmp(argv[0], "IP") == 0) { - netif_ip4_config_t ap_ip4_info = {0}; - err = bk_netif_get_ip4_config(NETIF_IF_STA, &ap_ip4_info); - if(err != kNoErr) { - os_printf("get ip fail!\n"); - err = kGeneralErr; - goto error; - } - os_printf("ip=%s,gate=%s,mask=%s,dns=%s\r\n", - ap_ip4_info.ip, ap_ip4_info.gateway, ap_ip4_info.mask, ap_ip4_info.dns); - } - else if (os_strcmp(argv[0], "SSID") == 0) { - os_printf("sta:ssid=%d\n", ssid); - } - else { - os_printf("bad parameters\r\n"); - err = kParamErr; - goto error; - } - } - else { - os_printf("sta: 0\n"); - } - if(err == kNoErr) { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - } -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -} -int at_wifi_ping_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) -{ -#if 0 - char *msg = NULL; - int err = kNoErr; - uint32_t cnt = 4; - if (argc == 0) { - os_printf("Please input: ping \n"); - goto error; - } - - if (argc == 1 && (os_strcmp("STOP", argv[0]) == 0)) { - ping_stop(); - if(err == kNoErr) { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - } - - if (argc > 1) - cnt = os_strtoul(argv[1], NULL, 10); - - os_printf("ping IP address:%s\n", argv[0]); - ping_start(argv[0], cnt, 0); - if(err == kNoErr) { - msg = AT_CMD_RSP_SUCCEED; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; - } - else - goto error; - -error: - msg = AT_CMD_RSP_ERROR; - os_memcpy(pcWriteBuffer, msg, os_strlen(msg)); - return err; -#else - return 0; -#endif -} -#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/base64/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/base64/BUILD.gn new file mode 100755 index 0000000..f586c3d --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/base64/BUILD.gn @@ -0,0 +1,24 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ "base_64.c" ] + public_configs = [ ":public" ] +} +config("public") { + include_dirs = [ "." ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_adapter/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_adapter/BUILD.gn new file mode 100755 index 0000000..19644b4 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_adapter/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ "lib_adapter.c" ] + include_dirs = [ + "include", + "include/bk_private", + ] + public_configs = [ "${beken_sdk_dir}/middleware/driver:public" ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_ate/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_ate/BUILD.gn new file mode 100755 index 0000000..07b98c1 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_ate/BUILD.gn @@ -0,0 +1,24 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ "ate.c" ] + public_configs = [ + "${beken_sdk_dir}/middleware/soc:public", + "${beken_sdk_dir}/middleware/driver:public", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_ble/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_ble/BUILD.gn new file mode 100755 index 0000000..b492acd --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_ble/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") + +config("public") { + include_dirs = [ "." ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/BUILD.gn new file mode 100755 index 0000000..dc625cb --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/BUILD.gn @@ -0,0 +1,51 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") + +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ + "cli_aon_rtc.c", + "cli_ble.c", + "cli_efuse.c", + "cli_flash.c", + "cli_flash_test.c", + "cli_main.c", + "cli_netif.c", + "cli_rpc.c", + "cli_wdt.c", + "cli_wifi.c", + "shell_task.c", + "shell_uart.c", + ] + public_configs = [ + ":public", + "${beken_sdk_dir}/middleware/driver:public", + "${beken_sdk_dir}/middleware/soc:public", + "${beken_sdk_dir}/components/bk_wifi:public", + "${beken_sdk_dir}/components/bk_os:public", + "${beken_sdk_dir}/components/utf8:public", + "${beken_sdk_dir}/components/bk_netif:public", + ] +} + +config("public") { + include_dirs = [ + ".", + "include", + "include/bk_private", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/CMakeLists.txt new file mode 100755 index 0000000..a3c78c8 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/CMakeLists.txt @@ -0,0 +1,306 @@ +set(incs include include/bk_private) + +list(APPEND incs + ../../properties/modules/aec/ + . + ) + +if (CONFIG_CLI) +set(srcs + #cli_adc.c + cli_ble.c + #cli_event.c + #cli_keyValue.c + #cli_gpio.c + cli_main.c + #cli_misc.c + #cli_mico.c + #cli_mem.c + #cli_os.c + cli_rpc.c + #cli_reg.c + #cli_timer.c + #cli_temp_detect.c + #cli_uart.c + #cli_security.c + #cli_spi.c + #cli_exception.c + #cli_icu.c + ) + +if (CONFIG_INT_WDT) + list(APPEND srcs + cli_wdt.c + ) +endif() + +if (CONFIG_STA_PS) + list(APPEND srcs + #cli_pwr.c + ) +endif() + +if (CONFIG_OTA_TFTP OR CONFIG_OTA_HTTP) + list(APPEND srcs + cli_ota.c + ) +endif() + +if (CONFIG_WIFI_ENABLE) + list(APPEND srcs + cli_wifi.c + #cli_phy.c + ) +endif() + +if (CONFIG_AIRKISS_TEST) + list(APPEND srcs + cli_airkiss.c + ) +endif() + +if (CONFIG_IPERF_TEST) + list(APPEND srcs + cli_iperf.c + ) +endif() + +if (CONFIG_GENERAL_DMA) + list(APPEND srcs + #cli_dma.c + ) +endif() + +if (CONFIG_SDCARD_HOST) + list(APPEND srcs + cli_sd.c + ) +endif() + +if (CONFIG_PWM) + list(APPEND srcs + cli_pwm.c + ) +endif() + +if (CONFIG_I2C) + list(APPEND srcs + cli_i2c.c + ) +endif() + +if (CONFIG_SUPPORT_MATTER) + list(APPEND srcs + cli_matter.c + ) +endif() + +if (CONFIG_FLASH) + list(APPEND srcs + cli_flash.c + ) +endif() + +if (CONFIG_FLASH) + list(APPEND srcs + cli_flash_test.c + ) +endif() + +if (CONFIG_TRNG_SUPPORT) + list(APPEND srcs + #cli_trng.c + ) +endif() + +if (CONFIG_I2S) + list(APPEND srcs + cli_i2s.c + ) +endif() + +if (CONFIG_FATFS) + list(APPEND srcs "cli_fatfs.c") +endif() + +if (CONFIG_EFUSE) + list(APPEND srcs + cli_efuse.c + ) +endif() + +if (CONFIG_SDIO_HOST) + list(APPEND srcs + cli_sdio_host.c + ) +endif() + +if (CONFIG_LWIP) + list(APPEND srcs + #cli_lwip.c + ) +endif() + +if (CONFIG_BK_NETIF) + list(APPEND srcs + cli_netif.c + ) +endif() + +if (CONFIG_SHELL_ASYNCLOG) + list(APPEND srcs + shell_task.c + shell_uart.c + ) + if (CONFIG_MASTER_CORE) + list(APPEND srcs + shell_mailbox_ipc.c + ) + endif() + if (CONFIG_SLAVE_CORE) + list(APPEND srcs + shell_mailbox_cp1.c + ) + endif() +endif() + +if (CONFIG_DUAL_CORE) + list(APPEND srcs + rpc_client_gpio.c + ) +endif() + +if (CONFIG_SOC_BK7271) + list(APPEND srcs "cli_dsp_bk7271.c") +endif() + +if (CONFIG_SOC_BK7256XX) + #list(APPEND srcs "cli_usb.c") +endif() + +if (CONFIG_SOC_BK7256XX OR CONFIG_USB_UVC) +if (CONFIG_DUAL_CORE AND CONFIG_PSRAM) + list(APPEND srcs "cli_uvc.c") +endif() +endif() + +if (CONFIG_SECURITYIP) + list(APPEND srcs "cli_securityip.c") +endif() + +if (CONFIG_QSPI) + list(APPEND srcs + "cli_qspi.c" + ) +endif() + +if (CONFIG_AON_RTC_TEST) + list(APPEND srcs + "cli_aon_rtc.c" + ) +endif() + +if (CONFIG_JPEG_ENCODE) + list(APPEND srcs + "cli_jpegenc.c" + ) +endif() + + +if (CONFIG_AT_CMD) + #list(APPEND srcs "cli_at.c") +endif() + +if (CONFIG_LCD_TEST) + list(APPEND srcs + "cli_lcd.c") +endif() #CONFIG_LCD_TEST +if (CONFIG_DMA2D_TEST) + list(APPEND srcs + "cli_dma2d.c" + ) +endif() #CONFIG_DMA2D_TEST + + +if (CONFIG_AUDIO_TEST AND CONFIG_AUDIO_RISCV_IP_V1_0) + list(APPEND srcs "cli_aud.c") +endif() #if(CONFIG_AUDIO) + +if (CONFIG_AUDIO_TEST) +if (CONFIG_AUDIO_RISCV_IP_V1_0 AND CONFIG_DUAL_CORE) +if (NOT CONFIG_SLAVE_CORE) + list(APPEND srcs cli_aud_cp0.c) +endif() +endif() +endif() + +if (CONFIG_AUDIO_AEC_TEST) + list(APPEND srcs "cli_aec.c") +endif() + +if (CONFIG_AUDIO_G711_TEST) + list(APPEND srcs "cli_g711.c") +endif() + +if (CONFIG_AUDIO_MP3_TEST) + list(APPEND srcs "cli_mp3.c") +endif() + +if (CONFIG_FFT_TEST) + list(APPEND srcs "cli_fft.c") +endif() + +if (CONFIG_SBC_TEST) + list(APPEND srcs "cli_sbc.c") +endif() + +if (CONFIG_I2S_TEST) + list(APPEND srcs "cli_i2s.c") +endif() + +if (CONFIG_TOUCH) + list(APPEND srcs "cli_touch.c") +endif() + +if (CONFIG_CALENDAR) + list(APPEND srcs "cli_calendar.c") +endif() + +endif() #if(CONFIG_CLI) + +if (CONFIG_JPEG_DECODE) + list(APPEND srcs cli_jpegdec.c) +endif() + +if (CONFIG_JPEG_DECODE) + list(APPEND srcs cli_jpegdec.c) +endif() + +if (CONFIG_CAMERA OR CONFIG_SPIDMA) +if (CONFIG_APP_DEMO_VIDEO_TRANSFER) + list(APPEND srcs "cli_dvp.c") +endif() +endif() + +if (CONFIG_DOORBELL) + list(APPEND srcs cli_doorbell.c) +endif() + +if (CONFIG_PSRAM) + list(APPEND srcs cli_psram.c) +endif() + +if (CONFIG_AUD_INTF_TEST) + list(APPEND srcs cli_aud_intf.c) +endif() + +armino_component_register(SRCS "${srcs}" + INCLUDE_DIRS "${incs}" + REQUIRES utf8 temp_detect driver user_driver bk_system user_driver + #PRIV_REQUIRES airkiss bk_common bk_netif bk_ble bk_ps http adc_key app iperf media_common + PRIV_REQUIRES bk_common bk_netif bk_ble bk_ps bk_init at bk_wifi compal media bk_bt + ) + +if(CONFIG_ARCH_RISCV) + target_compile_options(${COMPONENT_LIB} PRIVATE -mno-relax) +endif() diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/Kconfig b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/Kconfig new file mode 100755 index 0000000..98061d1 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/Kconfig @@ -0,0 +1,157 @@ +menu "Cli" + config CLI + bool "Enable BK Cli" + default y + + config BKREG + depends on CLI + bool "Enable BK Reg read/write" + default y + + config MAX_COMMANDS + depends on CLI + int "MAX number of commands is configured by default" + range 0 65535 + default 255 + + config IPERF_TEST + depends on CLI + bool "Enable Iperf Test" + default y + + config TCP_SERVER_TEST + depends on CLI + bool "Enable TCP server Test" + default n + + config AIRKISS_TEST + depends on CLI + bool "Enable Airkiss Test" + default n + + config WIFI_RAW_TX_TEST + depends on CLI + bool "Enable WiFi Raw TX" + default n + + #TODO Exculsive?? + config I2C1_TEST + depends on CLI + bool "Enable I2C1 Test" + default n + + config I2C2_TEST + depends on CLI + bool "Enable I2C2 Test" + default n + + config UART_TEST + depends on CLI + bool "Enable Uart Test" + default n + + config SPI_TEST + depends on CLI + bool "Enable SPI Test" + default n + + config PERI_TEST + depends on CLI + bool "Enable Periperal Test" + default n + + config RF_OTA_TEST + depends on CLI + bool "Enable RF OTA Test" + default n + + config SHELL_ASYNCLOG + depends on CLI + bool "Enable Shell and Async log optimize" + default n + + config TOUCH + depends on CLI + bool "Enable TOUCH Test" + default n + config SBC_TEST + depends on CLI + bool "Enable SBC Test" + default n + + config AUDIO + depends on CLI + bool "Enable AUDIO" + default n + + config EFUSE + bool "Enable Efuse" + default y + + config ICU + bool "Enable ICU" + default y + + config SECURITYIP + bool "Enable securityIP" + default n + + config KEYVALUE + bool "Enable KEYVALUE" + default n + + config IDLE_UART_OUT_TEST + bool "Enable idle uart out test" + default n + + config COMPONENTS_WPA2_ENTERPRISE + bool "Enable WPA2 ENTERPRISE" + default n + + config COMPONENTS_WPA_TWT_TEST + bool "Enable WPA TWT TEST" + default n + + config COMPONENTS_WFA_CA + bool "WFA_CA" + default n + + config ENABLE_WIFI_DEFAULT_CONNECT + bool "Enable Wi-Fi Default Connect" + default n +endmenu + +menu "DUAL_CORE" + config DUAL_CORE + bool "Dual cpu core run as master core" + default n + + config MASTER_CORE + depends on DUAL_CORE + bool "Dual cpu core run as master core" + default n + + config SLAVE_CORE + depends on DUAL_CORE + bool "Dual cpu core run as slave core" + default n + + config SLAVE_CORE_OFFSET + depends on MASTER_CORE + int "Slave core offset address default 0x2e0000" + range 0 4194304 + default 3014656 + + config SLAVE_CORE_RESET_VALUE + depends on MASTER_CORE + int "Slave core reset value" + range 0 1 + default 1 + config EFUSE + bool "Enable Efuse" + default y + + config ICU + bool "Enable ICU" + default y +endmenu diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli.h b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli.h new file mode 100755 index 0000000..1f48074 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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. + */ + + +#pragma once + +#include +#include +#include +#include "cli_config.h" +#include "param_config.h" +#include "bk_cli.h" +#include +#include +#include +#include +#include +#include +#include "bk_uart.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define CLI_TAG "cli" + +#define CLI_LOGI(...) BK_LOGI(CLI_TAG, ##__VA_ARGS__) +#define CLI_LOGW(...) BK_LOGW(CLI_TAG, ##__VA_ARGS__) +#define CLI_LOGE(...) BK_LOGE(CLI_TAG, ##__VA_ARGS__) +#define CLI_LOGD(...) BK_LOGD(CLI_TAG, ##__VA_ARGS__) + +#define CLI_RET_ON_INVALID_ARGC(_actual_argc, _expect_minimum_argc) do {\ + if ((_actual_argc) < (_expect_minimum_argc)) {\ + CLI_LOGE("invalid argc, expect %d actual %d\n", (_expect_minimum_argc), (_actual_argc));\ + return;\ + }\ + }while(0) + +int cli_wifi_init(void); +int cli_ble_init(void); +int cli_netif_init(void); +int cli_misc_init(void); +int cli_mem_init(void); +int cli_airkiss_init(void); +int cli_phy_init(void); + +#if CONFIG_LWIP +int cli_lwip_init(void); +#endif + +int cli_iperf_init(void); +int cli_pwr_init(void); +int cli_timer_init(void); +int cli_wdt_init(void); +int cli_trng_init(void); +int cli_efuse_init(void); +int cli_gpio_init(void); +int cli_os_init(void); +int cli_ota_init(void); +int cli_flash_init(void); +int cli_flash_test_init(void); +int cli_keyVaule_init(void); +int cli_matter_init(void); + +int cli_uart_init(void); +int cli_adc_init(void); +int cli_spi_init(void); +int cli_qspi_init(void); +int cli_i2c_init(void); +int cli_aon_rtc_init(void); +int cli_sd_init(void); +int cli_fatfs_init(void); +int cli_temp_detect_init(void); +int cli_security_init(void); +int cli_mico_init(void); +int cli_peri_init(void); +int cli_event_init(void); +int cli_pwm_init(void); +int cli_reg_init(void); +int cli_dma_init(void); +int cli_exception_init(void); +int cli_icu_init(void); +int cli_at_init(void); +#if CONFIG_SECURITYIP +int cli_vault_init(void); +#endif +int cli_aud_init(void); +int cli_aud_intf_init(void); +int cli_fft_init(void); +int cli_sbc_init(void); +int cli_touch_init(void); +int cli_jpeg_init(void); +int cli_lcd_init(void); +int cli_dma2d_init(void); +int cli_i2s_init(void); +int cli_uvc_init(void); +int cli_aud_cp0_init(void); +int cli_calendar_init(void); +int cli_jpegdec_init(void); +int cli_aec_init(void); +int cli_g711_init(void); +int cli_mp3_init(void); +int cli_dvp_init(void); +int cli_doorbell_init(void); +int cli_sdio_host_init(void); +int cli_psram_init(void); + +extern int hexstr2bin(const char *hex, u8 *buf, size_t len); + +#ifdef __cplusplus +} +#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_aon_rtc.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_aon_rtc.c new file mode 100755 index 0000000..46bdbf4 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_aon_rtc.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include "cli.h" +#include + +static void alarm_auto_test_callback(aon_rtc_id_t id, uint8_t *name_p, void *param); + + +static void cli_aon_rtc_help(void) +{ + CLI_LOGI("aon_rtc_driver init\r\n"); + CLI_LOGI("aon_rtc_driver deinit\r\n"); + CLI_LOGI("aon_rtc_register {id} {name} {period_tick} {period_cnt}, {callback}\r\n"); + CLI_LOGI("aon_rtc_unregister {id} {name}\r\n"); + CLI_LOGI("aon_rtc_timing_test {id} {rounds} {cycles} {set tick val}\r\n"); +} + +static void cli_aon_rtc_driver_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc < 2) { + cli_aon_rtc_help(); + return; + } + + if (os_strcmp(argv[1], "init") == 0) { + BK_LOG_ON_ERR(bk_aon_rtc_driver_init()); + CLI_LOGI("aon_rtc driver init\n"); + } else if (os_strcmp(argv[1], "deinit") == 0) { + BK_LOG_ON_ERR(bk_aon_rtc_driver_deinit()); + CLI_LOGI("aon_rtc driver deinit\n"); + } else { + cli_aon_rtc_help(); + return; + } +} +static uint8_t alarm_param[12] = {'a', 'l', 'a', 'r', 'm', 'p', 'r', 'm', 0, 0, 0, 0}; +static void alarm_callback(aon_rtc_id_t id, uint8_t *name_p, void *param) +{ + CLI_LOGI("id=%d, name=%s %s\r\n", id, name_p, alarm_param); +} + +static void cli_aon_rtc_get_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t aon_rtc_id; + uint64_t tick = 0; + + aon_rtc_id = os_strtoul(argv[1], NULL, 10); + tick = bk_aon_rtc_get_current_tick(aon_rtc_id); + + //CLI_LOGI("id=%d, tick_h=%d tick_l=%d\r\n", aon_rtc_id, (uint32_t)(tick>>32), (uint32_t)tick); + CLI_LOGI("id=%d, tick_h=%d tick_l=%d ms\r\n", aon_rtc_id, (uint32_t)((tick/32)>>32), (uint32_t)(tick/32)); +} + +static void cli_aon_rtc_register_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t aon_rtc_id; + alarm_info_t alarm_info; + + if (argc != 5) { + cli_aon_rtc_help(); + return; + } + + aon_rtc_id = os_strtoul(argv[1], NULL, 10); + strncpy((char *)alarm_info.name, argv[2], ALARM_NAME_MAX_LEN); + alarm_info.period_tick = os_strtoul(argv[3], NULL, 10); + alarm_info.period_cnt = os_strtoul(argv[4], NULL, 10); + alarm_info.param_p = (void *)alarm_param; + alarm_info.callback = alarm_callback; + bk_alarm_register(aon_rtc_id, &alarm_info); +} + +static void cli_aon_rtc_unregister_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t aon_rtc_id; + uint8_t name[ALARM_NAME_MAX_LEN+1]; + + if (argc != 3) { + cli_aon_rtc_help(); + return; + } + + aon_rtc_id = os_strtoul(argv[1], NULL, 10); + strncpy((char *)name, argv[2], ALARM_NAME_MAX_LEN); + + bk_alarm_unregister(aon_rtc_id, name); +} + +static alarm_info_t s_cli_alarm_info[] = +{ + {"alarm_1", (1000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL}, + {"alarm_2", (6000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL}, + {"alarm_3", (12000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL}, + {"alarm_4", (48000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL}, + {"alarm_5", (3000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL}, + {"alarm_6", (4000 * AON_RTC_MS_TICK_CNT), 0xFFFFFFFF, alarm_auto_test_callback, NULL}, +}; + +static void alarm_auto_test_callback(aon_rtc_id_t id, uint8_t *name_p, void *param) +{ + uint32_t i = 0; + uint32_t arr_size = sizeof(s_cli_alarm_info)/sizeof(alarm_info_t); + + CLI_LOGI("id=%d, name=%s\r\n", id, name_p); + for(i = 0; i < arr_size; i++) + { + if(os_strcmp((const char*)s_cli_alarm_info[i].name, (const char*)name_p) == 0) + { + //forbid unregister self in the callback + //CLI_LOGI("Unregister name=%s\r\n", name_p); + //bk_alarm_unregister(id, s_cli_alarm_info[i].name); + + CLI_LOGI("register name=%s\r\n", s_cli_alarm_info[(i+3)%arr_size].name); + bk_alarm_register(id, &s_cli_alarm_info[(i+3)%arr_size]); + + break; + } + } +} + +static void aon_rtc_autotest_start(aon_rtc_id_t id) +{ + uint32_t i = 0; + + for(i = 0; i < sizeof(s_cli_alarm_info)/sizeof(alarm_info_t); i++) + { + bk_alarm_register(id, &s_cli_alarm_info[i]); + } +} + +static void aon_rtc_autotest_stop(aon_rtc_id_t id) +{ + uint32_t i = 0; + for(i = 0; i < sizeof(s_cli_alarm_info)/sizeof(alarm_info_t); i++) + { + bk_alarm_unregister(id, s_cli_alarm_info[i].name); + } +} + +static void cli_aon_rtc_auto_test_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t aon_rtc_id; + + if (argc != 3) { + cli_aon_rtc_help(); + return; + } + + aon_rtc_id = os_strtoul(argv[1], NULL, 10); + if (os_strcmp(argv[2], "start") == 0) + { + aon_rtc_autotest_start(aon_rtc_id); + } + else if (os_strcmp(argv[2], "stop") == 0) + { + aon_rtc_autotest_stop(aon_rtc_id); + } + else + cli_aon_rtc_help(); +} + +#if AON_RTC_DEBUG +static void cli_aon_rtc_timing_test_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t aon_rtc_id; + uint32_t round, cnts, set_tick_val = 0xfffffff0; + + if (argc != 5) { + cli_aon_rtc_help(); + return; + } + + aon_rtc_id = os_strtoul(argv[1], NULL, 10); + round = os_strtoul(argv[2], NULL, 10); + cnts = os_strtoul(argv[3], NULL, 10); + set_tick_val = os_strtoul(argv[4], NULL, 10); + + bk_aon_rtc_timing_test(aon_rtc_id, round, cnts, set_tick_val); +} +#endif + +static void cli_aon_rtc_dump_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t aon_rtc_id; + + if (argc != 2) { + cli_aon_rtc_help(); + return; + } + + aon_rtc_id = os_strtoul(argv[1], NULL, 10); + + bk_aon_rtc_dump(aon_rtc_id); +} + + +#define AON_RTC_CMD_CNT (sizeof(s_aon_rtc_commands) / sizeof(struct cli_command)) +static const struct cli_command s_aon_rtc_commands[] = { + {"aon_rtc_driver", "aon_rtc_driver {init|deinit}", cli_aon_rtc_driver_cmd}, + {"aon_rtc_get_time", "aon_rtc_get_time {id}", cli_aon_rtc_get_time}, + {"aon_rtc_register", "aon_rtc_register {id} {name} {period_tick} {period_cnt}, {callback}", cli_aon_rtc_register_cmd}, + {"aon_rtc_unregister", "aon_rtc_unregister {id} {name}", cli_aon_rtc_unregister_cmd}, + {"aon_rtc_auto_test", "{id} {start|stop}", cli_aon_rtc_auto_test_cmd}, +#if AON_RTC_DEBUG + {"aon_rtc_timing_test", "{id} {rounds} {cycles} {set tick val}", cli_aon_rtc_timing_test_cmd}, +#endif + {"aon_rtc_dump", "{id}", cli_aon_rtc_dump_cmd}, +}; + +int cli_aon_rtc_init(void) +{ + BK_LOG_ON_ERR(bk_aon_rtc_driver_init()); + return cli_register_commands(s_aon_rtc_commands, AON_RTC_CMD_CNT); +} + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_ble.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_ble.c new file mode 100755 index 0000000..770dcbc --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_ble.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 "bk_cli.h" +#include + +#define BLE_CMD_CNT (sizeof(s_ble_commands) / sizeof(struct cli_command)) + +static const struct cli_command s_ble_commands[] = { +#if (CONFIG_BLE == 1) + {"ble", "ble arg1 arg2", ble_command}, +#endif +}; + +int cli_ble_init(void) +{ + return cli_register_commands(s_ble_commands, BLE_CMD_CNT); +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_config.h b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_config.h new file mode 100755 index 0000000..501b6fd --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_config.h @@ -0,0 +1,277 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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. + */ + + +#pragma once + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if (CONFIG_WIFI_ENABLE) +#define CLI_CFG_WIFI 1 +#else +#define CLI_CFG_WIFI 0 +#endif //#if (CONFIG_WIFI_ENABLE) +#define CLI_CFG_BLE 1 + +#if (CONFIG_BK_NETIF) +#define CLI_CFG_NETIF 1 +#else +#define CLI_CFG_NETIF 0 +#endif //#if (CONFIG_LWIP) + +#define CLI_CFG_MISC 0 +#define CLI_CFG_MEM 0 + +#if (CONFIG_WIFI_ENABLE) +#define CLI_CFG_PHY 0 +#else +#define CLI_CFG_PHY 0 +#endif //#if (CONFIG_WIFI_ENABLE) + +#if (CONFIG_STA_PS) +#define CLI_CFG_PWR 0 +#else +#define CLI_CFG_PWR 0 +#endif +#define CLI_CFG_TIMER 0 +#if CONFIG_INT_WDT +#define CLI_CFG_WDT 0 +#endif +#if CONFIG_TRNG_SUPPORT +#define CLI_CFG_TRNG 0 +#else +#define CLI_CFG_TRNG 0 +#endif +#if CONFIG_EFUSE +#define CLI_CFG_EFUSE 0 +#else +#define CLI_CFG_EFUSE 0 +#endif +#define CLI_CFG_GPIO 0 +#define CLI_CFG_OS 0 +#if ((CONFIG_OTA_TFTP) || (CONFIG_OTA_HTTP)) +#define CLI_CFG_OTA 0 +#else +#define CLI_CFG_OTA 0 +#endif +#if(CONFIG_KEYVALUE) +#define CLI_CFG_KEYVALUE 0 +#else +#define CLI_CFG_KEYVALUE 0 +#endif +#if(CONFIG_SUPPORT_MATTER) +#define CLI_CFG_MATTER 0 +#else +#define CLI_CFG_MATTER 0 +#endif +#define CLI_CFG_UART 0 +#define CLI_CFG_ADC 0 +#define CLI_CFG_SPI 0 +#define CLI_CFG_MICO 0 +#define CLI_CFG_REG 0 +#define CLI_CFG_EXCEPTION 0 + +#if(CONFIG_GENERAL_DMA) +#define CLI_CFG_DMA 0 +#else +#define CLI_CFG_DMA 0 +#endif + +#if(CONFIG_PWM) +#define CLI_CFG_PWM 0 +#else +#define CLI_CFG_PWM 0 +#endif + +#if(CONFIG_FLASH) +#define CLI_CFG_FLASH 0 +#else +#define CLI_CFG_FLASH 0 +#endif + +#if(CONFIG_SDIO_HOST) +#define CLI_CFG_SDIO_HOST 0 +#else +#define CLI_CFG_SDIO_HOST 0 +#endif + +#if(CONFIG_ICU) +#define CLI_CFG_ICU 0 +#else +#define CLI_CFG_ICU 0 +#endif + +#if CONFIG_I2C +#define CLI_CFG_I2C 0 +#else +#define CLI_CFG_I2C 0 +#endif + +#if CONFIG_QSPI +#define CLI_CFG_QSPI 0 +#else +#define CLI_CFG_QSPI 0 +#endif + +#if CONFIG_AON_RTC_TEST +#define CLI_CFG_AON_RTC 0 +#else +#define CLI_CFG_AON_RTC 0 +#endif + +#if CONFIG_JPEG_ENCODE +#define CLI_CFG_JPEGENC 0 +#else +#define CLI_CFG_JPEGENC 0 +#endif + +#if CONFIG_JPEG_DECODE +#define CLI_CFG_JPEGDEC 0 +#else +#define CLI_CFG_JPEGDEC 0 +#endif + +#if CONFIG_CALENDAR +#define CLI_CFG_CALENDAR 0 +#else +#define CLI_CFG_CALENDAR 0 +#endif + +//TODO default to 0 +#define CLI_CFG_EVENT 0 + +#if (CONFIG_SOC_BK7251) +#define CLI_CFG_SECURITY 0 +#else +#define CLI_CFG_SECURITY 0 +#endif + +#if CONFIG_TEMP_DETECT +#define CLI_CFG_TEMP_DETECT 0 +#else +#define CLI_CFG_TEMP_DETECT 0 +#endif + +#if CONFIG_SDCARD_HOST +#define CLI_CFG_SD 0 +#else +#define CLI_CFG_SD 0 +#endif + +#if CONFIG_FATFS +#define CLI_FATFS 0 +#else +#define CLI_FATFS 0 +#endif + +#if CONFIG_AIRKISS_TEST +#define CLI_CFG_AIRKISS 0 +#else +#define CLI_CFG_AIRKISS 0 +#endif + +#if CONFIG_IPERF_TEST +#define CLI_CFG_IPERF 0 +#else +#define CLI_CFG_IPERF 0 +#endif + +#if (CONFIG_I2S) +#define CLI_CFG_I2S 0 +#else +#define CLI_CFG_I2S 0 +#endif + +#if (CONFIG_SOC_BK7256XX) + +#if CONFIG_DMA2D_TEST +#define CLI_CFG_DMA2D 0 +#else +#define CLI_CFG_DMA2D 0 +#endif + +#if (CONFIG_AUDIO && CONFIG_DUAL_CORE && CONFIG_AUDIO_TEST && CONFIG_AUDIO_RISCV_IP_V1_0) +#define CLI_CFG_AUD 0 +#endif + +#if CONFIG_AUD_INTF_TEST +#define CLI_CFG_AUD_INTF 0 +#endif + +#if (CONFIG_SBC) +#define CLI_CFG_SBC 0 +#endif + +#if CONFIG_LCD_TEST +#define CLI_CFG_LCD 0 +#else +#define CLI_CFG_LCD 0 +#endif + +#if (CONFIG_DUAL_CORE && CONFIG_AUDIO_TEST && !CONFIG_SLAVE_CORE) +#define CLI_CFG_AUD_CP0 0 +#endif + +#if (CONFIG_FFT_TEST) +#define CLI_CFG_FFT 0 +#else +#define CLI_CFG_FFT 0 +#endif +#endif + +#if (CONFIG_AUDIO_AEC_TEST) +#define CLI_CFG_AEC 0 +#endif + +#if (CONFIG_AUDIO_G711_TEST) +#define CLI_CFG_G711 0 +#endif + +#if (CONFIG_AUDIO_MP3_TEST) +#define CLI_CFG_MP3 0 +#endif + +#if (CONFIG_SECURITYIP) +#define CLI_CFG_VAULT 0 +#else +#define CLI_CFG_vault 0 +#endif + +#if ((CONFIG_SOC_BK7256XX || CONFIG_USB_UVC) && CONFIG_DUAL_CORE && CONFIG_PSRAM) +#define CLI_CFG_UVC 0 +#else +#define CLI_CFG_UVC 0 +#endif + +#if ((CONFIG_CAMERA || CONFIG_SPIDMA) && CONFIG_APP_DEMO_VIDEO_TRANSFER) +#define CLI_CFG_DVP 0 +#else +#define CLI_CFG_DVP 0 +#endif + +#if (CONFIG_PSRAM && !CONFIG_SLAVE_CORE) +#define CLI_CFG_PSRAM 0 +#else +#define CLI_CFG_PSRAM 0 + +#endif + +#ifdef __cplusplus +} +#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_efuse.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_efuse.c new file mode 100755 index 0000000..0a0ad0d --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_efuse.c @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include "cli.h" +#include + +static void cli_efuse_help(void) +{ + CLI_LOGI("efuse_driver init\r\n"); + CLI_LOGI("efuse_driver deinit\r\n"); + CLI_LOGI("efuse_test write [addr] [data]\r\n"); + CLI_LOGI("efuse_test read [addr]\r\n"); +} + +static void cli_efuse_driver_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc < 2) { + cli_efuse_help(); + return; + } + + if (os_strcmp(argv[1], "init") == 0) { + BK_LOG_ON_ERR(bk_efuse_driver_init()); + CLI_LOGI("efuse driver init\n"); + } else if (os_strcmp(argv[1], "deinit") == 0) { + BK_LOG_ON_ERR(bk_efuse_driver_deinit()); + CLI_LOGI("efuse driver deinit\n"); + } else { + cli_efuse_help(); + return; + } +} + +static void cli_efuse_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc < 2) { + cli_efuse_help(); + return; + } + + uint8_t addr, data; + + if (os_strcmp(argv[1], "write") == 0) { + addr = os_strtoul(argv[2], NULL, 16); + data = os_strtoul(argv[3], NULL, 16); + BK_LOG_ON_ERR(bk_efuse_write_byte(addr, data)); + CLI_LOGI("efuse write addr:0x%02x, data:0x%02x\r\n", addr, data); + } else if (os_strcmp(argv[1], "read") == 0) { + addr = os_strtoul(argv[2], NULL, 16); + data = 0; + BK_LOG_ON_ERR(bk_efuse_read_byte(addr, &data)); + CLI_LOGI("efuse read addr:0x%02x, data:0x%02x\r\n", addr, data); + } else { + cli_efuse_help(); + return; + } +} + +#define EFUSE_CMD_CNT (sizeof(s_efuse_commands) / sizeof(struct cli_command)) +static const struct cli_command s_efuse_commands[] = { + {"efuse_driver", "efuse_driver {init|deinit}", cli_efuse_driver_cmd}, + {"efuse_test", "efuse_test {write|read}", cli_efuse_cmd} +}; + +int cli_efuse_init(void) +{ + BK_LOG_ON_ERR(bk_efuse_driver_init()); + return cli_register_commands(s_efuse_commands, EFUSE_CMD_CNT); +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_flash.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_flash.c new file mode 100755 index 0000000..b936800 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_flash.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include +#include "cli.h" +#include "flash_driver.h" + +static void cli_flash_help(void) +{ + CLI_LOGI("flash driver init\n"); + CLI_LOGI("flash_driver deinit\n"); + CLI_LOGI("flash {erase|write|read} [start_addr] [len]\n"); + CLI_LOGI("flash_partition show\n"); +} + +static void cli_flash_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc < 2) { + cli_flash_help(); + return; + } + + uint32_t start_addr = os_strtoul(argv[2], NULL, 16); + uint32_t len = os_strtoul(argv[3], NULL, 10); + + if (os_strcmp(argv[1], "erase") == 0) { + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + for (uint32_t addr = start_addr; addr < (start_addr + len); addr += FLASH_SECTOR_SIZE) { + bk_flash_erase_sector(addr); + } + bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK); + } else if (os_strcmp(argv[1], "read") == 0) { + uint8_t buf[FLASH_PAGE_SIZE] = {0}; + for (uint32_t addr = start_addr; addr < (start_addr + len); addr += FLASH_PAGE_SIZE) { + os_memset(buf, 0, FLASH_PAGE_SIZE); + bk_flash_read_bytes(addr, buf, FLASH_PAGE_SIZE); + CLI_LOGI("flash read addr:%x\r\n", addr); + + CLI_LOGI("dump read flash data:\r\n"); + for (uint32_t i = 0; i < 16; i++) { + for (uint32_t j = 0; j < 16; j++) { + os_printf("%02x ", buf[i * 16 + j]); + } + os_printf("\r\n"); + } + } + } else if (os_strcmp(argv[1], "write") == 0) { + uint8_t buf[FLASH_PAGE_SIZE] = {0}; + for (uint32_t i = 0; i < FLASH_PAGE_SIZE; i++) { + buf[i] = i; + } + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + for (uint32_t addr = start_addr; addr < (start_addr + len); addr += FLASH_PAGE_SIZE) { + bk_flash_write_bytes(addr, buf, FLASH_PAGE_SIZE); + } + bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK); + } else if (os_strcmp(argv[1], "get_id") == 0) { + uint32_t flash_id = bk_flash_get_id(); + CLI_LOGI("flash_id:%x\r\n", flash_id); + } else { + cli_flash_help(); + } +} + +static void cli_flash_partition_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + bk_logic_partition_t *partition; + + if (os_strcmp(argv[1], "show") == 0) { + for (bk_partition_t par= BK_PARTITION_BOOTLOADER; par <= BK_PARTITION_MAX; par++) { + partition = bk_flash_partition_get_info(par); + if (partition == NULL) + continue; + + CLI_LOGI("%4d | %11s | Dev:%d | 0x%08lx | 0x%08lx |\r\n", par, + partition->partition_description, partition->partition_owner, + partition->partition_start_addr, partition->partition_length); + } + } else { + cli_flash_help(); + } +} + +#define FLASH_CMD_CNT (sizeof(s_flash_commands) / sizeof(struct cli_command)) +static const struct cli_command s_flash_commands[] = { + {"flash", "flash {erase|read|write} [start_addr] [len]", cli_flash_cmd}, + {"flash_partition", "flash_partition {show}", cli_flash_partition_cmd}, +}; + +int cli_flash_init(void) +{ + BK_LOG_ON_ERR(bk_flash_driver_init()); + return cli_register_commands(s_flash_commands, FLASH_CMD_CNT); +} + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_flash_test.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_flash_test.c new file mode 100755 index 0000000..d2364ee --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_flash_test.c @@ -0,0 +1,508 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include "cli.h" +#include "driver/flash.h" +#include +#include "sys_driver.h" +#include "flash_bypass.h" +#include "flash.h" +#include + +#define TICK_PER_US 26 +beken_thread_t idle_read_flash_handle = NULL; +beken_thread_t idle_read_psram_handle = NULL; +extern void delay_ms(UINT32 ms_count); + +static bk_err_t test_flash_write(volatile uint32_t start_addr, uint32_t len) +{ + uint32_t i; + u8 buf[256]; + uint32_t addr = start_addr; + uint32_t length = len; + uint32_t tmp = addr + length; + + for (i = 0; i < 256; i++) + buf[i] = i; + + for (; addr < tmp; addr += 256) { + os_printf("write addr(size:256):%d\r\n", addr); + bk_flash_write_bytes(addr, (uint8_t *)buf, 256); + } + + return kNoErr; +} + +static bk_err_t test_flash_erase(volatile uint32_t start_addr, uint32_t len) +{ + uint32_t addr = start_addr; + uint32_t length = len; + uint32_t tmp = addr + length; + + for (; addr < tmp; addr += 0x1000) { + os_printf("erase addr:%d\r\n", addr); + bk_flash_erase_sector(addr); + } + return kNoErr; +} + +static bk_err_t test_flash_read(volatile uint32_t start_addr, uint32_t len) +{ + uint32_t i, j, tmp; + u8 buf[256]; + uint32_t addr = start_addr; + uint32_t length = len; + tmp = addr + length; + + for (; addr < tmp; addr += 256) { + os_memset(buf, 0, 256); + bk_flash_read_bytes(addr, (uint8_t *)buf, 256); + os_printf("read addr:%x\r\n", addr); + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) + os_printf("%02x ", buf[i * 16 + j]); + os_printf("\r\n"); + } + } + + return kNoErr; +} + +static bk_err_t test_flash_read_without_print(volatile uint32_t start_addr, uint32_t len) +{ + uint32_t tmp; + u8 buf[256]; + uint32_t addr = start_addr; + uint32_t length = len; + tmp = addr + length; + + for (; addr < tmp; addr += 256) { + os_memset(buf, 0, 256); + bk_flash_read_bytes(addr, (uint8_t *)buf, 256); + } + + return kNoErr; +} + +static bk_err_t test_flash_read_time(volatile uint32_t start_addr, uint32_t len) +{ + UINT32 time_start, time_end; + uint32_t tmp; + u8 buf[256]; + uint32_t addr = start_addr; + uint32_t length = len; + + tmp = addr + length; + beken_time_get_time((beken_time_t *)&time_start); + os_printf("read time start:%d\r\n", time_start); + + for (; addr < tmp; addr += 256) { + os_memset(buf, 0, 256); + bk_flash_read_bytes(addr, (uint8_t *)buf, 256); + } + beken_time_get_time((beken_time_t *)&time_end); + os_printf("read time end:%d\r\n", time_end); + os_printf("cost time:%d\r\n", time_end - time_start); + + return kNoErr; +} + +#if (CONFIG_SYSTEM_CTRL) +static bk_err_t test_flash_count_time(volatile uint32_t start_addr, uint32_t len, uint32_t test_times) +{ + UINT32 time_start, time_end; + uint32_t tmp; + u8 buf[256]; + uint32_t addr = start_addr; + uint32_t length = len; + extern u64 riscv_get_mtimer(void); + uint64_t start_tick, end_tick, tick_cnt = 0; + + tmp = addr + length; + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + + beken_time_get_time((beken_time_t *)&time_start); + os_printf("----- FLASH COUNT TIME TEST BEGIN: start time:%d ms -----\r\n", time_start); + os_printf("===============================\r\n"); + + start_tick = riscv_get_mtimer(); + for (addr = start_addr; addr < tmp; addr += 256) { + os_memset(buf, 0, 256); + bk_flash_read_bytes(addr, (uint8_t *)buf, 256); + } + end_tick = riscv_get_mtimer(); + tick_cnt = end_tick - start_tick; + os_printf("[read 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) (tick_cnt / TICK_PER_US)); + os_printf("===============================\r\n"); + + + start_tick = riscv_get_mtimer(); + for (int i = 0; i < test_times; i++ ) { + for (addr = start_addr; addr < tmp; addr += 256) { + os_memset(buf, 0, 256); + bk_flash_read_bytes(addr, (uint8_t *)buf, 256); + } + } + end_tick = riscv_get_mtimer(); + tick_cnt = end_tick - start_tick; + os_printf("[read %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t) (tick_cnt / TICK_PER_US / test_times)); + os_printf("===============================\r\n"); + + + start_tick = riscv_get_mtimer(); + for (addr = start_addr; addr < tmp; addr += 0x1000) { + os_printf("erase addr:%d\r\n", addr); + bk_flash_erase_sector(addr); + } + end_tick = riscv_get_mtimer(); + tick_cnt = end_tick - start_tick; + os_printf("[erase 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) (tick_cnt / TICK_PER_US)); + os_printf("===============================\r\n"); + + + start_tick = riscv_get_mtimer(); + for (int i = 0; i < test_times; i++ ) { + for (addr = start_addr; addr < tmp; addr += 0x1000) { + bk_flash_erase_sector(addr); + } + } + end_tick = riscv_get_mtimer(); + tick_cnt = end_tick - start_tick; + os_printf("[erase %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t) (tick_cnt / TICK_PER_US / test_times)); + os_printf("===============================\r\n"); + + + start_tick = riscv_get_mtimer(); + for (int i = 0; i < 256; i++) + buf[i] = i; + + for (addr = start_addr; addr < tmp; addr += 256) { + bk_flash_write_bytes(addr, (uint8_t *)buf, 256); + } + end_tick = riscv_get_mtimer(); + tick_cnt = end_tick - start_tick; + os_printf("[write 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) (tick_cnt / TICK_PER_US)); + os_printf("===============================\r\n"); + + + start_tick = riscv_get_mtimer(); + for (int i = 0; i < test_times; i++ ) { + for (addr = start_addr; addr < tmp; addr += 256) { + bk_flash_write_bytes(addr, (uint8_t *)buf, 256); + } + } + end_tick = riscv_get_mtimer(); + tick_cnt = end_tick - start_tick; + os_printf("[write %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t) (tick_cnt / TICK_PER_US / test_times)); + os_printf("===============================\r\n"); + + + start_tick = riscv_get_mtimer(); + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + end_tick = riscv_get_mtimer(); + tick_cnt = end_tick - start_tick; + os_printf("[enable security 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t)(tick_cnt / TICK_PER_US)); + os_printf("===============================\r\n"); + + + start_tick = riscv_get_mtimer(); + for (int i = 0; i < test_times; i++ ) { + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + } + end_tick = riscv_get_mtimer(); + tick_cnt = end_tick - start_tick; + os_printf("[enable security %d time] >>>>> average tick time: %d us.\r\n", test_times, (uint32_t)(tick_cnt / TICK_PER_US / test_times)); + os_printf("===============================\r\n"); + + + start_tick = riscv_get_mtimer(); + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK); + end_tick = riscv_get_mtimer(); + tick_cnt = end_tick - start_tick; + os_printf("[en/dis security 1 time] >>>>> cost tick time: %d us.\r\n", (uint32_t) ((tick_cnt / TICK_PER_US))); + os_printf("===============================\r\n"); + + + beken_time_get_time((beken_time_t *)&time_end); + os_printf("----- FLASH COUNT TIME TEST END: end time:%d ms -----\r\n", time_end); + os_printf("----- OVERALL TEST TIME:%d ms -----\r\n", time_end - time_start); + + bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK); + return kNoErr; +} +#endif + +static void test_idle_read_flash(void *arg) { + while (1) { + test_flash_read_without_print(0x1000, 1000); + test_flash_read_without_print(0x100000, 1000); + test_flash_read_without_print(0x200000, 1000); + test_flash_read_without_print(0x300000, 0x1000); + } + rtos_delete_thread(&idle_read_flash_handle); +} + +#define write_data(addr,val) *((volatile unsigned long *)(addr)) = val +#define read_data(addr,val) val = *((volatile unsigned long *)(addr)) +#define get_addr_data(addr) *((volatile unsigned long *)(addr)) + +#if (CONFIG_SYSTEM_CTRL && CONFIG_PSRAM) +static void test_idle_read_psram(void *arg) { + uint32_t i,val = 0; + uint32_t s0 = 0; + uint32_t s1 = 0; + uint32_t s2 = 0; + uint32_t s3 = 0; + + os_printf("enter test_idle_read_psram\r\n"); + + bk_psram_init(); + + while (1) { + for(i=0;i<1024;i++){ + write_data((0x60000000+i*0x4),0x11+i); + write_data((0x60001000+i*0x4),0x22+i); + write_data((0x60002000+i*0x4),0x33+i); + write_data((0x60003000+i*0x4),0x44+i); + } + for(i=0;i<1024;i++){ + write_data((0x60004000+i*0x4),0x55+i); + write_data((0x60005000+i*0x4),0x66+i); + write_data((0x60006000+i*0x4),0x77+i); + write_data((0x60007000+i*0x4),0x88+i); + } + for(i=0;i<4*1024;i++){ + val = get_addr_data(0x60000000+i*0x4); + s0 += val; + } + for(i=0;i<4*1024;i++){ + val = get_addr_data(0x60004000+i*0x4); + s1 += val; + } + for(i=0;i<4*1024;i++){ + val = get_addr_data(0x60000000+i*0x4); + s2 += val; + } + for(i=0;i<4*1024;i++){ + val = get_addr_data(0x60004000+i*0x4); + s3 += val; + } + + } + rtos_delete_thread(&idle_read_psram_handle); +} +#endif +static void flash_command_test(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + char cmd = 0; + uint32_t len = 0; + uint32_t addr = 0; +#if (CONFIG_SYSTEM_CTRL) + if (os_strcmp(argv[1], "config") == 0) { + uint32_t flash_src_clk = os_strtoul(argv[2], NULL, 10); + uint32_t flash_div_clk = os_strtoul(argv[3], NULL, 10); + uint32_t flash_line_mode = os_strtoul(argv[4], NULL, 10); + + if (FLASH_CLK_XTAL == flash_src_clk) { + sys_drv_flash_cksel(flash_src_clk); + } + + if((FLASH_CLK_XTAL != sys_drv_flash_get_clk_sel()) && (0 == flash_div_clk)) { + os_printf("Config fail. Please set src clk as 26M, or set div larger than 0 firstly.\n"); + return; + } + + sys_drv_flash_set_clk_div(flash_div_clk); + sys_drv_flash_cksel(flash_src_clk); + bk_flash_set_line_mode(flash_line_mode); + os_printf("flash_src_clk = %u. [0 -> 26M; 1->98M; 2-> 120M]\n", flash_src_clk); + os_printf("flash_div_clk = %u. \n", flash_div_clk); + os_printf("flash_line_mode = %u. \n", flash_line_mode); + + return; + } + if (os_strcmp(argv[1], "qe") == 0) { + uint32_t param = 0; + uint32_t quad_enable = os_strtoul(argv[2], NULL, 10); + uint32_t delay_cycle1 = os_strtoul(argv[3], NULL, 10); + uint32_t delay_cycle2 = os_strtoul(argv[4], NULL, 10); + + for(int i = 0; i< 20; i++) { + bk_flash_set_line_mode(2); + flash_bypass_quad_test(quad_enable, delay_cycle1, delay_cycle2); + while (REG_READ(REG_FLASH_OPERATE_SW) & BUSY_SW); + param = bk_flash_read_status_reg(); + if (quad_enable) { + if(param & 0x200){ + break; + } else { + os_printf("retry quad test, i = %d, flash status: 0x%x.\n", i, param); + } + } else { + if(param & 0x200){ + os_printf("retry quad test, i = %d, flash status: 0x%x.\n", i, param); + } else { + break; + } + } + } + + if (quad_enable) { + if(param & 0x200){ + os_printf("flash quad enable success, flash status: 0x%x.\n", param); + } else { + os_printf("flash quad enable fail, flash status: 0x%x.\n", param); + } + } else { + if(param & 0x200){ + os_printf("flash quad disable fail, flash status: 0x%x.\n", param); + } else { + os_printf("flash quad disable success, flash status: 0x%x.\n", param); + } + } + return; + } +#endif + if (os_strcmp(argv[1], "idle_read_start") == 0) { + uint32_t task_prio = os_strtoul(argv[2], NULL, 10); + os_printf("idle_read_flash task start: task_prio = %u.\n", task_prio); + rtos_create_thread(&idle_read_flash_handle, task_prio, + "idle_read_flash", + (beken_thread_function_t) test_idle_read_flash, + CONFIG_APP_MAIN_TASK_STACK_SIZE, + (beken_thread_arg_t)0); + + return; + } else if (os_strcmp(argv[1], "idle_read_stop") == 0) { + if (idle_read_flash_handle) { + rtos_delete_thread(&idle_read_flash_handle); + idle_read_flash_handle = NULL; + os_printf("idle_read_flash task stop\n"); + } + return; + } + +#if (CONFIG_SYSTEM_CTRL && CONFIG_PSRAM) + if (os_strcmp(argv[1], "idle_read_psram_start") == 0) { + uint32_t task_prio = os_strtoul(argv[2], NULL, 10); + os_printf("idle_read_psram task start: task_prio = %u.\n", task_prio); + rtos_create_thread(&idle_read_psram_handle, task_prio, + "idle_read_psram", + (beken_thread_function_t) test_idle_read_psram, + CONFIG_APP_MAIN_TASK_STACK_SIZE, + (beken_thread_arg_t)0); + + return; + } else if (os_strcmp(argv[1], "idle_read_psram_stop") == 0) { + if (idle_read_psram_handle) { + rtos_delete_thread(&idle_read_psram_handle); + idle_read_psram_handle = NULL; + os_printf("idle_read_psram task stop\n"); + } + return; + } +#endif + + if (os_strcmp(argv[1], "U") == 0) { + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + return; + } else if (os_strcmp(argv[1], "P") == 0) { + bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK); + return; + } else if (os_strcmp(argv[1], "RSR") == 0) { + uint16_t sts_val = bk_flash_read_status_reg(); + os_printf("read sts_val = 0x%x\n", sts_val); + return; + } else if (os_strcmp(argv[1], "WSR") == 0) { + uint16_t sts_val = os_strtoul(argv[2], NULL, 16); + bk_flash_write_status_reg(sts_val); + return; + } else if (os_strcmp(argv[1], "C") == 0) { +#if (CONFIG_SYSTEM_CTRL) + addr = atoi(argv[2]); + len = atoi(argv[3]); + uint32_t test_times = os_strtoul(argv[4], NULL, 10); + test_flash_count_time(addr, len, test_times); +#endif + return; + } + + if (argc == 4) { + cmd = argv[1][0]; + addr = atoi(argv[2]); + len = atoi(argv[3]); + + switch (cmd) { + case 'E': + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + test_flash_erase(addr, len); + bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK); + break; + + case 'R': + test_flash_read(addr, len); + break; + case 'W': + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + test_flash_write(addr, len); + bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK); + break; + //to check whether protection mechanism can work + case 'N': + test_flash_erase(addr, len); + break; + case 'M': + test_flash_write(addr, len); + break; + case 'T': + test_flash_read_time(addr, len); + break; + default: + break; + } + } else + os_printf("FLASH \r\n"); +} + + +static void partShow_Command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + bk_partition_t i; + bk_logic_partition_t *partition; + + for (i = BK_PARTITION_BOOTLOADER; i <= BK_PARTITION_MAX; i++) { + partition = bk_flash_partition_get_info(i); + if (partition == NULL) + continue; + + os_printf("%4d | %11s | Dev:%d | 0x%08lx | 0x%08lx |\r\n", i, + partition->partition_description, partition->partition_owner, + partition->partition_start_addr, partition->partition_length); + }; + +} + +#define FLASH_CMD_CNT (sizeof(s_flash_commands) / sizeof(struct cli_command)) +static const struct cli_command s_flash_commands[] = { + {"fmap_test", "flash_test memory map", partShow_Command}, + {"flash_test", "flash_test ", flash_command_test}, +}; + +int cli_flash_test_init(void) +{ + return cli_register_commands(s_flash_commands, FLASH_CMD_CNT); +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_main.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_main.c new file mode 100755 index 0000000..235f356 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_main.c @@ -0,0 +1,1575 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include "sys_rtos.h" +#include +#include + +#include "bk_cli.h" +#include "stdarg.h" +#include +#include +#include +#include "bk_phy.h" +#include "cli.h" +#include "cli_config.h" +#include +#include +#include "bk_rtos_debug.h" +#if CONFIG_SHELL_ASYNCLOG +#include "components/shell_task.h" +#endif +#include "bk_uart_debug.h" +#include "bk_api_cli.h" +#if (CONFIG_SLAVE_CORE && CONFIG_MEDIA) +#include "media_common.h" +#endif + +#ifdef CONFIG_MEDIA +#include "media_cli.h" +#endif + + +#define TAG "cli" + +static struct cli_st *pCli = NULL; + +#if (!CONFIG_SHELL_ASYNCLOG) +beken_semaphore_t log_rx_interrupt_sema = NULL; +#endif + +static uint16_t s_running_command_index = MAX_COMMANDS; +#if CFG_CLI_DEBUG +static uint8_t s_running_status = 0; +#endif + +extern int cli_putstr(const char *msg); +extern int hexstr2bin(const char *hex, u8 *buf, size_t len); + +#if CONFIG_CAMERA +extern int video_demo_register_cmd(void); +#endif + +#if CONFIG_BKREG +#define BKREG_MAGIC_WORD0 (0x01) +#define BKREG_MAGIC_WORD1 (0xE0) +#define BKREG_MAGIC_WORD2 (0xFC) +#define BKREG_MIN_LEN 3 +#endif + +#define SHELL_TASK_PRIORITY 1 + +/* Find the command 'name' in the cli commands table. +* If len is 0 then full match will be performed else upto len bytes. +* Returns: a pointer to the corresponding cli_command struct or NULL. +*/ +const struct cli_command *lookup_command(char *name, int len) +{ + int i = 0; + int n = 0; + + while (i < MAX_COMMANDS && n < pCli->num_commands) { + if (pCli->commands[i]->name == NULL) { + i++; + continue; + } + + /* See if partial or full match is expected */ + if (len != 0) { + if (!os_strncmp(pCli->commands[i]->name, name, len)) { + s_running_command_index = i; + return pCli->commands[i]; + } + } else { + if (!os_strcmp(pCli->commands[i]->name, name)) { + s_running_command_index = i; + return pCli->commands[i]; + } + } + + i++; + n++; + } + + return NULL; +} + +int lookup_cmd_table(const struct cli_command *cmd_table, int table_items, char *name, int len) +{ + int i; + + for (i = 0; i < table_items; i++) + { + if (cmd_table[i].name == NULL) + { + continue; + } + + /* See if partial or full match is expected */ + if (len != 0) + { + if (!os_strncmp(cmd_table[i].name, name, len)) + { + return i; + } + } + else + { + if (!os_strcmp(cmd_table[i].name, name)) + { + return i; + } + } + } + + return -1; +} + +#if (CONFIG_SHELL_ASYNCLOG && !CONFIG_ATE_TEST) + +/* Parse input line and locate arguments (if any), keeping count of the number +* of arguments and their locations. Look up and call the corresponding cli +* function if one is found and pass it the argv array. +* +* Returns: 0 on success: the input line contained at least a function name and +* that function exists and was called. +* 1 on lookup failure: there is no corresponding function for the +* input line. +* 2 on invalid syntax: the arguments list couldn't be parsed +*/ +int handle_shell_input(char *inbuf, int in_buf_size, char * outbuf, int out_buf_size) +{ + struct { + unsigned inArg: 1; + unsigned inQuote: 1; + unsigned done: 1; + unsigned limQ : 1; + unsigned isD : 2; + } stat; + static char *argv[16]; + int argc = 0; + int i = 0; + const struct cli_command *command = NULL; + const char *p; + + os_memset((void *)&argv, 0, sizeof(argv)); + os_memset(&stat, 0, sizeof(stat)); + + if(outbuf != NULL) + os_memset(outbuf, 0, out_buf_size); + + if (inbuf[i] == '\0') + return 0; + + do { + switch (inbuf[i]) { + case '\0': + if (((argc == 0)||(stat.isD == 1))||(stat.limQ)||(stat.inQuote)) + { + if(outbuf != NULL) + strcpy(&outbuf[0], "syntax error\r\n"); + return 2; + } + stat.done = 1; + break; + + case '"': + if (i > 0 && inbuf[i - 1] == '\\' && stat.inArg) { + os_memcpy(&inbuf[i - 1], &inbuf[i], + os_strlen(&inbuf[i]) + 1); + --i; + break; + } + if (!stat.inQuote && stat.inArg) + break; + if (stat.inQuote && !stat.inArg) + { + if(outbuf != NULL) + strcpy(&outbuf[0], "syntax error\r\n"); + return 2; + } + + if (!stat.inQuote && !stat.inArg) { + stat.inArg = 1; + stat.inQuote = 1; + argc++; + argv[argc - 1] = &inbuf[i + 1]; + } else if (stat.inQuote && stat.inArg) { + stat.inArg = 0; + stat.inQuote = 0; + inbuf[i] = '\0'; + } + break; + + case ' ': + if (i > 0 && inbuf[i - 1] == '\\' && stat.inArg) { + os_memcpy(&inbuf[i - 1], &inbuf[i], + os_strlen(&inbuf[i]) + 1); + --i; + break; + } + if (!stat.inQuote && stat.inArg) { + stat.inArg = 0; + inbuf[i] = '\0'; + } + break; + + case '=': + if(argc == 1) { + inbuf[i] = '\0'; + stat.inArg = 0; + stat.isD = 1; + } + else if(argc == 0){ + if(outbuf != NULL) + strcpy(&outbuf[0], "syntax error\r\n"); + return 2; + } + break; + + case ',': + if((stat.isD == 1)&&(argc == 1)) ///=, + { + if(outbuf != NULL) + strcpy(&outbuf[0], "syntax error\r\n"); + return 2; + } + if(!stat.inQuote && stat.inArg) { + stat.inArg = 0; + inbuf[i] = '\0'; + stat.limQ = 1; + } + break; + + default: + if (!stat.inArg) { + stat.inArg = 1; + argc++; + argv[argc - 1] = &inbuf[i]; + stat.limQ = 0; + if(stat.isD == 1) { + stat.isD = 2; + } + } + break; + } + } while (!stat.done && ++i < in_buf_size); + + if (stat.inQuote) + { + if(outbuf != NULL) + strcpy(&outbuf[0], "syntax error\r\n"); + return 2; + } + + if (argc < 1) + { + if(outbuf != NULL) + strcpy(&outbuf[0], "argc = 0\r\n"); + return 0; + } + + /* + * Some comamands can allow extensions like foo.a, foo.b and hence + * compare commands before first dot. + */ + i = ((p = os_strchr(argv[0], '.')) == NULL) ? 0 : + (p - argv[0]); + command = lookup_command(argv[0], i); + if (command == NULL) + { + if(outbuf != NULL) + sprintf(&outbuf[0], "cmd: %s NOT found.\r\n", inbuf); + return 1; + } + +#if CONFIG_STA_PS + /*if cmd,exit dtim ps*/ + if (os_strncmp(command->name, "ps", 2)) { + } +#endif + +#if CFG_CLI_DEBUG + s_running_status |= CLI_COMMAND_IS_RUNNING; + command->function(outbuf, out_buf_size , argc, argv); + s_running_status &= ~CLI_COMMAND_IS_RUNNING; +#else + command->function(outbuf, out_buf_size , argc, argv); +#endif + + return 0; +} + +#elif CONFIG_ATE_TEST +static beken_semaphore_t ate_test_semaphore = NULL; +static void ate_uart_rx_isr(uart_id_t id, void *param) +{ + int ret; + + ret = rtos_set_semaphore(&ate_test_semaphore); + if(kNoErr !=ret) + os_printf("ate_uart_rx_isr: ATE set sema failed\r\n"); +} + +static void ate_uart_tx_isr(uart_id_t id, void *param) +{ + bk_uart_disable_tx_interrupt(CONFIG_UART_PRINT_PORT); +} + +static void cli_ate_main(uint32_t data) +{ + + char *msg = NULL; + int ret = -1; + int cnt = 0; + uint8_t rx_data; + + if(NULL == ate_test_semaphore) + { + ret = rtos_init_semaphore(&ate_test_semaphore, 1); + if (kNoErr != ret) + os_printf("cli_ate_main: ATE create background sema failed\r\n"); + } + + bk_uart_disable_sw_fifo(CONFIG_UART_PRINT_PORT); + bk_uart_register_rx_isr(CONFIG_UART_PRINT_PORT, (uart_isr_t)ate_uart_rx_isr, NULL); + bk_uart_enable_rx_interrupt(CONFIG_UART_PRINT_PORT); + + bk_uart_register_tx_isr(CONFIG_UART_PRINT_PORT, (uart_isr_t)ate_uart_tx_isr, NULL); + bk_uart_enable_tx_interrupt(CONFIG_UART_PRINT_PORT); + + send_device_id(); + ate_test_multiple_cpus_init(); + + while (1) { + + ret = rtos_get_semaphore(&ate_test_semaphore, BEKEN_WAIT_FOREVER); + if(kNoErr == ret) { + while(1) /* read all data from rx-FIFO. */ + { + ret = uart_read_byte_ex(CONFIG_UART_PRINT_PORT, &rx_data); + if (ret == -1) + break; + + pCli->inbuf[cnt] = (char)rx_data; + cnt++; + + if(cnt >= INBUF_SIZE) + break; + } + + bkreg_run_command1(pCli->inbuf, cnt); + + if (cnt > 0) { + for (int i = 0;i < cnt; i++) + pCli->inbuf[i] = 0; + cnt = 0; + } + } + + msg = pCli->inbuf; + if (os_strcmp(msg, EXIT_MSG) == 0) + break; + } + + os_printf("CLI exited\r\n"); + os_free(pCli); + pCli = NULL; + + rtos_delete_thread(NULL); +} + +#else + +/* Parse input line and locate arguments (if any), keeping count of the number +* of arguments and their locations. Look up and call the corresponding cli +* function if one is found and pass it the argv array. +* +* Returns: 0 on success: the input line contained at least a function name and +* that function exists and was called. +* 1 on lookup failure: there is no corresponding function for the +* input line. +* 2 on invalid syntax: the arguments list couldn't be parsed +*/ +static int handle_input(char *inbuf) +{ + struct { + unsigned inArg: 1; + unsigned inQuote: 1; + unsigned done: 1; + unsigned limQ : 1; + unsigned isD : 2; + } stat; + static char *argv[16]; + int argc = 0; + int i = 0; + const struct cli_command *command = NULL; + const char *p; + + os_memset((void *)&argv, 0, sizeof(argv)); + os_memset(&stat, 0, sizeof(stat)); + + if (inbuf[i] == '\0') + return 0; + + do { + switch (inbuf[i]) { + case '\0': + if (((argc == 0)||(stat.isD == 1))||(stat.limQ)||(stat.inQuote)) + return 2; + stat.done = 1; + break; + + case '"': + if (i > 0 && inbuf[i - 1] == '\\' && stat.inArg) { + os_memcpy(&inbuf[i - 1], &inbuf[i], + os_strlen(&inbuf[i]) + 1); + --i; + break; + } + if (!stat.inQuote && stat.inArg) + break; + if (stat.inQuote && !stat.inArg) + return 2; + + if (!stat.inQuote && !stat.inArg) { + stat.inArg = 1; + stat.inQuote = 1; + argc++; + argv[argc - 1] = &inbuf[i + 1]; + } else if (stat.inQuote && stat.inArg) { + stat.inArg = 0; + stat.inQuote = 0; + inbuf[i] = '\0'; + } + break; + + case ' ': + if (i > 0 && inbuf[i - 1] == '\\' && stat.inArg) { + os_memcpy(&inbuf[i - 1], &inbuf[i], + os_strlen(&inbuf[i]) + 1); + --i; + break; + } + if (!stat.inQuote && stat.inArg) { + stat.inArg = 0; + inbuf[i] = '\0'; + } + break; + + case '=': + if(argc == 1) { + inbuf[i] = '\0'; + stat.inArg = 0; + stat.isD = 1; + } + else if(argc == 0){ + os_printf("The data does not conform to the regulations %d\r\n",__LINE__); + return 2; + } + break; + + case ',': + if((stat.isD == 1)&&(argc == 1)) ///=, + { + os_printf("The data does not conform to the regulations %d\r\n",__LINE__); + return 2; + } + if(!stat.inQuote && stat.inArg) { + stat.inArg = 0; + inbuf[i] = '\0'; + stat.limQ = 1; + } + break; + + default: + if (!stat.inArg) { + stat.inArg = 1; + argc++; + argv[argc - 1] = &inbuf[i]; + stat.limQ = 0; + if(stat.isD == 1) { + stat.isD = 2; + } + } + break; + } + } while (!stat.done && ++i < INBUF_SIZE); + + if (stat.inQuote) + return 2; + + if (argc < 1) + return 0; + + if (!pCli->echo_disabled) + os_printf("\r\n"); + + /* + * Some comamands can allow extensions like foo.a, foo.b and hence + * compare commands before first dot. + */ + i = ((p = os_strchr(argv[0], '.')) == NULL) ? 0 : + (p - argv[0]); + command = lookup_command(argv[0], i); + if (command == NULL) + return 1; + + os_memset(pCli->outbuf, 0, OUTBUF_SIZE); + cli_putstr("\r\n"); + +#if CONFIG_STA_PS + /*if cmd,exit dtim ps*/ + if (os_strncmp(command->name, "ps", 2)) { + } +#endif + +#if CFG_CLI_DEBUG + s_running_status |= CLI_COMMAND_IS_RUNNING; + command->function(pCli->outbuf, OUTBUF_SIZE, argc, argv); + s_running_status &= ~CLI_COMMAND_IS_RUNNING; +#else + command->function(pCli->outbuf, OUTBUF_SIZE, argc, argv); +#endif + cli_putstr(pCli->outbuf); + return 0; +} + +/* Perform basic tab-completion on the input buffer by string-matching the +* current input line against the cli functions table. The current input line +* is assumed to be NULL-terminated. */ +static void tab_complete(char *inbuf, unsigned int *bp) +{ + int i, n, m; + const char *fm = NULL; + + os_printf("\r\n"); + + /* show matching commands */ + for (i = 0, n = 0, m = 0; i < MAX_COMMANDS && n < pCli->num_commands; + i++) { + if (pCli->commands[i]->name != NULL) { + if (!os_strncmp(inbuf, pCli->commands[i]->name, *bp)) { + m++; + if (m == 1) + fm = pCli->commands[i]->name; + else if (m == 2) + os_printf("%s %s ", fm, + pCli->commands[i]->name); + else + os_printf("%s ", + pCli->commands[i]->name); + } + n++; + } + } + + /* there's only one match, so complete the line */ + if (m == 1 && fm) { + n = os_strlen(fm) - *bp; + if (*bp + n < INBUF_SIZE) { + os_memcpy(inbuf + *bp, fm + *bp, n); + *bp += n; + inbuf[(*bp)++] = ' '; + inbuf[*bp] = '\0'; + } + } + + /* just redraw input line */ + os_printf("%s%s", PROMPT, inbuf); +} +/* Get an input line. +* +* Returns: 1 if there is input, 0 if the line should be ignored. */ +static int get_input(char *inbuf, unsigned int *bp) +{ + if (inbuf == NULL) { + os_printf("inbuf_null\r\n"); + return 0; + } + + while (cli_getchar(&inbuf[*bp]) == 1) { +#if CONFIG_BKREG + if ((0x01U == (UINT8)inbuf[*bp]) && (*bp == 0)) { + (*bp)++; + continue; + } else if ((0xe0U == (UINT8)inbuf[*bp]) && (*bp == 1)) { + (*bp)++; + continue; + } else if ((0xfcU == (UINT8)inbuf[*bp]) && (*bp == 2)) { + (*bp)++; + continue; + } else { + if ((0x01U == (UINT8)inbuf[0]) + && (0xe0U == (UINT8)inbuf[1]) + && (0xfcU == (UINT8)inbuf[2]) + && (*bp == 3)) { + uint8_t ch = inbuf[*bp]; + uint8_t left = ch, len = 4 + (uint8_t)ch; + inbuf[*bp] = ch; + (*bp)++; + + if (ch >= INBUF_SIZE) { + os_printf("Error: input buffer overflow\r\n"); + os_printf(PROMPT); + *bp = 0; + return 0; + } + + while (left--) { + if (0 == cli_getchar((char *)&ch)) + break; + + inbuf[*bp] = ch; + (*bp)++; + } + + bkreg_run_command(inbuf, len); + os_memset(inbuf, 0, len); + *bp = 0; + continue; + } + } +#endif + if (inbuf[*bp] == RET_CHAR) + continue; + if (inbuf[*bp] == END_CHAR) { /* end of input line */ + inbuf[*bp] = '\0'; + *bp = 0; + return 1; + } + + if ((inbuf[*bp] == 0x08) || /* backspace */ + (inbuf[*bp] == 0x7f)) { /* DEL */ + if (*bp > 0) { + (*bp)--; + if (!pCli->echo_disabled) + os_printf("%c %c", 0x08, 0x08); + } + continue; + } + + if (inbuf[*bp] == '\t') { + inbuf[*bp] = '\0'; + tab_complete(inbuf, bp); + continue; + } + + if (!pCli->echo_disabled) + os_printf("%c", inbuf[*bp]); + + (*bp)++; + if (*bp >= INBUF_SIZE) { + os_printf("Error: input buffer overflow\r\n"); + os_printf(PROMPT); + *bp = 0; + return 0; + } + } + + return 0; +} + +/* Print out a bad command string, including a hex +* representation of non-printable characters. +* Non-printable characters show as "\0xXX". +*/ +static void print_bad_command(char *cmd_string) +{ + if (cmd_string != NULL) { + char *c = cmd_string; + os_printf("command '"); + while (*c != '\0') { + if (is_print(*c)) + os_printf("%c", *c); + else + os_printf("\\0x%x", *c); + ++c; + } + os_printf("' not found\r\n"); + } +} + +/* Main CLI processing thread +* +* Waits to receive a command buffer pointer from an input collector, and +* then processes. Note that it must cleanup the buffer when done with it. +* +* Input collectors handle their own lexical analysis and must pass complete +* command lines to CLI. +*/ +void icu_struct_dump(void); + +static void cli_main(uint32_t data) +{ + + char *msg = NULL; + int ret; + +#if CONFIG_RF_OTA_TEST + demo_sta_app_init("CMW-AP", "12345678"); +#endif /* CONFIG_RF_OTA_TEST*/ + + bk_uart_enable_rx_interrupt(CONFIG_UART_PRINT_PORT); + + while (1) { + + if (get_input(pCli->inbuf, &pCli->bp)) { + msg = pCli->inbuf; + + if (os_strcmp(msg, EXIT_MSG) == 0) + break; + + ret = handle_input(msg); + if (ret == 1) + print_bad_command(msg); + else if (ret == 2) + os_printf("syntax error\r\n"); + + os_printf(PROMPT); + } + } + + os_printf("CLI exited\r\n"); + os_free(pCli); + pCli = NULL; + + rtos_delete_thread(NULL); +} + +#endif // #if (!CONFIG_SHELL_ASYNCLOG) + +void help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); +void cli_sort_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); + +extern const struct cli_command * cli_debug_cmd_table(int *num); + +void cli_debug_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + int i, tbl_num = 0; + const struct cli_command *cmd_tbl; + + if (argc < 2) + { + if(pcWriteBuffer != NULL) + strcpy(&pcWriteBuffer[0], "argc < 2\r\n"); + return; + } + + cmd_tbl = cli_debug_cmd_table(&tbl_num); + + i = lookup_cmd_table(cmd_tbl, tbl_num, argv[1], 0); + + if (i < 0) + { + if(pcWriteBuffer != NULL) + sprintf(&pcWriteBuffer[0], "cmd: %s NOT found.\r\n", argv[1]); + return; + } + + cmd_tbl[i].function(pcWriteBuffer, xWriteBufferLen , argc - 1, &argv[1]); + +} + +static void log_setting_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + int echo_level; + int level; + int sync_lvl; + + if (argc > 1) + { + echo_level = strtoul(argv[1], NULL, 0); + +#if (CONFIG_SHELL_ASYNCLOG) + shell_echo_set(echo_level); +#else + if(echo_level) + echo_level = 0; + else + echo_level = 1; + pCli->echo_disabled = echo_level; +#endif //#if (CONFIG_SHELL_ASYNCLOG) + } + +#if (CONFIG_SHELL_ASYNCLOG) + if (argc > 2) + { + level = strtoul(argv[2], NULL, 0); + shell_set_log_level(level); + } + if (argc > 3) + { + sync_lvl = strtoul(argv[3], NULL, 0); + bk_set_printf_sync(sync_lvl); + } +#endif + +#if (CONFIG_SHELL_ASYNCLOG) + echo_level = shell_echo_get(); + level = shell_get_log_level(); + sync_lvl = bk_get_printf_sync(); + + sprintf(pcWriteBuffer, "log: echo %d, level %d, sync %d.\r\n", echo_level, level, sync_lvl); +#else + + sprintf(pcWriteBuffer,"log: echo %d.\r\n", pCli->echo_disabled ? 0 : 1); +#endif //#if (CONFIG_SHELL_ASYNCLOG) + + return; + + (void)level; + (void)sync_lvl; + +} + +#if (CONFIG_SHELL_ASYNCLOG && CONFIG_MASTER_CORE) +#if 0 +#define CPU1_CMD_BUF_SIZE 128 +static char cpu1_cmd_buf[CPU1_CMD_BUF_SIZE]; +void cli_cpu1_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + int i; + int buf_len = 0; + int str_len = 0; + + for(i = 1; i < argc; i++) + { + str_len = strlen(argv[i]); + if ((buf_len + str_len + 3) < CPU1_CMD_BUF_SIZE) + { + os_memcpy(&cpu1_cmd_buf[buf_len], argv[i], str_len); + buf_len += str_len; + cpu1_cmd_buf[buf_len++] = ' '; + } + else + break; + } + + cpu1_cmd_buf[buf_len++] = '\r'; + cpu1_cmd_buf[buf_len++] = '\n'; + + shell_cmd_forward(cpu1_cmd_buf, buf_len); +} +#endif + +/* it is a new implementation of the cli_cpu1_command, combine cpu1 cmd & paramters into argv[0] buffer. */ +void cli_cpu1_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + int i, j; + int buf_len = 0; + int str_len = 0; + + for(i = 1; i < argc; i++) + { + str_len = strlen(argv[i]); + for(j = 0; j < str_len; j++) + { + if(argv[i][j] == ' ') + { + break; + } + } + + if(j < str_len) /* contains ' ' in string. */ + { + argv[0][buf_len++] = '"'; + for(j = 0; j < str_len; j++) + { + if(argv[i][j] == '"') + { + argv[0][buf_len++] = '\\'; + } + argv[0][buf_len++] = argv[i][j]; + } + argv[0][buf_len++] = '"'; + } + else + { + memcpy(&argv[0][buf_len], argv[i], str_len); + buf_len += str_len; + argv[0][buf_len++] = ' '; + } + } + + argv[0][buf_len++] = '\r'; + argv[0][buf_len++] = '\n'; + + shell_cmd_forward(argv[0], buf_len); +} + +#endif + +#if (CONFIG_SHELL_ASYNCLOG) +void cli_log_statist(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + int data_cnt, i, buf_len = 0; + u32 log_statist[5]; + data_cnt = shell_get_log_statist(log_statist, ARRAY_SIZE(log_statist)); + + if(data_cnt == 0) + { + strcpy(pcWriteBuffer, "\r\n Nothing \r\n"); + return; + } + + buf_len = sprintf(&pcWriteBuffer[0], "\r\nlog overflow: %d.", log_statist[0]); + buf_len += sprintf(&pcWriteBuffer[buf_len], "\r\nlog out count: %d.", log_statist[1]); + + for(i = 2; i < data_cnt; i++) + { + buf_len += sprintf(&pcWriteBuffer[buf_len], "\r\nBuffer[%d] run out count: %d.", i - 2, log_statist[i]); + } + + return; + +} + +static void cli_log_disable(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc < 3) + { + int i = 0, buf_len = 0; + char * mod_name; + + buf_len = sprintf(&pcWriteBuffer[0], "Usage: modlog tag_name on/off\r\n"); + + while(1) + { + mod_name = bk_get_disable_mod(&i); + + if(mod_name != NULL) + { + if(buf_len == 0) + { + buf_len = sprintf(&pcWriteBuffer[0], "disabled mod list:\r\n%s\r\n", mod_name); + } + else + { + buf_len += sprintf(&pcWriteBuffer[buf_len], "%s\r\n", mod_name); + } + } + else + break; + } + + return; + } + + if (!os_strcasecmp(argv[2], "on")) + { + bk_disable_mod_printf(argv[1], 0); + } + else if (!os_strcasecmp(argv[2], "off")) + { + bk_disable_mod_printf(argv[1], 1); + } +} +#endif + +#if CONFIG_BKREG +#define BKCMD_RXSENS_R 'r' +#define BKCMD_RXSENS_X 'x' +#define BKCMD_RXSENS_s 's' + +#define BKCMD_TXEVM_T 't' +#define BKCMD_TXEVM_X 'x' +#define BKCMD_TXEVM_E 'e' + +void bkreg_cmd_handle_input(char *inbuf, int len) +{ + if (((char)BKREG_MAGIC_WORD0 == inbuf[0]) + && ((char)BKREG_MAGIC_WORD1 == inbuf[1]) + && ((char)BKREG_MAGIC_WORD2 == inbuf[2])) { + if (cli_getchars(inbuf, len)) { + bkreg_run_command(inbuf, len); + os_memset(inbuf, 0, len); + } + } else if ((((char)BKCMD_RXSENS_R == inbuf[0]) + && ((char)BKCMD_RXSENS_X == inbuf[1]) + && ((char)BKCMD_RXSENS_s == inbuf[2])) + || (((char)BKCMD_TXEVM_T == inbuf[0]) + && ((char)BKCMD_TXEVM_X == inbuf[1]) + && ((char)BKCMD_TXEVM_E == inbuf[2]))) { + if (cli_getchars(inbuf, len)) { +#if (CONFIG_SHELL_ASYNCLOG) + handle_shell_input(inbuf, len, 0, 0); +#else //#if (CONFIG_SHELL_ASYNCLOG) + handle_input(inbuf); +#endif // #if (CONFIG_SHELL_ASYNCLOG) + os_memset(inbuf, 0, len); + } + } + +} +#endif + +static const struct cli_command built_ins[] = { + {"help", NULL, help_command}, + {"log", "log [echo(0,1)] [level(0~5)] [sync(0,1)]", log_setting_cmd}, +// {"sort", NULL, cli_sort_command}, + {"debug", "debug cmd [param] (ex:debug help)", cli_debug_command}, +#if (CONFIG_SHELL_ASYNCLOG && CONFIG_MASTER_CORE) + {"cpu1", "cpu1 cmd (ex:cpu1 help)", cli_cpu1_command}, +#endif +#if (CONFIG_SHELL_ASYNCLOG) + {"loginfo", "log statistics.", cli_log_statist}, + {"modlog", "modlog tag_name on/off", cli_log_disable}, +#endif +}; + +static int _cli_name_cmp(const void *a, const void *b) +{ + struct cli_command *cli0, *cli1; + + cli0 = *(struct cli_command **)a; + cli1 = *(struct cli_command **)b; + + if ((NULL == a) || (NULL == b)) + return 0; + + return os_strcmp(cli0->name, cli1->name); +} + +void cli_sort_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t build_in_count; + GLOBAL_INT_DECLARATION(); + + build_in_count = sizeof(built_ins) / sizeof(struct cli_command); + + os_printf("cmd_count:%d, built_in_count:%d\r\n", pCli->num_commands, build_in_count); + + GLOBAL_INT_DISABLE(); + qsort(&pCli->commands[build_in_count], pCli->num_commands - build_in_count, sizeof(struct cli_command *), _cli_name_cmp); + GLOBAL_INT_RESTORE(); +} + +/* Built-in "help" command: prints all registered commands and their help +* text string, if any. */ +void help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + int i, n; + uint32_t build_in_count = sizeof(built_ins) / sizeof(struct cli_command); + +#if (DEBUG) + build_in_count++; //For command: micodebug +#endif + + os_printf("====Build-in Commands====\r\n"); + for (i = 0, n = 0; i < MAX_COMMANDS && n < pCli->num_commands; i++) { + if (pCli->commands[i]->name) { + if (pCli->commands[i]->help) + os_printf("%s: %s\r\n", pCli->commands[i]->name, + pCli->commands[i]->help ? + pCli->commands[i]->help : ""); + else + os_printf("%s\r\n", pCli->commands[i]->name); + + n++; + if (n == build_in_count) + os_printf("\r\n====User Commands====\r\n"); + + if((n & 0x0f) == 0) + rtos_delay_milliseconds(50); + } + } +} + +int cli_register_command(const struct cli_command *command) +{ + int i; + if (!command->name || !command->function) + return 1; + + if (pCli->num_commands < MAX_COMMANDS) { + /* Check if the command has already been registered. + * Return 0, if it has been registered. + */ + for (i = 0; i < pCli->num_commands; i++) { + if (pCli->commands[i] == command) + return 0; + } + pCli->commands[pCli->num_commands++] = command; + return 0; + } + + return 1; +} + +int cli_unregister_command(const struct cli_command *command) +{ + int i; + if (!command->name || !command->function) + return 1; + + for (i = 0; i < pCli->num_commands; i++) { + if (pCli->commands[i] == command) { + pCli->num_commands--; + int remaining_cmds = pCli->num_commands - i; + if (remaining_cmds > 0) { + os_memmove(&pCli->commands[i], &pCli->commands[i + 1], + (remaining_cmds * + sizeof(struct cli_command *))); + } + pCli->commands[pCli->num_commands] = NULL; + return 0; + } + } + + return 1; +} + + +int cli_register_commands(const struct cli_command *commands, int num_commands) +{ + int i; + for (i = 0; i < num_commands; i++) + if (cli_register_command(commands++)) + return 1; + return 0; +} + +int cli_unregister_commands(const struct cli_command *commands, + int num_commands) +{ + int i; + for (i = 0; i < num_commands; i++) + if (cli_unregister_command(commands++)) + return 1; + + return 0; +} + +/* ========= CLI input&output APIs ============ */ +int cli_printf(const char *msg, ...) +{ + va_list ap; + char *pos, message[256]; + int sz; + int nMessageLen = 0; + + os_memset(message, 0, 256); + pos = message; + + sz = 0; + va_start(ap, msg); + nMessageLen = vsnprintf(pos, 256 - sz, msg, ap); + va_end(ap); + + if (nMessageLen <= 0) return 0; + + cli_putstr((const char *)message); + return 0; +} + +int cli_putstr(const char *msg) +{ + if (msg[0] != 0) + uart_write_string(CLI_UART, msg); + return 0; +} + +int cli_getchar(char *inbuf) +{ + if (bk_uart_read_bytes(CLI_UART, inbuf, 1, CLI_GETCHAR_TIMEOUT) > 0) + return 1; + else + return 0; +} + +int cli_getchars(char *inbuf, int len) +{ + if (bk_uart_read_bytes(CLI_UART, inbuf, len, CLI_GETCHAR_TIMEOUT) > 0) + return 1; + else + return 0; +} + +int cli_getchars_prefetch(char *inbuf, int len) +{ + return 0; +} + +int cli_get_all_chars_len(void) +{ + return uart_get_length_in_buffer(CLI_UART); +} + +static const struct cli_command user_clis[] = { +}; + +beken_thread_t cli_thread_handle = NULL; +int bk_cli_init(void) +{ + int ret; + + pCli = (struct cli_st *)os_malloc(sizeof(struct cli_st)); + if (pCli == NULL) + return kNoMemoryErr; + + os_memset((void *)pCli, 0, sizeof(struct cli_st)); + + if (cli_register_commands(&built_ins[0], + sizeof(built_ins) / sizeof(struct cli_command))) + goto init_general_err; + + if (cli_register_commands(user_clis, sizeof(user_clis) / sizeof(struct cli_command))) + goto init_general_err; + +#if (CLI_CFG_WIFI == 1) + cli_wifi_init(); +#endif + +#if (CLI_CFG_NETIF == 1) + cli_netif_init(); +#endif + +#if (CLI_CFG_BLE == 1) + cli_ble_init(); +#endif + +#if (CLI_CFG_MISC == 1) + cli_misc_init(); +#endif + +#if (CLI_CFG_MEM == 1) + cli_mem_init(); +#endif + +#if (CLI_CFG_AIRKISS == 1) + cli_airkiss_init(); +#endif + +#if (CLI_CFG_PHY == 1) + cli_phy_init(); +#endif + +#if (CLI_CFG_IPERF == 1) + cli_phy_init(); +#endif + +#if (CLI_CFG_TIMER == 1) + cli_timer_init(); +#endif + +#if (CLI_CFG_WDT == 1) + cli_wdt_init(); +#endif + +#if (CLI_CFG_TRNG == 1) + cli_trng_init(); +#endif + +#if (CLI_CFG_EFUSE == 1) + cli_efuse_init(); +#endif + +#if (CLI_CFG_DMA == 1) + cli_dma_init(); +#endif + +#if (CLI_CFG_GPIO == 1) + cli_gpio_init(); +#endif + +#if (CLI_CFG_OS == 1) + cli_os_init(); +#endif + +#if (CLI_CFG_OTA == 1) + cli_ota_init(); +#endif + +#if (CLI_CFG_FLASH == 1) + cli_flash_init(); +#endif + +#if (CLI_CFG_FLASH == 1) + cli_flash_test_init(); +#endif + +#if (CLI_CFG_SDIO_HOST == 1) + cli_sdio_host_init(); +#endif + +#if (CLI_CFG_KEYVALUE == 1) + cli_keyVaule_init(); +#endif + +#if (CLI_CFG_MATTER == 1) + cli_matter_init(); +#endif + +#if (CLI_CFG_UART == 1) + cli_uart_init(); +#endif + +#if (CLI_CFG_SPI == 1) + cli_spi_init(); +#endif + +#if (CLI_CFG_QSPI == 1) + cli_qspi_init(); +#endif + +#if (CONFIG_AON_RTC_TEST == 1) + cli_aon_rtc_init(); +#endif + +#if (CLI_CFG_I2C == 1) + cli_i2c_init(); +#endif + +#if (CLI_CFG_JPEGENC == 1) + cli_jpeg_init(); +#endif + +#if (CLI_CFG_ADC == 1) + cli_adc_init(); +#endif + +#if (CLI_CFG_SD == 1) + cli_sd_init(); +#endif + +#if (CLI_FATFS == 1) + cli_fatfs_init(); +#endif + +#if (CLI_CFG_TEMP_DETECT == 1) + cli_temp_detect_init(); +#endif + +#if (CLI_CFG_SECURITY == 1) + cli_security_init(); +#endif + +#if (CLI_CFG_MICO == 1) + cli_mico_init(); +#endif + +#if (CLI_CFG_EVENT == 1) + cli_event_init(); +#endif + +#if (CLI_CFG_PWR == 1) + cli_pwr_init(); +#endif + +#if (CLI_CFG_REG == 1) + cli_reg_init(); +#endif + +#if CONFIG_CAMERA + if (video_demo_register_cmd()) + goto init_general_err; +#endif +#if (CONFIG_SOC_BK7271) +#if CONFIG_BT + bk7271_ble_cli_init(); +#endif +#if CONFIG_USB_HOST + bk7271_dsp_cli_init(); +#endif +#endif + +#if (CONFIG_SOC_BK7256XX) +#if CONFIG_USB_HOST + usb_cli_init(); +#endif +#endif + +#if (CLI_CFG_PWM == 1) + cli_pwm_init(); +#endif + +#if (CLI_CFG_IPERF == 1) + cli_iperf_init(); +#endif + +#if CONFIG_LWIP + //cli_lwip_init(); +#endif + +#if (CLI_CFG_EXCEPTION == 1) + cli_exception_init(); +#endif + +#if (CLI_CFG_ICU == 1) + cli_icu_init(); +#endif + +#if (CLI_CFG_VAULT == 1) + cli_vault_init(); +#endif + +#if (CLI_CFG_AUD == 1) + cli_aud_init(); +#endif + +#if (CLI_CFG_AUD_INTF == 1) + cli_aud_intf_init(); +#endif + +#if (CLI_CFG_AUD_CP0 == 1) + cli_aud_cp0_init(); +#endif + +#if (CLI_CFG_FFT == 1) + cli_fft_init(); +#endif + +#if (CLI_CFG_SBC == 1) + cli_sbc_init(); +#endif + +#if (CLI_CFG_I2S == 1) + cli_i2s_init(); +#endif + +#if (CONFIG_TOUCH) + cli_touch_init(); +#endif + +#if (CLI_CFG_LCD == 1) + cli_lcd_init(); +#endif + +#if (CLI_CFG_DMA2D == 1) + cli_dma2d_init(); +#endif + +#if (CLI_CFG_CALENDAR == 1) + cli_calendar_init(); +#endif + +#if (CLI_CFG_UVC == 1) + cli_uvc_init(); +#endif + +#if (CONFIG_AT_CMD) + cli_at_init(); +#endif + +#if (CLI_CFG_JPEGDEC == 1) + cli_jpegdec_init(); +#endif + +#if (CLI_CFG_AEC == 1) + cli_aec_init(); +#endif + +#if (CLI_CFG_G711 == 1) + cli_g711_init(); +#endif + +#if (CLI_CFG_MP3 == 1) + cli_mp3_init(); +#endif + +#if (CLI_CFG_DVP == 1) + cli_dvp_init(); +#endif + +#if (CONFIG_DOORBELL == 1) +//#if (CONFIG_DUAL_CORE) + cli_doorbell_init(); +//#endif +#endif + +#if (CONFIG_MEDIA == 1) + media_cli_init(); +#endif + +#if (CLI_CFG_PSRAM) + cli_psram_init(); +#endif + + + /* sort cmds after registered all cmds. */ + cli_sort_command(NULL, 0, 0, NULL); + +#if CONFIG_SHELL_ASYNCLOG +#if CONFIG_ATE_TEST + ret = rtos_create_thread(&cli_thread_handle, + SHELL_TASK_PRIORITY, + "cli", + (beken_thread_function_t)cli_ate_main /*cli_main*/, + 4096, + 0); +#else + ret = rtos_create_thread(&cli_thread_handle, + SHELL_TASK_PRIORITY, + "cli", + (beken_thread_function_t)shell_task /*cli_main*/, + 4096, + 0); +#endif +#else // #if CONFIG_SHELL_ASYNCLOG + ret = rtos_create_thread(&cli_thread_handle, + BEKEN_DEFAULT_WORKER_PRIORITY, + "cli", + (beken_thread_function_t)cli_main, + 4096, + 0); +#endif // #if CONFIG_SHELL_ASYNCLOG + if (ret != kNoErr) { + os_printf("Error: Failed to create cli thread: %d\r\n", + ret); + goto init_general_err; + } + + pCli->initialized = 1; +#if (!CONFIG_SHELL_ASYNCLOG) + pCli->echo_disabled = 0; +#endif + +#if (CONFIG_SLAVE_CORE && CONFIG_MEDIA) + ret = common_mb_init(); + if (ret != kNoErr) { + os_printf("Error: Failed to create common_mb thread: %d\r\n", ret); + } +#endif + + return kNoErr; + +init_general_err: + if (pCli) { + os_free(pCli); + pCli = NULL; + } + + return kGeneralErr; +} + +#if CFG_CLI_DEBUG +void cli_show_running_command(void) +{ + if (s_running_command_index < MAX_COMMANDS) { + const struct cli_command *cmd = pCli->commands[s_running_command_index]; + + CLI_LOGI("last cli command[%d]: %s(%s)\n", s_running_command_index, cmd->name, + (s_running_status & CLI_COMMAND_IS_RUNNING) ? "running" : "stopped"); + rtos_dump_task_list(); + rtos_dump_backtrace(); + } else + CLI_LOGI("no command running\n"); +} +#endif + +// eof + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_netif.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_netif.c new file mode 100755 index 0000000..1b2dbeb --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_netif.c @@ -0,0 +1,241 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 "bk_cli.h" +#include "wlan_defs_pub.h" +#include "bk_private/bk_wifi_wrapper.h" +#if CONFIG_LWIP +#if CONFIG_HARMONY_LWIP +//#include "ping.h" +#else +#include "lwip/ping.h" +#endif + +#endif +#include +#include "cli.h" + +extern void make_tcp_server_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); + +#define CLI_DUMP_IP(_prompt, _ifx, _cfg) do {\ + CLI_LOGI("%s netif(%s) ip4=%s mask=%s gate=%s dns=%s\n", (_prompt),\ + (_ifx) == NETIF_IF_STA ? "sta" : "ap",\ + (_cfg)->ip, (_cfg)->mask, (_cfg)->gateway, (_cfg)->dns);\ +} while(0) + +#if (CLI_CFG_NETIF == 1) + +static void ip_cmd_show_ip(int ifx) +{ + netif_ip4_config_t config; + + if (ifx == NETIF_IF_STA || ifx == NETIF_IF_AP) { + BK_LOG_ON_ERR(bk_netif_get_ip4_config(ifx, &config)); + CLI_DUMP_IP(" ", ifx, &config); + } else { + BK_LOG_ON_ERR(bk_netif_get_ip4_config(NETIF_IF_STA, &config)); + CLI_DUMP_IP(" ", NETIF_IF_STA, &config); + BK_LOG_ON_ERR(bk_netif_get_ip4_config(NETIF_IF_AP, &config)); + CLI_DUMP_IP(" ", NETIF_IF_AP, &config); + } +} + +void cli_ip_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + netif_ip4_config_t config = {0}; + int ifx = NETIF_IF_COUNT; + + if (argc > 1) { + if (os_strcmp("sta", argv[1]) == 0) { + ifx = NETIF_IF_STA; + } else if (os_strcmp("ap", argv[1]) == 0) { + ifx = NETIF_IF_AP; + } else { + CLI_LOGE("invalid netif name\n"); + return; + } + } + + if (argc == 1) { + ip_cmd_show_ip(NETIF_IF_COUNT); + } else if (argc == 2) { + ip_cmd_show_ip(ifx); + } else if (argc == 6) { + os_strncpy(config.ip, argv[2], NETIF_IP4_STR_LEN); + os_strncpy(config.mask, argv[3], NETIF_IP4_STR_LEN); + os_strncpy(config.gateway, argv[4], NETIF_IP4_STR_LEN); + os_strncpy(config.dns, argv[5], NETIF_IP4_STR_LEN); + BK_LOG_ON_ERR(bk_netif_set_ip4_config(ifx, &config)); + CLI_DUMP_IP("set static ip, ", ifx, &config); + } else { + CLI_LOGE("usage: ip [sta|ap][{ip}{mask}{gate}{dns}]\n"); + } +} + +#if CONFIG_IPV6 +static void ip6_cmd_show_ip(int ifx) +{ + if (ifx == NETIF_IF_STA || ifx == NETIF_IF_AP) { + bk_netif_get_ip6_addr_info(ifx); + } else { + CLI_LOGI("[sta]\n"); + bk_netif_get_ip6_addr_info(NETIF_IF_STA); + CLI_LOGI("[ap]\n"); + bk_netif_get_ip6_addr_info(NETIF_IF_AP); + } +} + +void cli_ip6_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) + +{ + int ifx = NETIF_IF_COUNT; + + if (argc > 1) { + if (os_strcmp("sta", argv[1]) == 0) { + ifx = NETIF_IF_STA; + } else if (os_strcmp("ap", argv[1]) == 0) { + ifx = NETIF_IF_AP; + } else { + CLI_LOGE("invalid netif name\n"); + return; + } + } + + if (argc == 1) { + ip6_cmd_show_ip(NETIF_IF_COUNT); + } else if (argc == 2) { + ip6_cmd_show_ip(ifx); + } +} +#endif + +void cli_dhcpc_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + BK_LOG_ON_ERR(bk_netif_dhcpc_start(NETIF_IF_STA)); + CLI_LOGI("STA start dhcp client\n"); +} + +void arp_Command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + os_printf("arp_Command\r\n"); +} + +void cli_ping_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ +#if 0 //CONFIG_LWIP + uint32_t cnt = 4; + if (argc == 1) { + os_printf("Please input: ping \n"); + return; + } + if (argc == 2 && (os_strcmp("--stop", argv[1]) == 0)) { + ping_stop(); + return; + } + if (argc > 2) + cnt = os_strtoul(argv[2], NULL, 10); + + os_printf("ping IP address:%s\n", argv[1]); + ping_start(argv[1], cnt, 0); +#endif +} + +#if CONFIG_ALI_MQTT +extern void test_mqtt_start(const char *host_name, const char *username, + const char *password, const char *topic); +void cli_ali_mqtt_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + os_printf("start test mqtt...\n"); + if (argc == 4) { + test_mqtt_start(argv[1], argv[2], argv[3], NULL); + } else if (argc == 5) { + test_mqtt_start(argv[1], argv[2], argv[3], argv[4]); + } else { + // mqttali 222.71.10.2 aclsemi ****** /aclsemi/bk7256/cmd/1234 + CLI_LOGE("usage: mqttali [host name|ip] [username] [password] [topic]\n"); + } +} +#endif + +#if CONFIG_HTTP +extern void LITE_openlog(const char *ident); +extern void LITE_closelog(void); +void cli_http_debug_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32 http_log = 0; + + if (argc == 2) { + http_log = os_strtoul(argv[1], NULL, 10); + if (1 == http_log ) { + LITE_openlog("http"); + } else { + LITE_closelog(); + } + } else { + CLI_LOGE("usage: httplog [1|0].\n"); + } +} +#endif + +uint32_t g_per_packet_info_output_bitmap = 0; + +void set_per_packet_info_output_bitmap(const char *bitmap) +{ + g_per_packet_info_output_bitmap = os_strtoul(bitmap, NULL, 16); + CLI_LOGI("set per_packet_info_output_bitmap:0x%x\n",g_per_packet_info_output_bitmap); +} + +void cli_per_packet_info_output_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc == 2) { + set_per_packet_info_output_bitmap(argv[1]); + } else { + CLI_LOGE("usage: per_packet_info [per_packet_info_output_bitmap(base 16)]\n"); + } +} + + +#define NETIF_CMD_CNT (sizeof(s_netif_commands) / sizeof(struct cli_command)) +static const struct cli_command s_netif_commands[] = { + {"ip", "ip [sta|ap][{ip}{mask}{gate}{dns}]", cli_ip_cmd}, + {"dhcpc", "dhcpc", cli_dhcpc_cmd}, + {"ping", "ping ", cli_ping_cmd}, +#ifdef CONFIG_IPV6 + {"ping6", "ping6 xxx", cli_ping_cmd}, + {"ip6", "ip6 [sta|ap][{ip}{state}]", cli_ip6_cmd}, +#endif +#ifdef TCP_CLIENT_DEMO + {"tcp_cont", "tcp_cont [ip] [port]", tcp_make_connect_server_command}, +#endif + +#if CONFIG_TCP_SERVER_TEST + {"tcp_server", "tcp_server [ip] [port]", make_tcp_server_command }, +#endif +#if CONFIG_ALI_MQTT + {"mqttali", "paho mqtt test", cli_ali_mqtt_cmd}, +#endif +#if CONFIG_OTA_HTTP + {"httplog", "httplog [1|0].", cli_http_debug_cmd}, +#endif + {"per_packet_info", "per_packet_info [per_packet_info_output_bitmap(base 16)]", cli_per_packet_info_output_cmd}, + +}; + +int cli_netif_init(void) +{ + return cli_register_commands(s_netif_commands, NETIF_CMD_CNT); +} + +#endif //#if (CLI_CFG_NETIF == 1) diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_reg.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_reg.c new file mode 100755 index 0000000..b1abaca --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_reg.c @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 "cli.h" +#include +#include +#include "icu_hal.h" +#include "pwm_hal.h" +#include "timer_hal.h" +#include "gpio_hal.h" +#include "dma_hal.h" +#include "uart_hal.h" +#include "wdt_hal.h" +#include "trng_hal.h" +#include "efuse_hal.h" +#include "adc_hal.h" +#include "spi_hal.h" +#include "i2c_hal.h" + +#if CONFIG_QSPI +#include "qspi_hal.h" +#endif +#if CONFIG_AON_RTC +#include "aon_rtc_hal.h" +#endif +#if CONFIG_CALENDAR +#include "calendar_hal.h" +#endif +#if CONFIG_FLASH +#include "flash_hal.h" +#endif +#if CONFIG_SDIO_HOST +#include "sdio_host_hal.h" +#endif + +static int hex2num(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return -1; +} + +static int hex2byte(const char *hex) +{ + int a, b; + a = hex2num(*hex++); + if (a < 0) + return -1; + b = hex2num(*hex++); + if (b < 0) + return -1; + return (a << 4) | b; +} + +/** + * hexstr2bin - Convert ASCII hex string into binary data + * @hex: ASCII hex string (e.g., "01ab") + * @buf: Buffer for the binary data + * @len: Length of the text to convert in bytes (of buf); hex will be double + * this size + * Returns: 0 on success, -1 on failure (invalid hex string) + */ +static int cli_hexstr2bin(const char *hex, u8 *buf, size_t len) +{ + size_t i; + int a; + const char *ipos = hex; + u8 *opos = buf; + + for (i = 0; i < len; i++) { + a = hex2byte(ipos); + if (a < 0) + return -1; + *opos++ = a; + ipos += 2; + } + return 0; +} + +#if CONFIG_JPEG_ENCODE +#include "jpeg_hal.h" +#endif + +static void cli_reg_write_read_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + UINT32 reg_addr = 0, reg_value = 0; + UINT8 optr_len = 0, optr_tab[9]; + + os_memset(optr_tab, 0, 9); + os_memset(optr_tab, 0x30, 8); + + if (os_strncmp(argv[1], "-r", 2) == 0) { + if (argc != 3) { + os_printf("regshow -r addr\r\n"); + return; + } + + optr_len = os_strlen(argv[2]); + if (optr_len > 8) { + os_printf("addr 0-FFFFFFFF\r\n"); + return; + } + optr_len = 8 - optr_len; + os_memcpy(&optr_tab[optr_len], argv[2], os_strlen(argv[2])); + + cli_hexstr2bin((char *)optr_tab, (u8 *)®_addr, 4); + reg_addr = ntohl(reg_addr); + os_printf("regshow R: addr:0x%08x, value:0x%08x\r\n", reg_addr, REG_READ(reg_addr)); + } else if (os_strncmp(argv[1], "-w", 2) == 0) { + if (argc != 4) { + os_printf("regshow -w addr value\r\n"); + return; + } + + optr_len = os_strlen(argv[2]); + if (optr_len > 8) { + os_printf("addr 0-FFFFFFFF\r\n"); + return; + } + optr_len = 8 - optr_len; + os_memcpy(&optr_tab[optr_len], argv[2], os_strlen(argv[2])); + + cli_hexstr2bin((char *)optr_tab, (u8 *)®_addr, 4); + reg_addr = ntohl(reg_addr); + + + os_memset(optr_tab, 0x30, 8); + optr_len = os_strlen(argv[3]); + if (optr_len > 8) { + os_printf("value 0-FFFFFFFF\r\n"); + return; + } + optr_len = 8 - optr_len; + os_memcpy(&optr_tab[optr_len], argv[3], os_strlen(argv[3])); + cli_hexstr2bin((char *)optr_tab, (u8 *)®_value, 4); + reg_value = ntohl(reg_value); + + REG_WRITE(reg_addr, reg_value); + +#if (CLI_CFG_WIFI == 1) + extern INT32 rwnx_cal_save_trx_rcbekn_reg_val(void); + // when write trx and rc beken regs, updata registers save. + if ((reg_addr & 0xfff0000) == 0x1050000) + rwnx_cal_save_trx_rcbekn_reg_val(); +#endif + + os_printf("regshow W: addr:0x%08x, value:0x%08x - check:0x%08x\r\n", + reg_addr, reg_value, REG_READ(reg_addr)); + } else + os_printf("regshow -w/r addr [value]\r\n"); +} + +static void cli_reg_dump_help(void) +{ + CLI_LOGI("regdump icu\n"); + CLI_LOGI(" pwm\n"); + CLI_LOGI(" gpio [index]\n"); + CLI_LOGI(" timer\n"); + CLI_LOGI(" dma [channel]\n"); + CLI_LOGI(" uart id\n"); + CLI_LOGI(" wdt\n"); + CLI_LOGI(" trng\n"); + CLI_LOGI(" efuse\n"); + CLI_LOGI(" adc\n"); + CLI_LOGI(" spi\n"); +} + +static void cli_reg_dump_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint8_t index = os_strtoul(argv[2], NULL, 10); + + if (argc == 1) { + cli_reg_dump_help(); + return; + } + + if (os_strcmp(argv[1], "icu") == 0) { +#if (CONFIG_ICU) + icu_struct_dump(); +#endif + } else if (os_strcmp(argv[1], "pwm") == 0) { + pwm_struct_dump(); + } else if (os_strcmp(argv[1], "timer") == 0) { + timer_struct_dump(); + } else if (os_strcmp(argv[1], "gpio") == 0) { + gpio_struct_dump(index); + } else if (os_strcmp(argv[1], "dma") == 0) { + dma_struct_dump(index); + } else if (os_strcmp(argv[1], "uart") == 0) { + uart_struct_dump(index); + } else if (os_strcmp(argv[1], "wdt") == 0) { + wdt_struct_dump(); + } else if (os_strcmp(argv[1], "trng") == 0) { +#if (CONFIG_TRNG_SUPPORT) + trng_struct_dump(); +#endif + } else if (os_strcmp(argv[1], "efuse") == 0) { +#if (CONFIG_EFUSE) + efuse_struct_dump(); +#endif + } else if (os_strcmp(argv[1], "adc") == 0) { + adc_struct_dump(); + } else if (os_strcmp(argv[1], "spi") == 0) { + spi_struct_dump(index); + } else if (os_strcmp(argv[1], "i2c") == 0) { + i2c_struct_dump(index); + } +#if CONFIG_QSPI + else if (os_strcmp(argv[1], "qspi") == 0) { + qspi_struct_dump(); + } +#endif +#if CONFIG_AON_RTC + else if (os_strcmp(argv[1], "aon_rtc") == 0) { + aon_rtc_struct_dump(); + } +#endif +#if CONFIG_JPEG_ENCODE + else if (os_strcmp(argv[1], "jpeg") == 0) { + jpeg_struct_dump(); + } +#endif +#if CONFIG_CALENDAR + else if (os_strcmp(argv[1], "calendar") == 0) { + calendar_struct_dump(); + } +#endif +#if CONFIG_FLASH + else if (os_strcmp(argv[1], "flash") == 0) { + flash_struct_dump(); + } +#endif +#if CONFIG_SDIO_HOST + else if (os_strcmp(argv[1], "sdio_host") == 0) { + sdio_host_struct_dump(); + } +#endif + else { + cli_reg_dump_help(); + return; + } +} + +#define REG_CMD_CNT (sizeof(s_reg_commands) / sizeof(struct cli_command)) +static const struct cli_command s_reg_commands[] = { + {"regshow", "regshow -w/r addr [value]", cli_reg_write_read_cmd}, + {"regdump", "regdump {module}", cli_reg_dump_cmd}, +}; + +int cli_reg_init(void) +{ + return cli_register_commands(s_reg_commands, REG_CMD_CNT); +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_rpc.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_rpc.c new file mode 100755 index 0000000..4aa1436 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_rpc.c @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include "sys_rtos.h" +#include +#include + +#include "bk_cli.h" +#include "stdarg.h" +#include +#include +#include +#include "bk_phy.h" +#include "cli.h" +#include "cli_config.h" +#include +#include +#include "bk_rtos_debug.h" +#if CONFIG_SHELL_ASYNCLOG +#include "components/shell_task.h" +#endif +#include "bk_api_cli.h" +#include "boot.h" + +static void debug_help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); + +#if CONFIG_DUAL_CORE +#include "mb_ipc_cmd.h" +#include + +#include "amp_lock_api.h" + +static void debug_ipc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); +static void debug_rpc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); +static void debug_rpc_gpio_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); +static void debug_cpulock_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); + +static u8 ipc_inited = 0; +static u8 rpc_inited = 0; + +#endif + +#if CONFIG_ARCH_RISCV +static void debug_perfmon_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); +static void debug_show_boot_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); +#endif + +const struct cli_command debug_cmds[] = { + {"help", "list debug cmds", debug_help_command}, +#if CONFIG_DUAL_CORE + {"ipc", "ipc", debug_ipc_command}, + {"rpc", "rpc", debug_rpc_command}, + {"gpio_out", "gpio_out gpio_id {0|1}", debug_rpc_gpio_command}, + {"cpu_lock", "cpu_lock [timeout 1~20]", debug_cpulock_command}, +#endif + +#if CONFIG_ARCH_RISCV + {"perfmon", "perfmon(calc MIPS)", debug_perfmon_command}, + {"boottime", "boottime(show boot mtime info)", debug_show_boot_time}, +#endif +}; + +const int cli_debug_table_size = ARRAY_SIZE(debug_cmds); + +void print_cmd_table(const struct cli_command *cmd_table, int table_items) +{ + int i; + + for (i = 0; i < table_items; i++) + { + if (cmd_table[i].name) + { + if (cmd_table[i].help) + os_printf("%s: %s\r\n", cmd_table[i].name, cmd_table[i].help); + else + os_printf("%s\r\n", cmd_table[i].name); + } + } +} + +void print_cmd_help(const struct cli_command *cmd_table, int table_items, void *func) +{ + int i; + + for (i = 0; i < table_items; i++) + { + if(cmd_table[i].function == func) + { + if (cmd_table[i].help) + os_printf("%s\r\n", cmd_table[i].help); + + break; + } + } +} + +static void debug_help_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + os_printf("====Debug Commands====\r\n"); + + print_cmd_table(debug_cmds, ARRAY_SIZE(debug_cmds)); +} + +#if CONFIG_DUAL_CORE +static void print_debug_cmd_help(void *func) +{ + print_cmd_help(debug_cmds, ARRAY_SIZE(debug_cmds), func); +} + +static void debug_rpc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + int ret_val; + + if(rpc_inited) + { + os_printf("rpc started\r\n"); + return; + } + + ret_val = rpc_init(); + os_printf("rpc init: %d\r\n", ret_val); + rpc_inited = 1; + +#if CONFIG_MASTER_CORE + + if(ipc_inited) + { + ret_val = ipc_send_test_cmd(0x12); + os_printf("ipc server test: ret=%d\r\n", ret_val); + + ret_val = ipc_send_get_ps_flag(); + os_printf("ipc server ps: ret= 0x%x\r\n", ret_val); + + ret_val = ipc_send_get_heart_rate(); + os_printf("ipc server hr: ret= 0x%x\r\n", ret_val); + + ret_val = ipc_send_set_heart_rate(0x33); + os_printf("ipc server set hr: ret= %d\r\n", ret_val); + } + +#endif + +} + +static void debug_ipc_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + int ret_val; + + if(ipc_inited) + { + os_printf("ipc started\r\n"); + return; + } + + ret_val = ipc_init(); + os_printf("ipc init: %d\r\n", ret_val); + ipc_inited = 1; + +#if CONFIG_SLAVE_CORE + + ret_val = ipc_send_power_up(); + os_printf("ipc client power: %d\r\n", ret_val); + + ret_val = ipc_send_heart_beat(0x34); + os_printf("ipc client heartbeat: %d\r\n", ret_val); + + ret_val = ipc_send_test_cmd(0x12); + os_printf("ipc client test: %d\r\n", ret_val); + +#endif +} + +extern bk_err_t bk_gpio_enable_output_rpc(gpio_id_t gpio_id); +extern bk_err_t bk_gpio_set_output_high_rpc(gpio_id_t gpio_id); +extern bk_err_t bk_gpio_set_output_low_rpc(gpio_id_t gpio_id); + +static void debug_rpc_gpio_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ +#if CONFIG_SLAVE_CORE + + int ret_val; + + u32 gpio_id = 0; + u32 level = 0; + + if (argc < 3) + { + print_debug_cmd_help(debug_rpc_gpio_command); + return; + } + + gpio_id = strtoul(argv[1], NULL, 0); + level = strtoul(argv[2], NULL, 0); + + ret_val = bk_gpio_enable_output_rpc(gpio_id); + os_printf("rpc gpio:ret=%d\r\n", ret_val); + + if(level) + ret_val = bk_gpio_set_output_high_rpc(gpio_id); + else + ret_val = bk_gpio_set_output_low_rpc(gpio_id); + + os_printf("rpc gpio:ret=%d\r\n", ret_val); + +#endif + +} + +static void debug_cpulock_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + u32 timeout_second = 10; // 10s + + if(ipc_inited == 0) + { + os_printf("Failed: no ipc client/server in CPU0/CPU1.\r\n"); + return; + } + + if (argc > 1) + { + timeout_second = strtoul(argv[1], NULL, 0); + + if(timeout_second > 20) + timeout_second = 20; + if(timeout_second == 0) + timeout_second = 10; + } + else + { + print_debug_cmd_help(debug_cpulock_command); + os_printf("default timeout 10s is used.\r\n"); + } + + int ret_val = BK_FAIL; + + ret_val = amp_res_init(AMP_RES_ID_GPIO); + os_printf("amp res init:ret=%d\r\n", ret_val); + + ret_val = amp_res_acquire(AMP_RES_ID_GPIO, timeout_second * 1000); + os_printf("amp res acquire:ret=%d\r\n", ret_val); + + rtos_delay_milliseconds(timeout_second * 1000); + + if(ret_val == 0) + { + ret_val = amp_res_release(AMP_RES_ID_GPIO); + os_printf("amp res release:ret=%d\r\n", ret_val); + } + else + { + os_printf("amp res release: no release\r\n"); + } + +} +#endif + +const struct cli_command * cli_debug_cmd_table(int *num) +{ + *num = ARRAY_SIZE(debug_cmds); + + return &debug_cmds[0]; +} + +#if CONFIG_ARCH_RISCV + +extern u64 riscv_get_instruct_cnt(void); +extern u64 riscv_get_mtimer(void); + +static u64 saved_time = 0; +static u64 saved_inst_cnt = 0; + +static void debug_perfmon_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + u64 cur_time = riscv_get_mtimer(); + u64 cur_inst_cnt = riscv_get_instruct_cnt(); + + os_printf("cur time: %x:%08x\r\n", (u32)(cur_time >> 32), (u32)(cur_time & 0xFFFFFFFF)); + os_printf("cur inst_cnt: %x:%08x\r\n", (u32)(cur_inst_cnt >> 32), (u32)(cur_inst_cnt & 0xFFFFFFFF)); + + saved_time = (cur_time - saved_time) / 26; + saved_inst_cnt = cur_inst_cnt - saved_inst_cnt; + +// os_printf("elapse time(us): %x:%08x\r\n", (u32)(saved_time >> 32), (u32)(saved_time & 0xFFFFFFFF)); +// os_printf("diff inst_cnt: %x:%08x\r\n", (u32)(saved_inst_cnt >> 32), (u32)(saved_inst_cnt & 0xFFFFFFFF)); + + os_printf("MIPS: %d KIPS\r\n", (u32)(saved_inst_cnt * 1000 / saved_time)); + + saved_time = cur_time; + saved_inst_cnt = cur_inst_cnt; +} + + +static void debug_show_boot_time(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + u64 cur_time = riscv_get_mtimer(); + u64 cur_inst_cnt = riscv_get_instruct_cnt(); + + BK_LOGI("debug","cur time: %x:%08x\r\n", (u32)(cur_time >> 32), (u32)(cur_time & 0xFFFFFFFF)); + BK_LOGI("debug","cur time: %ldms\r\n", (u32)(cur_time/26000)); + BK_LOGI("debug","cur inst_cnt: %x:%08x\r\n", (u32)(cur_inst_cnt >> 32), (u32)(cur_inst_cnt & 0xFFFFFFFF)); + +#if CONFIG_SAVE_BOOT_TIME_POINT + show_saved_mtime_info(); +#endif + +} +#endif + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_uart.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_uart.c new file mode 100755 index 0000000..6d63781 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_uart.c @@ -0,0 +1,405 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include "cli.h" +#include +#include +#include "uart_statis.h" +#include "bk_misc.h" + +#define CLI_UART_RECV_BUF_LEN 1024 + +static void cli_uart_help(void) +{ + CLI_LOGI("uart_driver init\n"); + CLI_LOGI("uart_driver deinit\n"); + CLI_LOGI("uart_int {id} {enable|disable|reg} {tx|rx}\n"); + CLI_LOGI("uart {id} {init|deinit|write|read|write_string|dump_statis} [...]\n"); + CLI_LOGI("uart_test {idle_start|idle_stop} {uart1|uart2|uart3}\n"); +} + +static void cli_uart_driver_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc < 2) { + cli_uart_help(); + return; + } + + if (os_strcmp(argv[1], "init") == 0) { + BK_LOG_ON_ERR(bk_uart_driver_init()); + CLI_LOGI("uart driver init\n"); + } else if (os_strcmp(argv[1], "deinit") == 0) { + BK_LOG_ON_ERR(bk_uart_driver_deinit()); + CLI_LOGI("uart driver deinit\n"); + } else { + cli_uart_help(); + return; + } +} + +static void cli_uart_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t uart_id; + + if (argc < 2) { + cli_uart_help(); + return; + } + + uart_id = os_strtoul(argv[1], NULL, 10); + + if (os_strcmp(argv[2], "init") == 0) { + CLI_RET_ON_INVALID_ARGC(argc, 5); + uart_config_t config = {0}; + os_memset(&config, 0, sizeof(uart_config_t)); + config.baud_rate = os_strtoul(argv[3], NULL, 10); + config.data_bits = os_strtoul(argv[4], NULL, 10); + config.parity = os_strtoul(argv[5], NULL, 10); + config.stop_bits = os_strtoul(argv[6], NULL, 10); + if (argc > 7) { + config.flow_ctrl = os_strtoul(argv[7], NULL, 10); + } + if (argc > 8) { + config.src_clk = os_strtoul(argv[8], NULL, 10); + } + + BK_LOG_ON_ERR(bk_uart_init(uart_id, &config)); + CLI_LOGI("uart init, uart_id=%d\n", uart_id); + } else if (os_strcmp(argv[2], "deinit") == 0) { + BK_LOG_ON_ERR(bk_uart_deinit(uart_id)); + CLI_LOGI("uart deinit, uart_id=%d\n", uart_id); + } else if (os_strcmp(argv[2], "write") == 0) { + uint32_t buf_len = os_strtoul(argv[3], NULL, 10); + uint8_t *send_data = (uint8_t *)os_malloc(buf_len); + if (send_data == NULL) { + CLI_LOGE("send buffer malloc failed\r\n"); + return; + } + os_memset(send_data, 0, buf_len); + for (int i = 0; i < buf_len; i++) { + send_data[i] = i & 0xff; + } + BK_LOG_ON_ERR(bk_uart_write_bytes(uart_id, send_data, buf_len)); + if (send_data) { + os_free(send_data); + } + send_data = NULL; + CLI_LOGI("uart write, uart_id=%d, data_len:%d\n", uart_id, buf_len); + } else if (os_strcmp(argv[2], "read") == 0) { + uint32_t buf_len = os_strtoul(argv[3], NULL, 10); + uint8_t *recv_data = (uint8_t *)os_malloc(buf_len); + if (recv_data == NULL) { + CLI_LOGE("recv buffer malloc failed\r\n"); + return; + } + int time_out = os_strtoul(argv[4], NULL, 10); + if (time_out < 0) { + time_out = BEKEN_WAIT_FOREVER; + } + int data_len = bk_uart_read_bytes(uart_id, recv_data, buf_len, time_out); + if (data_len < 0) { + CLI_LOGE("uart read failed, ret:-0x%x\r\n", -data_len); + goto exit; + } + CLI_LOGI("uart read, uart_id=%d, time_out:%x data_len:%d\n", uart_id, time_out, data_len); + for (int i = 0; i < data_len; i++) { + CLI_LOGI("recv_buffer[%d]=0x%x\n", i, recv_data[i]); + } +exit: + if (recv_data) { + os_free(recv_data); + } + recv_data = NULL; + } else if (os_strcmp(argv[2], "write_string") == 0) { + char send_data[] = "beken uart write string test\r\n"; + BK_LOG_ON_ERR(bk_uart_write_bytes(uart_id, send_data, os_strlen(send_data))); + CLI_LOGI("uart write string, uart_id=%d, data_len:%d\n", uart_id, os_strlen(send_data)); + } +#if CONFIG_UART_STATIS + else if (os_strcmp(argv[2], "dump_statis") == 0) { + uart_statis_dump(uart_id); + CLI_LOGI("uart dump statis ok\r\n"); + } else if (os_strcmp(argv[2], "reset_statis") == 0) { + uart_statis_id_init(uart_id); + CLI_LOGI("uart reset statis ok\r\n"); + } +#endif + else { + cli_uart_help(); + return; + } +} + +static void cli_uart_config_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t uart_id; + + if (argc < 4) { + cli_uart_help(); + return; + } + + uart_id = os_strtoul(argv[1], NULL, 10); + + if (os_strcmp(argv[2], "baud_rate") == 0) { + CLI_RET_ON_INVALID_ARGC(argc, 4); + uint32_t baud_rate = os_strtoul(argv[3], NULL, 10); + BK_LOG_ON_ERR(bk_uart_set_baud_rate(uart_id, baud_rate)); + CLI_LOGI("uart(%d) config baud_rate:%d\n", uart_id, baud_rate); + } else if (os_strcmp(argv[2], "data_bits") == 0) { + CLI_RET_ON_INVALID_ARGC(argc, 4); + uint32_t data_bits = os_strtoul(argv[3], NULL, 10); + BK_LOG_ON_ERR(bk_uart_set_data_bits(uart_id, data_bits)); + CLI_LOGI("uart(%d) config data_bits:%d\n", uart_id, data_bits); + } else if (os_strcmp(argv[2], "stop_bits") == 0) { + CLI_RET_ON_INVALID_ARGC(argc, 4); + uint32_t stop_bits = os_strtoul(argv[3], NULL, 10); + BK_LOG_ON_ERR(bk_uart_set_stop_bits(uart_id, stop_bits)); + CLI_LOGI("uart(%d) config stop_bits:%d\n", uart_id, stop_bits); + } else if (os_strcmp(argv[2], "parity") == 0) { + CLI_RET_ON_INVALID_ARGC(argc, 4); + uint32_t parity = os_strtoul(argv[3], NULL, 10); + BK_LOG_ON_ERR(bk_uart_set_parity(uart_id, parity)); + CLI_LOGI("uart(%d) config parity:%d\n", uart_id, parity); + } else if (os_strcmp(argv[2], "flow_ctrl") == 0) { + CLI_RET_ON_INVALID_ARGC(argc, 4); + uint32_t rx_threshold = os_strtoul(argv[3], NULL, 10); + BK_LOG_ON_ERR(bk_uart_set_hw_flow_ctrl(uart_id, rx_threshold)); + CLI_LOGI("uart(%d) config flow_ctrl:%d\n", uart_id, rx_threshold); + } else if (os_strcmp(argv[2], "rx_thresh") == 0) { + CLI_RET_ON_INVALID_ARGC(argc, 4); + uint32_t rx_thresh = os_strtoul(argv[3], NULL, 10); + BK_LOG_ON_ERR(bk_uart_set_rx_full_threshold(uart_id, rx_thresh)); + CLI_LOGI("uart(%d) config rx_thresh:%d\n", uart_id, rx_thresh); + } else if (os_strcmp(argv[2], "tx_thresh") == 0) { + CLI_RET_ON_INVALID_ARGC(argc, 4); + uint32_t tx_thresh = os_strtoul(argv[3], NULL, 10); + BK_LOG_ON_ERR(bk_uart_set_tx_empty_threshold(uart_id, tx_thresh)); + CLI_LOGI("uart(%d) config tx_thresh:%d\n", uart_id, tx_thresh); + } else if (os_strcmp(argv[2], "rx_timeout") == 0) { + CLI_RET_ON_INVALID_ARGC(argc, 4); + uint32_t timeout_thresh = os_strtoul(argv[3], NULL, 10); + BK_LOG_ON_ERR(bk_uart_set_rx_timeout(uart_id, timeout_thresh)); + CLI_LOGI("uart(%d) config rx_timeout:%d\n", uart_id, timeout_thresh); + } else { + cli_uart_help(); + return; + } +} + +static void cli_uart_rx_isr(uart_id_t id, void *param) +{ + CLI_LOGI("uart_rx_isr(%d)\n", id); +} + +static void cli_uart_tx_isr(uart_id_t id, void *param) +{ + CLI_LOGI("uart_tx_isr(%d)\n", id); +} + +static void cli_uart_int_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t uart_id; + + if (argc != 4) { + cli_uart_help(); + return; + } + + uart_id = os_strtoul(argv[1], NULL, 10); + + if (os_strcmp(argv[2], "enable") == 0) { + if (os_strcmp(argv[3], "tx") == 0) { + BK_LOG_ON_ERR(bk_uart_enable_tx_interrupt(uart_id)); + CLI_LOGI("uart id:%d enable tx interrupt\n", uart_id); + } else { + BK_LOG_ON_ERR(bk_uart_enable_rx_interrupt(uart_id)); + CLI_LOGI("uart id:%d enable rx interrupt\n", uart_id); + } + } else if (os_strcmp(argv[2], "disable") == 0) { + if (os_strcmp(argv[3], "tx") == 0) { + BK_LOG_ON_ERR(bk_uart_disable_tx_interrupt(uart_id)); + CLI_LOGI("uart id:%d disable tx interrupt\n", uart_id); + } else { + BK_LOG_ON_ERR(bk_uart_disable_rx_interrupt(uart_id)); + CLI_LOGI("uart id:%d disable rx interrupt\n", uart_id); + } + } else if (os_strcmp(argv[2], "reg") == 0) { + if (os_strcmp(argv[3], "tx") == 0) { + BK_LOG_ON_ERR(bk_uart_register_tx_isr(uart_id, cli_uart_tx_isr, NULL)); + CLI_LOGI("uart id:%d register tx interrupt isr\n", uart_id); + } else { + BK_LOG_ON_ERR(bk_uart_register_rx_isr(uart_id, cli_uart_rx_isr, NULL)); + CLI_LOGI("uart id:%d register rx interrupt isr\n", uart_id); + } + } else { + cli_uart_help(); + return; + } +} + +#if CONFIG_IDLE_UART_OUT_TEST +static beken_thread_t idle_uart_out_test_handle = NULL; +static uint16_t idle_uart_out_test_id = 0; +static void cli_idle_uart_out_test_isr(uart_id_t id, void *param) +{ + return; +} + +static void cli_idle_uart_out_test(void *arg) +{ + while (1) { + unsigned long random; + char tx_buffer[16]; + + random = bk_rand(); + itoa(random, tx_buffer, 14); + tx_buffer[16] = '\0'; + uart_write_string(idle_uart_out_test_id, tx_buffer); + + } + rtos_delete_thread(&idle_uart_out_test_handle); +} + +static void cli_uart_test_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc < 2) { + cli_uart_help(); + return; + } + + if (os_strcmp(argv[1], "idle_start") == 0) { + if (!idle_uart_out_test_handle) { + if (os_strcmp(argv[2], "uart1") == 0) { +#if !CONFIG_PRINT_PORT_UART1 + idle_uart_out_test_id = UART_ID_0; + CLI_LOGI("idle_uart_out task start: uart_id = UART1\n" ); + +#else + CLI_LOGI("cli_uart_test_cmd UART1 for log output!!!\n"); + return; +#endif + } else if (os_strcmp(argv[2], "uart2")== 0) { +#if !CONFIG_PRINT_PORT_UART2 + idle_uart_out_test_id = UART_ID_1; + CLI_LOGI("idle_uart_out task start: uart_id = UART2\n" ); + +#else + CLI_LOGI("cli_uart_test_cmd UART2 for log output!!!\n"); + return; +#endif + } else if (os_strcmp(argv[2], "uart3")== 0) { +#if !CONFIG_PRINT_PORT_UART3 + idle_uart_out_test_id = UART_ID_2; + CLI_LOGI("idle_uart_out task start: uart_id = UART3\n" ); + +#else + CLI_LOGI("cli_uart_test_cmd UART3 for log output!!!\n"); + return; +#endif + + } else { + cli_uart_help(); + return; + } + + uart_config_t config = {0}; + os_memset(&config, 0, sizeof(uart_config_t)); + + config.baud_rate = UART_BAUD_RATE; + config.data_bits = UART_DATA_8_BITS; + config.parity = UART_PARITY_NONE; + config.stop_bits = UART_STOP_BITS_1; + config.flow_ctrl = UART_FLOWCTRL_DISABLE; + config.src_clk = UART_SCLK_XTAL_26M; + + BK_LOG_ON_ERR(bk_uart_init(idle_uart_out_test_id, &config)); + BK_LOG_ON_ERR(bk_uart_deinit(idle_uart_out_test_id)); + + BK_LOG_ON_ERR(bk_uart_register_tx_isr(idle_uart_out_test_id, cli_idle_uart_out_test_isr, NULL)); + BK_LOG_ON_ERR(bk_uart_enable_tx_interrupt(idle_uart_out_test_id)); + BK_LOG_ON_ERR(bk_uart_init(idle_uart_out_test_id, &config)); + BK_LOG_ON_ERR(bk_trng_driver_init()); + BK_LOG_ON_ERR(bk_trng_start()); + if(rtos_create_thread(&idle_uart_out_test_handle, 8, "idle_uart_out", + (beken_thread_function_t) cli_idle_uart_out_test, 2048, 0)) { + CLI_LOGI("cli_uart_test_cmd rtos_create_thread FAILED!\n"); + return; + } + }else { + CLI_LOGI("PLEASE stop the task\n"); + } + return; + } else if (os_strcmp(argv[1], "idle_stop") == 0) { + + if (idle_uart_out_test_handle) { + if (os_strcmp(argv[2], "uart1") == 0) { + if(idle_uart_out_test_id != UART_ID_0) { + CLI_LOGI("PLEASE enter a correct ID\n"); + return; + } else + idle_uart_out_test_id = UART_ID_0; + } else if (os_strcmp(argv[2], "uart2")== 0) { + if(idle_uart_out_test_id != UART_ID_1) { + CLI_LOGI("PLEASE enter a correct ID\n"); + return; + } else + idle_uart_out_test_id = UART_ID_1; + } else if (os_strcmp(argv[2], "uart3")== 0) { + if(idle_uart_out_test_id != UART_ID_2) { + CLI_LOGI("PLEASE enter a correct ID\n"); + return; + } else + idle_uart_out_test_id = UART_ID_2; + } else { + cli_uart_help(); + return; + } + + rtos_delete_thread(&idle_uart_out_test_handle); + idle_uart_out_test_handle = NULL; + BK_LOG_ON_ERR(bk_uart_disable_tx_interrupt(idle_uart_out_test_id)); + BK_LOG_ON_ERR(bk_uart_register_tx_isr(idle_uart_out_test_id, NULL, NULL)); + BK_LOG_ON_ERR(bk_uart_deinit(idle_uart_out_test_id)); + BK_LOG_ON_ERR(bk_trng_stop()); + CLI_LOGI("idle_uart_out task stop\n"); + } else { + CLI_LOGI("PLEASE start task FIRST!!!\n"); + } + return; + } + +} +#endif //CONFIG_IDLE_UART_OUT_TEST + +#define UART_CMD_CNT (sizeof(s_uart_commands) / sizeof(struct cli_command)) +static const struct cli_command s_uart_commands[] = { + {"uart_driver", "{init|deinit}", cli_uart_driver_cmd}, + {"uart", "uart {id} {init|deinit|write|read|write_string|dump_statis} [...]", cli_uart_cmd}, + {"uart_config", "uart_config {id} {baud_rate|data_bits} [...]", cli_uart_config_cmd}, + {"uart_int", "uart_int {id} {enable|disable|reg} {tx|rx}", cli_uart_int_cmd}, +#if CONFIG_IDLE_UART_OUT_TEST + {"uart_test", "{idle_start|idle_stop} {uart1|uart2|uart3}", cli_uart_test_cmd}, +#endif //CONFIG_IDLE_UART_OUT_TEST +}; + +int cli_uart_init(void) +{ + BK_LOG_ON_ERR(bk_uart_driver_init()); + return cli_register_commands(s_uart_commands, UART_CMD_CNT); +} + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_wdt.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_wdt.c new file mode 100755 index 0000000..9380caf --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_wdt.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include "cli.h" +#include +#include + +static void cli_wdt_help(void) +{ + CLI_LOGI("wdt_driver init\n"); + CLI_LOGI("wdt_driver deinit\n"); + CLI_LOGI("wdt start [timeout]\n"); + CLI_LOGI("wdt stop\n"); + CLI_LOGI("wdt feed\n"); +} + +static void cli_wdt_driver_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc < 2) { + cli_wdt_help(); + return; + } + + if (os_strcmp(argv[1], "init") == 0) { + BK_LOG_ON_ERR(bk_wdt_driver_init()); + CLI_LOGI("wdt driver init\n"); + } else if (os_strcmp(argv[1], "deinit") == 0) { + BK_LOG_ON_ERR(bk_wdt_driver_deinit()); + CLI_LOGI("wdt driver deinit\n"); + } else { + cli_wdt_help(); + return; + } +} + +static void cli_wdt_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc < 2) { + cli_wdt_help(); + return; + } + + if (os_strcmp(argv[1], "start") == 0) { + uint32_t timeout = os_strtoul(argv[2], NULL, 10); + BK_LOG_ON_ERR(bk_wdt_start(timeout)); + CLI_LOGI("wdt start, timeout=%d\n", timeout); + } else if (os_strcmp(argv[1], "stop") == 0) { + BK_LOG_ON_ERR(bk_wdt_stop()); + CLI_LOGI("wdt stop\n"); + }else if (os_strcmp(argv[1], "feed") == 0) { + BK_LOG_ON_ERR(bk_wdt_feed()); + CLI_LOGI("wdt feed\n"); + }else if (os_strcmp(argv[1], "disable") == 0) { + extern void wdt_debug_disable(void); + wdt_debug_disable(); + bk_wdt_stop(); + bk_task_wdt_stop(); + CLI_LOGI("wdt debug disabled\n"); + }else if (os_strcmp(argv[1], "enable") == 0) { + extern void wdt_debug_enable(void); + extern void wdt_init(void); + wdt_debug_enable(); + wdt_init(); + CLI_LOGI("wdt debug enabled\n"); + }else if (os_strcmp(argv[1], "while") == 0) { + GLOBAL_INT_DECLARATION(); + GLOBAL_INT_DISABLE(); + CLI_LOGI("wdt enter while1\n"); + while(1); + GLOBAL_INT_RESTORE(); + } else { + cli_wdt_help(); + return; + } +} + +#define WDT_CMD_CNT (sizeof(s_wdt_commands) / sizeof(struct cli_command)) +static const struct cli_command s_wdt_commands[] = { + {"wdt_driver", "{init|deinit}", cli_wdt_driver_cmd}, + {"wdt", "wdt {start|stop|feed} [...]", cli_wdt_cmd} +}; + +int cli_wdt_init(void) +{ + BK_LOG_ON_ERR(bk_wdt_driver_init()); + return cli_register_commands(s_wdt_commands, WDT_CMD_CNT); +} + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_wifi.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_wifi.c new file mode 100755 index 0000000..b62e441 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/cli_wifi.c @@ -0,0 +1,1150 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include +#include "bk_uart.h" +#include "param_config.h" +#include "bk_private/bk_wifi_wrapper.h" +#if CONFIG_LWIP +#include "net.h" +#endif +#include "bk_private/bk_wifi.h" +#include "bk_wifi_private.h" +#include "bk_cli.h" +#include "cli.h" +#include +#include +#include "bk_wifi_wpa.h" +#include "bk_wifi_wpa_cmd.h" +#include "bk_wifi_frame.h" +#include "bk_wifi_types.h" +#if CONFIG_WIFI6_CODE_STACK +#include "bk_wifi_netif.h" +#include "bk_wifi.h" +#endif +#include "bk_wifi_rw.h" + +#if CONFIG_ENABLE_WIFI_DEFAULT_CONNECT +#include "driver/flash.h" +#include +#include +#include "bk_wifi_private.h" +#include "boot.h" +#endif + +#define TAG "wifi_cli" +#define CMD_WLAN_MAX_BSS_CNT 50 + +#if (CLI_CFG_WIFI == 1) +#if CONFIG_ENABLE_WIFI_DEFAULT_CONNECT +typedef struct bk_fast_connect_t +{ + uint8_t flag; //to check if ssid/pwd saved in easy flash is valid, default 0x70 + //bit[0]:write sta deault info;bit[1]:write ap deault info + uint8_t sta_ssid[33]; + uint8_t sta_pwd[65]; + uint8_t ap_ssid[33]; + uint8_t ap_pwd[65]; + uint8_t ap_channel; +}BK_FAST_CONNECT_T; + +int wifi_cli_find_id(int argc, char **argv, char *param) +{ + int i; + int index; + + index = -1; + if (NULL == param) + goto find_over; + + for (i = 1; i < argc; i ++) { + if (os_strcmp(argv[i], param) == 0) { + index = i; + break; + } + } + +find_over: + return index; +} + +static BK_FAST_CONNECT_T info_t; +static int fast_connect_cb(void *arg, event_module_t event_module, + int event_id, void *event_data) +{ + bk_logic_partition_t *pt = bk_flash_partition_get_info(BK_PARTITION_USR_CONFIG); + BK_FAST_CONNECT_T info_tmp; + + CLI_LOGI("%s, flag:%x\r\n", __func__, info_t.flag); + bk_flash_read_bytes(pt->partition_start_addr + pt->partition_length -4096, + (uint8_t *)&info_tmp, sizeof(BK_FAST_CONNECT_T)); + + if (info_t.flag == 0x71l) { + if ((info_tmp.flag & 0xf8l) == 0x70l) + info_tmp.flag |= 0x1l; + else + info_tmp.flag = 0x71l; + os_strcpy((char *)info_tmp.sta_ssid, (char *)info_t.sta_ssid); + os_strcpy((char *)info_tmp.sta_pwd, (char *)info_t.sta_pwd); + } else if (info_t.flag == 0x72l) { + if ((info_tmp.flag & 0xf8l) == 0x70l) + info_tmp.flag |= 0x2l; + else + info_tmp.flag = 0x72l; + os_strcpy((char *)info_tmp.ap_ssid, (char *)info_t.ap_ssid); + os_strcpy((char *)info_tmp.ap_pwd, (char *)info_t.ap_pwd); + } else + return -1; + + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + bk_flash_erase_sector(pt->partition_start_addr + pt->partition_length -4096); + bk_flash_write_bytes(pt->partition_start_addr + pt->partition_length -4096, + (uint8_t *)&info_tmp, sizeof(BK_FAST_CONNECT_T)); + bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK); + + return 0; +} + +#if 0 +static int demo_tcp_send(void *arg, event_module_t event_module, + int event_id, void *event_data) +{ + struct sockaddr_in addr; + int flag = 1, sock, ret = -1, len = 40*1024; + struct timeval tv; + uint8_t *send_buf; + + send_buf = (uint8_t *) os_malloc(len); + for (int i = 0; i < len; i++) + send_buf[i] = i & 0xff; + + sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (sock < 0) { + CLI_LOGI("create socket failed, err=%d!\n", errno); + return -1; + } + addr.sin_family = PF_INET; + addr.sin_port = htons(5001); + addr.sin_addr.s_addr = inet_addr((char *)"192.168.1.102"); + + ret = connect(sock, (const struct sockaddr *)&addr, sizeof(addr)); + if (ret == -1) { + CLI_LOGI("connect failed, err=%d!\n", errno); + closesocket(sock); + return -1; + } + + setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + (void *)&flag, sizeof(int)); + + tv.tv_sec = 3; + tv.tv_usec = 0; + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + + tv.tv_sec = 3; + tv.tv_usec = 0; + setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + + ret = send(sock, send_buf, len, 0); + + closesocket(sock); + + return 0; +} +#endif + +void demo_wifi_fast_connect(void) +{ + bk_logic_partition_t *pt = bk_flash_partition_get_info(BK_PARTITION_USR_CONFIG); + BK_FAST_CONNECT_T info; + + bk_flash_read_bytes(pt->partition_start_addr + pt->partition_length -4096, + (uint8_t *)&info, sizeof(BK_FAST_CONNECT_T)); + CLI_LOGD("%s, flag:%x\r\n", __func__, info.flag); + if (info.flag == 0x71l) { + demo_sta_app_init((char *)info.sta_ssid, (char *)info.sta_pwd); +#if 0 + bk_event_register_cb(EVENT_MOD_NETIF, EVENT_NETIF_GOT_IP4, + demo_tcp_send, &info_t); +#endif + } else if (info.flag == 0x72l) { + demo_softap_app_init((char *)info.ap_ssid, (char *)info.ap_pwd, NULL); + } else if (info.flag == 0x73l) { + demo_sta_app_init((char *)info.sta_ssid, (char *)info.sta_pwd); + demo_softap_app_init((char *)info.ap_ssid, (char *)info.ap_pwd, NULL); + } +} +#endif + +void cli_wifi_scan_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc < 2) { + demo_scan_app_init(); + return; + } else { + uint8_t *ap_ssid; + + ap_ssid = (uint8_t *)argv[1]; + demo_scan_adv_app_init(ap_ssid); + } +} + +void cli_wifi_ap_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + char *ap_ssid = NULL; + char *ap_key = ""; + char *ap_channel = NULL; + +#if CONFIG_ENABLE_WIFI_DEFAULT_CONNECT + if (wifi_cli_find_id(argc, argv, "-w") > 0 || + wifi_cli_find_id(argc, argv, "-e") > 0) { + if (argc == 3) + ap_ssid = argv[2]; + else if (argc == 4) { + ap_ssid = argv[2]; + if (os_strlen(argv[3]) <= 2) + ap_channel = argv[3]; + else + ap_key = argv[3]; + } else if (argc == 5) { + ap_ssid = argv[2]; + ap_key = argv[3]; + ap_channel = argv[4]; + } + } else { +#endif + if (argc == 2) + ap_ssid = argv[1]; + else if (argc == 3) { + ap_ssid = argv[1]; + if (os_strlen(argv[2]) <= 2) + ap_channel = argv[2]; + else + ap_key = argv[2]; + } else if (argc == 4) { + ap_ssid = argv[1]; + ap_key = argv[2]; + ap_channel = argv[3]; + } +#if CONFIG_ENABLE_WIFI_DEFAULT_CONNECT + } +#endif + + if (ap_ssid) { + demo_softap_app_init(ap_ssid, ap_key, ap_channel); +#if CONFIG_ENABLE_WIFI_DEFAULT_CONNECT + bk_event_unregister_cb(EVENT_MOD_WIFI, EVENT_WIFI_STA_CONNECTED, + fast_connect_cb); + if (wifi_cli_find_id(argc, argv, "-w") > 0) { + bk_logic_partition_t *pt = bk_flash_partition_get_info(BK_PARTITION_USR_CONFIG); + + bk_flash_read_bytes(pt->partition_start_addr + pt->partition_length -4096, + (uint8_t *)&info_t, sizeof(BK_FAST_CONNECT_T)); + if ((info_t.flag & 0xf0l) == 0x70l) + info_t.flag |= 0x2l; + else + info_t.flag = 0x72l; + os_strcpy((char *)info_t.ap_ssid, (char *)ap_ssid); + os_strcpy((char *)info_t.ap_pwd, ap_key); + fast_connect_cb(NULL, 0, 0, NULL); + } else if (wifi_cli_find_id(argc, argv, "-e") > 0) { + bk_logic_partition_t *pt = bk_flash_partition_get_info(BK_PARTITION_USR_CONFIG); + + bk_flash_read_bytes(pt->partition_start_addr + pt->partition_length -4096, + (uint8_t *)&info_t, sizeof(BK_FAST_CONNECT_T)); + if (info_t.flag == 0x72l || info_t.flag == 0x73l) { + info_t.flag &= ~0x2l; + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + bk_flash_erase_sector(pt->partition_start_addr + pt->partition_length -4096); + bk_flash_write_bytes(pt->partition_start_addr + pt->partition_length -4096, + (uint8_t *)&info_t, sizeof(BK_FAST_CONNECT_T)); + bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK); + } + } +#endif + } +} + +void cli_wifi_stop_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc == 2) { + if (os_strcmp(argv[1], "sta") == 0) { +#if CONFIG_ENABLE_WIFI_DEFAULT_CONNECT + bk_event_unregister_cb(EVENT_MOD_WIFI, EVENT_WIFI_STA_CONNECTED, + fast_connect_cb); +#endif + BK_LOG_ON_ERR(bk_wifi_sta_stop()); + } else if (os_strcmp(argv[1], "ap") == 0) + BK_LOG_ON_ERR(bk_wifi_ap_stop()); + else + CLI_LOGI("unknown WiFi interface\n"); + } else + CLI_LOGI("bad parameters\r\n"); +} + +void cli_wifi_iplog_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + char *iplog_mode = NULL; + + if (argc == 2) + iplog_mode = argv[1]; + + if (iplog_mode) + demo_wifi_iplog_init(iplog_mode); +} +void cli_wifi_ipdbg_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + char *ipdbg_module = NULL; + char *ipdbg_para = NULL; + char *ipdbg_para_value = NULL; + + if (argc == 3) + { + ipdbg_module = argv[1]; + ipdbg_para = argv[2]; + if (ipdbg_module && ipdbg_para) + demo_wifi_ipdbg_init(ipdbg_module, ipdbg_para, ipdbg_para_value); + else + CLI_LOGI("cli_wifi_ipdbg_cmd:invalid argc param\r\n"); + } + else if(argc == 4) + { + ipdbg_module = argv[1]; + ipdbg_para = argv[2]; + ipdbg_para_value = argv[3]; + if (ipdbg_module && ipdbg_para && ipdbg_para_value) + demo_wifi_ipdbg_init(ipdbg_module, ipdbg_para, ipdbg_para_value); + else + CLI_LOGI("cli_wifi_ipdbg_cmd:invalid argc param\r\n"); + } + else + { + CLI_LOGI("cli_wifi_ipdbg_cmd:invalid argc num\r\n"); + return; + } +} + +typedef struct { + uint8_t channel; + uint32_t rx_cnt_mgmt; + uint32_t rx_cnt_data; + uint32_t rx_cnt_ctrl; + uint32_t rx_cnt_0_255; + uint32_t rx_cnt_256_511; + uint32_t rx_cnt_512_1023; + uint32_t rx_cnt_1024; + uint32_t rx_cnt_total; +} cli_monitor_result_t; +static cli_monitor_result_t *s_monitor_result = NULL; + +bk_err_t cli_monitor_cb(const uint8_t *data, uint32_t len, const wifi_frame_info_t *info) +{ + if (s_monitor_result) { + s_monitor_result->rx_cnt_total++; + + if (data) { + if ((data[0] & 0xc) == 0x8) + s_monitor_result->rx_cnt_data ++; + else if ((data[0] & 0xc) == 0x0) + s_monitor_result->rx_cnt_mgmt ++; + else + s_monitor_result->rx_cnt_ctrl ++; + } + + if (len < 256) + s_monitor_result->rx_cnt_0_255++; + else if (len < 512) + s_monitor_result->rx_cnt_256_511++; + else if (len < 1024) + s_monitor_result->rx_cnt_512_1023++; + else + s_monitor_result->rx_cnt_1024++; + } + + return BK_OK; +} + +void cli_monitor_show(void) +{ + if (s_monitor_result) { + BK_LOG_RAW("total: %u\n", s_monitor_result->rx_cnt_total); + BK_LOG_RAW("mgmt: %u\n", s_monitor_result->rx_cnt_mgmt); + BK_LOG_RAW("data: %u\n", s_monitor_result->rx_cnt_data); + BK_LOG_RAW("ctrl: %u\n", s_monitor_result->rx_cnt_ctrl); + BK_LOG_RAW("0 - 255: %u\n", s_monitor_result->rx_cnt_0_255); + BK_LOG_RAW("256 - 511: %u\n", s_monitor_result->rx_cnt_256_511); + BK_LOG_RAW("512 - 1023: %u\n", s_monitor_result->rx_cnt_512_1023); + BK_LOG_RAW(">=1024: %u\n", s_monitor_result->rx_cnt_1024); + } +} + +void cli_wifi_set_interval_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint8_t interval = 0; + int ret = 0; + + if (argc < 2) { + CLI_LOGI("invalid argc num"); + return; + } + + interval = (uint8_t)os_strtoul(argv[1], NULL, 10); + ret = bk_wifi_send_listen_interval_req(interval); + + if (!ret) + CLI_LOGI("set_interval ok"); + else + CLI_LOGI("set_interval failed"); +} + +void cli_monitor_stop(void) +{ + if (s_monitor_result) { + os_free(s_monitor_result); + s_monitor_result = NULL; + } + + BK_LOG_ON_ERR(bk_wifi_monitor_stop()); +} + +void cli_monitor_start(uint32_t primary_channel) +{ + wifi_channel_t chan = {0}; + + chan.primary = primary_channel; + + if (!s_monitor_result) { + s_monitor_result = os_zalloc(sizeof(cli_monitor_result_t)); + if (!s_monitor_result) + CLI_LOGI("failed to alloc monitor result\n"); + } + + BK_LOG_ON_ERR(bk_wifi_monitor_register_cb(cli_monitor_cb)); + BK_LOG_ON_ERR(bk_wifi_monitor_start()); + BK_LOG_ON_ERR(bk_wifi_monitor_set_channel(&chan)); +} + +void cli_wifi_monitor_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint32_t primary_channel; + + if (argc != 2) { + CLI_LOGI("monitor_parameter invalid\r\n"); + return; + } + + primary_channel = os_strtoul(argv[1], NULL, 10); + if (99 == primary_channel) + cli_monitor_stop(); + else if ((primary_channel > 0) && (primary_channel < 15)) + cli_monitor_start(primary_channel); + else + cli_monitor_show(); +} + +#include "conv_utf8_pub.h" +void cli_wifi_sta_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + char *ssid = NULL; + char *password = ""; + + if ((argc < 2) || (argc > 6)) { + CLI_LOGI("invalid argc number\n"); + return; + } + +#if CONFIG_ENABLE_WIFI_DEFAULT_CONNECT + if (wifi_cli_find_id(argc, argv, "-w") > 0 || + wifi_cli_find_id(argc, argv, "-e") > 0) { + if (argc >= 2) + ssid = argv[2]; + + if (argc >= 3) + password = argv[3]; + } else { +#endif + if (argc >= 2) + ssid = argv[1]; + + if (argc >= 3) + password = argv[2]; +#if CONFIG_ENABLE_WIFI_DEFAULT_CONNECT + } +#endif + +#if 0 //TODO support BSSID/Channel configuration + if (argc >= 4) + bssid = argv[3]; + + if (argc >= 5) + channel = argv[4]; +#endif + + char *oob_ssid_tp = ssid; +#if CONFIG_USE_CONV_UTF8 + oob_ssid_tp = (char *)conv_utf8((uint8_t *)ssid); +#endif + + if (oob_ssid_tp) { + demo_sta_app_init((char *)oob_ssid_tp, password); +#if CONFIG_ENABLE_WIFI_DEFAULT_CONNECT + if (wifi_cli_find_id(argc, argv, "-w") > 0) { + bk_logic_partition_t *pt = bk_flash_partition_get_info(BK_PARTITION_USR_CONFIG); + bk_flash_read_bytes(pt->partition_start_addr + pt->partition_length -4096, + (uint8_t *)&info_t, sizeof(BK_FAST_CONNECT_T)); + if ((info_t.flag & 0xf0l) == 0x70l) + info_t.flag |= 0x1l; + else + info_t.flag = 0x71l; + os_strcpy((char *)info_t.sta_ssid, (char *)oob_ssid_tp); + os_strcpy((char *)info_t.sta_pwd, password); + bk_event_register_cb(EVENT_MOD_WIFI, EVENT_WIFI_STA_CONNECTED, + fast_connect_cb, &info_t); + } else if (wifi_cli_find_id(argc, argv, "-e") > 0) { + bk_logic_partition_t *pt = bk_flash_partition_get_info(BK_PARTITION_USR_CONFIG); + + bk_flash_read_bytes(pt->partition_start_addr + pt->partition_length -4096, + (uint8_t *)&info_t, sizeof(BK_FAST_CONNECT_T)); + if (info_t.flag == 0x71l || info_t.flag == 0x73l) { + info_t.flag &= ~0x1l; + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + bk_flash_write_bytes(pt->partition_start_addr + pt->partition_length -4096, + (uint8_t *)&info_t, sizeof(BK_FAST_CONNECT_T)); + bk_flash_set_protect_type(FLASH_UNPROTECT_LAST_BLOCK); + } + } +#endif +#if CONFIG_USE_CONV_UTF8 + os_free(oob_ssid_tp); +#endif + } else { + CLI_LOGI("not buf for utf8\r\n"); + } +} + +#if CONFIG_COMPONENTS_WPA2_ENTERPRISE +/** + * cli command: sta_eap , connect to EAP-TLS AP. + * + * restrictions: EAP-TLS is based on PKI, both AP and STA may have certificate. So + * we must install certificate and private key to system. For example, `beken-iot-1.pem' + * is STA's certificate, `beken-iot-1.key' is private key, `rootca.pem' is the RootCA. + * These certificates and private key may be registered to system via `register_xfile' + * function. + */ +void cli_wifi_sta_eap_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + char *ssid = NULL; + char *ca = "cacert.pem"; + char *client_cert = "beken-iot-1.pem"; + char *private_key = "beken-iot-1.key"; + char *private_key_passwd = "12345678"; + char *identity = "user"; + + if ((argc < 2) || (argc > 5)) { + CLI_LOGI("invalid argc number\n"); + return; + } + + ssid = argv[1]; + + char *oob_ssid_tp = ssid; +#if CONFIG_USE_CONV_UTF8 + oob_ssid_tp = (char *)conv_utf8((uint8_t *)ssid); +#endif + + if (oob_ssid_tp) { + int len; + wifi_sta_config_t *sta_config; + + len = os_strlen((char *)oob_ssid_tp); + if (WLAN_SSID_MAX_LEN < len) { + CLI_LOGI("ssid name more than 32 Bytes\n"); + return; + } + + sta_config = os_zalloc(sizeof(*sta_config)); + if (!sta_config) { + CLI_LOGI("Cannot alloc STA config\n"); + return; + } + + os_strlcpy(sta_config->ssid, oob_ssid_tp, sizeof(sta_config->ssid)); + sta_config->password[0] = '\0'; // No passwd needed fo EAP. + os_strlcpy(sta_config->eap, "TLS", sizeof(sta_config->eap)); + os_strlcpy(sta_config->identity, identity, sizeof(sta_config->identity)); + os_strlcpy(sta_config->ca, ca, sizeof(sta_config->ca)); + os_strlcpy(sta_config->client_cert, client_cert, sizeof(sta_config->client_cert)); + os_strlcpy(sta_config->private_key, private_key, sizeof(sta_config->private_key)); + os_strlcpy(sta_config->private_key_passwd, private_key_passwd, sizeof(sta_config->private_key_passwd)); + os_strlcpy(sta_config->phase1, "tls_disable_time_checks=1", sizeof(sta_config->phase1)); + + CLI_LOGI("ssid:%s key:%s\n", sta_config->ssid, sta_config->password); + CLI_LOGI("eap:%s identity:%s\n", sta_config->eap, sta_config->identity); + CLI_LOGI("ca:%s client_cert:%s\n", sta_config->ca, sta_config->client_cert); + CLI_LOGI("private_key:%s\n", sta_config->private_key); + BK_LOG_ON_ERR(bk_wifi_sta_set_config(sta_config)); + BK_LOG_ON_ERR(bk_wifi_sta_start()); + + os_free(sta_config); + +#if CONFIG_USE_CONV_UTF8 + os_free(oob_ssid_tp); +#endif + } else { + CLI_LOGI("not buf for utf8\r\n"); + } +} +#endif + +void cli_wifi_state_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + demo_state_app_init(); +} + +#if CONFIG_WIFI_SENSOR +static void cli_wifi_sensor_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + int status; + + if (argc != 2) + bk_printf("param error"); + + + if (os_strcmp(argv[1], "start") == 0) + bk_wifi_detect_movement_start(); + + if (os_strcmp(argv[1], "stop") == 0) + bk_wifi_detect_movement_stop(); + + if (os_strcmp(argv[1], "status") == 0) { + status = bk_get_movement_status(); + + if (status == 0) + bk_printf("detect something"); + else + bk_printf("detect nothing"); + } +} +#endif + +#if CONFIG_COMPONENTS_WFA_CA +extern void wfa_ca_start(); +extern void wfa_ca_stop(); + +void cli_wifi_wfa_ca_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + if (argc != 2) { + os_printf("param error"); + return; + } + + if (os_strcmp(argv[1], "start") == 0) + wfa_ca_start(); + else if (os_strcmp(argv[1], "stop") == 0) + wfa_ca_stop(); +} +#endif + +typedef struct { + uint16_t cnt_probe_req; + uint16_t cnt_probe_rsp; + uint16_t cnt_beacon; + uint16_t cnt_action; + uint16_t cnt_auth; + uint16_t cnt_assoc_req; + uint16_t cnt_assoc_rsp; + uint16_t cnt_others; + uint16_t cnt_total; +} wifi_filter_result_t; + +static wifi_filter_result_t *s_filter_result = NULL; + +static int wifi_filter_cb(const uint8_t *data, uint32_t len, const wifi_frame_info_t *frame_info) +{ + if (!data) { + CLI_LOGE("null data\n"); + return BK_OK; + } + + if (!s_filter_result) + return BK_OK; + + uint16_t framectrl = *(uint16_t*)(data); + uint16_t type_subtype = framectrl & MAC_FCTRL_TYPESUBTYPE_MASK; + + if (type_subtype == MAC_FCTRL_BEACON) + s_filter_result->cnt_beacon ++; + else if (type_subtype == MAC_FCTRL_PROBEREQ) + s_filter_result->cnt_probe_req++; + else if (type_subtype == MAC_FCTRL_PROBERSP) + s_filter_result->cnt_probe_rsp++; + else if (type_subtype == MAC_FCTRL_ACTION) + s_filter_result->cnt_action++; + else if (type_subtype == MAC_FCTRL_AUTHENT) + s_filter_result->cnt_auth++; + else if (type_subtype == MAC_FCTRL_ASSOCREQ) + s_filter_result->cnt_assoc_req++; + else if (type_subtype == MAC_FCTRL_ASSOCRSP) + s_filter_result->cnt_assoc_rsp++; + else + s_filter_result->cnt_others++; + + s_filter_result->cnt_total++; + return BK_OK; +} + +static void wifi_filter_result_dump(void) +{ + if (!s_filter_result) + return; + + bk_printf("filter result:\n"); + bk_printf("total: %u\n", s_filter_result->cnt_total); + bk_printf("beacon: %u\n", s_filter_result->cnt_beacon); + bk_printf("probe req: %u\n", s_filter_result->cnt_probe_req); + bk_printf("probe rsp: %u\n", s_filter_result->cnt_probe_rsp); + bk_printf("auth: %u\n", s_filter_result->cnt_auth); + bk_printf("assoc req: %u\n", s_filter_result->cnt_assoc_req); + bk_printf("assoc rsp: %u\n", s_filter_result->cnt_assoc_rsp); + bk_printf("action: %u\n", s_filter_result->cnt_action); + bk_printf("others: %u\n", s_filter_result->cnt_others); +} + +static void wifi_mgmt_filter_help(void) +{ + bk_printf("filter {filter_bitmap}\n"); + bk_printf(" bit0 - default management\n"); + bk_printf(" bit1 - probe req\n"); + bk_printf(" bit2 - probe rsp\n"); + bk_printf(" bit3 - all beacon\n"); + bk_printf(" bit4 - action\n"); + bk_printf(" 0 - stop filter\n"); + bk_printf(" -1 - display result\n"); +} + +static void cli_wifi_filter_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + wifi_filter_config_t filter_config = {0}; + uint32_t filter = 0; + + if (argc != 2) { + wifi_mgmt_filter_help(); + return; + } + + filter = os_strtoul(argv[1], NULL, 0); + + if (filter == 0) { + if (s_filter_result) { + os_free(s_filter_result); + s_filter_result = NULL; + } + BK_LOG_ON_ERR(bk_wifi_filter_set_config(&filter_config)); + BK_LOG_ON_ERR(bk_wifi_filter_register_cb(NULL)); + return; + } else if (filter == -1) { + wifi_filter_result_dump(); + return; + } + + if (!s_filter_result) { + s_filter_result = (wifi_filter_result_t *)os_zalloc(sizeof(wifi_filter_result_t)); + if (!s_filter_result) + return; + } + + if (filter & (1 << 0)) + filter_config.rx_all_default_mgmt = 1; + + if (filter & (1 << 1)) + filter_config.rx_probe_req = 1; + + if (filter & (1 << 2)) + filter_config.rx_probe_rsp = 1; + + if (filter & (1 << 3)) + filter_config.rx_all_beacon = 1; + + if (filter & (1 << 4)) + filter_config.rx_action = 1; + + BK_LOG_ON_ERR(bk_wifi_filter_set_config(&filter_config)); + BK_LOG_ON_ERR(bk_wifi_filter_register_cb(wifi_filter_cb)); +} + +#if CONFIG_WIFI_RAW_TX_TEST + +typedef struct { + uint32_t interval; + uint32_t counter; +} wifi_raw_tx_param_t; + +static void wifi_raw_tx_thread(void *arg) +{ + char frame[] = { + 0xB0, //version, type, subtype + 0x00, //frame control + 0x3A, 0x01, //duration + 0xC8, 0x47, 0x8C, 0x42, 0x00, 0x48, //Address1 - destination + 0x4C, 0xD1, 0xA1, 0xC5, 0x38, 0xE4, //Address2 - source + 0x4C, 0xD1, 0xA1, 0xC5, 0x38, 0xE4, //Address3 - bssid + 0x20, 0xC0, //sequence + + //Auth Response + 0x00, 0x00, //Auth algorithm - open system + 0x02, 0x00, //Auth seq num + 0x00, 0x00, //Status code + }; + wifi_raw_tx_param_t *tx_param; + int ret; + + tx_param = (wifi_raw_tx_param_t *)arg; + CLI_LOGI("wifi raw tx begin, interval=%u counter=%d\n", tx_param->interval, + tx_param->counter); + + for (uint32_t i = 0; i < tx_param->counter; i++) { + ret = bk_wlan_send_80211_raw_frame((unsigned char *)frame, sizeof(frame)); + if (ret != kNoErr) + CLI_LOGI("raw tx error, ret=%d\n", ret); + + rtos_delay_milliseconds(tx_param->interval); + } + + os_free(arg); + CLI_LOGI("wifi raw tx end\n"); + rtos_delete_thread(NULL); +} + +static void cli_wifi_raw_tx_cmd(char *pcWriteBuffer, int xWriteBufferLen, + int argc, char **argv) +{ + bk_err_t ret; + + if (argc != 3) { + CLI_LOGE("param error"); + CLI_LOGI("usage: wifi_raw_tx interval counter"); + return; + } + + wifi_raw_tx_param_t *tx_param; + tx_param = (wifi_raw_tx_param_t *)os_malloc(sizeof(wifi_raw_tx_param_t)); + if (!tx_param) { + CLI_LOGE("out of memory\n"); + return; + } + + tx_param->interval = os_strtoul(argv[1], NULL, 10); + tx_param->counter = os_strtoul(argv[2], NULL, 10); + ret = rtos_create_thread(NULL, 2, "raw_tx", + (beken_thread_function_t)wifi_raw_tx_thread, + 2048, tx_param); + if (kNoErr != ret) { + os_free(tx_param); + CLI_LOGI("Create raw tx thread failed, ret=%d\r\n", ret); + return; + } +} +#endif + +static void cli_wifi_monitor_channel_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + wifi_channel_t chan = {0}; + int channel, i = 0; + + if (argc == 1) { + CLI_LOGI("Usage: channel [1~13]."); + return; + } + + while (argv[1][i]) { + if ((argv[1][i] < '0') || (argv[1][i] > '9')) { + CLI_LOGE("parameter should be a number\r\n"); + return ; + } + i++; + } + + channel = atoi(argv[1]); + + if ((channel < 1) || (channel > 13)) { + CLI_LOGE("Invalid channel number \r\n"); + return ; + } + BK_LOG_RAW("monitor mode, set to channel %d\r\n", channel); + chan.primary = channel; + BK_LOG_ON_ERR(bk_wifi_monitor_set_channel(&chan)); +} + +int cli_netif_event_cb(void *arg, event_module_t event_module, + int event_id, void *event_data) +{ + netif_event_got_ip4_t *got_ip; + + switch (event_id) { + case EVENT_NETIF_GOT_IP4: + got_ip = (netif_event_got_ip4_t *)event_data; + CLI_LOGI("%s got ip\n", got_ip->netif_if == NETIF_IF_STA ? "BK STA" : "unknown netif"); +#if CONFIG_WIFI6_CODE_STACK + unsigned char vif_idx = wifi_netif_mac_to_vifid((uint8_t*)&g_sta_param_ptr->own_mac); + wlan_dhcp_done_ind(vif_idx); +#endif + break; + default: + CLI_LOGI("rx event <%d %d>\n", event_module, event_id); + break; + } + + return BK_OK; +} + +int cli_wifi_event_cb(void *arg, event_module_t event_module, + int event_id, void *event_data) +{ + wifi_event_sta_disconnected_t *sta_disconnected; + wifi_event_sta_connected_t *sta_connected; + wifi_event_ap_disconnected_t *ap_disconnected; + wifi_event_ap_connected_t *ap_connected; + + switch (event_id) { + case EVENT_WIFI_STA_CONNECTED: + sta_connected = (wifi_event_sta_connected_t *)event_data; + CLI_LOGI("BK STA connected %s\n", sta_connected->ssid); + break; + + case EVENT_WIFI_STA_DISCONNECTED: + sta_disconnected = (wifi_event_sta_disconnected_t *)event_data; + CLI_LOGI("BK STA disconnected, reason(%d)%s\n", sta_disconnected->disconnect_reason, + sta_disconnected->local_generated ? ", local_generated" : ""); + break; + + case EVENT_WIFI_AP_CONNECTED: + ap_connected = (wifi_event_ap_connected_t *)event_data; + CLI_LOGI(BK_MAC_FORMAT" connected to BK AP\n", BK_MAC_STR(ap_connected->mac)); + break; + + case EVENT_WIFI_AP_DISCONNECTED: + ap_disconnected = (wifi_event_ap_disconnected_t *)event_data; + CLI_LOGI(BK_MAC_FORMAT" disconnected from BK AP\n", BK_MAC_STR(ap_disconnected->mac)); + break; + + default: + CLI_LOGI("rx event <%d %d>\n", event_module, event_id); + break; + } + + return BK_OK; +} + +void cli_wifi_net_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + char buf[128]; + int i, left = sizeof(buf) - 1, len = 0; + + // net sta xxx + // net ap xxx + if (argc <= 2) { + CLI_LOGI("Usage: net sta/ap \n"); + return; + } + + buf[0] = 0; + for (i = 2; i < argc; i++) { + len = os_strlen(buf); + snprintf(buf + len, left - len, "%s ", argv[i]); + } + buf[strlen(buf) - 1] = 0; + //CLI_LOGI("CMD: |%s|\n", buf); + +#if 1 + if (os_strcmp(argv[1], "sta") == 0) + cmd_wlan_sta_exec(buf); + else if (os_strcmp(argv[1], "ap") == 0) + cmd_wlan_ap_exec(buf); +#if CONFIG_COMPONENTS_P2P + else if (os_strcmp(argv[1], "p2p") == 0) + cmd_wlan_p2p_exec(buf); +#endif + else { + CLI_LOGI("Usage: net sta/ap \n"); + return; + } +#endif +} + +void cli_wifi_get_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { + // get pm status + // get xx status + if (argc <= 2) { + CLI_LOGI("Usage get xx status\n"); + return; + } + + if(os_strcmp(argv[1], "ps") == 0) { + int state = 0; + if(os_strcmp(argv[2], "status") == 0) { + state = cmd_wlan_get_ps_status(); + CLI_LOGI("ps status: %s \n", (state?"sleep":"active")); + } else { + CLI_LOGI("Usage get ps status\n"); + } + } + else if (os_strcmp(argv[1], "mac_trx") == 0) { + + bool reset_status = false; + + if ((argc == 4) && (os_strcmp(argv[3], "-r") == 0)) + { + reset_status = true; + } + + if(os_strcmp(argv[2], "status") == 0) { + bk_wifi_get_mac_trx_status(reset_status); + } else { + CLI_LOGI("Usage get MAC TRX status\n"); + } + } +} +void cli_wifi_rc_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { + + uint8_t sta_idx = 0; + uint16_t rate_cfg = 0; + + if (argc <= 2) { + CLI_LOGI("invalid RC command\n"); + return; + } + + if(os_strcmp(argv[1], "set_fixrate") == 0) { + sta_idx = os_strtoul(argv[2], NULL, 10) & 0xFFFF; + rate_cfg = os_strtoul(argv[3], NULL, 10) & 0xFFFF; + bk_wifi_rc_config(sta_idx, rate_cfg); + } + else { + CLI_LOGI("invalid RC paramter\n"); + } +} +void cli_wifi_capa_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) { + uint32_t capa_id = 0; + uint32_t capa_val = 0; + + if (argc <= 2) { + CLI_LOGI("invalid CAPA command\n"); + return; + } + + if(os_strcmp(argv[1], "ht") == 0) { + capa_id = WIFI_CAPA_ID_HT_EN; + } + else if(os_strcmp(argv[1], "vht") == 0) { + capa_id = WIFI_CAPA_ID_VHT_EN; + } + else if(os_strcmp(argv[1], "he") == 0) { + capa_id = WIFI_CAPA_ID_HE_EN; + } + else if(os_strcmp(argv[1], "tx_ampdu") == 0) { + capa_id = WIFI_CAPA_ID_TX_AMPDU_EN; + } + else if(os_strcmp(argv[1], "rx_ampdu") == 0) { + capa_id = WIFI_CAPA_ID_RX_AMPDU_EN; + } + else if(os_strcmp(argv[1], "he_mcs") == 0) { + capa_id = WIFI_CAPA_ID_HE_MCS; + } + else { + CLI_LOGI("invalid CAPA paramter\n"); + return; + } + + capa_val = os_strtoul(argv[2], NULL, 10) & 0xFFFF; + bk_wifi_capa_config(capa_id, capa_val); +} + +#ifdef CONFIG_COMPONENTS_WPA_TWT_TEST +void cli_wifi_twt_cmd(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +{ + uint16_t mantissa = 0; + uint8_t min_twt = 0; + + if(os_strcmp(argv[1], "setup") == 0) { + int setup_command = 0; + + if(os_strcmp(argv[2], "suggest") == 0) { + setup_command = 1; + } + else if(os_strcmp(argv[2], "demand") == 0) { + setup_command = 2; + } + else { + CLI_LOGI("Usage: twt setup suggest/demand \n"); + return; + } + mantissa = os_strtoul(argv[3], NULL, 10) & 0xFF; + min_twt = os_strtoul(argv[4], NULL, 10) & 0xFF; + bk_wifi_twt_setup(setup_command, mantissa, min_twt); + } + else if (os_strcmp(argv[1], "teardown") == 0) + bk_wifi_twt_teardown(); + else + CLI_LOGI("Usage: twt setup/teardown \n"); +} +#endif + +#define WIFI_CMD_CNT (sizeof(s_wifi_commands) / sizeof(struct cli_command)) +static const struct cli_command s_wifi_commands[] = { + {"scan", "scan [ssid]", cli_wifi_scan_cmd}, + {"ap", "ap ssid [password] [channel[1:14]]", cli_wifi_ap_cmd}, + {"sta", "sta ssid [password][bssid][channel]", cli_wifi_sta_cmd}, //TODO support connect speicific BSSID +#if CONFIG_COMPONENTS_WPA2_ENTERPRISE + {"sta_eap", "sta_eap ssid password [identity] [client_cert] [private_key]", cli_wifi_sta_eap_cmd}, +#endif + {"stop", "stop {sta|ap}", cli_wifi_stop_cmd}, + {"set_interval", "set listen interval}", cli_wifi_set_interval_cmd}, + {"monitor", "monitor {1~13|15|99}", cli_wifi_monitor_cmd}, + {"state", "state - show STA/AP state", cli_wifi_state_cmd}, + {"channel", "channel {1~13} - set monitor channel", cli_wifi_monitor_channel_cmd}, + {"net", "net {sta/ap} ... - wifi net config", cli_wifi_net_cmd}, + {"get", "get wifi status", cli_wifi_get_cmd}, + {"iplog", "iplog [modle]", cli_wifi_iplog_cmd}, + {"ipdbg", "ipdbg [module][para][value]", cli_wifi_ipdbg_cmd}, + +#ifdef CONFIG_COMPONENTS_WPA_TWT_TEST + {"twt", "twt {setup|teardown}", cli_wifi_twt_cmd}, +#endif + +#if CONFIG_COMPONENTS_WFA_CA + {"wfa_ca", "wfa_ca ", cli_wifi_wfa_ca_cmd}, +#endif + +#if CONFIG_WIFI_SENSOR + {"wifisensor", "wifi sensor", cli_wifi_sensor_cmd}, +#endif + {"filter", "filter - bit0/d, 1/preq, 2/prsp, 3/b, 4/a", cli_wifi_filter_cmd}, +#if CONFIG_WIFI_RAW_TX_TEST + {"wifi_tx", "wifi_tx - Tx WiFi raw frame", cli_wifi_raw_tx_cmd}, +#endif + {"rc", "wifi rate control config", cli_wifi_rc_cmd}, + {"capa", "wifi capability config", cli_wifi_capa_cmd}, +}; + +int cli_wifi_init(void) +{ + BK_LOG_ON_ERR(bk_event_register_cb(EVENT_MOD_WIFI, EVENT_ID_ALL, cli_wifi_event_cb, NULL)); + BK_LOG_ON_ERR(bk_event_register_cb(EVENT_MOD_NETIF, EVENT_ID_ALL, cli_netif_event_cb, NULL)); + return cli_register_commands(s_wifi_commands, WIFI_CMD_CNT); +} + +#endif //#if (CLI_CFG_WIFI == 1) diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/include/bk_api_cli.h b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/include/bk_api_cli.h new file mode 100755 index 0000000..a62d85f --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/include/bk_api_cli.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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. + */ + +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +int bk_cli_init(void); + +#if CONFIG_SHELL_ASYNCLOG +#include + +#include "components/shell_task.h" + +#endif // #if CONFIG_SHELL_ASYNCLOG + + +#ifdef __cplusplus +} +#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/include/bk_private/bk_cli.h b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/include/bk_private/bk_cli.h new file mode 100755 index 0000000..c60ffda --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/include/bk_private/bk_cli.h @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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. + */ + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#define CLI_UART CONFIG_UART_PRINT_PORT + +#define RX_WAIT BEKEN_WAIT_FOREVER +#define SEND_WAIT BEKEN_WAIT_FOREVER + +#define RET_CHAR '\n' +#define END_CHAR '\r' +#define PROMPT "\r\n# " +#define EXIT_MSG "exit" + +#define NUM_BUFFERS 1 + +#ifndef CONFIG_MAX_COMMANDS +#define MAX_COMMANDS 255 +#else +#define MAX_COMMANDS CONFIG_MAX_COMMANDS +#endif + +#ifdef CONFIG_KEYVALUE +#define INBUF_SIZE 1024 +#else +#define INBUF_SIZE 128 +#endif +#define OUTBUF_SIZE 2048 + +#define LOG_SERVICE_BUFLEN 100 + +#ifndef CFG_CLI_DEBUG +#define CFG_CLI_DEBUG 1 +#endif + +#if CFG_CLI_DEBUG +#define CLI_GETCHAR_TIMEOUT (120000) +#define CLI_COMMAND_IS_RUNNING (1) +#else +#define CLI_GETCHAR_TIMEOUT BEKEN_NEVER_TIMEOUT +#endif + +/** Structure for registering CLI commands */ +struct cli_command +{ + /** The name of the CLI command */ + const char *name; + /** The help text associated with the command */ + const char *help; + /** The function that should be invoked for this command. */ + void (*function) (char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); +}; + +struct cli_st +{ + int initialized; + const struct cli_command *commands[MAX_COMMANDS]; + unsigned int num_commands; +#if ((!CONFIG_SHELL_ASYNCLOG) || CONFIG_ATE_TEST) + int echo_disabled; + + unsigned int bp; /* buffer pointer */ + char inbuf[INBUF_SIZE]; + + char outbuf[OUTBUF_SIZE]; +#endif +} ; + + +#define cmd_printf(...) do{\ + if (xWriteBufferLen > 0) {\ + snprintf(pcWriteBuffer, xWriteBufferLen, __VA_ARGS__);\ + xWriteBufferLen-= os_strlen(pcWriteBuffer);\ + pcWriteBuffer+= os_strlen(pcWriteBuffer);\ + }\ + }while(0) + + +#define CLI_ARGS char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv + +#define is_print(c) ((uint8_t)c >= 0x20 && (uint8_t)c <= 0x7f) + +#if (CONFIG_SOC_BK7271) +void bk7271_dsp_cli_init(void); +#if CONFIG_BT +void bk7271_ble_cli_init(void); +#endif +#endif + +#if (CONFIG_SOC_BK7256XX) +void usb_cli_init(void); +#endif + +/** Register a CLI command + * + * This function registers a command with the command-line interface. + * + * \param[in] command The structure to register one CLI command + * \return 0 on success + * \return 1 on failure + */ +int cli_register_command(const struct cli_command *command); + +/** Unregister a CLI command + * + * This function unregisters a command from the command-line interface. + * + * \param[in] command The structure to unregister one CLI command + * \return 0 on success + * \return 1 on failure + */ +int cli_unregister_command(const struct cli_command *command); + + + +/** Stop the CLI thread and carry out the cleanup + * + * \return kNoErr on success + * \return error code otherwise. + * + */ +int cli_stop(void); + +/** Register a batch of CLI commands + * + * Often, a module will want to register several commands. + * + * \param[in] commands Pointer to an array of commands. + * \param[in] num_commands Number of commands in the array. + * \return 0 on success + * \return 1 on failure + */ +int cli_register_commands(const struct cli_command *commands, int num_commands); + +/** Unregister a batch of CLI commands + * + * \param[in] commands Pointer to an array of commands. + * \param[in] num_commands Number of commands in the array. + * \return 0 on success + * \return 1 on failure + */ +int cli_unregister_commands(const struct cli_command *commands, + int num_commands); + +/* Get a CLI msg + * + * If an external input task wants to use the CLI, it can use + * cli_get_cmd_buffer() to get a command buffer that it can then + * submit to the CLI later using cli_submit_cmd_buffer(). + * + * \param buff Pointer to a char * to place the buffer pointer in. + * \return 0 on success + * \return error code otherwise. + */ +int cli_getchar(char *inbuf); +int cli_getchars(char *inbuf, int len); +int cli_get_all_chars_len(void); +int cli_getchars_prefetch(char *inbuf, int len); + +/* Send CLI output msg + * + * \param buff Pointer to a char * buffer. + * \return 0 on success + * \return error code otherwise. + */ +int cli_printf(const char *buff, ...); + + +// library CLI APIs +void ifconfig_Command(CLI_ARGS); +void arp_Command(CLI_ARGS); +void ping_Command(CLI_ARGS); +void dns_Command(CLI_ARGS); +void socket_show_Command(CLI_ARGS); +void memory_show_Command(CLI_ARGS); +void memory_dump_Command(CLI_ARGS); +void memory_set_Command(CLI_ARGS); +void memp_dump_Command(CLI_ARGS); +void cli_show_running_command(void); + +int cli_init(void); +void ble_command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv); + +#ifdef MOC +void task_Command(CLI_ARGS); +#endif + +#if CONFIG_SHELL_ASYNCLOG +int handle_shell_input(char *inbuf, int in_buf_size, char * outbuf, int out_buf_size); +#endif + +#ifdef __cplusplus +} +#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/shell_drv.h b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/shell_drv.h new file mode 100755 index 0000000..f5f9d48 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/shell_drv.h @@ -0,0 +1,141 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 _shell_drv_h_ +#define _shell_drv_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +typedef enum +{ + bFALSE = 0, + bTRUE = !bFALSE, +} bool_t; + +typedef enum +{ + SHELL_IO_CTRL_GET_STATUS = 0, + SHELL_IO_CTRL_RX_RESET, + SHELL_IO_CTRL_TX_RESET, + SHELL_IO_CTRL_FLUSH, + SHELL_IO_CTRL_SET_UART_PORT, + SHELL_IO_CTRL_GET_RX_STATUS, +} shell_ctrl_cmd_t; + +enum +{ + SHELL_DEV_UART = 0, + SHELL_DEV_MAILBOX, +}; + +struct _shell_dev_drv; + +typedef struct +{ + struct _shell_dev_drv *dev_drv; + u8 dev_type; + void * dev_ext; +} shell_dev_t; + +typedef void (* tx_complete_t)(u8 *pbuf, u16 Tag); +typedef void (* rx_indicate_t)(void); + +typedef struct _shell_dev_drv +{ + bool_t (*init)(shell_dev_t * shell_dev); + bool_t (*open)(shell_dev_t * shell_dev, tx_complete_t tx_callback, rx_indicate_t rx_callback); + u16 (*write_async)(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen, u16 Tag); + u16 (*read)(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen); + u16 (*write_sync)(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen); + u16 (*write_echo)(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen); + bool_t (*io_ctrl)(shell_dev_t * shell_dev, u8 cmd, void * param); + bool_t (*close)(shell_dev_t * shell_dev); +} shell_dev_drv_t; + +extern shell_dev_t shell_uart; +extern shell_dev_t shell_dev_mb; +extern shell_dev_t shell_uart3; + + +#ifdef CONFIG_DUAL_CORE + +#include "mailbox_channel.h" + +struct _shell_ipc_drv; + +typedef struct +{ + struct _shell_ipc_drv *dev_drv; + u8 dev_type; + void * dev_ext; +} shell_dev_ipc_t; + +typedef int (* shell_ipc_rx_t)(u16 cmd, void *data_buf, u16 dataLen); + +typedef struct _shell_ipc_drv +{ + bool_t (*init)(shell_dev_ipc_t * dev_ipc); + bool_t (*open)(shell_dev_ipc_t * dev_ipc, shell_ipc_rx_t rx_callback); + u16 (*read)(shell_dev_ipc_t * dev_ipc, u8 * pBuf, u16 BufLen); + u16 (*write_sync)(shell_dev_ipc_t * dev_ipc, u8 * pBuf, u16 BufLen); + bool_t (*io_ctrl)(shell_dev_ipc_t * dev_ipc, u8 cmd, void * param); + bool_t (*close)(shell_dev_ipc_t * dev_ipc); +} shell_ipc_drv_t; + +typedef union +{ + struct + { + mb_chnl_hdr_t hdr; + u8 * buf; + u16 len; + u16 tag; + }; + mb_chnl_cmd_t cmd_buf; +} log_cmd_t; + +typedef union +{ + struct + { + mb_chnl_hdr_t hdr; + u8 * buf; + u16 len; + }; + mb_chnl_cmd_t cmd_buf; +} user_cmd_t; + +enum +{ + MB_CMD_LOG_OUT = 1, + MB_CMD_LOG_OUT_OK, + MB_CMD_USER_INPUT, + MB_CMD_ASSERT_OUT, +} ; + +extern shell_dev_ipc_t shell_dev_ipc; + +#endif /* CONFIG_DUAL_CORE */ + +#ifdef __cplusplus +} +#endif + +#endif /* _shell_drv_h_ */ + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/shell_task.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/shell_task.c new file mode 100755 index 0000000..f2b88e3 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/shell_task.c @@ -0,0 +1,1567 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include +#include + +#include "cli.h" +#include +#include +#include "shell_drv.h" + +#define SHELL_TASK_DEF_TICK (1000) // 1000ms -> 1s +#define SHELL_EVENT_TX_REQ 0x01 +#define SHELL_EVENT_RX_IND 0x02 + +#define SHELL_LOG_BUF1_LEN 136 +#define SHELL_LOG_BUF2_LEN 64 +#define SHELL_LOG_BUF3_LEN 40 + +#ifdef CONFIG_SLAVE_CORE +#define SHELL_LOG_BUF1_NUM 6 +#define SHELL_LOG_BUF2_NUM 16 +#define SHELL_LOG_BUF3_NUM 20 + +#define SHELL_LOG_BUF_NUM (SHELL_LOG_BUF1_NUM + SHELL_LOG_BUF2_NUM + SHELL_LOG_BUF3_NUM) +#define SHELL_LOG_PEND_NUM (SHELL_LOG_BUF_NUM + 3) /* 1: for RSP, 1: reserved(queue empty), 1: cmd ovf. */ +#define SHELL_LOG_BUSY_NUM (SHELL_LOG_PEND_NUM) /* depending on lower driver's pending queue size. IPC drv no busy state. */ +#else +#define SHELL_LOG_BUF1_NUM 16 +#define SHELL_LOG_BUF2_NUM 48 +#define SHELL_LOG_BUF3_NUM 64 + +#define SHELL_LOG_BUF_NUM (SHELL_LOG_BUF1_NUM + SHELL_LOG_BUF2_NUM + SHELL_LOG_BUF3_NUM) +#define SHELL_LOG_PEND_NUM (SHELL_LOG_BUF_NUM * 2 + 3) /* 1: for RSP, 1: reserved(queue empty, 1: cmd ovf). */ /* the worst case may be (one log + one hint) in pending queue.*/ +#define SHELL_LOG_BUSY_NUM (20) /* depending on lower driver's pending queue size. drv's queue size < BUSY_NUM <= PEND_NUM. */ +#endif + +#define SHELL_ASSERT_BUF_LEN 140 +#define SHELL_CMD_BUF_LEN 140 +#define SHELL_RSP_BUF_LEN 200 + +#define SHELL_RSP_QUEUE_ID (7) +#define SHELL_FW_QUE_ID (8) +#define SHELL_ROM_QUEUE_ID (9) + +#define MAX_TRACE_ARGS 10 +#define MOD_NAME_LEN 4 + +#define HEX_SYNC_CHAR 0xFE +#define HEX_MOD_CHAR 0xFF +#define HEX_ESC_CHAR 0xFD + +#ifndef MIN +#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#endif + +#define TBL_SIZE(tbl) (sizeof(tbl) / sizeof(tbl[0])) + +enum +{ + CMD_TYPE_TEXT = 0, + CMD_TYPE_HEX, + CMD_TYPE_BKREG, /* patch for BK_REG tool cmd. */ + CMD_TYPE_INVALID, +}; + +/* patch for BK_REG tool. */ +enum +{ + BKREG_WAIT_01 = 0, + BKREG_WAIT_E0, + BKREG_WAIT_FC, +}; + +typedef struct +{ + u8 rsp_buff[SHELL_RSP_BUF_LEN]; + bool_t rsp_ongoing; + + u8 cur_cmd_type; + u8 cmd_buff[SHELL_CMD_BUF_LEN]; + u8 cmd_data_len; + + /* patch for BK_REG tool. */ + /* added one state machine for BK_REG tool cmd. */ + u8 bkreg_state; + u8 bkreg_left_byte; + /* patch end. */ + + u8 assert_buff[SHELL_ASSERT_BUF_LEN]; + u8 assert_data_len; + + u8 log_level; + bool_t echo_enable; +} cmd_line_t; + +#define GET_BLOCK_ID(blocktag) ((blocktag) & 0xFF) +#define GET_QUEUE_ID(blocktag) (((blocktag) & 0x0F00) >> 8) +#define MAKE_BLOCK_TAG(blk_id, q_id) (((blk_id) & 0xFF) | (((q_id) & 0x0F) << 8) ) + +typedef struct +{ + u16 blk_tag; /* bit0~bit7: blk_id, bit8~bit11: queue_id; */ + u16 packet_len; +} tx_packet_t; + +typedef struct +{ + tx_packet_t packet_list[SHELL_LOG_PEND_NUM]; + u16 list_out_idx; + u16 list_in_idx; +} pending_queue_t; + +typedef struct +{ + u16 blk_list[SHELL_LOG_BUSY_NUM]; + u16 list_out_idx; + u16 list_in_idx; +} busy_queue_t; + +typedef struct +{ + u8 * const log_buf; + u16 * const blk_list; + const u16 blk_num; + const u16 blk_len; + u16 list_out_idx; + u16 list_in_idx; + u16 free_blk_num; + u32 empty_cnt; +} free_queue_t; + +#if CONFIG_ARCH_RISCV && !CONFIG_SLAVE_CORE +static __attribute__((section(".dtcm_sec_data "))) u8 shell_log_buff1[SHELL_LOG_BUF1_NUM * SHELL_LOG_BUF1_LEN]; +static __attribute__((section(".dtcm_sec_data "))) u8 shell_log_buff2[SHELL_LOG_BUF2_NUM * SHELL_LOG_BUF2_LEN]; +static __attribute__((section(".dtcm_sec_data "))) u8 shell_log_buff3[SHELL_LOG_BUF3_NUM * SHELL_LOG_BUF3_LEN]; +static __attribute__((section(".dtcm_sec_data "))) u16 buff1_free_list[SHELL_LOG_BUF1_NUM]; +static __attribute__((section(".dtcm_sec_data "))) u16 buff2_free_list[SHELL_LOG_BUF2_NUM]; +static __attribute__((section(".dtcm_sec_data "))) u16 buff3_free_list[SHELL_LOG_BUF3_NUM]; +#else +static u8 shell_log_buff1[SHELL_LOG_BUF1_NUM * SHELL_LOG_BUF1_LEN]; +static u8 shell_log_buff2[SHELL_LOG_BUF2_NUM * SHELL_LOG_BUF2_LEN]; +static u8 shell_log_buff3[SHELL_LOG_BUF3_NUM * SHELL_LOG_BUF3_LEN]; +static u16 buff1_free_list[SHELL_LOG_BUF1_NUM]; +static u16 buff2_free_list[SHELL_LOG_BUF2_NUM]; +static u16 buff3_free_list[SHELL_LOG_BUF3_NUM]; +#endif + +/* queue sort ascending in blk_len. */ +static free_queue_t free_queue[3] = + { + {.log_buf = shell_log_buff3, .blk_list = buff3_free_list, .blk_num = SHELL_LOG_BUF3_NUM, \ + .blk_len = SHELL_LOG_BUF3_LEN, .list_out_idx = 0, .list_in_idx = 0, \ + .free_blk_num = SHELL_LOG_BUF3_NUM, .empty_cnt = 0}, + + {.log_buf = shell_log_buff2, .blk_list = buff2_free_list, .blk_num = SHELL_LOG_BUF2_NUM, \ + .blk_len = SHELL_LOG_BUF2_LEN, .list_out_idx = 0, .list_in_idx = 0, \ + .free_blk_num = SHELL_LOG_BUF2_NUM, .empty_cnt = 0}, + + {.log_buf = shell_log_buff1, .blk_list = buff1_free_list, .blk_num = SHELL_LOG_BUF1_NUM, \ + .blk_len = SHELL_LOG_BUF1_LEN, .list_out_idx = 0, .list_in_idx = 0, \ + .free_blk_num = SHELL_LOG_BUF1_NUM, .empty_cnt = 0}, + }; + +static busy_queue_t log_busy_queue; +static pending_queue_t pending_queue; + +static cmd_line_t cmd_line_buf; + +#ifdef CONFIG_SLAVE_CORE +#if 1 +static shell_dev_t * log_dev = &shell_dev_mb; +static shell_dev_t * cmd_dev = &shell_dev_mb; +#else +static shell_dev_t * log_dev = &shell_uart3; +static shell_dev_t * cmd_dev = &shell_uart3; +#endif +static const char shell_fault_str[] = "\r\n!!CPU1:some LOGs discarded!!\r\n"; +static const u16 shell_fault_str_len = sizeof(shell_fault_str) - 1; +#else + +static shell_dev_t * log_dev = &shell_uart; +static shell_dev_t * cmd_dev = &shell_uart; + +#ifdef CONFIG_MASTER_CORE +static shell_dev_ipc_t * ipc_dev = &shell_dev_ipc; +static int shell_ipc_rx_indication(u16 cmd, u8 *data, u16 data_len); +#endif +static const char shell_fault_str[] = "\r\n!!some LOGs discarded!!\r\n"; +static const u16 shell_fault_str_len = sizeof(shell_fault_str) - 1; +#endif + +static const char shell_cmd_ovf_str[] = "\r\n!!some CMDs lost!!\r\n"; +static const u16 shell_cmd_ovf_str_len = sizeof(shell_cmd_ovf_str) - 1; + +static bool_t shell_init_ok = bFALSE; +static u8 fault_hint_print = 0; +static u32 shell_log_overflow = 0; +static u32 shell_log_count = 0; + +static beken_semaphore_t shell_semaphore; // will release from ISR. + + +static bool_t create_shell_event(void) +{ + rtos_init_semaphore(&shell_semaphore, 1); + + return bTRUE; +} + +static bool_t set_shell_event(u32 event_flag) +{ + (void)event_flag; + + rtos_set_semaphore(&shell_semaphore); + + return bTRUE; +} + +static u32 wait_any_event(u32 timeout) +{ + int result; + + result = rtos_get_semaphore(&shell_semaphore, timeout); + + if(result == kTimeoutErr) + return 0; + + return SHELL_EVENT_RX_IND; +} + +static void tx_req_process(void); + +#if 0 +static u16 get_free_buff_cnt(free_queue_t *free_q) +{ + u16 free_cnt; + + if(free_q->list_out_idx >= free_q->list_in_idx) + { + free_cnt = free_q->blk_num + free_q->list_in_idx - free_q->list_out_idx; + } + else + { + free_cnt = free_q->list_in_idx - free_q->list_out_idx; + } + + return free_cnt; /* should reserve 1 block. *//* (list_out_idx == list_in_idx) means all buf free. */ +} +#endif + +static u8 * alloc_log_blk(u16 log_len, u16 *blk_tag) +{ + u16 free_blk_id; + u8 queue_id; + free_queue_t * free_q; + u8 * blk_buf = NULL; + + //disable_interrupt(); // called from task context, use semaphore instead of locking interrupt. + //get_shell_mutex(); + u32 int_mask = rtos_disable_int(); + + for(queue_id = 0; queue_id < TBL_SIZE(free_queue); queue_id++) + { + free_q = &free_queue[queue_id]; + + /* queue ascending in blk_len. */ + if(free_q->blk_len < log_len) + continue; + + if(/*get_free_buff_cnt(free_q) */ free_q->free_blk_num > 0) + { + free_blk_id = free_q->blk_list[free_q->list_out_idx]; + free_q->list_out_idx = (free_q->list_out_idx + 1) % free_q->blk_num; + free_q->free_blk_num--; + + blk_buf = &free_q->log_buf[free_blk_id * free_q->blk_len]; + *blk_tag = MAKE_BLOCK_TAG(free_blk_id, queue_id); + + break; + } + else + { + free_q->empty_cnt++; + } + } + + if(blk_buf == NULL) + { + shell_log_overflow++; + } + else + { + fault_hint_print = 0; + shell_log_count++; + } + + //enable_interrupt(); // called from task context, use semaphore instead of locking interrupt. + //release_shell_mutex(); + rtos_enable_int(int_mask); + + return blk_buf; +} + +static bool_t free_log_blk(u16 block_tag) +{ + u8 queue_id = GET_QUEUE_ID(block_tag); + u16 blk_id = GET_BLOCK_ID(block_tag); + free_queue_t *free_q; + + if(queue_id >= TBL_SIZE(free_queue)) + return bFALSE; + + free_q = &free_queue[queue_id]; + + if(blk_id >= free_q->blk_num) + return bFALSE; + + //disable_interrupt(); // called from tx-complete only, don't lock interrupt. + + free_q->blk_list[free_q->list_in_idx] = blk_id; + free_q->list_in_idx = (free_q->list_in_idx + 1) % free_q->blk_num; + free_q->free_blk_num++; + + //enable_interrupt(); // called from tx-complete only, don't lock interrupt. + + return bTRUE; +} + +static void push_pending_queue(u16 blk_tag, u16 data_len) +{ + //get_shell_mutex(); + + pending_queue.packet_list[pending_queue.list_in_idx].blk_tag = blk_tag; + pending_queue.packet_list[pending_queue.list_in_idx].packet_len = data_len; + + pending_queue.list_in_idx = (pending_queue.list_in_idx + 1) % SHELL_LOG_PEND_NUM; + + //release_shell_mutex(); + + return; +} + +static void pull_pending_queue(u16 *blk_tag, u16 *data_len) +{ + *blk_tag = pending_queue.packet_list[pending_queue.list_out_idx].blk_tag; + *data_len = pending_queue.packet_list[pending_queue.list_out_idx].packet_len; + + pending_queue.list_out_idx = (pending_queue.list_out_idx + 1) % SHELL_LOG_PEND_NUM; + + return; +} + +int shell_assert_out(bool bContinue, char * format, ...); + +/* call from TX ISR. */ +static void shell_tx_complete(u8 *pbuf, u16 buf_tag) +{ + u16 block_tag; + u8 queue_id = GET_QUEUE_ID(buf_tag); + u16 blk_id = GET_BLOCK_ID(buf_tag); + free_queue_t *free_q; + + /* rsp ok ?? */ + if( queue_id == SHELL_RSP_QUEUE_ID ) /* rsp. */ + { + /* it is called from cmd_dev tx ISR. */ + + if ( (pbuf != cmd_line_buf.rsp_buff) || (blk_id != 0) || + ( !cmd_line_buf.rsp_ongoing ) ) + { + /* something wrong!!! */ + shell_assert_out(bTRUE, "FAULT: in rsp.\r\n"); + } + + cmd_line_buf.rsp_ongoing = bFALSE; /* rsp compelete, rsp_buff can be used for next cmd/response. */ + + //set_shell_event(SHELL_EVENT_TX_REQ); // notify shell task to process the log tx. + tx_req_process(); + + return; + } + + if( queue_id == SHELL_ROM_QUEUE_ID ) /* fault hints buffer, point to flash. */ + { + /* it is called from log_dev/cmd_dev tx ISR. */ + + if ( (blk_id == 0) && (pbuf == (u8 *)shell_fault_str) ) + { + } + else if ( (blk_id == 1) && (pbuf == (u8 *)shell_cmd_ovf_str) ) + { + } + else + { + /* something wrong!!! */ + shell_assert_out(bTRUE, "FATAL:t-%x,p-%x\r\n", buf_tag, pbuf); + } + + //set_shell_event(SHELL_EVENT_TX_REQ); // notify shell task to process the log tx. + tx_req_process(); + + return; + } + + if (queue_id < TBL_SIZE(free_queue)) /* from log busy queue. */ + { + /* it is called from log_dev tx ISR. */ + + free_q = &free_queue[queue_id]; + + block_tag = log_busy_queue.blk_list[log_busy_queue.list_out_idx]; + + if( ( buf_tag != block_tag ) || (blk_id >= free_q->blk_num) || + ( (&free_q->log_buf[blk_id * free_q->blk_len]) != pbuf) ) + { + /* something wrong!!! */ + /* FAULT !!!! */ + shell_assert_out(bTRUE, "FATAL:%x,%x\r\n", buf_tag, block_tag); + + return; + } + + /* de-queue from busy queue. */ + log_busy_queue.list_out_idx = (log_busy_queue.list_out_idx + 1) % SHELL_LOG_BUSY_NUM; + + /* free buffer to queue. */ + free_log_blk(block_tag); + + //set_shell_event(SHELL_EVENT_TX_REQ); // notify shell task to process the log tx. + tx_req_process(); + + return; + } + + /* FAULT !!!! */ + shell_assert_out(bTRUE, "FATAL:%x,\r\n", buf_tag); + + return; +} + +/* call from RX ISR. */ +static void shell_rx_indicate(void) +{ + set_shell_event(SHELL_EVENT_RX_IND); + + return; +} + +static u16 append_link_data_byte(u8 * link_buf, u16 buf_len, u8 * data_ptr, u16 data_len) +{ + u16 cnt = 0, i; + + for(i = 0; i < data_len; i++) + { + if( (*data_ptr == HEX_SYNC_CHAR) || + (*data_ptr == HEX_ESC_CHAR) ) + { + if(cnt < (buf_len - 1)) + { + link_buf[cnt] = HEX_ESC_CHAR; + cnt++; + link_buf[cnt] = (*data_ptr) ^ HEX_MOD_CHAR; + cnt++; + } + } + else + { + if(cnt < buf_len) + { + link_buf[cnt] = (*data_ptr); + cnt++; + } + } + + data_ptr++; + } + + return cnt; +} + +static bool_t echo_out(u8 * echo_str, u16 len) +{ + u16 wr_cnt; + + if(len == 0) + return bTRUE; + + wr_cnt = cmd_dev->dev_drv->write_echo(cmd_dev, echo_str, len); + + return (wr_cnt == len); +} + +/* NOTICE: this can only be called by shell task internally (cmd handler). */ +/* it is not re-enterance function. */ +static bool_t rsp_out(u8 * rsp_msg, u16 msg_len) +{ + u16 rsp_blk_tag = MAKE_BLOCK_TAG(0, SHELL_RSP_QUEUE_ID); + + if(rsp_msg != cmd_line_buf.rsp_buff) + { + if(msg_len > sizeof(cmd_line_buf.rsp_buff)) + { + msg_len = sizeof(cmd_line_buf.rsp_buff);; + } + + memcpy(cmd_line_buf.rsp_buff, rsp_msg, msg_len); + } + + if(log_dev != cmd_dev) + { + // set TRUE, then call driver, in case TX_COMPLETE_ISR will happen before set TRUE. + cmd_line_buf.rsp_ongoing = bTRUE; // one by one for cmd handler. + + /* dedicated device for cmd/response, don't enqueue the msg to pending queue. */ + /* send to cmd dev directly. */ + cmd_dev->dev_drv->write_async(cmd_dev, cmd_line_buf.rsp_buff, msg_len, rsp_blk_tag); + } + else + { + /* shared device for response & log, push the rsp msg to pending queue. */ + + u32 int_mask = rtos_disable_int(); + + cmd_line_buf.rsp_ongoing = bTRUE; // one by one for cmd handler. set to true before trigger the TX. + + push_pending_queue(rsp_blk_tag, msg_len); + + //set_shell_event(SHELL_EVENT_TX_REQ); // notify shell task to process the log tx. + tx_req_process(); + + rtos_enable_int(int_mask); + } + + return bTRUE; +} + +static bool_t cmd_hint_out(void) +{ + u16 hint_blk_tag = MAKE_BLOCK_TAG(1, SHELL_ROM_QUEUE_ID); + + if(log_dev != cmd_dev) + { + /* dedicated device for cmd_hint, don't enqueue the msg to pending queue. */ + /* send to cmd dev directly. */ + cmd_dev->dev_drv->write_async(cmd_dev, (u8 *)shell_cmd_ovf_str, shell_cmd_ovf_str_len, hint_blk_tag); + } + else + { + /* shared device for response & log, push the cmd_hint msg to pending queue. */ + + u32 int_mask = rtos_disable_int(); + + push_pending_queue(hint_blk_tag, shell_fault_str_len); + + //set_shell_event(SHELL_EVENT_TX_REQ); // notify shell task to process the log tx. + tx_req_process(); + + rtos_enable_int(int_mask); + } + + return bTRUE; +} + +static bool_t log_hint_out(void) +{ + if(fault_hint_print) /* sent one hint since last allocation fail.*/ + return bTRUE; + + u16 hint_blk_tag = MAKE_BLOCK_TAG(0, SHELL_ROM_QUEUE_ID); + + u32 int_mask = rtos_disable_int(); + + push_pending_queue(hint_blk_tag, shell_fault_str_len); + + //set_shell_event(SHELL_EVENT_TX_REQ); // notify shell task to process the log tx. + tx_req_process(); + + fault_hint_print = 1; + + rtos_enable_int(int_mask); + + return bTRUE; +} + +/* call this in !* DISABLE *! interrupt context. */ +static void tx_req_process(void) +{ + u8 *packet_buf = NULL; + u16 block_tag; + u16 log_len; + u16 tx_ready; + u16 blk_id; + u8 queue_id; + free_queue_t *free_q; + + /* maybe tx_req is from tx_complete_callback, check if there any log in queue. */ + if(pending_queue.list_out_idx == pending_queue.list_in_idx) /* queue empty! */ + return; + + tx_ready = 0; + + log_dev->dev_drv->io_ctrl(log_dev, SHELL_IO_CTRL_GET_STATUS, &tx_ready); + + if(tx_ready == 0) + return; + + /** ==== POP from pending queue ==== **/ + pull_pending_queue(&block_tag, &log_len); + + queue_id = GET_QUEUE_ID(block_tag); + blk_id = GET_BLOCK_ID(block_tag); + + if (queue_id < TBL_SIZE(free_queue)) + { + free_q = &free_queue[queue_id]; + + if(blk_id < free_q->blk_num) + { + packet_buf = &free_q->log_buf[blk_id * free_q->blk_len]; + } + } + else if(queue_id == SHELL_RSP_QUEUE_ID) + { + packet_buf = cmd_line_buf.rsp_buff; + + if((cmd_line_buf.rsp_ongoing == bFALSE) || (log_dev != cmd_dev) || (blk_id != 0)) + { + shell_assert_out(bTRUE, "xFATAL: in Tx_req\r\n"); + /* FAULT !!!! */ + /* if log_dev is not the same with cmd_dev, + * rsp will not be pushed into pending queue. + */ + } + } + else if(queue_id == SHELL_ROM_QUEUE_ID) + { + if(blk_id == 0) + { + packet_buf = (u8 *)shell_fault_str; + } + else if(blk_id == 1) + { + packet_buf = (u8 *)shell_cmd_ovf_str; + if(log_dev != cmd_dev) + { + shell_assert_out(bTRUE, "xFATAL: in Tx_req id=%x\r\n", blk_id); + /* FAULT !!!! */ + /* if log_dev is not the same with cmd_dev, + * cmd_hint will not be pushed into pending queue. + */ + } + } + else + { + /* FAULT !!!! */ + shell_assert_out(bTRUE, "xFATAL: in Tx_req id=%x\r\n", blk_id); + } + } + else + { + /* FAULT !!!! */ + shell_assert_out(bTRUE, "xFATAL: in Tx_req %x.\r\n", block_tag); + } + + if(packet_buf == NULL) + return; + + /* rom & rsp buff not enter busy-queue. */ + if(queue_id < TBL_SIZE(free_queue)) + { + log_busy_queue.blk_list[log_busy_queue.list_in_idx] = block_tag; + log_busy_queue.list_in_idx = (log_busy_queue.list_in_idx + 1) % SHELL_LOG_BUSY_NUM; + } + + log_dev->dev_drv->write_async(log_dev, packet_buf, log_len, block_tag); /* send to log dev driver. */ + /* if driver return 0, should free log-block or not de-queue pending queue and try again. */ + /* if return 1, push log-block into busy queue is OK. */ + + return; +} + +int shell_trace_out( u32 trace_id, ... ); +int shell_spy_out( u16 spy_id, u8 * data_buf, u16 data_len); + +static void rx_ind_process(void) +{ + u16 read_cnt, buf_len, echo_len; + u16 i = 0; + bool_t cmd_rx_done = bFALSE, need_backspace = bFALSE; + + if(cmd_line_buf.rsp_ongoing) + { + /* previous cmd not complete, inform itself to handle it later. */ + set_shell_event(SHELL_EVENT_RX_IND); + + rtos_delay_milliseconds(100); /* delay 100ms, wait cmd to be completed. */ + + return; + } + + /* cmd_line_buf.rsp_buff is free, can be used for read buff temporarily */ + + if(cmd_dev->dev_type == SHELL_DEV_MAILBOX) + { + buf_len = MIN(SHELL_CMD_BUF_LEN, SHELL_RSP_BUF_LEN); + } + else /* if(cmd_dev->dev_type == SHELL_DEV_UART) */ + { + buf_len = 1; /* for UART device, read one by one. */ + } + + while(bTRUE) + { + u8 * rx_temp_buff = &cmd_line_buf.rsp_buff[0]; + + read_cnt = cmd_dev->dev_drv->read(cmd_dev, rx_temp_buff, buf_len); + + echo_len = 0; + + for(i = 0; i < read_cnt; i++) + { + if(cmd_line_buf.cur_cmd_type == CMD_TYPE_INVALID) + { + #if 0 + if(rx_temp_buff[i] == HEX_SYNC_CHAR) // SYNC_CHAR, hex frame start. + { + cmd_line_buf.cur_cmd_type = CMD_TYPE_HEX; + + cmd_line_buf.cmd_data_len = 0; + cmd_line_buf.cmd_buff[cmd_line_buf.cmd_data_len] = HEX_SYNC_CHAR; + cmd_line_buf.cmd_data_len++; + + continue; + } + #endif + + echo_len++; /* SYNC_CHAR not echo. */ + + if((rx_temp_buff[i] >= 0x20) && (rx_temp_buff[i] < 0x7f)) + { + cmd_line_buf.cur_cmd_type = CMD_TYPE_TEXT; + + cmd_line_buf.cmd_data_len = 0; + cmd_line_buf.cmd_buff[cmd_line_buf.cmd_data_len] = rx_temp_buff[i]; + cmd_line_buf.cmd_data_len++; + + continue; + } + + /* patch for BK_REG tool. */ + if(cmd_line_buf.bkreg_state == BKREG_WAIT_01) + { + if(rx_temp_buff[i] == 0x01) + cmd_line_buf.bkreg_state = BKREG_WAIT_E0; + } + else if(cmd_line_buf.bkreg_state == BKREG_WAIT_E0) + { + if(rx_temp_buff[i] == 0xE0) + cmd_line_buf.bkreg_state = BKREG_WAIT_FC; + else if(rx_temp_buff[i] != 0x01) + cmd_line_buf.bkreg_state = BKREG_WAIT_01; + } + else if(cmd_line_buf.bkreg_state == BKREG_WAIT_FC) + { + if(rx_temp_buff[i] == 0xFC) + { + cmd_line_buf.cur_cmd_type = CMD_TYPE_BKREG; + + cmd_line_buf.cmd_buff[0] = 0x01; + cmd_line_buf.cmd_buff[1] = 0xE0; + cmd_line_buf.cmd_buff[2] = 0xFC; + + cmd_line_buf.cmd_data_len = 3; + + echo_len = 0; // cann't echo anything. + + continue; + } + else if(rx_temp_buff[i] != 0x01) + cmd_line_buf.bkreg_state = BKREG_WAIT_01; + else + cmd_line_buf.bkreg_state = BKREG_WAIT_E0; + } + + } + + #if 0 + if(cmd_line_buf.cur_cmd_type == CMD_TYPE_HEX) + { + if(cmd_line_buf.cmd_data_len < sizeof(cmd_line_buf.cmd_buff)) + { + cmd_line_buf.cmd_buff[cmd_line_buf.cmd_data_len] = rx_temp_buff[i]; + cmd_line_buf.cmd_data_len++; + } + + if(rx_temp_buff[i] == HEX_SYNC_CHAR) // SYNC_CHAR, hex frame end. + { + cmd_line_buf.cmd_buff[cmd_line_buf.cmd_data_len - 1] = HEX_SYNC_CHAR; // in case cmd_data_len overflow. + cmd_rx_done = bTRUE; + break; + } + } + #endif + + if(cmd_line_buf.cur_cmd_type == CMD_TYPE_TEXT) + { + echo_len++; + if(rx_temp_buff[i] == '\b') + { + if(cmd_line_buf.cmd_data_len > 0) + { + cmd_line_buf.cmd_data_len--; + + if(cmd_line_buf.cmd_data_len == 0) + need_backspace = bTRUE; + } + } + else if((rx_temp_buff[i] == '\n') || (rx_temp_buff[i] == '\r')) + { + if(cmd_line_buf.cmd_data_len < sizeof(cmd_line_buf.cmd_buff)) + { + cmd_line_buf.cmd_buff[cmd_line_buf.cmd_data_len] = 0; + } + else + { + cmd_line_buf.cmd_buff[cmd_line_buf.cmd_data_len - 1] = 0; // in case cmd_data_len overflow. + } + + cmd_rx_done = bTRUE; + break; + } + else if((rx_temp_buff[i] >= 0x20)) + { + if(cmd_line_buf.cmd_data_len < sizeof(cmd_line_buf.cmd_buff)) + { + cmd_line_buf.cmd_buff[cmd_line_buf.cmd_data_len] = rx_temp_buff[i]; + cmd_line_buf.cmd_data_len++; + } + } + + } + + /* patch for BK_REG tool. */ + if(cmd_line_buf.cur_cmd_type == CMD_TYPE_BKREG) + { + echo_len = 0; // cann't echo anything. + + /* p[0] = 0x1, p[1]=0xe0, p[2]=0xfc, p[3]=len. */ + if(cmd_line_buf.cmd_data_len == 3) + { + cmd_line_buf.bkreg_left_byte = rx_temp_buff[i] + 1; // +1, because will -1 in next process. + + if((cmd_line_buf.bkreg_left_byte + 3) >= sizeof(cmd_line_buf.cmd_buff)) // 3 bytes of header + 1 byte of len. + { + cmd_line_buf.cmd_data_len = 0; + + cmd_rx_done = bTRUE; + break; + } + } + + if(cmd_line_buf.cmd_data_len < sizeof(cmd_line_buf.cmd_buff)) + { + cmd_line_buf.cmd_buff[cmd_line_buf.cmd_data_len] = rx_temp_buff[i]; + cmd_line_buf.cmd_data_len++; + } + + cmd_line_buf.bkreg_left_byte--; + + if(cmd_line_buf.bkreg_left_byte == 0) + { + cmd_rx_done = bTRUE; + break; + } + } + } + + if( cmd_rx_done ) + { + /* patch for BK_REG tool. */ + if(cmd_line_buf.cur_cmd_type == CMD_TYPE_BKREG) + { + break; // cann't echo anything. + } + + if(cmd_line_buf.echo_enable) + { + echo_out(&rx_temp_buff[0], echo_len); + echo_out((u8 *)"\r\n", 2); + } + + break; + } + else + { + /* patch for BK_REG tool. */ + if( (cmd_line_buf.cur_cmd_type == CMD_TYPE_BKREG) || + ((cmd_line_buf.cur_cmd_type == CMD_TYPE_INVALID) && (cmd_line_buf.bkreg_state != BKREG_WAIT_01)) ) + { + // cann't echo anything. + } + else if(cmd_line_buf.echo_enable) + { + if(echo_len > 0) + { + if( (rx_temp_buff[echo_len - 1] == '\b') || + (rx_temp_buff[echo_len - 1] == 0x7f) ) /* DEL */ + { + echo_len--; + if((cmd_line_buf.cmd_data_len > 0) || need_backspace) + echo_out((u8 *)"\b \b", 3); + } + + u8 cr_lf = 0; + + if(echo_len == 1) + { + if( (rx_temp_buff[echo_len - 1] == '\r') || + (rx_temp_buff[echo_len - 1] == '\n') ) + { + cr_lf = 1; + } + } + else if(echo_len == 2) + { + if( (memcmp(rx_temp_buff, "\r\n", 2) == 0) || + (memcmp(rx_temp_buff, "\n\r", 2) == 0) ) + { + cr_lf = 1; + } + } + + if(cr_lf != 0) + { + echo_out((u8 *)"\r\n#", sizeof("\r\n#") - 1); + echo_len = 0; + } + } + echo_out(rx_temp_buff, echo_len); + } + } + + if(read_cnt < buf_len) /* all data are read out. */ + break; + } + + if(read_cnt < buf_len) /* all data are read out. */ + { + } + else /* cmd pends in buffer, handle it in new loop cycle. */ + { + set_shell_event(SHELL_EVENT_RX_IND); + } + + /* can re-use *buf_len*. */ + if( cmd_rx_done ) + { + #if 0 + if(cmd_line_buf.cur_cmd_type == CMD_TYPE_HEX) + { + #if 1 /* it's test code. */ + buf_len = sprintf((char *)&cmd_line_buf.rsp_buff[0], "\r\nHex count: %d, ", cmd_line_buf.cmd_data_len); + buf_len += sprintf((char *)&cmd_line_buf.rsp_buff[buf_len], "Hdr: %x, Tail: %x.\r\n", \ + cmd_line_buf.cmd_buff[0], cmd_line_buf.cmd_buff[cmd_line_buf.cmd_data_len - 1]); + + for(i = 1; (i < cmd_line_buf.cmd_data_len) && (i < 18); i++) + { + buf_len += sprintf((char *)&cmd_line_buf.rsp_buff[buf_len], "%x ", cmd_line_buf.cmd_buff[i]); + } + + strcpy((char *)&cmd_line_buf.rsp_buff[buf_len], "\r\n#"); + rsp_out(cmd_line_buf.rsp_buff, strlen((char *)cmd_line_buf.rsp_buff)); + + shell_trace_out(0x39, 8, cmd_line_buf.cmd_buff[0], cmd_line_buf.cmd_buff[1], cmd_line_buf.cmd_buff[2], cmd_line_buf.cmd_buff[3], \ + cmd_line_buf.cmd_buff[4], cmd_line_buf.cmd_buff[5], cmd_line_buf.cmd_buff[6], cmd_line_buf.cmd_buff[7]); + shell_spy_out(0x40, cmd_line_buf.cmd_buff, 9); + + #endif + } + #endif + + if(cmd_line_buf.cur_cmd_type == CMD_TYPE_TEXT) + { + u16 rx_ovf = 0; + cmd_dev->dev_drv->io_ctrl(cmd_dev, SHELL_IO_CTRL_GET_RX_STATUS, &rx_ovf); + + if(rx_ovf != 0) + { + cmd_hint_out(); + } + + cmd_line_buf.rsp_buff[0] = 0; + /* handle command. */ + if( cmd_line_buf.cmd_data_len > 0 ) + handle_shell_input( (char *)cmd_line_buf.cmd_buff, cmd_line_buf.cmd_data_len, (char *)cmd_line_buf.rsp_buff, sizeof(cmd_line_buf.rsp_buff) ); + + cmd_line_buf.rsp_buff[SHELL_RSP_BUF_LEN - 4] = 0; + + buf_len = strlen((char *)cmd_line_buf.rsp_buff); + if(buf_len > (SHELL_RSP_BUF_LEN - 4)) + buf_len = (SHELL_RSP_BUF_LEN - 4); + buf_len += sprintf((char *)&cmd_line_buf.rsp_buff[buf_len], "\r\n#"); + + rsp_out(cmd_line_buf.rsp_buff, buf_len); + } + + /* patch for BK_REG tool. */ + if(cmd_line_buf.cur_cmd_type == CMD_TYPE_BKREG) + { + if(cmd_line_buf.cmd_data_len > 3) + { +#if CONFIG_BKREG + extern int bkreg_run_command(const char *cmd, int flag); + + bkreg_run_command((const char *)&cmd_line_buf.cmd_buff[0], (int)cmd_line_buf.cmd_data_len); +#endif // CONFIG_BKREG + } + } + + cmd_line_buf.cur_cmd_type = CMD_TYPE_INVALID; /* reset cmd line to interpret new cmd. */ + cmd_line_buf.cmd_data_len = 0; + cmd_line_buf.bkreg_state = BKREG_WAIT_01; /* reset state machine. */ + } + + return; +} + +static void shell_task_init(void) +{ + u16 i; + + for(i = 0; i < SHELL_LOG_BUF1_NUM; i++) + { + buff1_free_list[i] = i; + } + for(i = 0; i < SHELL_LOG_BUF2_NUM; i++) + { + buff2_free_list[i] = i; + } + for(i = 0; i < SHELL_LOG_BUF3_NUM; i++) + { + buff3_free_list[i] = i; + } + + memset(&log_busy_queue, 0, sizeof(log_busy_queue)); + memset(&pending_queue, 0, sizeof(pending_queue)); + + cmd_line_buf.rsp_ongoing = bFALSE; + cmd_line_buf.cur_cmd_type = CMD_TYPE_INVALID; + cmd_line_buf.cmd_data_len = 0; + cmd_line_buf.bkreg_state = BKREG_WAIT_01; + cmd_line_buf.assert_data_len = 0; + cmd_line_buf.log_level = LOG_LEVEL; + cmd_line_buf.echo_enable = bTRUE; + + create_shell_event(); + + cmd_dev->dev_drv->init(cmd_dev); + cmd_dev->dev_drv->open(cmd_dev, shell_tx_complete, shell_rx_indicate); + + if(log_dev != cmd_dev) + { + log_dev->dev_drv->init(log_dev); + log_dev->dev_drv->open(log_dev, shell_tx_complete, NULL); + } + + #ifdef CONFIG_MASTER_CORE + ipc_dev->dev_drv->init(ipc_dev); + ipc_dev->dev_drv->open(ipc_dev, (shell_ipc_rx_t)shell_ipc_rx_indication); /* register rx-callback to copy log data to buffer. */ + #endif + + shell_init_ok = bTRUE; + +} + +void shell_task( void *para ) +{ + u32 Events; + + shell_task_init(); + + echo_out((u8 *)"\r\n#", sizeof("\r\n#") - 1); + + while(bTRUE) + { + Events = wait_any_event(SHELL_TASK_DEF_TICK); // WAIT_EVENT; + + if(Events & SHELL_EVENT_TX_REQ) + { + echo_out((u8 *)"Unsolicited\r\n#", sizeof("Unsolicited\r\n#") - 1); + } + + if(Events & SHELL_EVENT_RX_IND) + { + rx_ind_process(); + } + } +} + +__bk_weak int shell_log_check(u8 level, char *mod_name) +{ + if(level > cmd_line_buf.log_level) + return 0; //bFALSE; + + return 1;// bTRUE; +} + +int shell_log_out_direct(const char *format, va_list ap) +{ + u32 int_mask; + char *pbuf; + u16 data_len, buf_len; + va_list arg_list; + + pbuf = (char *)&cmd_line_buf.assert_buff[0]; + buf_len = sizeof(cmd_line_buf.assert_buff); + + int_mask = rtos_disable_int(); + + va_copy(arg_list, ap); + data_len = vsnprintf( pbuf, buf_len -1, format, arg_list ); + va_end( arg_list ); + + if ( (data_len != 0) && (pbuf[data_len - 1] == '\n') ) + { + if (data_len == 1 || pbuf[data_len - 2] != '\r') + { + pbuf[data_len] = '\n'; + pbuf[data_len - 1] = '\r'; + data_len++; + } + } + + log_dev->dev_drv->write_sync(log_dev, (u8 *)pbuf, data_len); + + rtos_enable_int(int_mask); + + return 1; +} + +int shell_log_raw_data(const u8 *data, u16 data_len) +{ + u8 *packet_buf; + u16 free_blk_tag; + + if (!shell_init_ok) + { + return 0; // bFALSE; + } + + if (NULL == data || 0 == data_len) + { + return 0; // bFALSE; + } + + packet_buf = alloc_log_blk(data_len, &free_blk_tag); + + if (NULL == packet_buf) + { + log_hint_out(); + return 0; // bFALSE; + } + + memcpy(packet_buf, data, data_len); + + u32 int_mask = rtos_disable_int(); + + // push to pending queue. + push_pending_queue(free_blk_tag, data_len); + + // notify shell task to process the log tx. + tx_req_process(); + + rtos_enable_int(int_mask); + + return 1; // bTRUE; +} + +void shell_log_out_port(int level, char *mod_name, const char *format, va_list ap) +{ + u8 * packet_buf; + u16 free_blk_tag; + u16 log_len = 0, buf_len; + va_list arg_list; + + if( !shell_init_ok ) + { + cmd_line_buf.log_level = LOG_LEVEL; // if not intialized, set log_level temporarily here. !!!patch!!! + shell_log_out_direct(format, ap); + return ; // bFALSE; + } + + if(shell_log_check(level, mod_name) == 0)//bFALSE) + { + return ; // bFALSE; + } + + va_copy(arg_list, ap); + buf_len = vsnprintf( NULL, 0, format, arg_list ) + 1; + va_end( arg_list ); + + if(mod_name != NULL) + buf_len += MOD_NAME_LEN + 2; + + packet_buf = alloc_log_blk(buf_len, &free_blk_tag); + + if(packet_buf == NULL) + { + log_hint_out(); + return ; // bFALSE; + } + + log_len = 0; + + if(mod_name != NULL) + { + memcpy(&packet_buf[0], mod_name, MOD_NAME_LEN); + packet_buf[MOD_NAME_LEN] = 0; + log_len = strlen((char *)packet_buf); // log_len <= MOD_NAME_LEN; + packet_buf[log_len] = ':'; + log_len++; + packet_buf[log_len] = 0; + } + + log_len += vsnprintf( (char *)&packet_buf[log_len], buf_len - log_len, format, ap ); + if ( (log_len != 0) && (packet_buf[log_len - 1] == '\n') ) + { + if (log_len == 1 || packet_buf[log_len - 2] != '\r') + { + packet_buf[log_len] = '\n'; + packet_buf[log_len - 1] = '\r'; + log_len++; + } + } + + u32 int_mask = rtos_disable_int(); + + // push to pending queue. + push_pending_queue(free_blk_tag, log_len); + + //set_shell_event(SHELL_EVENT_TX_REQ); // notify shell task to process the log tx. + tx_req_process(); + + rtos_enable_int(int_mask); + + return ; // bTRUE;; +} + +int shell_log_out(u8 level, char *mod_name, const char *format, ...) +{ + va_list arg_list; + + if ( !shell_init_ok ) + return 0; // bFALSE; + + if (shell_log_check(level, mod_name) == 0) + { + return 0; // bFALSE; + } + + va_start(arg_list, format); + shell_log_out_port(level, mod_name, format, arg_list); + va_end(arg_list); + + return 1; // bTRUE;; +} + +int shell_trace_out( u32 trace_id, ... ) +{ + u8 * packet_buf; + u16 free_blk_tag; + u16 trace_len = 0, buf_len; + + va_list arg_list; + u32 arg_num, i, temp; + + if( !shell_init_ok ) + return 0; //bFALSE; + + /* init variable length argument list */ + va_start( arg_list, trace_id ); + arg_num = ( u32 ) va_arg( arg_list, u32 ); + /* clean up variable argument pointer */ + va_end( arg_list ); + + if(arg_num > MAX_TRACE_ARGS) + arg_num = MAX_TRACE_ARGS; + + arg_num++; /* one u32 for system time. */ + + /* treat trace_id as u16 type. */ + + buf_len = (sizeof(u16) + arg_num * sizeof(u32)) * 2 + 2; /* +2 for hdr&tail, *2 for the worst case of escape every byte. */ + + packet_buf = alloc_log_blk(buf_len, &free_blk_tag); + + if(packet_buf == NULL) + { + log_hint_out(); + return 0; // bFALSE; + } + + packet_buf[0] = HEX_SYNC_CHAR; + trace_len = 1; + trace_len += append_link_data_byte(&packet_buf[trace_len], buf_len - trace_len, (u8 *)&trace_id, sizeof(u16)); + + temp = rtos_get_time(); + trace_len += append_link_data_byte(&packet_buf[trace_len], buf_len - trace_len, (u8 *)&temp, sizeof(u32)); + + /* init variable length argument list */ + va_start( arg_list, trace_id ); + arg_num = ( u32 ) va_arg( arg_list, u32 ); + + for (i = 0; (i < arg_num) && (i < MAX_TRACE_ARGS); i++) + { + temp = ( u32 ) va_arg( arg_list, u32 ); + trace_len += append_link_data_byte(&packet_buf[trace_len], buf_len - trace_len, (u8 *)&temp, sizeof(u32)); + } + + packet_buf[trace_len] = HEX_SYNC_CHAR; + trace_len++; + + /* clean up variable argument pointer */ + va_end( arg_list ); + + u32 int_mask = rtos_disable_int(); + + // push to pending queue. + push_pending_queue(free_blk_tag, trace_len); + + //set_shell_event(SHELL_EVENT_TX_REQ); // notify shell task to process the log tx. + tx_req_process(); + + rtos_enable_int(int_mask); + + return 1;//bTRUE;; +} + +int shell_spy_out( u16 spy_id, u8 * data_buf, u16 data_len) +{ + u8 * packet_buf; + u16 free_blk_tag; + u16 spy_len = 0, buf_len; + + u32 temp; + + if( !shell_init_ok ) + return 0; //bFALSE; + + buf_len = (sizeof(u16) + sizeof(u32) + data_len) * 2 + 2; /* +2 for hdr&tail, *2 for the worst case of escape every byte. */ + + packet_buf = alloc_log_blk(buf_len, &free_blk_tag); + + if(packet_buf == NULL) + { + log_hint_out(); + return 0; // bFALSE; + } + + packet_buf[0] = HEX_SYNC_CHAR; + spy_len = 1; + spy_len += append_link_data_byte(&packet_buf[spy_len], buf_len - spy_len, (u8 *)&spy_id, sizeof(u16)); + + temp = rtos_get_time(); + spy_len += append_link_data_byte(&packet_buf[spy_len], buf_len - spy_len, (u8 *)&temp, sizeof(u32)); + + spy_len += append_link_data_byte(&packet_buf[spy_len], buf_len - spy_len, data_buf, data_len); + + packet_buf[spy_len] = HEX_SYNC_CHAR; + spy_len++; + + u32 int_mask = rtos_disable_int(); + + // push to pending queue. + push_pending_queue(free_blk_tag, spy_len); + + //set_shell_event(SHELL_EVENT_TX_REQ); // notify shell task to process the log tx. + tx_req_process(); + + rtos_enable_int(int_mask); + + return 1;//bTRUE;; +} + +int shell_assert_out(bool bContinue, char * format, ...) +{ + u32 int_mask; + char *pbuf; + u16 data_len, buf_len; + va_list arg_list; + + pbuf = (char *)&cmd_line_buf.assert_buff[0]; + buf_len = sizeof(cmd_line_buf.assert_buff); + + int_mask = rtos_disable_int(); + + va_start( arg_list, format ); + + data_len = vsnprintf( pbuf, buf_len - 1, format, arg_list ); + + va_end( arg_list ); + + log_dev->dev_drv->write_sync(log_dev, (u8 *)pbuf, data_len); + + if( bContinue ) + { + rtos_enable_int(int_mask); + } + else + { + while(bTRUE) + { + } + } + + return 1;//bTRUE;; + +} + +int shell_assert_raw(bool bContinue, char * data_buff, u16 data_len) +{ + u32 int_mask; + + int_mask = rtos_disable_int(); + + log_dev->dev_drv->write_sync(log_dev, (u8 *)data_buff, data_len); + + if( bContinue ) + { + rtos_enable_int(int_mask); + } + else + { + while(1) + { + } + } + + return 1;//bTRUE;; + +} + +#ifdef CONFIG_MASTER_CORE +static int shell_ipc_rx_indication(u16 cmd, u8 *data, u16 data_len) +{ + if(cmd == MB_CMD_LOG_OUT) + { + return shell_log_raw_data(data, data_len); + } + + if(cmd == MB_CMD_ASSERT_OUT) + { + return shell_assert_raw(true, (char *)data, data_len); + } + + /* no cmd handler. */ + return 0; +} + +int shell_cmd_forward(char *cmd, u16 cmd_len) +{ + ipc_dev->dev_drv->write_sync(ipc_dev, (u8 *)cmd, cmd_len); + + return 1;//bTRUE; +} +#endif + +void shell_echo_set(int en_flag) +{ + if(en_flag != 0) + cmd_line_buf.echo_enable = bTRUE; + else + cmd_line_buf.echo_enable = bFALSE; +} + +int shell_echo_get(void) +{ + if(cmd_line_buf.echo_enable) + return 1; + + return 0; +} + +void shell_set_log_level(int level) +{ + cmd_line_buf.log_level = level; +} + +int shell_get_log_level(void) +{ + return cmd_line_buf.log_level; +} + +int shell_get_log_statist(u32 * info_list, u32 num) +{ + int cnt = 0; + if(num > 0) + { + info_list[0] = shell_log_overflow; + cnt++; + } + if(num > 1) + { + info_list[1] = shell_log_count; + cnt++; + } + if(num > 2) + { + info_list[2] = free_queue[0].empty_cnt; + cnt++; + } + if(num > 3) + { + info_list[3] = free_queue[1].empty_cnt; + cnt++; + } + if(num > 4) + { + info_list[4] = free_queue[2].empty_cnt; + cnt++; + } + + return cnt; +} + +void shell_log_flush(void) +{ + u32 int_mask; + + int_mask = rtos_disable_int(); + + log_dev->dev_drv->io_ctrl(log_dev, SHELL_IO_CTRL_FLUSH, NULL); + + rtos_enable_int(int_mask); +} + +void shell_set_uart_port(uint8_t uart_port) { +#if (!CONFIG_SLAVE_CORE) + if (bk_get_printf_port() != uart_port && uart_port < UART_ID_MAX) { + u32 int_mask = rtos_disable_int(); + + shell_log_flush(); + bk_set_printf_port(uart_port); + + log_dev->dev_drv->close(log_dev); + log_dev->dev_drv->io_ctrl(log_dev, SHELL_IO_CTRL_SET_UART_PORT, &uart_port); + log_dev->dev_drv->init(log_dev); + log_dev->dev_drv->open(log_dev, shell_tx_complete, shell_rx_indicate); + + rtos_enable_int(int_mask); + } +#endif +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/shell_uart.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/shell_uart.c new file mode 100755 index 0000000..1c85b58 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_cli/shell_uart.c @@ -0,0 +1,536 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include + +#include "cli.h" +#include "shell_drv.h" + +#define TX_QUEUE_LEN 8 +#define RX_BUFF_SIZE 160 +#define ECHO_BUFF_SIZE 64 + + +typedef struct +{ + u8 * packet; + u16 len; + u16 tag; +} dev_tx_packet_t; + + +typedef struct +{ + u8 uart_id; + + /* ======== TX channel ======= */ + /* tx queue */ + dev_tx_packet_t tx_list[TX_QUEUE_LEN]; + u16 list_out_idx; + u16 list_in_idx; + + /* currently tx packet info */ + u8 *cur_packet; + u16 packet_len; + u16 packet_tag; + u16 packet_tx_len; + + u8 tx_stopped; + + u8 echo_buff[ECHO_BUFF_SIZE]; + u8 echo_wr_idx; + u8 echo_rd_idx; + + tx_complete_t tx_complete_callback; + + /* ======== RX channel ======= */ + /* rx buffer */ + u8 rx_buff[RX_BUFF_SIZE]; + u16 rx_buff_wr_idx; + u16 rx_buff_rd_idx; + + u8 rx_over_flow; + + rx_indicate_t rx_indicate_callback; + +} shell_uart_ext_t; + +static bool_t shell_uart_init(shell_dev_t * shell_dev); +static bool_t shell_uart_open(shell_dev_t * shell_dev, tx_complete_t tx_callback, rx_indicate_t rx_callback); +static u16 shell_uart_write_async(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen, u16 Tag); +static u16 shell_uart_read(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen); +static u16 shell_uart_write_sync(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen); +static u16 shell_uart_write_echo(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen); +static bool_t shell_uart_ctrl(shell_dev_t * shell_dev, u8 cmd, void *param); +static bool_t shell_uart_close(shell_dev_t * shell_dev); + +static const shell_dev_drv_t shell_uart_drv = + { + .init = shell_uart_init, + .open = shell_uart_open, + .write_async = shell_uart_write_async, + .read = shell_uart_read, + .write_sync = shell_uart_write_sync, + .write_echo = shell_uart_write_echo, + .io_ctrl = shell_uart_ctrl, + .close = shell_uart_close + }; + +static shell_uart_ext_t uart1_ext = + { + .uart_id = CONFIG_UART_PRINT_PORT + }; + +shell_dev_t shell_uart = + { + .dev_drv = (struct _shell_dev_drv *)&shell_uart_drv, + .dev_type = SHELL_DEV_UART, + .dev_ext = &uart1_ext + }; + +#if 0 +static shell_uart_ext_t uart3_ext = + { + .uart_id = UART_ID_2 + }; + +shell_dev_t shell_uart3 = + { + .dev_drv = (struct _shell_dev_drv *)&shell_uart_drv, + .dev_type = SHELL_DEV_UART, + .dev_ext = &uart3_ext + }; +#endif + +/* =============================== internal functions =========================== */ + +static void shell_uart_rx_isr(int uartn, shell_uart_ext_t *uart_ext) +{ + u16 free_buff_len, rx_cnt = 0; + u8 rx_data; + int ret = -1; + + (void)uartn; + + if(uart_ext->rx_buff_wr_idx >= uart_ext->rx_buff_rd_idx) + { + free_buff_len = RX_BUFF_SIZE - uart_ext->rx_buff_wr_idx + uart_ext->rx_buff_rd_idx; + } + else + { + free_buff_len = uart_ext->rx_buff_rd_idx - uart_ext->rx_buff_wr_idx; + } + + while(bTRUE) /* read all data from rx-FIFO. */ + { + ret = uart_read_byte_ex(uart_ext->uart_id, &rx_data); + if (ret == -1) + break; + + rx_cnt++; + + /* rx_buff_wr_idx == rx_buff_rd_idx means empty, so reserve one byte. */ + if(rx_cnt < free_buff_len) /* reserved one byte space. */ + { + uart_ext->rx_buff[uart_ext->rx_buff_wr_idx] = rx_data; + + uart_ext->rx_buff_wr_idx = (uart_ext->rx_buff_wr_idx + 1) % RX_BUFF_SIZE; + + } + else + { + /* discard rx-data, rx overflow. */ + uart_ext->rx_over_flow = 1; // bTRUE; // rx overflow, disable rx interrupt to stop rx. + } + } + + if(uart_ext->rx_indicate_callback != NULL) + { + uart_ext->rx_indicate_callback(); + } +} + +static void shell_uart_tx_isr(int uartn, shell_uart_ext_t *uart_ext) +{ + int ret; + (void)uartn; + + while(bTRUE) /* write data to tx-FIFO. */ + { + ret = uart_write_ready(uart_ext->uart_id); + if(ret != 0) + break; + + /* previous packet tx complete, check ECHO before new packet. */ + if((uart_ext->cur_packet == NULL) || (uart_ext->packet_len == 0)) + { + if(uart_ext->echo_rd_idx != uart_ext->echo_wr_idx) /* tx echo firstly. */ + { + uart_write_byte(uart_ext->uart_id, uart_ext->echo_buff[uart_ext->echo_rd_idx]); + + uart_ext->echo_rd_idx = (uart_ext->echo_rd_idx + 1) % ECHO_BUFF_SIZE; + + continue; /* continue to ECHO next byte to tx-FIFO. */ + } + else + { + if(uart_ext->list_out_idx != uart_ext->list_in_idx) + { + uart_ext->cur_packet = uart_ext->tx_list[uart_ext->list_out_idx].packet; + uart_ext->packet_len = uart_ext->tx_list[uart_ext->list_out_idx].len; + uart_ext->packet_tag = uart_ext->tx_list[uart_ext->list_out_idx].tag; + uart_ext->packet_tx_len = 0; + } + else + { + /* all packets tx complete. */ + /* disable tx interrupt ? */ // disable TX firstly, then set tx_stopped to 1. + bk_uart_disable_tx_interrupt(uart_ext->uart_id); + + uart_ext->tx_stopped = 1; /* bTRUE;*/ /* all data tranferred, tx stopped.*/ + break; + } + } + } + + if(uart_ext->packet_tx_len < uart_ext->packet_len) + { + uart_write_byte(uart_ext->uart_id, uart_ext->cur_packet[uart_ext->packet_tx_len]); + + uart_ext->packet_tx_len++; + + continue; /* continue to TX next byte to tx-FIFO. */ + } + else + { + /* sent the whole packet, notify app. */ + if(uart_ext->tx_complete_callback != NULL) + { + uart_ext->tx_complete_callback(uart_ext->cur_packet, uart_ext->packet_tag); + } + + uart_ext->cur_packet = NULL; + uart_ext->packet_len = 0; + uart_ext->packet_tx_len = 0; + + /* to next packet. */ + uart_ext->list_out_idx = (uart_ext->list_out_idx + 1) % TX_QUEUE_LEN; + + continue; /* continue to TX next packet. */ + } + } + +} + +static void shell_uart_flush(shell_uart_ext_t *uart_ext) +{ + int ret; + + while(uart_ext->tx_stopped == 0) /* log tx pending. */ + { + ret = uart_write_ready(uart_ext->uart_id); + if(ret == BK_OK) + { + shell_uart_tx_isr(uart_ext->uart_id, uart_ext); + } + } +} + +static void shell_uart_tx_trigger(shell_uart_ext_t *uart_ext) +{ + if(uart_ext->tx_stopped == 0) + return; + + uart_ext->tx_stopped = 0; // set tx_stopped to 0 firstly, then enable TX. + + bk_uart_enable_tx_interrupt(uart_ext->uart_id); +} + +/* =============================== shell uart driver APIs =========================== */ + +static bool_t shell_uart_init(shell_dev_t * shell_dev) +{ + u8 uart_id; + shell_uart_ext_t *uart_ext; + + if(shell_dev == NULL) + return bFALSE; + + uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext; + uart_id = uart_ext->uart_id; + + memset(uart_ext, 0, sizeof(shell_uart_ext_t)); + uart_ext->rx_over_flow = 0; + uart_ext->tx_stopped = 1; + uart_ext->uart_id = uart_id; + + return bTRUE; +} + +static bool_t shell_uart_open(shell_dev_t * shell_dev, tx_complete_t tx_callback, rx_indicate_t rx_callback) +{ + shell_uart_ext_t *uart_ext; + + if(shell_dev == NULL) + return bFALSE; + + uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext; + + uart_ext->tx_complete_callback = tx_callback; + uart_ext->rx_indicate_callback = rx_callback; + + bk_uart_disable_sw_fifo(uart_ext->uart_id); + + // call uart driver to register isr callback; + bk_uart_register_rx_isr(uart_ext->uart_id, (uart_isr_t)shell_uart_rx_isr, uart_ext); + bk_uart_register_tx_isr(uart_ext->uart_id, (uart_isr_t)shell_uart_tx_isr, uart_ext); + + bk_uart_enable_rx_interrupt(uart_ext->uart_id); + + return bTRUE; +} + +static u16 shell_uart_write_async(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen, u16 Tag) +{ + u16 free_items; + shell_uart_ext_t *uart_ext; + + if(shell_dev == NULL) + return 0; + + uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext; + + if((pBuf == NULL) /*|| (BufLen == 0)*/) + return 0; + + /* enqueue pBuf even if BufLen is 0, upper layer need tx-complete-callback to free this pBuf. */ + + if(uart_ext->list_out_idx > uart_ext->list_in_idx) + free_items = uart_ext->list_out_idx - uart_ext->list_in_idx; + else + free_items = TX_QUEUE_LEN - uart_ext->list_in_idx + uart_ext->list_out_idx; + + /* list_out_idx == list_in_idx means empty, so reserved one item. */ + if(free_items > 1) + { + uart_ext->tx_list[uart_ext->list_in_idx].packet = pBuf; + uart_ext->tx_list[uart_ext->list_in_idx].len = BufLen; + uart_ext->tx_list[uart_ext->list_in_idx].tag = Tag; + + uart_ext->list_in_idx = (uart_ext->list_in_idx + 1) % TX_QUEUE_LEN; + + shell_uart_tx_trigger(uart_ext); + + return 1; + } + else + { + return 0; + } +} + +static u16 shell_uart_read(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen) +{ + u16 read_cnt = 0; + + shell_uart_ext_t *uart_ext; + + if(shell_dev == NULL) + return 0; + + uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext; + + if((pBuf == NULL) || (BufLen == 0)) + return 0; + + while(uart_ext->rx_buff_rd_idx != uart_ext->rx_buff_wr_idx) + { + pBuf[read_cnt] = uart_ext->rx_buff[uart_ext->rx_buff_rd_idx]; + + uart_ext->rx_buff_rd_idx = (uart_ext->rx_buff_rd_idx + 1) % RX_BUFF_SIZE; + + read_cnt++; + if(read_cnt >= BufLen) + break; + } + + return read_cnt; + +} + +/* call this after interrupt is DISABLED. */ +static u16 shell_uart_write_sync(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen) +{ + shell_uart_ext_t *uart_ext; + + if(shell_dev == NULL) + return 0; + + uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext; + + if((pBuf == NULL) || (BufLen == 0)) + return 0; + + u16 wr_cnt = 0; + + while(bTRUE) /* write data to tx-FIFO. */ + { + uart_write_byte(uart_ext->uart_id, *pBuf); // it is macro define, do NOT use *pBuf++; + + pBuf++; wr_cnt++; + + if(wr_cnt >= BufLen) + break; + } + + return BufLen; +} + +static u16 shell_uart_write_echo(shell_dev_t * shell_dev, u8 * pBuf, u16 BufLen) +{ + u16 free_buff_len, wr_cnt = 0; + + shell_uart_ext_t *uart_ext; + + if(shell_dev == NULL) + return 0; + + uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext; + + if((pBuf == NULL) || (BufLen == 0)) + return 0; + + if(uart_ext->echo_wr_idx >= uart_ext->echo_rd_idx) + { + free_buff_len = ECHO_BUFF_SIZE - uart_ext->echo_wr_idx + uart_ext->echo_rd_idx; + } + else + { + free_buff_len = uart_ext->echo_rd_idx - uart_ext->echo_wr_idx; + } + + /* echo_wr_idx == echo_rd_idx means empty, so reserved one byte. */ + while(free_buff_len > 1) + { + uart_ext->echo_buff[uart_ext->echo_wr_idx] = pBuf[wr_cnt]; + uart_ext->echo_wr_idx = (uart_ext->echo_wr_idx + 1) % ECHO_BUFF_SIZE; + + free_buff_len--; + + wr_cnt++; + if(wr_cnt >= BufLen) + break; + } + + if(wr_cnt > 0) + shell_uart_tx_trigger(uart_ext); + + return wr_cnt; + +} + +static bool_t shell_uart_ctrl(shell_dev_t * shell_dev, u8 cmd, void *param) +{ + shell_uart_ext_t *uart_ext; + + if(shell_dev == NULL) + return bFALSE; + + uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext; + + switch(cmd) + { + case SHELL_IO_CTRL_GET_STATUS: + if(param == NULL) + return bFALSE; + + u16 free_items; + + if(uart_ext->list_out_idx > uart_ext->list_in_idx) + free_items = uart_ext->list_out_idx - uart_ext->list_in_idx; + else + free_items = TX_QUEUE_LEN - uart_ext->list_in_idx + uart_ext->list_out_idx; + + if(free_items > 1) + *((u16 *)param) = free_items - 1; + else + *((u16 *)param) = 0; + + break; + + case SHELL_IO_CTRL_RX_RESET: + uart_ext->rx_buff_rd_idx = 0; + uart_ext->rx_buff_wr_idx = 0; + break; + + case SHELL_IO_CTRL_TX_RESET: + uart_ext->list_out_idx = 0; + uart_ext->list_in_idx = 0; + + uart_ext->cur_packet = NULL; + uart_ext->packet_len = 0; + uart_ext->packet_tx_len = 0; + + break; + + case SHELL_IO_CTRL_FLUSH: + shell_uart_flush(uart_ext); + break; + + case SHELL_IO_CTRL_SET_UART_PORT: + if(param == NULL) { + return bFALSE; + } + u8 uart_port = *(u8 *)param; + uart_ext->uart_id = uart_port; + break; + + case SHELL_IO_CTRL_GET_RX_STATUS: + if(param == NULL) + return bFALSE; + + *((u16 *)param) = uart_ext->rx_over_flow; + uart_ext->rx_over_flow = 0; // clear it after read by user. + + break; + + default: + return bFALSE; + break; + } + + return bTRUE; +} + +static bool_t shell_uart_close(shell_dev_t * shell_dev) +{ + shell_uart_ext_t *uart_ext; + + if(shell_dev == NULL) + return bFALSE; + + uart_ext = (shell_uart_ext_t *)shell_dev->dev_ext; + + // call uart driver to register isr callback; + bk_uart_register_rx_isr(uart_ext->uart_id, NULL, NULL); + bk_uart_register_tx_isr(uart_ext->uart_id, NULL, NULL); + + uart_ext->tx_complete_callback = NULL; + uart_ext->rx_indicate_callback = NULL; + + return bTRUE; +} + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_event/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_event/BUILD.gn new file mode 100755 index 0000000..7dbadb0 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_event/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ "event.c" ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_init/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_init/BUILD.gn new file mode 100755 index 0000000..8c6ed80 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_init/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ + "components_init.c", + "legacy_init.c", + ] + public_configs = [ + "${beken_sdk_dir}/components/bk_cli:public", + "${beken_sdk_dir}/components/easy_flash:public", + "${beken_sdk_dir}/middleware/driver:public", + "${beken_sdk_dir}/middleware/boards:public", + "${beken_sdk_dir}/middleware/soc:public", + "${beken_sdk_dir}/middleware/arch:public", + ] +} + +config("public") { + include_dirs = [ + ".", + "include", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_log/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_log/BUILD.gn new file mode 100755 index 0000000..f122edb --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_log/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ "log.c" ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_netif/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_netif/BUILD.gn new file mode 100755 index 0000000..93f8dde --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_netif/BUILD.gn @@ -0,0 +1,33 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ "bk_netif.c" ] + public_configs = [ + ":public", + "${beken_sdk_dir}/components/bk_os:public", + "${beken_sdk_dir}/components/bk_wifi:public", + ] +} + +config("public") { + include_dirs = [ + "include", + "//third_party/lwip/src/include", + "${third_party_adatpter_path}/lwip_intf_v2_1/lwip-2.1.2/port", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_os/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_os/BUILD.gn new file mode 100755 index 0000000..363a415 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_os/BUILD.gn @@ -0,0 +1,41 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ + "liteos_m_mst/mem_arch.c", + "liteos_m_mst/os_clock.c", + "liteos_m_mst/port.c", + "liteos_m_mst/rtos_pub.c", + "liteos_m_mst/str_arch.c", + "platform_stub.c", + "rtos_ext.c", + ] + public_configs = [ + ":public", + "${beken_sdk_dir}/middleware/arch:public", + "${beken_sdk_dir}/middleware/driver:public", + ] +} + +config("public") { + include_dirs = [ + ".", + "include", + "liteos_m_mst", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_os/liteos_m_mst/port.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_os/liteos_m_mst/port.c index e1832cb..819ac06 100755 --- a/bk7235/liteos_m/bk_sdk_armino/components/bk_os/liteos_m_mst/port.c +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_os/liteos_m_mst/port.c @@ -35,6 +35,7 @@ #include "los_arch_timer.h" #include "los_sched.h" +#include "platform.h" #define ISR_STACK_SIZE 1024 #define BYTE_ALIGNMENT_MASK ( 0x000f ) diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_os/liteos_m_mst/str_arch.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_os/liteos_m_mst/str_arch.c new file mode 100755 index 0000000..048281e --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_os/liteos_m_mst/str_arch.c @@ -0,0 +1,153 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 + +#include +#include +#include +#include +#include + +char *os_strchr(const char *s, int c) +{ + return strchr(s, c); +} + +UINT32 os_strlen(const char *str) +{ + return strlen(str); +} + +INT32 os_strcmp(const char *s1, const char *s2) +{ + return strcmp(s1, s2); +} + +UINT32 os_strtoul(const char *nptr, char **endptr, int base) +{ + return strtoul(nptr, endptr, base); +} + +char *os_strcpy(char *out, const char *in) +{ + return strcpy(out, in); +} + +char *os_strncpy(char *out, const char *in, const UINT32 n) +{ + return strncpy(out, in, (unsigned int)n); +} + +size_t os_strlcpy(char *dest, const char *src, size_t siz) +{ + const char *s = src; + size_t left = siz; + + if (left) + { + /* Copy string up to the maximum size of the dest buffer */ + while (--left != 0) + { + if ((*dest++ = *s++) == '\0') + break; + } + } + + if (left == 0) + { + /* Not enough room for the string; force NUL-termination */ + if (siz != 0) + *dest = '\0'; + + while (*s++) + ; /* determine total src string length */ + } + + return s - src - 1; +} + +INT32 os_strncmp(const char *s1, const char *s2, const UINT32 n) +{ + return strncmp(s1, s2, (unsigned int)n); +} + +INT32 os_snprintf(char *buf, UINT32 size, const char *fmt, ...) +{ + va_list args; + INT32 rc; + + va_start(args, fmt); + rc = vsnprintf(buf, size, fmt, args); + va_end(args); + + /* if want to print more than the limitation */ + if (rc > size) + rc = (INT32)size - rc; + + return rc; +} + +INT32 os_vsnprintf(char *buf, UINT32 size, const char *fmt, va_list ap) +{ + return vsnprintf(buf, size, fmt, ap); +} + +char *os_strdup(const char *s) +{ + char *res; + size_t len; + + if (s == NULL) + return NULL; + + len = os_strlen(s); + res = os_malloc(len + 1); + if (res) + os_memcpy(res, s, len + 1); + + return res; +} + + +int os_strcasecmp(const char *s1, const char *s2) +{ + /* + * Ignoring case is not required for main functionality, so just use + * the case sensitive version of the function. + */ + return os_strcmp(s1, s2); +} + + +int os_strncasecmp(const char *s1, const char *s2, size_t n) +{ + /* + * Ignoring case is not required for main functionality, so just use + * the case sensitive version of the function. + */ + return os_strncmp(s1, s2, n); +} + +char *os_strrchr(const char *s, int c) +{ + return strrchr(s, c); +} + +char *os_strstr(const char *haystack, const char *needle) +{ + return strstr(haystack, needle); +} +// EOF diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_os/platform_stub.c b/bk7235/liteos_m/bk_sdk_armino/components/bk_os/platform_stub.c index 93ecbe7..ef6bbdb 100644 --- a/bk7235/liteos_m/bk_sdk_armino/components/bk_os/platform_stub.c +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_os/platform_stub.c @@ -17,7 +17,7 @@ #include #include #include -#include +//#include #include @@ -25,7 +25,6 @@ #include #include "common/bk_assert.h" - /************** wrap C library functions **************/ void *__wrap_malloc(size_t size) { diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_ps/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_ps/BUILD.gn new file mode 100755 index 0000000..2b26b90 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_ps/BUILD.gn @@ -0,0 +1,26 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +kernel_module(module_name) { +} + +config("public") { + include_dirs = [ + ".", + "include", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_startup/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_startup/BUILD.gn new file mode 100755 index 0000000..c211bee --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_startup/BUILD.gn @@ -0,0 +1,31 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ + "liteos_m/rtos_init.c", + "system_main.c", + ] + include_dirs = [ "liteos_m" ] + public_configs = [ + "${beken_sdk_dir}/components/bk_init:public", + "${beken_sdk_dir}/components/bk_os:public", + "${beken_sdk_dir}/middleware/driver:public", + "${beken_sdk_dir}/middleware/arch:public", + "${beken_sdk_dir}/middleware/soc:public", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_system/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_system/BUILD.gn new file mode 100755 index 0000000..69e914c --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_system/BUILD.gn @@ -0,0 +1,43 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ + "mac.c", + "os/liteos_m/tick.c", + "printf.c", + "printf_base.c", + "reboot.c", + "target_util.c", + "tick_base.c", + ] + public_configs = [ + ":public", + "${beken_sdk_dir}/components/bk_os:public", + "${beken_sdk_dir}/components/bk_cli:public", + "${beken_sdk_dir}/components/bk_wifi:public", + "${beken_sdk_dir}/middleware/driver:public", + "${beken_sdk_dir}/middleware/soc:public", + ] +} + +config("public") { + include_dirs = [ + "os/liteos_m", + "soc/bk7235", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_system/soc/bk7231n/tick_timer_id.h b/bk7235/liteos_m/bk_sdk_armino/components/bk_system/soc/bk7235/tick_timer_id.h old mode 100644 new mode 100755 similarity index 100% rename from bk7235/liteos_m/bk_sdk_armino/components/bk_system/soc/bk7231n/tick_timer_id.h rename to bk7235/liteos_m/bk_sdk_armino/components/bk_system/soc/bk7235/tick_timer_id.h diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_system/soc/bk7271/tick_timer_id.h b/bk7235/liteos_m/bk_sdk_armino/components/bk_system/soc/bk7271/tick_timer_id.h deleted file mode 100644 index 9e9a8e0..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/bk_system/soc/bk7271/tick_timer_id.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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. - -#pragma once - -#define TICK_TIMER_ID BK_TIMER_ID1 diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_usb/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/components/bk_usb/CMakeLists.txt deleted file mode 100644 index 4598300..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/bk_usb/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -armino_component_register() diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_usb/Kconfig b/bk7235/liteos_m/bk_sdk_armino/components/bk_usb/Kconfig deleted file mode 100755 index 3d3a663..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/bk_usb/Kconfig +++ /dev/null @@ -1,66 +0,0 @@ -menu "USB configuration" - -config USB - bool "Enable USB" - default y - -menu "USB" - depends on USB - - #TODO HOST/DEVICE mode mutual exclusive - choice USB_MODE - prompt "Enable USB HOST mode" - default USB_HOST - - config USB_HOST - bool "USB Host Mode" - config USB_DEVICE - bool "USB Device Mode" - endchoice - - choice USB_PORT - prompt "Select USB Port" - default USB2_PORT - config USB1_PORT - bool "USB1 port" - config USB2_PORT - bool "USB2 port" - endchoice - - config TASK_USB_PRIO - int "Priority of USB task" - range 1 10 - default 5 - - config USB_MSD - bool "Enable USB MSD" - default y - - config USB_HID - bool "Enable USB HID" - default n - - config USB_CCD - bool "Enable USB CCD" - default n - - config USB_UVC - bool "Enable USB UVC" - default n - - config USB_CHARGE - bool "Enable USB Charge" - default n - menu "DSP" - - config DSP - bool "Enable DSP" - default n - - #TODO delete it - config DSP_SRC_ADD - hex "DSP srouce address" - default 0x130000 - endmenu -endmenu -endmenu diff --git a/bk7235/liteos_m/bk_sdk_armino/components/bk_wifi/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/bk_wifi/BUILD.gn new file mode 100755 index 0000000..a0a812c --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/bk_wifi/BUILD.gn @@ -0,0 +1,24 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") + +config("public") { + include_dirs = [ + "include", + "include/bk_private", + "include/bk_private/legacy", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/.gitattributes b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/.gitattributes new file mode 100755 index 0000000..a6ec1ac --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/.gitattributes @@ -0,0 +1,40 @@ +* text=auto + +*.S text +*.asm text +*.c text +*.cc text +*.cpp text +*.cxx text +*.h text +*.htm text +*.html text +*.in text +*.ld text +*.m4 text +*.mak text +*.mk text +*.py text +*.rb text +*.s text +*.sct text +*.sh text +*.txt text +*.xml text +Makefile text +AUTHORS text +COPYING text + +*.LZO -text +*.Opt -text +*.Uv2 -text +*.ewp -text +*.eww -text +*.vcproj -text +*.bat -text +*.dos -text +*.icf -text +*.inf -text +*.ini -text +*.sct -text +*.xsd -text diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/BUILD.gn new file mode 100755 index 0000000..9f36cb8 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/BUILD.gn @@ -0,0 +1,42 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ + "bk_ef.c", + "port/ef_port.c", + "src/easyflash.c", + "src/ef_env.c", + "src/ef_env_wl.c", + "src/ef_iap.c", + "src/ef_log.c", + "src/ef_utils.c", + ] + public_configs = [ + ":public", + "${beken_sdk_dir}/components/base64:public", + "${beken_sdk_dir}/middleware/driver:public", + ] +} + +config("public") { + include_dirs = [ + ".", + "inc", + "port", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/CMakeLists.txt new file mode 100755 index 0000000..35b8e10 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/CMakeLists.txt @@ -0,0 +1,25 @@ +set(incs + . + inc + port + ) + +set(srcs) + +if (CONFIG_EASY_FLASH) + list(APPEND srcs + bk_ef.c + src/easyflash.c + src/ef_env.c + src/ef_env_wl.c + src/ef_iap.c + src/ef_log.c + src/ef_utils.c + port/ef_port.c + ) +endif() + +armino_component_register(SRCS "${srcs}" + INCLUDE_DIRS "${incs}" + REQUIRES base64 + PRIV_REQUIRES bk_common) diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/Kconfig b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/Kconfig new file mode 100755 index 0000000..d1a954e --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/Kconfig @@ -0,0 +1,3 @@ +config EASY_FLASH + bool "Enable Easy Flash" + default n \ No newline at end of file diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/LICENSE b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/LICENSE new file mode 100755 index 0000000..9b802d2 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2014-2018 Armink (armink.ztl@gmail.com) + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/bk_ef.c b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/bk_ef.c new file mode 100755 index 0000000..0ec864b --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/bk_ef.c @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include "bk_ef.h" +#include "base_64.h" +#include +#include + +#if CONFIG_EASY_FLASH +char *bk_get_env(const char *key) +{ + return ef_get_env(key); +} + +EfErrCode bk_set_env(const char *key, const char *value) +{ + return ef_set_env(key, value); +} + +EfErrCode bk_save_env(void) +{ + return ef_save_env(); +} + +EfErrCode bk_set_buf_env(const char *key, const char *buf, int len) +{ + EfErrCode result; + unsigned char ret; + unsigned char *ef_value; + uint32_t buf_len; + int out_len; + + if ((0 == len) || (NULL == key) + || (NULL == buf)) + return EF_ENV_INIT_FAILED; + + buf_len = base64_calc_encode_length(len) + 4; + ef_value = os_zalloc(buf_len); + if (NULL == ef_value) + return EF_ENV_INIT_FAILED; + + ret = base64_encode((unsigned char *)buf, len, &out_len, ef_value); + if (0 == ret) { + os_free(ef_value); + ef_value = NULL; + return EF_ENV_INIT_FAILED; + } + + result = ef_set_env(key, (char *)ef_value); + + os_free(ef_value); + + return result; +} + +EfErrCode bk_get_buf_env(const char *key, const char *buf, int len) +{ + unsigned char *out_ptr; + unsigned char ret; + char *ef_value; + int out_buf_len, count; + int out_len, value_len; + + ef_value = ef_get_env(key); + if (NULL == ef_value) + return EF_ENV_NAME_ERR; + + value_len = os_strlen(ef_value); + if (0 == value_len) + return EF_ENV_INIT_FAILED; + + out_buf_len = base64_calc_decode_length((unsigned char *)ef_value, value_len); + out_ptr = (unsigned char *)os_zalloc(out_buf_len + 4); + if (NULL == out_ptr) + return EF_ENV_INIT_FAILED; + + ret = base64_decode((unsigned char *)ef_value, value_len, &out_len, out_ptr); + if (0 == ret) { + os_free(out_ptr); + out_ptr = NULL; + return EF_ENV_INIT_FAILED; + } + + if (out_len) { + count = min(len, out_len); + BK_ASSERT(len == out_len); + + os_memcpy((void *)buf, out_ptr, count); + } + + os_free(out_ptr); + + return EF_NO_ERR; +} +#endif // CONFIG_EASY_FLASH + +// eof + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/bk_ef.h b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/bk_ef.h new file mode 100755 index 0000000..bd7468d --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/bk_ef.h @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 _BK_EASY_FLASH_H_ +#define _BK_EASY_FLASH_H_ + +#include "easyflash.h" + +#if CONFIG_EASY_FLASH +EfErrCode bk_save_env(void); +char *bk_get_env(const char *key); +EfErrCode bk_set_env(const char *key, const char *value); +EfErrCode bk_set_buf_env(const char *key, const char *buf, int len); +EfErrCode bk_get_buf_env(const char *key, const char *buf, int len); +#endif // CONFIG_EASY_FLASH + +#endif // _BK_EASY_FLASH_H_ +// eof + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/inc/easyflash.h b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/inc/easyflash.h new file mode 100755 index 0000000..45f6e10 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/inc/easyflash.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2014-2018, Armink, + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Function: It is an head file for this library. You can see all be called functions. + * Created on: 2014-09-10 + */ +#ifndef _EASYFLASH_H_ +#define _EASYFLASH_H_ + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(EF_USING_ENV) && (!defined(ENV_USER_SETTING_SIZE) || !defined(ENV_AREA_SIZE)) +#error "Please configure user setting ENV size or ENV area size (in ef_cfg.h)" +#endif + +#if defined(EF_USING_LOG) && !defined(LOG_AREA_SIZE) +#error "Please configure log area size (in ef_cfg.h)" +#endif + +#if !defined(EF_START_ADDR) +#error "Please configure backup area start address (in ef_cfg.h)" +#endif + +#if !defined(EF_ERASE_MIN_SIZE) +#error "Please configure minimum size of flash erasure (in ef_cfg.h)" +#endif + +/* EasyFlash debug print function. Must be implement by user. */ +#define EF_DEBUG(...) ef_log_debug(__FILE__, __LINE__, __VA_ARGS__) +/* EasyFlash routine print function. Must be implement by user. */ +#define EF_INFO(...) ef_log_info(__VA_ARGS__) +/* EasyFlash assert for developer. */ +#define EF_ASSERT(EXPR) \ + if (!(EXPR)) \ + { \ + EF_DEBUG("(%s) has assert failed at %s.\n", #EXPR, __FUNCTION__); \ + while (1); \ + } +/* EasyFlash software version number */ +#define EF_SW_VERSION "3.0.4" + +typedef struct _ef_env { + char *key; + char *value; +} ef_env, *ef_env_t; + +/* EasyFlash error code */ +typedef enum { + EF_NO_ERR, + EF_ERASE_ERR, + EF_WRITE_ERR, + EF_ENV_NAME_ERR, + EF_ENV_NAME_EXIST, + EF_ENV_FULL, + EF_ENV_INIT_FAILED, +} EfErrCode; + +/* the flash sector current status */ +typedef enum { + EF_SECTOR_EMPTY, + EF_SECTOR_USING, + EF_SECTOR_FULL, +} EfSecrorStatus; + +/* easyflash.c */ +EfErrCode easyflash_init(void); + +#ifdef EF_USING_ENV +/* ef_env.c ef_env_wl.c */ +EfErrCode ef_load_env(void); +void ef_print_env(void); +char *ef_get_env(const char *key); +EfErrCode ef_set_env(const char *key, const char *value); +EfErrCode ef_save_env(void); +EfErrCode ef_env_set_default(void); +size_t ef_get_env_write_bytes(void); +EfErrCode ef_set_and_save_env(const char *key, const char *value); +#endif + +#ifdef EF_USING_IAP +/* ef_iap.c */ +EfErrCode ef_erase_bak_app(size_t app_size); +EfErrCode ef_erase_user_app(uint32_t user_app_addr, size_t user_app_size); +EfErrCode ef_erase_spec_user_app(uint32_t user_app_addr, size_t app_size, + EfErrCode(*app_erase)(uint32_t addr, size_t size)); +EfErrCode ef_erase_bl(uint32_t bl_addr, size_t bl_size); +EfErrCode ef_write_data_to_bak(uint8_t *data, size_t size, size_t *cur_size, + size_t total_size); +EfErrCode ef_copy_app_from_bak(uint32_t user_app_addr, size_t app_size); +EfErrCode ef_copy_spec_app_from_bak(uint32_t user_app_addr, size_t app_size, + EfErrCode(*app_write)(uint32_t addr, const uint32_t *buf, size_t size)); +EfErrCode ef_copy_bl_from_bak(uint32_t bl_addr, size_t bl_size); +uint32_t ef_get_bak_app_start_addr(void); +#endif + +#ifdef EF_USING_LOG +/* ef_log.c */ +EfErrCode ef_log_read(size_t index, uint32_t *log, size_t size); +EfErrCode ef_log_write(const uint32_t *log, size_t size); +EfErrCode ef_log_clean(void); +size_t ef_log_get_used_size(void); +#endif + +/* ef_utils.c */ +uint32_t ef_calc_crc32(uint32_t crc, const void *buf, size_t size); + +/* ef_port.c */ +EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size); +EfErrCode ef_port_erase(uint32_t addr, size_t size); +EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size); +void ef_port_env_lock(void); +void ef_port_env_unlock(void); +void ef_log_debug(const char *file, const long line, const char *format, ...); +void ef_log_info(const char *format, ...); +void ef_print(const char *format, ...); + +#ifdef __cplusplus +} +#endif + +#endif /* EASYFLASH_H_ */ diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/port/ef_cfg.h b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/port/ef_cfg.h new file mode 100755 index 0000000..42e20e6 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/port/ef_cfg.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2015, Armink, + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Function: It is the configure head file for this library. + * Created on: 2015-07-14 + */ +#ifndef _EF_CFG_H_ +#define _EF_CFG_H_ + +/* using ENV function */ +#define EF_USING_ENV + +/* using wear leveling mode for ENV */ +/* #define EF_ENV_USING_WL_MODE */ + +/* using power fail safeguard mode for ENV */ +#define EF_ENV_USING_PFS_MODE + +/* using IAP function */ +//#define EF_USING_IAP + +/* using save log function */ +//#define EF_USING_LOG + +/* the minimum size of flash erasure */ +#define EF_ERASE_MIN_SIZE 4096 + +/** + * + * This all Backup Area Flash storage index. All used flash area configure is under here. + * |----------------------------| Storage Size + * | Environment variables area | ENV area size @see ENV_AREA_SIZE + * | 1.system section | ENV_SYSTEM_SIZE + * | 2:data section | ENV_AREA_SIZE - ENV_SYSTEM_SIZE + * |----------------------------| + * | Saved log area | Log area size @see LOG_AREA_SIZE + * |----------------------------| + * |(IAP)Downloaded application | IAP already downloaded application, unfixed size + * |----------------------------| + * + * @note all area size must be aligned with EF_ERASE_MIN_SIZE + * @note EasyFlash will use ram to buffered the ENV. At some time flash's EF_ERASE_MIN_SIZE is so big, + * and you want use ENV size is less than it. So you must defined ENV_USER_SETTING_SIZE for ENV. + * @note ENV area size has some limitations in different modes. + * 1.Normal mode: no more limitations + * 2.Wear leveling mode: system section will used an flash section and the data section will used at least 2 flash sections + * 3.Power fail safeguard mode: ENV area will has an backup. It is twice as normal mode. + * 4.wear leveling and power fail safeguard mode: The required capacity will be 2 times the total capacity in wear leveling mode. + * For example: + * The EF_ERASE_MIN_SIZE is 128K and the ENV_USER_SETTING_SIZE: 2K. The ENV_AREA_SIZE in different mode you can define + * 1.Normal mode: 1*EF_ERASE_MIN_SIZE + * 2.Wear leveling mode: 3*EF_ERASE_MIN_SIZE (It has 2 data section to store ENV. So ENV can erase at least 200,000 times) + * 3.Power fail safeguard mode: 2*EF_ERASE_MIN_SIZE + * 4.Wear leveling and power fail safeguard mode: 6*EF_ERASE_MIN_SIZE + * @note the log area size must be more than twice of EF_ERASE_MIN_SIZE + */ +/* backup area start address */ /* start address of param partition */ +#define EF_START_ADDR 0x3FA000 //(0x400000 - 12*2*1024) //(0x1FC000) + +/* the user setting size of ENV, must be word alignment */ +#define ENV_USER_SETTING_SIZE (12 * 1024 - 20)//(8 * 1024 - 20) + +#ifndef EF_ENV_USING_PFS_MODE +#ifndef EF_ENV_USING_WL_MODE +/* ENV area total bytes size in normal mode. */ +#define ENV_AREA_SIZE (1 * EF_ERASE_MIN_SIZE) /* 4K */ +#else +/* ENV area total bytes size in wear leveling mode. */ +#define ENV_AREA_SIZE (4 * EF_ERASE_MIN_SIZE) /* 16K */ +#endif +#else +#ifndef EF_ENV_USING_WL_MODE +/* ENV area total bytes size in power fail safeguard mode. */ +#define ENV_AREA_SIZE ((12*2/4) * EF_ERASE_MIN_SIZE) /* 16K */ +#else +/* ENV area total bytes size in wear leveling and power fail safeguard mode. */ +#define ENV_AREA_SIZE (6 * EF_ERASE_MIN_SIZE) /* 24K */ +#endif +#endif +/* saved log area size */ +#define LOG_AREA_SIZE (254 * EF_ERASE_MIN_SIZE) /* 1016K */ + +/* print debug information of flash */ +//#define PRINT_DEBUG + +#endif /* EF_CFG_H_ */ diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/port/ef_port.c b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/port/ef_port.c new file mode 100755 index 0000000..5c8491a --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/port/ef_port.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2015, Armink, + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Function: Portable interface for stm32f4xx platform. + * Created on: 2015-01-16 + */ +#include +#include +#include +#include +#include + +#if CONFIG_FLASH_ORIGIN_API +#include "bk_flash.h" +#include "flash.h" +#else +#include "driver/flash.h" +#endif + +#include +#include "bk_uart.h" +#include "bk_drv_model.h" + +/* default ENV set for user */ +static const ef_env default_env_set[] = { + {"user", "user"}, +}; + +static beken_semaphore_t env_cache_lock = NULL; + +#ifdef PRINT_DEBUG +static char log_buf[256]; +#endif + +/** + * Flash port for hardware initialize. + * + * @param default_env default ENV set for user + * @param default_env_size default ENV size + * + * @return result + */ +EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size) +{ + bk_err_t ret; + EfErrCode result = EF_NO_ERR; + + *default_env = default_env_set; + *default_env_size = sizeof(default_env_set) / sizeof(default_env_set[0]); + + ret = rtos_init_semaphore_adv(&env_cache_lock, 1, 1); + BK_ASSERT(kNoErr == ret); + + return result; +} + +/** + * Read data from flash. + * @note This operation's units is word. + * + * @param addr flash address + * @param buf buffer to store read data + * @param size read bytes size + * + * @return result + */ +EfErrCode ef_port_read(uint32_t addr, uint32_t *buf, size_t size) +{ + EfErrCode result = EF_NO_ERR; + + EF_ASSERT(size % 4 == 0); + +#if CONFIG_FLASH_ORIGIN_API + flash_read((char *)buf, (unsigned long)size, addr); +#else + bk_flash_read_bytes(addr, (uint8_t *)buf, (unsigned long)size); +#endif + + return result; +} + +/* + * size param: The flash size of you want to erase in bytes. + * return: Returns the size of the actual erase. + */ +static int bk_erase(uint32_t addr, size_t size) +{ +#if CONFIG_FLASH_ORIGIN_API + int param; + UINT32 status; + int protect_type; + DD_HANDLE flash_handle; +#else + flash_protect_type_t protect_type; +#endif + unsigned int _size = size; + +#if CONFIG_FLASH_ORIGIN_API + flash_handle = ddev_open(DD_DEV_TYPE_FLASH, &status, 0); + ddev_control(flash_handle, CMD_FLASH_GET_PROTECT, (void *)&protect_type); + + if (FLASH_PROTECT_NONE != protect_type) { + param = FLASH_PROTECT_NONE; + ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)¶m); + } +#else + protect_type = bk_flash_get_protect_type(); + if (FLASH_PROTECT_NONE != protect_type) { + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + } +#endif + + /* Calculate the start address of the flash sector(4kbytes) */ + addr = addr & 0x00FFF000; + + do { +#if CONFIG_FLASH_ORIGIN_API + flash_ctrl(CMD_FLASH_ERASE_SECTOR, &addr); +#else + bk_flash_erase_sector(addr); +#endif + addr += 4096; + + if (_size < 4096) + _size = 0; + else + _size -= 4096; + + } while (_size); + + if (FLASH_PROTECT_NONE != protect_type) { +#if CONFIG_FLASH_ORIGIN_API + param = protect_type; + ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)¶m); +#else + bk_flash_set_protect_type(protect_type); +#endif + } + + return size; // return true erase size +} + +/** + * Erase data on flash. + * @note This operation is irreversible. + * @note This operation's units is different which on many chips. + * + * @param addr flash address + * @param size erase bytes size + * + * @return result + */ +EfErrCode ef_port_erase(uint32_t addr, size_t size) +{ + EfErrCode result = EF_NO_ERR; + + /* make sure the start address is a multiple of FLASH_ERASE_MIN_SIZE */ + EF_ASSERT(addr % EF_ERASE_MIN_SIZE == 0); + + bk_erase(addr, size); + + return result; +} + +/** + * Write data to flash. + * @note This operation's units is word. + * @note This operation must after erase. @see flash_erase. + * + * @param addr flash address + * @param buf the write data buffer + * @param size write bytes size + * + * @return result + */ +EfErrCode ef_port_write(uint32_t addr, const uint32_t *buf, size_t size) +{ +#if CONFIG_FLASH_ORIGIN_API + int param; + UINT32 status; + int protect_type; + DD_HANDLE flash_handle; +#else + flash_protect_type_t protect_type; +#endif + EfErrCode result = EF_NO_ERR; + + EF_ASSERT(size % 4 == 0); + +#if CONFIG_FLASH_ORIGIN_API + flash_handle = ddev_open(DD_DEV_TYPE_FLASH, &status, 0); + ddev_control(flash_handle, CMD_FLASH_GET_PROTECT, (void *)&protect_type); + + if (FLASH_PROTECT_NONE != protect_type) { + param = FLASH_PROTECT_NONE; + ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)¶m); + } + + flash_write((char *)buf, (unsigned long)size, addr); + if (FLASH_PROTECT_NONE != protect_type) { + param = protect_type; + ddev_control(flash_handle, CMD_FLASH_SET_PROTECT, (void *)¶m); + } +#else + protect_type = bk_flash_get_protect_type(); + if (FLASH_PROTECT_NONE != protect_type) { + bk_flash_set_protect_type(FLASH_PROTECT_NONE); + } + + bk_flash_write_bytes(addr, (const uint8_t *)buf, size); + bk_flash_set_protect_type(protect_type); +#endif + + return result; +} + +/** + * lock the ENV ram cache + */ +void ef_port_env_lock(void) +{ + rtos_get_semaphore(&env_cache_lock, BEKEN_WAIT_FOREVER); +} + +/** + * unlock the ENV ram cache + */ +void ef_port_env_unlock(void) +{ + rtos_set_semaphore(&env_cache_lock); +} + +/** + * This function is print flash debug info. + * + * @param file the file which has call this function + * @param line the line number which has call this function + * @param format output format + * @param ... args + * + */ +void ef_log_debug(const char *file, const long line, const char *format, ...) +{ +#ifdef PRINT_DEBUG + va_list args; + + /* args point to the first variable parameter */ + va_start(args, format); + ef_print("[Flash](%s:%ld) ", file, line); + /* must use vprintf to print */ + vsprintf(log_buf, format, args); + ef_print("%s", log_buf); + va_end(args); +#endif +} + +/** + * This function is print flash routine info. + * + * @param format output format + * @param ... args + */ +void ef_log_info(const char *format, ...) +{ +#ifdef PRINT_DEBUG + va_list args; + + /* args point to the first variable parameter */ + va_start(args, format); + ef_print("[Flash]"); + /* must use vprintf to print */ + vsprintf(log_buf, format, args); + ef_print("%s", log_buf); + va_end(args); +#endif +} +/** + * This function is print flash non-package info. + * + * @param format output format + * @param ... args + */ +void ef_print(const char *format, ...) +{ +#ifdef PRINT_DEBUG + va_list args; + + /* args point to the first variable parameter */ + va_start(args, format); + /* must use vprintf to print */ + vsprintf(log_buf, format, args); + os_printf("%s", log_buf); + va_end(args); +#endif +} +// eof + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/easyflash.c b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/easyflash.c new file mode 100755 index 0000000..1cabd63 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/easyflash.c @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2014-2016, Armink, + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Function: Initialize interface for this library. + * Created on: 2014-09-09 + */ + +/** + * + * This all Backup Area Flash storage index. All used flash area configure is under here. + * |----------------------------| Storage Size + * | Environment variables area | ENV area size @see ENV_AREA_SIZE + * | 1.system section | ENV system section size + * | 2:data section | ENV_AREA_SIZE - ENV system section size + * |----------------------------| + * | Saved log area | Log area size @see LOG_AREA_SIZE + * |----------------------------| + * |(IAP)Downloaded application | IAP already downloaded application, unfixed size + * |----------------------------| + * + * @note all area size must be aligned with EF_ERASE_MIN_SIZE + * @note EasyFlash will use ram to buffered the ENV. At some time flash's EF_ERASE_MIN_SIZE is so big, + * and you want use ENV size is less than it. So you must defined ENV_USER_SETTING_SIZE for ENV. + * @note ENV area size has some limitations in different modes. + * 1.Normal mode: no more limitations + * 2.Wear leveling mode: system section will used an flash section and the data section will used at least 2 flash sections + * 3.Power fail safeguard mode: ENV area will has an backup. It is twice as normal mode. + * 4.wear leveling and power fail safeguard mode: The required capacity will be 2 times the total capacity in wear leveling mode. + * For example: + * The EF_ERASE_MIN_SIZE is 128K and the ENV_USER_SETTING_SIZE: 2K. The ENV_AREA_SIZE in different mode you can define + * 1.Normal mode: 1*EF_ERASE_MIN_SIZE + * 2.Wear leveling mode: 3*EF_ERASE_MIN_SIZE (It has 2 data section to store ENV. So ENV can erase at least 200,000 times) + * 3.Power fail safeguard mode: 2*EF_ERASE_MIN_SIZE + * 4.Wear leveling and power fail safeguard mode: 6*EF_ERASE_MIN_SIZE + * @note the log area size must be more than twice of EF_ERASE_MIN_SIZE + */ +#include + +/** + * EasyFlash system initialize. + * + * @return result + */ +EfErrCode easyflash_init(void) +{ + extern EfErrCode ef_port_init(ef_env const **default_env, size_t *default_env_size); + extern EfErrCode ef_env_init(ef_env const * default_env, size_t default_env_size); + extern EfErrCode ef_iap_init(void); + extern EfErrCode ef_log_init(void); + + size_t default_env_set_size = 0; + const ef_env *default_env_set; + EfErrCode result = EF_NO_ERR; + + result = ef_port_init(&default_env_set, &default_env_set_size); + +#ifdef EF_USING_ENV + if (result == EF_NO_ERR) + result = ef_env_init(default_env_set, default_env_set_size); +#endif + +#ifdef EF_USING_IAP + if (result == EF_NO_ERR) + result = ef_iap_init(); +#endif + +#ifdef EF_USING_LOG + if (result == EF_NO_ERR) + result = ef_log_init(); +#endif + + if (result == EF_NO_ERR) + EF_INFO("EasyFlash V%s is initialize success.\n", EF_SW_VERSION); + else + EF_INFO("EasyFlash V%s is initialize fail.\n", EF_SW_VERSION); + EF_INFO("You can get the latest version on https://github.com/armink/EasyFlash .\n"); + + return result; +} +// eof + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_env.c b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_env.c new file mode 100755 index 0000000..b1fe1bc --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_env.c @@ -0,0 +1,812 @@ +/* + * Copyright (c) 2014-2018, Armink, + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Function: Environment variables operating interface. (normal mode) + * Created on: 2014-10-06 + */ + +#include +#include +#include + +#ifdef EF_USING_ENV + +#ifndef EF_ENV_USING_WL_MODE + +/** + * ENV area has 2 sections + * 1. System section + * It storage ENV parameters. (Units: Word) + * 2. Data section + * It storage all ENV. Storage format is key=value\0. + * All ENV must be 4 bytes alignment. The remaining part must fill '\0'. + * + * @note Word = 4 Bytes in this file + * @note It will has two ENV areas(Area0, Area1) when used power fail safeguard mode. + */ + +/* flash ENV parameters index and size in system section */ +enum { + /* data section ENV end address index in system section */ + ENV_PARAM_INDEX_END_ADDR = 0, + +#ifdef EF_ENV_USING_PFS_MODE + /* saved count for ENV area */ + ENV_PARAM_INDEX_SAVED_COUNT, +#endif + + /* data section CRC32 code index in system section */ + ENV_PARAM_INDEX_DATA_CRC, + /* flash ENV parameters word size */ + ENV_PARAM_WORD_SIZE, + /* flash ENV parameters byte size */ + ENV_PARAM_BYTE_SIZE = ENV_PARAM_WORD_SIZE * 4, +}; + +/* default ENV set, must be initialized by user */ +static ef_env const *default_env_set; +/* default ENV set size, must be initialized by user */ +static size_t default_env_set_size = 0; +/* ENV ram cache */ +static uint32_t env_cache[ENV_USER_SETTING_SIZE / 4] = { 0 }; +/* ENV start address in flash */ +static uint32_t env_start_addr = 0; +/* ENV ram cache has changed when ENV created, deleted and changed value. */ +static bool env_cache_changed = false; +/* initialize OK flag */ +static bool init_ok = false; + +#ifdef EF_ENV_USING_PFS_MODE +/* current load ENV area address */ +static uint32_t cur_load_area_addr = 0; +/* next save ENV area address */ +static uint32_t next_save_area_addr = 0; +#endif + +static uint32_t get_env_system_addr(void); +static uint32_t get_env_data_addr(void); +static uint32_t get_env_end_addr(void); +static void set_env_end_addr(uint32_t end_addr); +static EfErrCode write_env(const char *key, const char *value); +static char *find_env(const char *key); +static EfErrCode del_env(const char *key); +static size_t get_env_data_size(void); +static size_t get_env_user_used_size(void); +static EfErrCode create_env(const char *key, const char *value); +static uint32_t calc_env_crc(void); +static bool env_crc_is_ok(void); + +/** + * Flash ENV initialize. + * + * @param default_env default ENV set for user + * @param default_env_size default ENV set size + * + * @note user_size must equal with total_size in normal mode + * + * @return result + */ +EfErrCode ef_env_init(ef_env const *default_env, size_t default_env_size) +{ + EfErrCode result = EF_NO_ERR; + + EF_ASSERT(ENV_AREA_SIZE); + EF_ASSERT(ENV_USER_SETTING_SIZE); + EF_ASSERT(EF_ERASE_MIN_SIZE); + /* must be word alignment for ENV */ + EF_ASSERT(ENV_USER_SETTING_SIZE % 4 == 0); + EF_ASSERT(ENV_AREA_SIZE % 4 == 0); + EF_ASSERT(default_env); + EF_ASSERT(default_env_size < ENV_USER_SETTING_SIZE); + +#ifndef EF_ENV_USING_PFS_MODE + /* total_size must be aligned with erase_min_size */ + if (ENV_USER_SETTING_SIZE % EF_ERASE_MIN_SIZE == 0) + EF_ASSERT(ENV_USER_SETTING_SIZE == ENV_AREA_SIZE); + else + EF_ASSERT((ENV_USER_SETTING_SIZE / EF_ERASE_MIN_SIZE + 1)*EF_ERASE_MIN_SIZE == ENV_AREA_SIZE); +#else + /* total_size must be aligned with erase_min_size */ + if (ENV_USER_SETTING_SIZE % EF_ERASE_MIN_SIZE == 0) { + /* it has double area when used power fail safeguard mode */ + EF_ASSERT(2 * ENV_USER_SETTING_SIZE == ENV_AREA_SIZE); + } else { + /* it has double area when used power fail safeguard mode */ + EF_ASSERT(2 * (ENV_USER_SETTING_SIZE / EF_ERASE_MIN_SIZE + 1)*EF_ERASE_MIN_SIZE == ENV_AREA_SIZE); + } +#endif + + env_start_addr = EF_START_ADDR; + default_env_set = default_env; + default_env_set_size = default_env_size; + + EF_DEBUG("ENV start address is 0x%08X, size is %d bytes.\n", EF_START_ADDR, ENV_AREA_SIZE); + + result = ef_load_env(); + + if (result == EF_NO_ERR) + init_ok = true; + + return result; +} + +/** + * ENV set default. + * + * @return result + */ +EfErrCode ef_env_set_default(void) +{ + EfErrCode result = EF_NO_ERR; + size_t i; + + EF_ASSERT(default_env_set); + EF_ASSERT(default_env_set_size); + + /* lock the ENV cache */ + ef_port_env_lock(); + + /* set environment end address is at data section start address */ + set_env_end_addr(get_env_data_addr()); + +#ifdef EF_ENV_USING_PFS_MODE + /* set saved count to default 0 */ + env_cache[ENV_PARAM_INDEX_SAVED_COUNT] = 0; +#endif + + /* create default ENV */ + for (i = 0; i < default_env_set_size; i++) + create_env(default_env_set[i].key, default_env_set[i].value); + + /* unlock the ENV cache */ + ef_port_env_unlock(); + + result = ef_save_env(); + +#ifdef EF_ENV_USING_PFS_MODE + /* reset other PFS area's data */ + if (result == EF_NO_ERR) { + env_cache_changed = true; + result = ef_save_env(); + } +#endif + + + return result; +} + +/** + * Get ENV system section start address. + * + * @return system section start address + */ +static uint32_t get_env_system_addr(void) +{ +#ifndef EF_ENV_USING_PFS_MODE + return env_start_addr; +#else + return cur_load_area_addr; +#endif +} + +/** + * Get ENV data section start address. + * + * @return data section start address + */ +static uint32_t get_env_data_addr(void) +{ + return get_env_system_addr() + ENV_PARAM_BYTE_SIZE; +} + +/** + * Get ENV end address. + * It's the first word in ENV. + * + * @return ENV end address + */ +static uint32_t get_env_end_addr(void) +{ + /* it is the first word */ + return env_cache[ENV_PARAM_INDEX_END_ADDR]; +} + +/** + * Set ENV end address. + * It's the first word in ENV. + * + * @param end_addr ENV end address + */ +static void set_env_end_addr(uint32_t end_addr) +{ + env_cache[ENV_PARAM_INDEX_END_ADDR] = end_addr; +} + +/** + * Get current ENV data section size. + * + * @return size + */ +static size_t get_env_data_size(void) +{ + if (get_env_end_addr() > get_env_data_addr()) + return get_env_end_addr() - get_env_data_addr(); + else + return 0; +} + +/** + * Get current user used ENV size. + * + * @return bytes + */ +static size_t get_env_user_used_size(void) +{ + if (get_env_end_addr() > get_env_system_addr()) + return get_env_end_addr() - get_env_system_addr(); + else + return 0; +} + +/** + * Get current ENV already write bytes. + * + * @return write bytes + */ +size_t ef_get_env_write_bytes(void) +{ +#ifndef EF_ENV_USING_PFS_MODE + return get_env_user_used_size(); +#else + return get_env_user_used_size() * 2; +#endif +} + +/** + * Write an ENV at the end of cache. + * + * @param key ENV name + * @param value ENV value + * + * @return result + */ +static EfErrCode write_env(const char *key, const char *value) +{ + EfErrCode result = EF_NO_ERR; + size_t key_len = strlen(key), value_len = strlen(value), env_str_len; + char *env_cache_bak = (char *)env_cache; + + /* calculate ENV storage length, contain '=' and '\0'. */ + env_str_len = key_len + value_len + 2; + if (env_str_len % 4 != 0) + env_str_len = (env_str_len / 4 + 1) * 4; + /* check capacity of ENV */ + if (env_str_len + get_env_user_used_size() >= ENV_USER_SETTING_SIZE) + return EF_ENV_FULL; + + /* calculate current ENV ram cache end address */ + env_cache_bak += get_env_user_used_size(); + + /* copy key name */ + memmove(env_cache_bak, key, key_len); + env_cache_bak += key_len; + /* copy equal sign */ + *env_cache_bak = '='; + env_cache_bak++; + /* copy value */ + memmove(env_cache_bak, value, value_len); + env_cache_bak += value_len; + /* fill '\0' for string end sign */ + *env_cache_bak = '\0'; + env_cache_bak ++; + /* fill '\0' for word alignment */ + memset(env_cache_bak, 0, env_str_len - (key_len + value_len + 2)); + set_env_end_addr(get_env_end_addr() + env_str_len); + /* ENV ram cache has changed */ + env_cache_changed = true; + + return result; +} + +/** + * Find ENV. + * + * @param key ENV name + * + * @return found ENV in ram cache + */ +static char *find_env(const char *key) +{ + char *env_start, *env_end, *env, *found_env = NULL; + size_t key_len = strlen(key), env_len; + + if ((key == NULL) || (*key == 0)) { + EF_INFO("Flash ENV name must be not empty!\n"); + return NULL; + } + + /* from data section start to data section end */ + env_start = (char *)((char *) env_cache + ENV_PARAM_BYTE_SIZE); + env_end = (char *)((char *) env_cache + get_env_user_used_size()); + + /* ENV is null */ + if (env_start == env_end) + return NULL; + + env = env_start; + while (env < env_end) { + /* the key length must be equal */ + if (!strncmp(env, key, key_len) && (env[key_len] == '=')) { + found_env = env; + break; + } else { + /* calculate ENV length, contain '\0'. */ + env_len = strlen(env) + 1; + /* next ENV and word alignment */ + if (env_len % 4 == 0) + env += env_len; + else + env += (env_len / 4 + 1) * 4; + } + } + return found_env; +} + +/** + * If the ENV is not exist, create it. + * @see flash_write_env + * + * @param key ENV name + * @param value ENV value + * + * @return result + */ +static EfErrCode create_env(const char *key, const char *value) +{ + EfErrCode result = EF_NO_ERR; + + EF_ASSERT(key); + EF_ASSERT(value); + + if ((key == NULL) || (*key == 0)) { + EF_INFO("Flash ENV name must be not empty!\n"); + return EF_ENV_NAME_ERR; + } + + if (strchr(key, '=')) { + EF_INFO("Flash ENV name can't contain '='.\n"); + return EF_ENV_NAME_ERR; + } + + /* find ENV */ + if (find_env(key)) { + EF_INFO("The name of \"%s\" is already exist.\n", key); + return EF_ENV_NAME_EXIST; + } + /* write ENV at the end of cache */ + result = write_env(key, value); + + return result; +} + +/** + * Delete an ENV in cache. + * + * @param key ENV name + * + * @return result + */ +static EfErrCode del_env(const char *key) +{ + EfErrCode result = EF_NO_ERR; + char *del_env = NULL; + size_t del_env_length, remain_env_length; + + EF_ASSERT(key); + + if ((key == NULL) || (*key == 0)) { + EF_INFO("Flash ENV name must be not NULL!\n"); + return EF_ENV_NAME_ERR; + } + + if (strchr(key, '=')) { + EF_INFO("Flash ENV name or value can't contain '='.\n"); + return EF_ENV_NAME_ERR; + } + + /* find ENV */ + del_env = find_env(key); + + if (!del_env) { + EF_INFO("Not find \"%s\" in ENV.\n", key); + return EF_ENV_NAME_ERR; + } + del_env_length = strlen(del_env); + /* '\0' also must be as ENV length */ + del_env_length ++; + /* the address must multiple of 4 */ + if (del_env_length % 4 != 0) + del_env_length = (del_env_length / 4 + 1) * 4; + /* calculate remain ENV length */ + remain_env_length = get_env_data_size() + - (((uint32_t) del_env + del_env_length) - ((uint32_t) env_cache + ENV_PARAM_BYTE_SIZE)); + /* remain ENV move forward */ + memmove(del_env, del_env + del_env_length, remain_env_length); + /* reset ENV end address */ + set_env_end_addr(get_env_end_addr() - del_env_length); + /* ENV ram cache has changed */ + env_cache_changed = true; + + return result; +} + +/** + * Set an ENV. If it value is empty, delete it. + * If not find it in ENV table, then create it. + * + * @param key ENV name + * @param value ENV value + * + * @return result + */ +EfErrCode ef_set_env(const char *key, const char *value) +{ + EfErrCode result = EF_NO_ERR; + char *old_env, *old_value; + + if (!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return EF_ENV_INIT_FAILED; + } + + /* lock the ENV cache */ + ef_port_env_lock(); + + /* if ENV value is empty, delete it */ + if ((value == NULL) || (*value == 0)) + result = del_env(key); + else { + old_env = find_env(key); + /* If find this ENV, then compare the new value and old value. */ + if (old_env) { + /* find the old value address */ + old_env = strchr(old_env, '='); + old_value = old_env + 1; + /* If it is changed then delete it and recreate it */ + if (strcmp(old_value, value)) { + result = del_env(key); + if (result == EF_NO_ERR) + result = create_env(key, value); + } + } else + result = create_env(key, value); + } + /* unlock the ENV cache */ + ef_port_env_unlock(); + + return result; +} + +/** + * Get an ENV value by key name. + * + * @param key ENV name + * + * @return value + */ +char *ef_get_env(const char *key) +{ + char *env = NULL, *value = NULL; + + if (!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return NULL; + } + + /* find ENV */ + env = find_env(key); + + if (env == NULL) + return NULL; + /* get value address */ + value = strchr(env, '='); + if (value != NULL) { + /* the equal sign next character is value */ + value++; + } + return value; +} +/** + * Print ENV. + */ +void ef_print_env(void) +{ + uint32_t *env_cache_data_addr = env_cache + ENV_PARAM_WORD_SIZE, + *env_cache_end_addr = + (uint32_t *)(env_cache + ENV_PARAM_WORD_SIZE + get_env_data_size() / 4); + uint8_t j; + char c; + + if (!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return; + } + + for (; env_cache_data_addr < env_cache_end_addr; env_cache_data_addr += 1) { + for (j = 0; j < 4; j++) { + c = (*env_cache_data_addr) >> (8 * j); + ef_print("%c", c); + if (c == 0) { + ef_print("\n"); + break; + } + } + } + +#ifndef EF_ENV_USING_PFS_MODE + ef_print("\nENV size: %ld/%ld bytes.\n", get_env_user_used_size(), ENV_USER_SETTING_SIZE); +#else + ef_print("\nENV size: %ld/%ld bytes, write bytes %ld/%ld, saved count: %ld, mode: power fail safeguard.\n", + get_env_user_used_size(), ENV_USER_SETTING_SIZE, ef_get_env_write_bytes(), + ENV_AREA_SIZE, env_cache[ENV_PARAM_INDEX_SAVED_COUNT]); + +#endif +} + +/** + * Load flash ENV to ram. + * + * @return result + */ +#ifndef EF_ENV_USING_PFS_MODE +EfErrCode ef_load_env(void) +{ + EfErrCode result = EF_NO_ERR; + uint32_t *env_cache_bak, env_end_addr; + + /* read ENV end address from flash */ + ef_port_read(get_env_system_addr() + ENV_PARAM_INDEX_END_ADDR * 4, &env_end_addr, 4); + /* if ENV is not initialize or flash has dirty data, set default for it */ + if ((env_end_addr == 0xFFFFFFFF) || (env_end_addr < env_start_addr) + || (env_end_addr > env_start_addr + ENV_USER_SETTING_SIZE)) + result = ef_env_set_default(); + else { + /* set ENV end address */ + set_env_end_addr(env_end_addr); + + env_cache_bak = env_cache + ENV_PARAM_WORD_SIZE; + /* read all ENV from flash */ + ef_port_read(get_env_data_addr(), env_cache_bak, get_env_data_size()); + /* read ENV CRC code from flash */ + ef_port_read(get_env_system_addr() + ENV_PARAM_INDEX_DATA_CRC * 4, + &env_cache[ENV_PARAM_INDEX_DATA_CRC], 4); + /* if ENV CRC32 check is fault, set default for it */ + if (!env_crc_is_ok()) { + EF_INFO("Warning: ENV CRC check failed. Set it to default.\n"); + result = ef_env_set_default(); + } + } + return result; +} +#else +EfErrCode ef_load_env(void) +{ + EfErrCode result = EF_NO_ERR; + uint32_t area0_start_address = env_start_addr, area1_start_address = env_start_addr + + ENV_AREA_SIZE / 2; + uint32_t area0_end_addr, area1_end_addr, area0_crc, area1_crc, area0_saved_count, area1_saved_count; + bool area0_is_valid = true, area1_is_valid = true; + /* read ENV area end address from flash */ + ef_port_read(area0_start_address + ENV_PARAM_INDEX_END_ADDR * 4, &area0_end_addr, 4); + ef_port_read(area1_start_address + ENV_PARAM_INDEX_END_ADDR * 4, &area1_end_addr, 4); + if ((area0_end_addr == 0xFFFFFFFF) || (area0_end_addr < area0_start_address) + || (area0_end_addr > area0_start_address + ENV_USER_SETTING_SIZE)) + area0_is_valid = false; + if ((area1_end_addr == 0xFFFFFFFF) || (area1_end_addr < area1_start_address) + || (area1_end_addr > area1_start_address + ENV_USER_SETTING_SIZE)) + area1_is_valid = false; + /* check area0 CRC when it is valid */ + if (area0_is_valid) { + /* read ENV area0 crc32 code from flash */ + ef_port_read(area0_start_address + ENV_PARAM_INDEX_DATA_CRC * 4, &area0_crc, 4); + /* read ENV from ENV area0 */ + ef_port_read(area0_start_address, env_cache, area0_end_addr - area0_start_address); + /* current load ENV area address is area0 start address */ + cur_load_area_addr = area0_start_address; + if (!env_crc_is_ok()) + area0_is_valid = false; + } + /* check area1 CRC when it is valid */ + if (area1_is_valid) { + /* read ENV area1 crc32 code from flash */ + ef_port_read(area1_start_address + ENV_PARAM_INDEX_DATA_CRC * 4, &area1_crc, 4); + /* read ENV from ENV area1 */ + ef_port_read(area1_start_address, env_cache, area1_end_addr - area1_start_address); + /* current load ENV area address is area1 start address */ + cur_load_area_addr = area1_start_address; + if (!env_crc_is_ok()) + area1_is_valid = false; + } + /* all ENV area CRC is OK then compare saved count */ + if (area0_is_valid && area1_is_valid) { + /* read ENV area saved count from flash */ + ef_port_read(area0_start_address + ENV_PARAM_INDEX_SAVED_COUNT * 4, + &area0_saved_count, 4); + ef_port_read(area1_start_address + ENV_PARAM_INDEX_SAVED_COUNT * 4, + &area1_saved_count, 4); + /* the bigger saved count area is valid */ + if ((area0_saved_count > area1_saved_count) || ((area0_saved_count == 0) && (area1_saved_count == 0xFFFFFFFF))) + area1_is_valid = false; + else + area0_is_valid = false; + } + if (area0_is_valid) { + /* current load ENV area address is area0 start address */ + cur_load_area_addr = area0_start_address; + /* next save ENV area address is area1 start address */ + next_save_area_addr = area1_start_address; + /* read all ENV from area0 */ + ef_port_read(area0_start_address, env_cache, area0_end_addr - area0_start_address); + } else if (area1_is_valid) { + /* next save ENV area address is area0 start address */ + next_save_area_addr = area0_start_address; + } else { + /* current load ENV area address is area1 start address */ + cur_load_area_addr = area1_start_address; + /* next save ENV area address is area0 start address */ + next_save_area_addr = area0_start_address; + /* set the ENV to default */ + result = ef_env_set_default(); + } + return result; +} +#endif + +/** + * Save ENV to flash. + */ +EfErrCode ef_save_env(void) +{ + EfErrCode result = EF_NO_ERR; + uint32_t write_addr, write_size; + + /* ENV ram cache has not changed don't need to save */ + if (!env_cache_changed) + return result; + +#ifndef EF_ENV_USING_PFS_MODE + write_addr = get_env_system_addr(); + write_size = get_env_user_used_size(); + /* calculate and cache CRC32 code */ + env_cache[ENV_PARAM_INDEX_DATA_CRC] = calc_env_crc(); +#else + write_addr = next_save_area_addr; + write_size = get_env_user_used_size(); + /* replace next_save_area_addr with cur_load_area_addr */ + next_save_area_addr = cur_load_area_addr; + cur_load_area_addr = write_addr; + /* change the ENV end address to next save area address */ + set_env_end_addr(write_addr + write_size); + /* ENV area saved count +1 */ + env_cache[ENV_PARAM_INDEX_SAVED_COUNT]++; + /* calculate and cache CRC32 code */ + env_cache[ENV_PARAM_INDEX_DATA_CRC] = calc_env_crc(); +#endif + + /* erase ENV */ + result = ef_port_erase(write_addr, write_size); + switch (result) { + case EF_NO_ERR: { + EF_INFO("Erased ENV OK.\n"); + break; + } + case EF_ERASE_ERR: { + EF_INFO("Error: Erased ENV fault! Start address is 0x%08X, size is %ld.\n", write_addr, write_size); + /* will return when erase fault */ + return result; + } + default: + break; + } + + /* write ENV to flash */ + result = ef_port_write(write_addr, env_cache, write_size); + switch (result) { + case EF_NO_ERR: { + EF_INFO("Saved ENV OK.\n"); + break; + } + case EF_WRITE_ERR: { + EF_INFO("Error: Saved ENV fault! Start address is 0x%08X, size is %ld.\n", write_addr, write_size); + break; + } + default: + break; + } + + env_cache_changed = false; + + return result; +} + +/** + * Calculate the cached ENV CRC32 value. + * + * @return CRC32 value + */ +static uint32_t calc_env_crc(void) +{ + uint32_t crc32 = 0; + + /* Calculate the ENV end address CRC32. The 4 is ENV end address bytes size. */ + crc32 = ef_calc_crc32(crc32, &env_cache[ENV_PARAM_INDEX_END_ADDR], 4); + +#ifdef EF_ENV_USING_PFS_MODE + /* Calculate the ENV area saved count CRC32. */ + crc32 = ef_calc_crc32(crc32, &env_cache[ENV_PARAM_INDEX_SAVED_COUNT], 4); +#endif + + /* Calculate the all ENV data CRC32. */ + crc32 = ef_calc_crc32(crc32, &env_cache[ENV_PARAM_WORD_SIZE], get_env_data_size()); + + EF_DEBUG("Calculate ENV CRC32 number is 0x%08X.\n", crc32); + + return crc32; +} + +/** + * Check the ENV CRC32 + * + * @return true is ok + */ +static bool env_crc_is_ok(void) +{ + if (calc_env_crc() == env_cache[ENV_PARAM_INDEX_DATA_CRC]) { + EF_DEBUG("Verify ENV CRC32 result is OK.\n"); + return true; + } else + return false; +} + +/** + * Set and save an ENV. If set ENV is success then will save it. + * + * @param key ENV name + * @param value ENV value + * + * @return result + */ +EfErrCode ef_set_and_save_env(const char *key, const char *value) +{ + EfErrCode result = EF_NO_ERR; + + result = ef_set_env(key, value); + + if (result == EF_NO_ERR) + result = ef_save_env(); + + return result; +} + +#endif /* EF_ENV_USING_WL_MODE */ + +#endif /* EF_USING_ENV */ diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_env_wl.c b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_env_wl.c new file mode 100755 index 0000000..7294160 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_env_wl.c @@ -0,0 +1,971 @@ +/* + * Copyright (c) 2015-2018, Armink, + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Function: Environment variables operating interface. (wear leveling mode) + * Created on: 2015-02-11 + */ + +#include +#include +#include + +#ifdef EF_USING_ENV + +#ifdef EF_ENV_USING_WL_MODE + +/** + * ENV area has 2 sections + * 1. System section + * Storage ENV current using data section address. + * Units: Word. Total size: @see EF_ERASE_MIN_SIZE. + * 2. Data section + * The data section storage ENV's parameters and detail. + * When an exception has occurred on flash erase or write. The current using data section + * address will move to next available position. This position depends on EF_ERASE_MIN_SIZE. + * 2.1 ENV parameters part + * It storage ENV's parameters. + * 2.2 ENV detail part + * It storage all ENV. Storage format is key=value\0. + * All ENV must be 4 bytes alignment. The remaining part must fill '\0'. + * + * @note Word = 4 Bytes in this file + * @note It will has two ENV areas(Area0, Area1) in data section when used power fail safeguard mode. + */ + +/* flash ENV parameters part index and size */ +enum { + /* data section ENV detail part end address index */ + ENV_PARAM_PART_INDEX_END_ADDR = 0, + +#ifdef EF_ENV_USING_PFS_MODE + /* saved count for ENV area */ + ENV_PARAM_PART_INDEX_SAVED_COUNT, +#endif + + /* data section CRC32 code index */ + ENV_PARAM_PART_INDEX_DATA_CRC, + /* ENV parameters part word size */ + ENV_PARAM_PART_WORD_SIZE, + /* ENV parameters part byte size */ + ENV_PARAM_PART_BYTE_SIZE = ENV_PARAM_PART_WORD_SIZE * 4, +}; + +/* default ENV set, must be initialized by user */ +static ef_env const *default_env_set; +/* default ENV set size, must be initialized by user */ +static size_t default_env_set_size = 0; +/* flash ENV data section size */ +static size_t env_data_section_size = 0; +/* ENV ram cache */ +static uint32_t env_cache[ENV_USER_SETTING_SIZE / 4] = { 0 }; +/* ENV start address in flash */ +static uint32_t env_start_addr = 0; +/* current using data section address */ +static uint32_t cur_using_data_addr = 0; +/* ENV ram cache has changed when ENV created, deleted and changed value. */ +static bool env_cache_changed = false; +/* initialize OK flag */ +static bool init_ok = false; + +#ifdef EF_ENV_USING_PFS_MODE +/* next save ENV area address */ +static uint32_t next_save_area_addr = 0; +#endif + +static uint32_t get_env_start_addr(void); +static uint32_t get_cur_using_data_addr(void); +static uint32_t get_env_detail_addr(void); +static uint32_t get_env_detail_end_addr(void); +static void set_cur_using_data_addr(uint32_t using_data_addr); +static void set_env_detail_end_addr(uint32_t end_addr); +static EfErrCode write_env(const char *key, const char *value); +static char *find_env(const char *key); +static size_t get_env_detail_size(void); +static size_t get_env_user_used_size(void); +static EfErrCode create_env(const char *key, const char *value); +static EfErrCode del_env(const char *key); +static EfErrCode save_cur_using_data_addr(uint32_t cur_data_addr); +static uint32_t calc_env_crc(void); +static bool env_crc_is_ok(void); + +/** + * Flash ENV initialize. + * + * @param default_env default ENV set for user + * @param default_env_size default ENV set size + * + * @return result + */ +EfErrCode ef_env_init(ef_env const *default_env, size_t default_env_size) +{ + EfErrCode result = EF_NO_ERR; + + EF_ASSERT(ENV_AREA_SIZE); + EF_ASSERT(ENV_USER_SETTING_SIZE); + /* must be word alignment for ENV */ + EF_ASSERT(ENV_USER_SETTING_SIZE % 4 == 0); + EF_ASSERT(ENV_AREA_SIZE % 4 == 0); + EF_ASSERT(default_env); + EF_ASSERT(default_env_size < ENV_USER_SETTING_SIZE); + +#ifndef EF_ENV_USING_PFS_MODE + /* system section size is erase_min_size, so last part is data section */ + env_data_section_size = ENV_AREA_SIZE - EF_ERASE_MIN_SIZE; +#else + /* system section size is erase_min_size, so last part is data section */ + env_data_section_size = ENV_AREA_SIZE / 2 - EF_ERASE_MIN_SIZE; + EF_ASSERT((ENV_AREA_SIZE / EF_ERASE_MIN_SIZE) % 2 == 0); +#endif + EF_ASSERT(env_data_section_size >= ENV_USER_SETTING_SIZE); + /* the ENV data section size should be an integral multiple of erase minimum size. */ + EF_ASSERT(env_data_section_size % EF_ERASE_MIN_SIZE == 0); + + + env_start_addr = EF_START_ADDR; + default_env_set = default_env; + default_env_set_size = default_env_size; + + EF_DEBUG("ENV start address is 0x%08X, size is %d bytes.\n", EF_START_ADDR, ENV_AREA_SIZE); + + result = ef_load_env(); + + if (result == EF_NO_ERR) + init_ok = true; + + return result; +} + +/** + * ENV set default. + * + * @return result + */ +EfErrCode ef_env_set_default(void) +{ + EfErrCode result = EF_NO_ERR; + size_t i; + + EF_ASSERT(default_env_set); + EF_ASSERT(default_env_set_size); + + /* lock the ENV cache */ + ef_port_env_lock(); + + /* set ENV detail part end address is at ENV detail part start address */ + set_env_detail_end_addr(get_env_detail_addr()); + +#ifdef EF_ENV_USING_PFS_MODE + /* set saved count to default 0 */ + env_cache[ENV_PARAM_PART_INDEX_SAVED_COUNT] = 0; +#endif + + /* create default ENV */ + for (i = 0; i < default_env_set_size; i++) + create_env(default_env_set[i].key, default_env_set[i].value); + + /* unlock the ENV cache */ + ef_port_env_unlock(); + + result = ef_save_env(); + +#ifdef EF_ENV_USING_PFS_MODE + /* reset other PFS area's data */ + if (result == EF_NO_ERR) { + env_cache_changed = true; + result = ef_save_env(); + } +#endif + + return result; +} + +/** + * Get ENV start address in flash. + * + * @return ENV start address in flash + */ +static uint32_t get_env_start_addr(void) +{ + return env_start_addr; +} +/** + * Get current using data section address. + * + * @return current using data section address + */ +static uint32_t get_cur_using_data_addr(void) +{ + return cur_using_data_addr; +} + +/** + * Set current using data section address. + * + * @param using_data_addr current using data section address + */ +static void set_cur_using_data_addr(uint32_t using_data_addr) +{ + cur_using_data_addr = using_data_addr; +} + +/** + * Get ENV detail part start address. + * + * @return detail part start address + */ +static uint32_t get_env_detail_addr(void) +{ + return get_cur_using_data_addr() + ENV_PARAM_PART_BYTE_SIZE; +} + +/** + * Get ENV detail part end address. + * It's the first word in ENV. + * + * @return ENV end address + */ +static uint32_t get_env_detail_end_addr(void) +{ + /* it is the first word */ + return env_cache[ENV_PARAM_PART_INDEX_END_ADDR]; +} + +/** + * Set ENV detail part end address. + * It's the first word in ENV. + * + * @param end_addr ENV end address + */ +static void set_env_detail_end_addr(uint32_t end_addr) +{ + env_cache[ENV_PARAM_PART_INDEX_END_ADDR] = end_addr; +} + +/** + * Get current ENV detail part size. + * + * @return size + */ +static size_t get_env_detail_size(void) +{ + if (get_env_detail_end_addr() > get_env_detail_addr()) + return get_env_detail_end_addr() - get_env_detail_addr(); + else + return 0; +} + +/** + * Get current user used ENV size. + * + * @see ENV_USER_SETTING_SIZE + * + * @return size + */ +/* must be initialized */ +static size_t get_env_user_used_size(void) +{ + if (get_env_detail_end_addr() > get_cur_using_data_addr()) + return get_env_detail_end_addr() - get_cur_using_data_addr(); + else + return 0; +} + +/** + * Get current ENV already write bytes. + * + * @return write bytes + */ +size_t ef_get_env_write_bytes(void) +{ +#ifndef EF_ENV_USING_PFS_MODE + return get_env_detail_end_addr() - get_env_start_addr(); +#else + return EF_ERASE_MIN_SIZE + get_env_detail_end_addr() - get_cur_using_data_addr(); +#endif +} + +/** + * Write an ENV at the end of cache. + * + * @param key ENV name + * @param value ENV value + * + * @return result + */ +static EfErrCode write_env(const char *key, const char *value) +{ + EfErrCode result = EF_NO_ERR; + size_t ker_len = strlen(key), value_len = strlen(value), env_str_len; + char *env_cache_bak = (char *)env_cache; + + /* calculate ENV storage length, contain '=' and '\0'. */ + env_str_len = ker_len + value_len + 2; + if (env_str_len % 4 != 0) + env_str_len = (env_str_len / 4 + 1) * 4; + /* check capacity of ENV */ + if (env_str_len + get_env_user_used_size() >= ENV_USER_SETTING_SIZE) + return EF_ENV_FULL; + /* calculate current ENV ram cache end address */ + env_cache_bak += ENV_PARAM_PART_BYTE_SIZE + get_env_detail_size(); + /* copy key name */ + memcpy(env_cache_bak, key, ker_len); + env_cache_bak += ker_len; + /* copy equal sign */ + *env_cache_bak = '='; + env_cache_bak++; + /* copy value */ + memcpy(env_cache_bak, value, value_len); + env_cache_bak += value_len; + /* fill '\0' for string end sign */ + *env_cache_bak = '\0'; + env_cache_bak ++; + /* fill '\0' for word alignment */ + memset(env_cache_bak, 0, env_str_len - (ker_len + value_len + 2)); + set_env_detail_end_addr(get_env_detail_end_addr() + env_str_len); + /* ENV ram cache has changed */ + env_cache_changed = true; + + return result; +} + +/** + * Find ENV. + * + * @param key ENV name + * + * @return found ENV in ram cache + */ +static char *find_env(const char *key) +{ + char *env_start, *env_end, *env, *found_env = NULL; + size_t key_len = strlen(key), env_len; + + if (*key == NULL) { + EF_INFO("Flash ENV name must be not empty!\n"); + return NULL; + } + + /* from data section start to data section end */ + env_start = (char *)((char *) env_cache + ENV_PARAM_PART_BYTE_SIZE); + env_end = (char *)((char *) env_cache + ENV_PARAM_PART_BYTE_SIZE + get_env_detail_size()); + + /* ENV is null */ + if (env_start == env_end) + return NULL; + + env = env_start; + while (env < env_end) { + /* the key length must be equal */ + if (!strncmp(env, key, key_len) && (env[key_len] == '=')) { + found_env = env; + break; + } else { + /* calculate ENV length, contain '\0'. */ + env_len = strlen(env) + 1; + /* next ENV and word alignment */ + if (env_len % 4 == 0) + env += env_len; + else + env += (env_len / 4 + 1) * 4; + } + } + + return found_env; +} + +/** + * If the ENV is not exist, create it. + * @see flash_write_env + * + * @param key ENV name + * @param value ENV value + * + * @return result + */ +static EfErrCode create_env(const char *key, const char *value) +{ + EfErrCode result = EF_NO_ERR; + + EF_ASSERT(key); + EF_ASSERT(value); + + if (*key == NULL) { + EF_INFO("Flash ENV name must be not empty!\n"); + return EF_ENV_NAME_ERR; + } + + if (strchr(key, '=')) { + EF_INFO("Flash ENV name can't contain '='.\n"); + return EF_ENV_NAME_ERR; + } + + /* find ENV */ + if (find_env(key)) { + EF_INFO("The name of \"%s\" is already exist.\n", key); + return EF_ENV_NAME_EXIST; + } + /* write ENV at the end of cache */ + result = write_env(key, value); + + return result; +} + +/** + * Delete an ENV in cache. + * + * @param key ENV name + * + * @return result + */ +static EfErrCode del_env(const char *key) +{ + EfErrCode result = EF_NO_ERR; + char *del_env = NULL; + size_t del_env_length, remain_env_length; + + EF_ASSERT(key); + + if (*key == NULL) { + EF_INFO("Flash ENV name must be not NULL!\n"); + return EF_ENV_NAME_ERR; + } + + if (strchr(key, '=')) { + EF_INFO("Flash ENV name or value can't contain '='.\n"); + return EF_ENV_NAME_ERR; + } + + /* find ENV */ + del_env = find_env(key); + + if (!del_env) { + EF_INFO("Not find \"%s\" in ENV.\n", key); + return EF_ENV_NAME_ERR; + } + del_env_length = strlen(del_env); + /* '\0' also must be as ENV length */ + del_env_length ++; + /* the address must multiple of 4 */ + if (del_env_length % 4 != 0) + del_env_length = (del_env_length / 4 + 1) * 4; + /* calculate remain ENV length */ + remain_env_length = get_env_detail_size() + - (((uint32_t) del_env + del_env_length) - ((uint32_t) env_cache + ENV_PARAM_PART_BYTE_SIZE)); + /* remain ENV move forward */ + memcpy(del_env, del_env + del_env_length, remain_env_length); + /* reset ENV end address */ + set_env_detail_end_addr(get_env_detail_end_addr() - del_env_length); + /* ENV ram cache has changed */ + env_cache_changed = true; + + return result; +} + +/** + * Set an ENV. If it value is empty, delete it. + * If not find it in ENV table, then create it. + * + * @param key ENV name + * @param value ENV value + * + * @return result + */ +EfErrCode ef_set_env(const char *key, const char *value) +{ + EfErrCode result = EF_NO_ERR; + char *old_env, *old_value; + + if (!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return EF_ENV_INIT_FAILED; + } + + /* lock the ENV cache */ + ef_port_env_lock(); + + /* if ENV value is empty, delete it */ + if (*value == NULL) + result = del_env(key); + else { + old_env = find_env(key); + /* If find this ENV, then compare the new value and old value. */ + if (old_env) { + /* find the old value address */ + old_env = strchr(old_env, '='); + old_value = old_env + 1; + /* If it is changed then delete it and recreate it */ + if (strcmp(old_value, value)) { + result = del_env(key); + if (result == EF_NO_ERR) + result = create_env(key, value); + } + } else + result = create_env(key, value); + } + /* unlock the ENV cache */ + ef_port_env_unlock(); + + return result; +} + +/** + * Get an ENV value by key name. + * + * @param key ENV name + * + * @return value + */ +char *ef_get_env(const char *key) +{ + char *env = NULL, *value = NULL; + + if (!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return NULL; + } + + /* find ENV */ + env = find_env(key); + + if (env == NULL) + return NULL; + /* get value address */ + value = strchr(env, '='); + if (value != NULL) { + /* the equal sign next character is value */ + value++; + } + return value; +} +/** + * Print ENV. + */ +void ef_print_env(void) +{ + uint32_t *env_cache_detail_addr = env_cache + ENV_PARAM_PART_WORD_SIZE, *env_cache_end_addr = + (uint32_t *)(env_cache + ENV_PARAM_PART_WORD_SIZE + get_env_detail_size() / 4); + uint8_t j; + char c; + + if (!init_ok) { + EF_INFO("ENV isn't initialize OK.\n"); + return; + } + + for (; env_cache_detail_addr < env_cache_end_addr; env_cache_detail_addr += 1) { + for (j = 0; j < 4; j++) { + c = (*env_cache_detail_addr) >> (8 * j); + ef_print("%c", c); + if (c == NULL) { + ef_print("\n"); + break; + } + } + } + +#ifndef EF_ENV_USING_PFS_MODE + ef_print("\nENV size: %ld/%ld bytes, write bytes %ld/%ld, mode: wear leveling.\n", + get_env_user_used_size(), ENV_USER_SETTING_SIZE, ef_get_env_write_bytes(), + ENV_AREA_SIZE); +#else + ef_print("\nENV size: %ld/%ld bytes, write bytes %ld/%ld, saved count: %ld, mode: wear leveling and power fail safeguard.\n", + get_env_user_used_size(), ENV_USER_SETTING_SIZE, ef_get_env_write_bytes(), + ENV_AREA_SIZE / 2, env_cache[ENV_PARAM_PART_INDEX_SAVED_COUNT]); +#endif +} + +/** + * Load flash ENV to ram. + * + * @return result + */ +#ifndef EF_ENV_USING_PFS_MODE +EfErrCode ef_load_env(void) +{ + EfErrCode result = EF_NO_ERR; + uint32_t *env_cache_bak, env_end_addr, using_data_addr; + + /* read current using data section address */ + ef_port_read(get_env_start_addr(), &using_data_addr, 4); + /* if ENV is not initialize or flash has dirty data, set default for it */ + if ((using_data_addr == 0xFFFFFFFF) + || (using_data_addr > get_env_start_addr() + ENV_AREA_SIZE) + || (using_data_addr < get_env_start_addr() + EF_ERASE_MIN_SIZE)) { + /* initialize current using data section address */ + set_cur_using_data_addr(get_env_start_addr() + EF_ERASE_MIN_SIZE); + /* save current using data section address to flash*/ + if ((result = save_cur_using_data_addr(get_cur_using_data_addr())) == EF_NO_ERR) { + /* set default ENV */ + result = ef_env_set_default(); + } + } else { + /* set current using data section address */ + set_cur_using_data_addr(using_data_addr); + /* read ENV detail part end address from flash */ + ef_port_read(get_cur_using_data_addr() + ENV_PARAM_PART_INDEX_END_ADDR * 4, &env_end_addr, 4); + /* if ENV end address has error, set default for ENV */ + if (env_end_addr > get_env_start_addr() + ENV_AREA_SIZE) { + /* initialize current using data section address */ + set_cur_using_data_addr(get_env_start_addr() + EF_ERASE_MIN_SIZE); + /* save current using data section address to flash*/ + if ((result = save_cur_using_data_addr(get_cur_using_data_addr())) == EF_NO_ERR) { + EF_INFO("Warning: ENV end address has error. Set it to default.\n"); + result = ef_env_set_default(); + } + } else { + /* set ENV detail part end address */ + set_env_detail_end_addr(env_end_addr); + + env_cache_bak = env_cache + ENV_PARAM_PART_WORD_SIZE; + /* read all ENV from flash */ + ef_port_read(get_env_detail_addr(), env_cache_bak, get_env_detail_size()); + /* read ENV CRC code from flash */ + ef_port_read(get_cur_using_data_addr() + ENV_PARAM_PART_INDEX_DATA_CRC * 4, + &env_cache[ENV_PARAM_PART_INDEX_DATA_CRC], 4); + /* if ENV CRC32 check is fault, set default for it */ + if (!env_crc_is_ok()) { + EF_INFO("Warning: ENV CRC check failed. Set it to default.\n"); + result = ef_env_set_default(); + } + } + + } + return result; +} +#else +EfErrCode ef_load_env(void) +{ + EfErrCode result = EF_NO_ERR; + /* ENV area0 current using address default value */ + uint32_t area0_default_cur_using_addr = get_env_start_addr() + EF_ERASE_MIN_SIZE; + /* ENV area1 current using address default value */ + uint32_t area1_default_cur_using_addr = area0_default_cur_using_addr + ENV_AREA_SIZE / 2; + uint32_t area0_cur_using_addr, area1_cur_using_addr, area0_end_addr, area1_end_addr; + uint32_t area0_crc, area1_crc, area0_saved_count, area1_saved_count; + bool area0_is_valid = true, area1_is_valid = true; + + /* read ENV area0 and area1 current using data section address */ + ef_port_read(get_env_start_addr(), &area0_cur_using_addr, 4); + ef_port_read(get_env_start_addr() + ENV_AREA_SIZE / 2, &area1_cur_using_addr, 4); + /* if ENV is not initialize or flash has dirty data, set it isn't valid */ + if ((area0_cur_using_addr == 0xFFFFFFFF) + || (area0_cur_using_addr > get_env_start_addr() + ENV_AREA_SIZE / 2) + || (area0_cur_using_addr < get_env_start_addr() + EF_ERASE_MIN_SIZE)) + area0_is_valid = false; + if ((area1_cur_using_addr == 0xFFFFFFFF) + || (area1_cur_using_addr > get_env_start_addr() + ENV_AREA_SIZE) + || (area1_cur_using_addr < get_env_start_addr() + ENV_AREA_SIZE / 2 + EF_ERASE_MIN_SIZE)) + area1_is_valid = false; + /* check area0 end address when it is valid */ + if (area0_is_valid) { + /* read ENV area end address from flash */ + ef_port_read(area0_cur_using_addr + ENV_PARAM_PART_INDEX_END_ADDR * 4, &area0_end_addr, 4); + if ((area0_end_addr == 0xFFFFFFFF) || (area0_end_addr < area0_cur_using_addr) + || (area0_end_addr > area0_cur_using_addr + ENV_USER_SETTING_SIZE)) + area0_is_valid = false; + } + /* check area1 end address when it is valid */ + if (area1_is_valid) { + /* read ENV area end address from flash */ + ef_port_read(area1_cur_using_addr + ENV_PARAM_PART_INDEX_END_ADDR * 4, &area1_end_addr, 4); + if ((area1_end_addr == 0xFFFFFFFF) || (area1_end_addr < area1_cur_using_addr) + || (area1_end_addr > area1_cur_using_addr + ENV_USER_SETTING_SIZE)) + area1_is_valid = false; + } + /* check area0 CRC when it is valid */ + if (area0_is_valid) { + /* read ENV area0 crc32 code from flash */ + ef_port_read(area0_cur_using_addr + ENV_PARAM_PART_INDEX_DATA_CRC * 4, &area0_crc, 4); + /* read ENV from ENV area0 */ + ef_port_read(area0_cur_using_addr, env_cache, area0_end_addr - area0_cur_using_addr); + /* current using data section address is area0 current using data section address */ + set_cur_using_data_addr(area0_cur_using_addr); + if (!env_crc_is_ok()) + area0_is_valid = false; + } + /* check area1 CRC when it is valid */ + if (area1_is_valid) { + /* read ENV area1 crc32 code from flash */ + ef_port_read(area1_cur_using_addr + ENV_PARAM_PART_INDEX_DATA_CRC * 4, &area1_crc, 4); + /* read ENV from ENV area1 */ + ef_port_read(area1_cur_using_addr, env_cache, area1_end_addr - area1_cur_using_addr); + /* current using data section address is area1 current using data section address */ + set_cur_using_data_addr(area1_cur_using_addr); + if (!env_crc_is_ok()) + area1_is_valid = false; + } + /* all ENV area CRC is OK then compare saved count */ + if (area0_is_valid && area1_is_valid) { + /* read ENV area saved count from flash */ + ef_port_read(area0_cur_using_addr + ENV_PARAM_PART_INDEX_SAVED_COUNT * 4, + &area0_saved_count, 4); + ef_port_read(area1_cur_using_addr + ENV_PARAM_PART_INDEX_SAVED_COUNT * 4, + &area1_saved_count, 4); + /* the bigger saved count area is valid */ + if ((area0_saved_count > area1_saved_count) || ((area0_saved_count == 0) && (area1_saved_count == 0xFFFFFFFF))) + area1_is_valid = false; + else + area0_is_valid = false; + } + if (area0_is_valid) { + /* current using data section address is area0 current using data section address */ + set_cur_using_data_addr(area0_cur_using_addr); + /* next save ENV area address is area1 current using address value */ + next_save_area_addr = area1_cur_using_addr; + /* read all ENV from area0 */ + ef_port_read(area0_cur_using_addr, env_cache, area0_end_addr - area0_cur_using_addr); + } else if (area1_is_valid) { + /* already read data section and set_cur_using_data_addr above current code, + * so just set next save ENV area address is area0 current using address value */ + next_save_area_addr = area0_cur_using_addr; + } else { + /* current using data section address is area1 current using address default value */ + set_cur_using_data_addr(area1_default_cur_using_addr); + /* next save ENV area address default is area0 current using address default value */ + next_save_area_addr = area0_default_cur_using_addr; + /* save current using data section address to flash*/ + if (((result = save_cur_using_data_addr(area0_default_cur_using_addr)) == EF_NO_ERR) + && ((result = save_cur_using_data_addr(area1_default_cur_using_addr)) == EF_NO_ERR)) { + /* set the ENV to default */ + result = ef_env_set_default(); + } + } + return result; +} +#endif + +/** + * Save ENV to flash. + */ +EfErrCode ef_save_env(void) +{ + EfErrCode result = EF_NO_ERR; + uint32_t cur_using_addr_bak, move_offset_addr; + size_t env_used_size = get_env_user_used_size(); + uint32_t data_sec_end_addr; + + /* ENV ram cache has not changed don't need to save */ + if (!env_cache_changed) + return result; + +#ifndef EF_ENV_USING_PFS_MODE + data_sec_end_addr = get_env_start_addr() + ENV_AREA_SIZE - 4; + cur_using_addr_bak = get_cur_using_data_addr(); +#else + cur_using_addr_bak = next_save_area_addr; + /* replace next_save_area_addr with cur_using_data_addr */ + next_save_area_addr = get_cur_using_data_addr(); + set_cur_using_data_addr(cur_using_addr_bak); + /* change the ENV detail end address to next save area address */ + set_env_detail_end_addr(get_cur_using_data_addr() + env_used_size); + /* area0 or area1 */ + if (get_cur_using_data_addr() < get_env_start_addr() + ENV_AREA_SIZE / 2) + data_sec_end_addr = get_env_start_addr() + ENV_AREA_SIZE / 2 - 4; + else + data_sec_end_addr = get_env_start_addr() + ENV_AREA_SIZE - 4; + /* ENV area saved count +1 */ + env_cache[ENV_PARAM_PART_INDEX_SAVED_COUNT]++; +#endif + + /* wear leveling process, automatic move ENV to next available position */ + while (get_cur_using_data_addr() + env_used_size < data_sec_end_addr) { + /* calculate and cache CRC32 code */ + env_cache[ENV_PARAM_PART_INDEX_DATA_CRC] = calc_env_crc(); + /* erase ENV */ + result = ef_port_erase(get_cur_using_data_addr(), env_used_size); + switch (result) { + case EF_NO_ERR: { + EF_INFO("Erased ENV OK.\n"); + break; + } + case EF_ERASE_ERR: { + EF_INFO("Warning: Erased ENV fault! Start address is 0x%08X, size is %ld.\n", + get_cur_using_data_addr(), env_used_size); + EF_INFO("Moving ENV to next available position.\n"); + /* Calculate move offset address. + * Current strategy is optimistic. It will offset the flash erasure minimum size. + */ + move_offset_addr = EF_ERASE_MIN_SIZE; + /* calculate and set next available data section address */ + set_cur_using_data_addr(get_cur_using_data_addr() + move_offset_addr); + /* calculate and set next available ENV detail part end address */ + set_env_detail_end_addr(get_env_detail_end_addr() + move_offset_addr); + continue; + } + } + /* write ENV to flash */ + result = ef_port_write(get_cur_using_data_addr(), env_cache, env_used_size); + switch (result) { + case EF_NO_ERR: { + EF_INFO("Saved ENV OK.\n"); + break; + } + case EF_WRITE_ERR: { + EF_INFO("Warning: Saved ENV fault! Start address is 0x%08X, size is %ld.\n", + get_cur_using_data_addr(), env_used_size); + EF_INFO("Moving ENV to next available position.\n"); + /* Calculate move offset address. + * Current strategy is optimistic. It will offset the flash erasure minimum size. + */ + move_offset_addr = EF_ERASE_MIN_SIZE; + /* calculate and set next available data section address */ + set_cur_using_data_addr(get_cur_using_data_addr() + move_offset_addr); + /* calculate and set next available ENV detail part end address */ + set_env_detail_end_addr(get_env_detail_end_addr() + move_offset_addr); + continue; + } + } + /* save ENV success */ + if (result == EF_NO_ERR) + break; + } + + if (get_cur_using_data_addr() + env_used_size < data_sec_end_addr) { + /* current using data section address has changed, save it */ + if (get_cur_using_data_addr() != cur_using_addr_bak) + result = save_cur_using_data_addr(get_cur_using_data_addr()); + } else { + result = EF_ENV_FULL; + EF_INFO("Error: The flash has no available space to save ENV.\n"); + } + + env_cache_changed = false; + + return result; +} + +/** + * Calculate the cached ENV CRC32 value. + * + * @return CRC32 value + */ +static uint32_t calc_env_crc(void) +{ + uint32_t crc32 = 0; + + /* Calculate the ENV end address and all ENV data CRC32. + * The 4 is ENV end address bytes size. */ + crc32 = ef_calc_crc32(crc32, &env_cache[ENV_PARAM_PART_INDEX_END_ADDR], 4); + crc32 = ef_calc_crc32(crc32, &env_cache[ENV_PARAM_PART_WORD_SIZE], get_env_detail_size()); + EF_DEBUG("Calculate ENV CRC32 number is 0x%08X.\n", crc32); + + return crc32; +} + +/** + * Check the ENV CRC32 + * + * @return true is ok + */ +static bool env_crc_is_ok(void) +{ + if (calc_env_crc() == env_cache[ENV_PARAM_PART_INDEX_DATA_CRC]) { + EF_DEBUG("Verify ENV CRC32 result is OK.\n"); + return true; + } else + return false; +} + +/** + * Save current using data section address to flash. + * + * @param cur_data_addr current using data section address + * + * @return result + */ +#ifndef EF_ENV_USING_PFS_MODE +static EfErrCode save_cur_using_data_addr(uint32_t cur_data_addr) +{ + EfErrCode result = EF_NO_ERR; + + /* erase ENV system section */ + result = ef_port_erase(get_env_start_addr(), 4); + if (result == EF_NO_ERR) { + /* write current using data section address to flash */ + result = ef_port_write(get_env_start_addr(), &cur_data_addr, 4); + if (result == EF_WRITE_ERR) { + EF_INFO("Error: Write system section fault! Start address is 0x%08X, size is %ld.\n", + get_env_start_addr(), 4); + EF_INFO("Note: The ENV can not be used.\n"); + } + } else { + EF_INFO("Error: Erased system section fault! Start address is 0x%08X, size is %ld.\n", + get_env_start_addr(), 4); + EF_INFO("Note: The ENV can not be used\n"); + } + return result; +} +#else +static EfErrCode save_cur_using_data_addr(uint32_t cur_data_addr) +{ + EfErrCode result = EF_NO_ERR; + uint32_t cur_system_sec_addr; + + if (cur_data_addr < get_env_start_addr() + ENV_AREA_SIZE / 2) { + /* current using system section is in ENV area0 */ + cur_system_sec_addr = get_env_start_addr(); + } else { + /* current using system section is in ENV area1 */ + cur_system_sec_addr = get_env_start_addr() + ENV_AREA_SIZE / 2; + } + /* erase ENV system section */ + result = ef_port_erase(cur_system_sec_addr, 4); + if (result == EF_NO_ERR) { + /* write area0 and area1 current using data section address to flash */ + result = ef_port_write(cur_system_sec_addr, &cur_data_addr, 4); + if (result == EF_WRITE_ERR) { + EF_INFO("Error: Write system section fault! Start address is 0x%08X, size is %ld.\n", + cur_system_sec_addr, 4); + EF_INFO("Note: The ENV can not be used.\n"); + } + } else { + EF_INFO("Error: Erased system section fault! Start address is 0x%08X, size is %ld.\n", + cur_system_sec_addr, 4); + EF_INFO("Note: The ENV can not be used\n"); + } + return result; +} +#endif + +/** + * Set and save an ENV. If set ENV is success then will save it. + * + * @param key ENV name + * @param value ENV value + * + * @return result + */ +EfErrCode ef_set_and_save_env(const char *key, const char *value) +{ + EfErrCode result = EF_NO_ERR; + + result = ef_set_env(key, value); + + if (result == EF_NO_ERR) + result = ef_save_env(); + + return result; +} + +#endif /* EF_ENV_USING_WL_MODE */ + +#endif /* EF_USING_ENV */ diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_iap.c b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_iap.c new file mode 100755 index 0000000..5f5d0a7 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_iap.c @@ -0,0 +1,294 @@ +/* + * Copyright (c) 2015-2017, Armink, + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Function: IAP(In-Application Programming) operating interface. + * Created on: 2015-01-05 + */ + +#include + +#ifdef EF_USING_IAP + +/* IAP section backup application section start address in flash */ +static uint32_t bak_app_start_addr = 0; + +/** + * Flash IAP function initialize. + * + * @return result + */ +EfErrCode ef_iap_init(void) +{ + EfErrCode result = EF_NO_ERR; + + bak_app_start_addr = EF_START_ADDR ; + +#if defined(EF_USING_ENV) + bak_app_start_addr += ENV_AREA_SIZE; +#endif + +#if defined(EF_USING_LOG) + bak_app_start_addr += LOG_AREA_SIZE; +#endif + + return result; +} + +/** + * Erase backup area application data. + * + * @param app_size application size + * + * @return result + */ +EfErrCode ef_erase_bak_app(size_t app_size) +{ + EfErrCode result = EF_NO_ERR; + + result = ef_port_erase(ef_get_bak_app_start_addr(), app_size); + switch (result) { + case EF_NO_ERR: { + EF_INFO("Erased backup area application OK.\n"); + break; + } + case EF_ERASE_ERR: { + EF_INFO("Warning: Erase backup area application fault!\n"); + /* will return when erase fault */ + return result; + } + } + + return result; +} + +/** + * Erase user old application by using specified erase function. + * + * @param user_app_addr application entry address + * @param app_size application size + * @param app_erase user specified application erase function + * + * @return result + */ +EfErrCode ef_erase_spec_user_app(uint32_t user_app_addr, size_t app_size, + EfErrCode(*app_erase)(uint32_t addr, size_t size)) +{ + EfErrCode result = EF_NO_ERR; + + result = app_erase(user_app_addr, app_size); + switch (result) { + case EF_NO_ERR: { + EF_INFO("Erased user application OK.\n"); + break; + } + case EF_ERASE_ERR: { + EF_INFO("Warning: Erase user application fault!\n"); + /* will return when erase fault */ + return result; + } + } + + return result; +} + +/** + * Erase user old application by using default `ef_port_erase` function. + * + * @param user_app_addr application entry address + * @param app_size application size + * + * @return result + */ +EfErrCode ef_erase_user_app(uint32_t user_app_addr, size_t app_size) +{ + return ef_erase_spec_user_app(user_app_addr, app_size, ef_port_erase); +} + +/** + * Erase old bootloader + * + * @param bl_addr bootloader entry address + * @param bl_size bootloader size + * + * @return result + */ +EfErrCode ef_erase_bl(uint32_t bl_addr, size_t bl_size) +{ + EfErrCode result = EF_NO_ERR; + + result = ef_port_erase(bl_addr, bl_size); + switch (result) { + case EF_NO_ERR: { + EF_INFO("Erased bootloader OK.\n"); + break; + } + case EF_ERASE_ERR: { + EF_INFO("Warning: Erase bootloader fault!\n"); + /* will return when erase fault */ + return result; + } + } + + return result; +} + +/** + * Write data of application to backup area. + * + * @param data a part of application + * @param size data size + * @param cur_size current write application size + * @param total_size application total size + * + * @return result + */ +EfErrCode ef_write_data_to_bak(uint8_t *data, size_t size, size_t *cur_size, + size_t total_size) +{ + EfErrCode result = EF_NO_ERR; + + /* make sure don't write excess data */ + if (*cur_size + size > total_size) + size = total_size - *cur_size; + + result = ef_port_write(ef_get_bak_app_start_addr() + *cur_size, (uint32_t *) data, size); + switch (result) { + case EF_NO_ERR: { + *cur_size += size; + EF_DEBUG("Write data to backup area OK.\n"); + break; + } + case EF_WRITE_ERR: { + EF_INFO("Warning: Write data to backup area fault!\n"); + break; + } + } + + return result; +} + +/** + * Copy backup area application to application entry by using specified write function. + * + * @param user_app_addr application entry address + * @param app_size application size + * @param app_write user specified application write function + * + * @return result + */ +EfErrCode ef_copy_spec_app_from_bak(uint32_t user_app_addr, size_t app_size, + EfErrCode(*app_write)(uint32_t addr, const uint32_t *buf, size_t size)) +{ + size_t cur_size; + uint32_t app_cur_addr, bak_cur_addr; + EfErrCode result = EF_NO_ERR; + /* 32 words size buffer */ + uint32_t buff[32]; + + /* cycle copy data */ + for (cur_size = 0; cur_size < app_size; cur_size += sizeof(buff)) { + app_cur_addr = user_app_addr + cur_size; + bak_cur_addr = ef_get_bak_app_start_addr() + cur_size; + ef_port_read(bak_cur_addr, buff, sizeof(buff)); + result = app_write(app_cur_addr, buff, sizeof(buff)); + if (result != EF_NO_ERR) + break; + } + + switch (result) { + case EF_NO_ERR: { + EF_INFO("Write data to application entry OK.\n"); + break; + } + case EF_WRITE_ERR: { + EF_INFO("Warning: Write data to application entry fault!\n"); + break; + } + } + + return result; +} + +/** + * Copy backup area application to application entry by using default `ef_port_write` function. + * + * @param user_app_addr application entry address + * @param app_size application size + * + * @return result + */ +EfErrCode ef_copy_app_from_bak(uint32_t user_app_addr, size_t app_size) +{ + return ef_copy_spec_app_from_bak(user_app_addr, app_size, ef_port_write); +} + +/** + * Copy backup area bootloader to bootloader entry. + * + * @param bl_addr bootloader entry address + * @param bl_size bootloader size + * + * @return result + */ +EfErrCode ef_copy_bl_from_bak(uint32_t bl_addr, size_t bl_size) +{ + size_t cur_size; + uint32_t bl_cur_addr, bak_cur_addr; + EfErrCode result = EF_NO_ERR; + /* 32 words buffer */ + uint32_t buff[32]; + + /* cycle copy data by 32bytes buffer */ + for (cur_size = 0; cur_size < bl_size; cur_size += sizeof(buff)) { + bl_cur_addr = bl_addr + cur_size; + bak_cur_addr = ef_get_bak_app_start_addr() + cur_size; + ef_port_read(bak_cur_addr, buff, sizeof(buff)); + result = ef_port_write(bl_cur_addr, buff, sizeof(buff)); + if (result != EF_NO_ERR) + break; + } + + switch (result) { + case EF_NO_ERR: { + EF_INFO("Write data to bootloader entry OK.\n"); + break; + } + case EF_WRITE_ERR: { + EF_INFO("Warning: Write data to bootloader entry fault!\n"); + break; + } + } + + return result; +} + +/** + * Get IAP section start address in flash. + * + * @return size + */ +uint32_t ef_get_bak_app_start_addr(void) +{ + return bak_app_start_addr; +} + +#endif /* EF_USING_IAP */ diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_log.c b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_log.c new file mode 100755 index 0000000..925f48e --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_log.c @@ -0,0 +1,698 @@ +/* + * Copyright (c) 2015-2017, Armink, + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Function: Save logs to flash. + * Created on: 2015-06-04 + */ + +#include + +#ifdef EF_USING_LOG + +/* magic code on every sector header. 'EF' is 0x4546 */ +#define LOG_SECTOR_MAGIC 0x4546 +/* sector header size, include the sector magic code and status magic code */ +#define LOG_SECTOR_HEADER_SIZE 4 + +/** + * Sector status magic code + * The sector status is 16-Bits after LOG_SECTOR_MAGIC at every sector header. + * ======================= + * | header(4B) | status | + * ----------------------- + * | 0x4546FFFF | empty | + * | 0x4546FFFE | using | + * | 0x4546FFFC | full | + * ======================= + * + * State transition relationship: empty->using->full + * The FULL status will change to EMPTY after sector clean. + */ +enum { + SECTOR_STATUS_MAGIC_EMPUT = 0xFFFF, + SECTOR_STATUS_MAGIC_USING = 0xFFFE, + SECTOR_STATUS_MAGIC_FULL = 0xFFFC, +}; + +typedef enum { + SECTOR_STATUS_EMPUT, + SECTOR_STATUS_USING, + SECTOR_STATUS_FULL, + SECTOR_STATUS_HEADER_ERROR, +} SectorStatus; + +/* the stored logs start address and end address. It's like a ring buffer which implement by flash. */ +static uint32_t log_start_addr = 0, log_end_addr = 0; +/* saved log area address for flash */ +static uint32_t log_area_start_addr = 0; +/* initialize OK flag */ +static bool init_ok = false; + +static void find_start_and_end_addr(void); +static uint32_t get_next_flash_sec_addr(uint32_t cur_addr); + +/** + * The flash save log function initialize. + * + * @return result + */ +EfErrCode ef_log_init(void) +{ + EfErrCode result = EF_NO_ERR; + + EF_ASSERT(LOG_AREA_SIZE); + EF_ASSERT(EF_ERASE_MIN_SIZE); + /* the log area size must be an integral multiple of erase minimum size. */ + EF_ASSERT(LOG_AREA_SIZE % EF_ERASE_MIN_SIZE == 0); + /* the log area size must be more than twice of EF_ERASE_MIN_SIZE */ + EF_ASSERT(LOG_AREA_SIZE / EF_ERASE_MIN_SIZE >= 2); + +#ifdef EF_USING_ENV + log_area_start_addr = EF_START_ADDR + ENV_AREA_SIZE; +#else + log_area_start_addr = EF_START_ADDR; +#endif + + /* find the log store start address and end address */ + find_start_and_end_addr(); + /* initialize OK */ + init_ok = true; + + return result; +} + +/** + * Get flash sector current status. + * + * @param addr sector address, this function will auto calculate the sector header address by this address. + * + * @return the flash sector current status + */ +static SectorStatus get_sector_status(uint32_t addr) +{ + uint32_t header = 0, header_addr = 0; + uint16_t sector_magic = 0, status_magic = 0; + + /* calculate the sector header address */ + header_addr = addr / EF_ERASE_MIN_SIZE * EF_ERASE_MIN_SIZE; + + if (ef_port_read(header_addr, &header, sizeof(header)) == EF_NO_ERR) { + sector_magic = header >> 16; + status_magic = header; + } else { + EF_DEBUG("Error: Read sector header data error.\n"); + return SECTOR_STATUS_HEADER_ERROR; + } + /* compare header magic code */ + if (sector_magic == LOG_SECTOR_MAGIC) { + switch (status_magic) { + case SECTOR_STATUS_MAGIC_EMPUT: + return SECTOR_STATUS_EMPUT; + case SECTOR_STATUS_MAGIC_USING: + return SECTOR_STATUS_USING; + case SECTOR_STATUS_MAGIC_FULL: + return SECTOR_STATUS_FULL; + default: + return SECTOR_STATUS_HEADER_ERROR; + } + } else + return SECTOR_STATUS_HEADER_ERROR; +} + +/** + * Write flash sector current status. + * + * @param addr sector address, this function will auto calculate the sector header address by this address. + * @param status sector cur status + * + * @return result + */ +static EfErrCode write_sector_status(uint32_t addr, SectorStatus status) +{ + uint32_t header = 0, header_addr = 0; + uint16_t status_magic; + + /* calculate the sector header address */ + header_addr = addr / EF_ERASE_MIN_SIZE * EF_ERASE_MIN_SIZE; + + switch (status) { + case SECTOR_STATUS_EMPUT: { + status_magic = SECTOR_STATUS_MAGIC_EMPUT; + break; + } + case SECTOR_STATUS_USING: { + status_magic = SECTOR_STATUS_MAGIC_USING; + break; + } + case SECTOR_STATUS_FULL: { + status_magic = SECTOR_STATUS_MAGIC_FULL; + break; + } + } + header = (LOG_SECTOR_MAGIC << 16) | status_magic; + + return ef_port_write(header_addr, &header, sizeof(header)); +} + +/** + * Find the current flash sector using end address by continuous 0xFF. + * + * @param addr sector address + * + * @return current flash sector using end address + */ +static uint32_t find_sec_using_end_addr(uint32_t addr) +{ + /* read section data buffer size */ +#define READ_BUF_SIZE 32 + + uint32_t sector_start = addr, data_start = addr, continue_ff = 0, read_buf_size = 0, i; + uint8_t buf[READ_BUF_SIZE]; + + EF_ASSERT(READ_BUF_SIZE % 4 == 0); + /* calculate the sector start and data start address */ + sector_start = addr / EF_ERASE_MIN_SIZE * EF_ERASE_MIN_SIZE; + data_start = sector_start + LOG_SECTOR_HEADER_SIZE; + + /* counts continuous 0xFF which is end of sector */ + while (data_start < sector_start + EF_ERASE_MIN_SIZE) { + if (data_start + READ_BUF_SIZE < sector_start + EF_ERASE_MIN_SIZE) + read_buf_size = READ_BUF_SIZE; + else + read_buf_size = sector_start + EF_ERASE_MIN_SIZE - data_start; + ef_port_read(data_start, (uint32_t *)buf, read_buf_size); + for (i = 0; i < read_buf_size; i++) { + if (buf[i] == 0xFF) + continue_ff++; + else + continue_ff = 0; + } + data_start += read_buf_size; + } + /* calculate current flash sector using end address */ + if (continue_ff >= EF_ERASE_MIN_SIZE - LOG_SECTOR_HEADER_SIZE) { + /* from 0 to sec_size all sector is 0xFF, so the sector is empty */ + return sector_start + LOG_SECTOR_HEADER_SIZE; + } else if (continue_ff >= 4) { + /* form end_addr - 4 to sec_size length all area is 0xFF, so it's used part of the sector. + * the address must be word alignment. */ + if (continue_ff % 4 != 0) + continue_ff = (continue_ff / 4 + 1) * 4; + return sector_start + EF_ERASE_MIN_SIZE - continue_ff; + } else { + /* all sector not has continuous 0xFF, so the sector is full */ + return sector_start + EF_ERASE_MIN_SIZE; + } +} + +/** + * Find the log store start address and end address. + * It's like a ring buffer which implement by flash. + * The flash log area has two state when find start address and end address. + * state 1 state 2 + * |============| |============| + * log area start--> |############| <-- start address |############| <-- end address + * |############| | empty | + * |------------| |------------| + * |############| |############| <-- start address + * |############| |############| + * |------------| |------------| + * | . | | . | + * | . | | . | + * | . | | . | + * |------------| |------------| + * |############| <-- end address |############| + * | empty | |############| + * log area end --> |============| |============| + * + * LOG_AREA_SIZE = log area end - log area star + * + */ +static void find_start_and_end_addr(void) +{ + size_t cur_size = 0; + SectorStatus cur_sec_status, last_sec_status; + uint32_t cur_using_sec_addr = 0; + /* all status sector counts */ + size_t empty_sec_counts = 0, using_sec_counts = 0, full_sector_counts = 0; + /* total sector number */ + size_t total_sec_num = LOG_AREA_SIZE / EF_ERASE_MIN_SIZE; + /* see comment of find_start_and_end_addr function */ + uint8_t cur_log_sec_state = 0; + + /* get the first sector status */ + cur_sec_status = get_sector_status(log_area_start_addr); + last_sec_status = cur_sec_status; + + for (cur_size = EF_ERASE_MIN_SIZE; cur_size < LOG_AREA_SIZE; cur_size += EF_ERASE_MIN_SIZE) { + /* get current sector status */ + cur_sec_status = get_sector_status(log_area_start_addr + cur_size); + /* compare last and current status */ + switch (last_sec_status) { + case SECTOR_STATUS_EMPUT: { + switch (cur_sec_status) { + case SECTOR_STATUS_EMPUT: + break; + case SECTOR_STATUS_USING: + EF_DEBUG("Error: Log area error! Now will clean all log area.\n"); + ef_log_clean(); + return; + case SECTOR_STATUS_FULL: + EF_DEBUG("Error: Log area error! Now will clean all log area.\n"); + ef_log_clean(); + return; + } + empty_sec_counts++; + break; + } + case SECTOR_STATUS_USING: { + switch (cur_sec_status) { + case SECTOR_STATUS_EMPUT: + /* like state 1 */ + cur_log_sec_state = 1; + log_start_addr = log_area_start_addr; + cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE; + break; + case SECTOR_STATUS_USING: + EF_DEBUG("Error: Log area error! Now will clean all log area.\n"); + ef_log_clean(); + return; + case SECTOR_STATUS_FULL: + /* like state 2 */ + cur_log_sec_state = 2; + log_start_addr = log_area_start_addr + cur_size; + cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE; + break; + } + using_sec_counts++; + break; + } + case SECTOR_STATUS_FULL: { + switch (cur_sec_status) { + case SECTOR_STATUS_EMPUT: + /* like state 1 */ + if (cur_log_sec_state == 2) { + EF_DEBUG("Error: Log area error! Now will clean all log area.\n"); + ef_log_clean(); + return; + } else { + cur_log_sec_state = 1; + log_start_addr = log_area_start_addr; + log_end_addr = log_area_start_addr + cur_size; + cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE; + } + break; + case SECTOR_STATUS_USING: + if (total_sec_num <= 2) { + /* like state 1 */ + cur_log_sec_state = 1; + log_start_addr = log_area_start_addr; + cur_using_sec_addr = log_area_start_addr + cur_size; + } else { + /* like state 2 when the sector is the last one */ + if (cur_size + EF_ERASE_MIN_SIZE >= LOG_AREA_SIZE) { + cur_log_sec_state = 2; + log_start_addr = log_area_start_addr + cur_size; + cur_using_sec_addr = log_area_start_addr + cur_size - EF_ERASE_MIN_SIZE; + } + } + break; + case SECTOR_STATUS_FULL: + break; + } + full_sector_counts++; + break; + } + case SECTOR_STATUS_HEADER_ERROR: + EF_DEBUG("Error: Log sector header error! Now will clean all log area.\n"); + ef_log_clean(); + return; + } + last_sec_status = cur_sec_status; + } + + /* the last sector status counts */ + if (cur_sec_status == SECTOR_STATUS_EMPUT) + empty_sec_counts++; + else if (cur_sec_status == SECTOR_STATUS_USING) + using_sec_counts++; + else if (cur_sec_status == SECTOR_STATUS_FULL) + full_sector_counts++; + else if (cur_sec_status == SECTOR_STATUS_HEADER_ERROR) { + EF_DEBUG("Error: Log sector header error! Now will clean all log area.\n"); + ef_log_clean(); + return; + } + + if (using_sec_counts != 1) { + /* this state is almost impossible */ + EF_DEBUG("Error: There must be only one sector status is USING! Now will clean all log area.\n"); + ef_log_clean(); + } else { + /* find the end address */ + log_end_addr = find_sec_using_end_addr(cur_using_sec_addr); + } +} + +/** + * Get log used flash total size. + * + * @return log used flash total size. @note NOT contain sector headers + */ +size_t ef_log_get_used_size(void) +{ + size_t header_total_num = 0, physical_size = 0; + /* must be call this function after initialize OK */ + if (!init_ok) + return 0; + + if (log_start_addr < log_end_addr) + physical_size = log_end_addr - log_start_addr; + else + physical_size = LOG_AREA_SIZE - (log_start_addr - log_end_addr); + + header_total_num = physical_size / EF_ERASE_MIN_SIZE + 1; + + return physical_size - header_total_num * LOG_SECTOR_HEADER_SIZE; +} + +/** + * Sequential reading log data. It will ignore sector headers. + * + * @param addr address + * @param log log buffer + * @param size log size, not contain sector headers. + * + * @return result + */ +static EfErrCode log_seq_read(uint32_t addr, uint32_t *log, size_t size) +{ + EfErrCode result = EF_NO_ERR; + size_t read_size = 0, read_size_temp = 0; + + while (size) { + /* move to sector data address */ + if ((addr + read_size) % EF_ERASE_MIN_SIZE == 0) + addr += LOG_SECTOR_HEADER_SIZE; + /* calculate current sector last data size */ + read_size_temp = EF_ERASE_MIN_SIZE - (addr % EF_ERASE_MIN_SIZE); + if (size < read_size_temp) + read_size_temp = size; + result = ef_port_read(addr + read_size, log + read_size / 4, read_size_temp); + if (result != EF_NO_ERR) + return result; + read_size += read_size_temp; + size -= read_size_temp; + } + + return result; +} + +/** + * Calculate flash physical address by log index. + * + * @param index log index + * + * @return flash physical address + */ +static uint32_t log_index2addr(size_t index) +{ + size_t header_total_offset = 0; + /* total include sector number */ + size_t sector_num = index / (EF_ERASE_MIN_SIZE - LOG_SECTOR_HEADER_SIZE) + 1; + + header_total_offset = sector_num * LOG_SECTOR_HEADER_SIZE; + if (log_start_addr < log_end_addr) + return log_start_addr + index + header_total_offset; + else { + if (log_start_addr + index + header_total_offset < log_area_start_addr + LOG_AREA_SIZE) + return log_start_addr + index + header_total_offset; + else + return log_start_addr + index + header_total_offset - LOG_AREA_SIZE; + + } +} + +/** + * Read log from flash. + * + * @param index index for saved log. + * Minimum index is 0. + * Maximum index is ef_log_get_used_size() - 1. + * @param log the log which will read from flash + * @param size read bytes size + * + * @return result + */ +EfErrCode ef_log_read(size_t index, uint32_t *log, size_t size) +{ + EfErrCode result = EF_NO_ERR; + size_t cur_using_size = ef_log_get_used_size(); + size_t read_size_temp = 0; + size_t header_total_num = 0; + + if (!size) + return result; + + EF_ASSERT(size % 4 == 0); + EF_ASSERT(index < cur_using_size); + + if (index + size > cur_using_size) { + EF_DEBUG("Warning: Log read size out of bound. Cut read size.\n"); + size = cur_using_size - index; + } + /* must be call this function after initialize OK */ + if (!init_ok) + return EF_ENV_INIT_FAILED; + + if (log_start_addr < log_end_addr) + log_seq_read(log_index2addr(index), log, size); + else { + if (log_index2addr(index) + size <= log_area_start_addr + LOG_AREA_SIZE) { + /* Flash log area + * |--------------| + * log_area_start_addr --> |##############| + * |##############| + * |##############| + * |--------------| + * |##############| + * |##############| + * |##############| <-- log_end_addr + * |--------------| + * log_start_addr --> |##############| + * read start --> |**************| <-- read end + * |##############| + * |--------------| + * + * read from (log_start_addr + log_index2addr(index)) to (log_start_addr + index + log_index2addr(index)) + */ + result = log_seq_read(log_index2addr(index), log, size); + } else if (log_index2addr(index) < log_area_start_addr + LOG_AREA_SIZE) { + /* Flash log area + * |--------------| + * log_area_start_addr --> |**************| <-- read end + * |##############| + * |##############| + * |--------------| + * |##############| + * |##############| + * |##############| <-- log_end_addr + * |--------------| + * log_start_addr --> |##############| + * read start --> |**************| + * |**************| + * |--------------| + * read will by 2 steps + * step1: read from (log_start_addr + log_index2addr(index)) to flash log area end address + * step2: read from flash log area start address to read size's end address + */ + read_size_temp = (log_area_start_addr + LOG_AREA_SIZE) - log_index2addr(index); + header_total_num = read_size_temp / EF_ERASE_MIN_SIZE; + /* Minus some ignored bytes */ + read_size_temp -= header_total_num * LOG_SECTOR_HEADER_SIZE; + result = log_seq_read(log_index2addr(index), log, read_size_temp); + if (result == EF_NO_ERR) + result = log_seq_read(log_area_start_addr, log + read_size_temp / 4, size - read_size_temp); + } else { + /* Flash log area + * |--------------| + * log_area_start_addr --> |##############| + * read start --> |**************| + * |**************| <-- read end + * |--------------| + * |##############| + * |##############| + * |##############| <-- log_end_addr + * |--------------| + * log_start_addr --> |##############| + * |##############| + * |##############| + * |--------------| + * read from (log_start_addr + log_index2addr(index) - LOG_AREA_SIZE) to read size's end address + */ + result = log_seq_read(log_index2addr(index) - LOG_AREA_SIZE, log, size); + } + } + + return result; +} + +/** + * Write log to flash. + * + * @param log the log which will be write to flash + * @param size write bytes size + * + * @return result + */ +EfErrCode ef_log_write(const uint32_t *log, size_t size) +{ + EfErrCode result = EF_NO_ERR; + size_t write_size = 0, writable_size = 0; + uint32_t write_addr = log_end_addr, erase_addr; + SectorStatus sector_status; + + EF_ASSERT(size % 4 == 0); + /* must be call this function after initialize OK */ + if (!init_ok) + return EF_ENV_INIT_FAILED; + + if ((sector_status = get_sector_status(write_addr)) == SECTOR_STATUS_HEADER_ERROR) + return EF_WRITE_ERR; + /* write some log when current sector status is USING and EMPTY */ + if ((sector_status == SECTOR_STATUS_USING) || (sector_status == SECTOR_STATUS_EMPUT)) { + /* write the already erased but not used area */ + writable_size = EF_ERASE_MIN_SIZE - ((write_addr - log_area_start_addr) % EF_ERASE_MIN_SIZE); + if (size >= writable_size) { + result = ef_port_write(write_addr, log, writable_size); + if (result != EF_NO_ERR) + goto exit; + /* change the current sector status to FULL */ + result = write_sector_status(write_addr, SECTOR_STATUS_FULL); + if (result != EF_NO_ERR) + goto exit; + write_size += writable_size; + } else { + result = ef_port_write(write_addr, log, size); + log_end_addr = write_addr + size; + goto exit; + } + } + /* erase and write remain log */ + while (true) { + /* calculate next available sector address */ + erase_addr = write_addr = get_next_flash_sec_addr(write_addr - 4); + /* move the flash log start address to next available sector address */ + if (log_start_addr == erase_addr) + log_start_addr = get_next_flash_sec_addr(log_start_addr); + /* erase sector */ + result = ef_port_erase(erase_addr, EF_ERASE_MIN_SIZE); + if (result != EF_NO_ERR) + goto exit; + /* change the sector status to USING when write begin sector start address */ + result = write_sector_status(write_addr, SECTOR_STATUS_USING); + if (result == EF_NO_ERR) + write_addr += LOG_SECTOR_HEADER_SIZE; + else + goto exit; + /* calculate current sector writable data size */ + writable_size = EF_ERASE_MIN_SIZE - LOG_SECTOR_HEADER_SIZE; + if (size - write_size >= writable_size) { + result = ef_port_write(write_addr, log + write_size / 4, writable_size); + if (result != EF_NO_ERR) + goto exit; + /* change the current sector status to FULL */ + result = write_sector_status(write_addr, SECTOR_STATUS_FULL); + if (result != EF_NO_ERR) + goto exit; + log_end_addr = write_addr + writable_size; + write_size += writable_size; + write_addr += writable_size; + } else { + result = ef_port_write(write_addr, log + write_size / 4, size - write_size); + if (result != EF_NO_ERR) + goto exit; + log_end_addr = write_addr + (size - write_size); + break; + } + } + +exit: + return result; +} + +/** + * Get next flash sector address.The log total sector like ring buffer which implement by flash. + * + * @param cur_addr cur flash address + * + * @return next flash sector address + */ +static uint32_t get_next_flash_sec_addr(uint32_t cur_addr) +{ + size_t cur_sec_id = (cur_addr - log_area_start_addr) / EF_ERASE_MIN_SIZE; + size_t sec_total_num = LOG_AREA_SIZE / EF_ERASE_MIN_SIZE; + + if (cur_sec_id + 1 >= sec_total_num) { + /* return to ring head */ + return log_area_start_addr; + } else + return log_area_start_addr + (cur_sec_id + 1) * EF_ERASE_MIN_SIZE; +} + +/** + * Clean all log which in flash. + * + * @return result + */ +EfErrCode ef_log_clean(void) +{ + EfErrCode result = EF_NO_ERR; + uint32_t write_addr = log_area_start_addr; + + /* clean address */ + log_start_addr = log_area_start_addr; + log_end_addr = log_start_addr + LOG_SECTOR_HEADER_SIZE; + /* erase log flash area */ + result = ef_port_erase(log_area_start_addr, LOG_AREA_SIZE); + if (result != EF_NO_ERR) + goto exit; + /* setting first sector is USING */ + write_sector_status(write_addr, SECTOR_STATUS_USING); + if (result != EF_NO_ERR) + goto exit; + write_addr += EF_ERASE_MIN_SIZE; + /* add sector header */ + while (true) { + write_sector_status(write_addr, SECTOR_STATUS_EMPUT); + if (result != EF_NO_ERR) + goto exit; + write_addr += EF_ERASE_MIN_SIZE; + if (write_addr >= log_area_start_addr + LOG_AREA_SIZE) + break; + } + +exit: + return result; +} + +#endif /* EF_USING_LOG */ diff --git a/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_utils.c b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_utils.c new file mode 100755 index 0000000..a7d938d --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/easy_flash/src/ef_utils.c @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2015-2017, Armink, + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * 'Software'), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Function: Some utils for this library. + * Created on: 2015-01-14 + */ + +#include + +static const uint32_t crc32_table[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, + 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, + 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, + 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, + 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, + 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, + 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, + 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, + 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, + 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, + 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, + 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, + 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, + 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, + 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, + 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, + 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, + 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, + 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, + 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, + 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, + 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +/** + * Calculate the CRC32 value of a memory buffer. + * + * @param crc accumulated CRC32 value, must be 0 on first call + * @param buf buffer to calculate CRC32 value for + * @param size bytes in buffer + * + * @return calculated CRC32 value + */ +uint32_t ef_calc_crc32(uint32_t crc, const void *buf, size_t size) +{ + const uint8_t *p; + + p = (const uint8_t *)buf; + crc = crc ^ ~0U; + + while (size--) + crc = crc32_table[(crc ^ *p++) & 0xFF] ^ (crc >> 8); + + return crc ^ ~0U; +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/key_handle/key_handle.c b/bk7235/liteos_m/bk_sdk_armino/components/key_handle/key_handle.c new file mode 100755 index 0000000..580dd2b --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/key_handle/key_handle.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 "key_handle.h" +#include +#include +#include +#include "bk_arm_arch.h" +#include "bk_gpio.h" +#include "bk_uart.h" +#include "bk_music_msg.h" + +#if(CONFIG_MP3PLAYER == 1) +#define SD_DEBOUNCE_COUNT 50 +#define KEY_SCAN_INTERVAL_10MS 10 + +#if (CONFIG_SOC_BK7251) +#define SD_CARD_DETECT_PIN 31 +#else +#define SD_CARD_DETECT_PIN 25 +#endif + +#define KEY_PLAY_PAUSE_PIN 28 + +#define SD_CARD_OFFLINE 0 +#define SD_CARD_ONLINE 1 + +#define KEY_SHORTUP_COUNTER 3 //30ms +#define KEY_LONG_COUNTER 80 //800ms +#define KEY_LONGUP_COUNTER 84 //840ms +#define KEY_HOLD_COUNTER 110 //1100ms + +static void key_scan_callback(void *arg); +extern void bmsg_music_sender(void *arg); + +static UINT16 backup_keyval = MSG_NO_KEY; +static UINT16 keycount = 0; +static UINT16 sd_online = SD_CARD_OFFLINE; +static UINT16 detect_cnt = 0; +static beken_timer_t key_handle_timer = {0}; + + +void key_init(void) +{ + UINT32 param; + bk_err_t err; + + param = GPIO_CFG_PARAM(SD_CARD_DETECT_PIN, GMODE_INPUT_PULLUP); + sddev_control(DD_DEV_TYPE_GPIO, CMD_GPIO_CFG, ¶m); + + param = GPIO_CFG_PARAM(KEY_PLAY_PAUSE_PIN, GMODE_INPUT_PULLUP); + sddev_control(DD_DEV_TYPE_GPIO, CMD_GPIO_CFG, ¶m); + + + err = rtos_init_timer(&key_handle_timer, + KEY_SCAN_INTERVAL_10MS, + key_scan_callback, + (void *)0); + BK_ASSERT(kNoErr == err); + err = rtos_start_timer(&key_handle_timer); + BK_ASSERT(kNoErr == err); + + KEY_PRT("==key init==\r\n"); +} + +uint8 sd_is_attached(void) +{ + return (sd_online); +} + +static void sd_detect_handle() +{ + UINT32 sd_pin_level; + UINT32 sd_detect_pin = SD_CARD_DETECT_PIN; + + sd_pin_level = sddev_control(DD_DEV_TYPE_GPIO, CMD_GPIO_INPUT, &sd_detect_pin); + UINT32 msg; + if (sd_pin_level) { + if (sd_online == SD_CARD_ONLINE) { + detect_cnt = 0; + sd_online = SD_CARD_OFFLINE; + msg = MSG_SD_DETACH; + //?detach??? + bmsg_music_sender((void *)msg); + } + } else { + if (sd_online == SD_CARD_OFFLINE) { + if (detect_cnt < SD_DEBOUNCE_COUNT) + detect_cnt++; + else { + sd_online = SD_CARD_ONLINE; + msg = MSG_SD_ATTACH; + //?attach??? + bmsg_music_sender((void *)msg); + } + } + } +} + +static UINT16 keyIOdetect(void) +{ + UINT16 key_pin_level; + UINT16 keyValue = MSG_NO_KEY;; + UINT32 key_detect_pin = KEY_PLAY_PAUSE_PIN; + + key_pin_level = sddev_control(DD_DEV_TYPE_GPIO, CMD_GPIO_INPUT, &key_detect_pin); + if (key_pin_level == 0) + keyValue = MSG_KEY_PLAY; + + return keyValue; +} + + +static void key_detect_handle(void) +{ + UINT32 msg; + UINT16 keyval = keyIOdetect(); + + if (keyval == MSG_NO_KEY) { + if (keycount >= KEY_SHORTUP_COUNTER) { + if (keycount > KEY_LONG_COUNTER) + msg = KEY_LONG_UP | backup_keyval; + else + msg = backup_keyval; + bmsg_music_sender((void *)msg); + } + keycount = 0; + backup_keyval = MSG_NO_KEY; + } else { + if (keyval != backup_keyval) { + keycount = 0; + backup_keyval = keyval; + } + + keycount++; + + if ((keycount == KEY_LONG_COUNTER) || (keycount == KEY_HOLD_COUNTER)) { + if (keycount == KEY_LONG_COUNTER) + msg = KEY_LONG | keyval; + else { + keycount = KEY_LONGUP_COUNTER; + msg = KEY_HOLD | keyval; + } + bmsg_music_sender((void *)msg); + } + } +} + + +static void key_scan_callback(void *arg) +{ + sd_detect_handle(); + key_detect_handle(); +} +#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/media/BUILD.gn new file mode 100755 index 0000000..c27126e --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/media/BUILD.gn @@ -0,0 +1,35 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ + "app/media_app.c", + "cli/media_cli.c", + "comm/comm_act.c", + "comm/frame_buffer.c", + "core/media_major.c", + ] + public_configs = [ + ":public", + "${beken_sdk_dir}/components/bk_wifi:public", + "${beken_sdk_dir}/components/bk_cli:public", + ] +} + +config("public") { + include_dirs = [ "include" ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/components/media/CMakeLists.txt index c1d96ef..b5d36ed 100755 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/CMakeLists.txt +++ b/bk7235/liteos_m/bk_sdk_armino/components/media/CMakeLists.txt @@ -8,7 +8,7 @@ if (NOT CONFIG_SLAVE_CORE) comm/comm_act.c comm/frame_buffer.c app/media_app.c - utils/mlist.c + #utils/mlist.c ) if (CONFIG_CAMERA OR CONFIG_USB_UVC) diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/aud/adc_ccb.c b/bk7235/liteos_m/bk_sdk_armino/components/media/aud/adc_ccb.c deleted file mode 100755 index 9f1baeb..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/aud/adc_ccb.c +++ /dev/null @@ -1,224 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "media_core.h" -#include "aud_act.h" - -#include -#include -#include -#include -#include -#include -#include "aud_hal.h" -#include "sys_driver.h" -#include "aud_driver.h" -#include -#include -#include -#include - -#include "gpio_driver.h" -#include -#include - -#include "adc_ccb.h" - -#define TAG "adc_ccb" - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - -#define AUD_8K_FRAME_SAMP_SIZE 160*2 - -dma_id_t aud_adc_dma_id = DMA_ID_MAX; - - -static bk_err_t audio_adc_config() -{ - bk_err_t ret = BK_OK; - aud_adc_config_t adc_config; - - adc_config.mic_config = AUD_MIC_MIC1_ENABLE; - adc_config.samp_rate = AUD_ADC_SAMP_RATE_8K; - adc_config.adc_enable = AUD_ADC_DISABLE; - adc_config.line_enable = AUD_ADC_LINE_DISABLE; - adc_config.dtmf_enable = AUD_DTMF_DISABLE; - adc_config.adc_hpf2_coef_B2 = 0; - adc_config.adc_hpf2_bypass_enable = AUD_ADC_HPF_BYPASS_ENABLE; - adc_config.adc_hpf1_bypass_enable = AUD_ADC_HPF_BYPASS_ENABLE; - adc_config.adc_set_gain = 0x2d; - adc_config.adc_samp_edge = AUD_ADC_SAMP_EDGE_RISING; - adc_config.adc_hpf2_coef_B0 = 0; - adc_config.adc_hpf2_coef_B1 = 0; - adc_config.adc_hpf2_coef_A0 = 0; - adc_config.adc_hpf2_coef_A1 = 0; - adc_config.dtmf_wr_threshold = 8; - adc_config.adcl_wr_threshold = 8; - adc_config.dtmf_int_enable = AUD_DTMF_INT_DISABLE; - adc_config.adcl_int_enable = AUD_ADCL_INT_DISABLE; - adc_config.loop_adc2dac = AUD_LOOP_ADC2DAC_DISABLE; - adc_config.agc_noise_thrd = 101; - adc_config.agc_noise_high = 101; - adc_config.agc_noise_low = 160; - adc_config.agc_noise_min = 1; - adc_config.agc_noise_tout = 0; - adc_config.agc_high_dur = 3; - adc_config.agc_low_dur = 3; - adc_config.agc_min = 1; - adc_config.agc_max = 4; - adc_config.agc_ng_method = AUD_AGC_NG_METHOD_MUTE; - adc_config.agc_ng_enable = AUD_AGC_NG_DISABLE; - adc_config.agc_decay_time = AUD_AGC_DECAY_TIME_128; - adc_config.agc_attack_time = AUD_AGC_ATTACK_TIME_128; - adc_config.agc_high_thrd = 18; - adc_config.agc_low_thrd = 0; - adc_config.agc_iir_coef = AUD_AGC_IIR_COEF_1_1024; - adc_config.agc_enable = AUD_AGC_DISABLE; - adc_config.manual_pga_value = 0; - adc_config.manual_pga_enable = AUD_GAC_MANUAL_PGA_DISABLE; - adc_config.adc_fracmod_manual = AUD_ADC_TRACMOD_MANUAL_DISABLE; - adc_config.adc_fracmod = 0; - - /* init audio driver and config adc */ - ret = bk_aud_driver_init(); - if (ret != BK_OK) - { - os_printf("cp1: init audio driver fail \r\n"); - goto aud_adc_exit; - } - - ret = bk_aud_adc_init(AUD_ADC_WORK_MODE_ADC, &adc_config, NULL); - if (ret != BK_OK) - { - os_printf("cp1: init audio adc fail \r\n"); - goto aud_adc_exit; - } - - return BK_OK; - -aud_adc_exit: - os_printf("cp1: audio adc config fail \r\n"); - bk_aud_driver_deinit(); - return BK_FAIL; -} - - -static void audio_dma_adc_finish_isr(void) -{ - bk_gpio_pull_up(GPIO_2); - - - - bk_gpio_pull_down(GPIO_2); -} - -static bk_err_t audio_adc_dma_config(dma_id_t dma_id, int32_t *ring_buff_addr, uint32_t ring_buff_size, uint32_t transfer_len) -{ - bk_err_t ret = BK_OK; - dma_config_t dma_config; - uint32_t adc_port_addr; - - dma_config.mode = DMA_WORK_MODE_REPEAT; - dma_config.chan_prio = 1; - dma_config.src.dev = DMA_DEV_AUDIO; - dma_config.dst.dev = DMA_DEV_DTCM; - dma_config.src.width = DMA_DATA_WIDTH_16BITS; - dma_config.dst.width = DMA_DATA_WIDTH_32BITS; - - /* get adc fifo address */ - if (bk_aud_get_adc_fifo_addr(&adc_port_addr) != BK_OK) - { - os_printf("get adc fifo address failed\r\n"); - return BK_FAIL; - } - else - { - dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE; - dma_config.src.addr_loop_en = DMA_ADDR_LOOP_ENABLE; - dma_config.src.start_addr = adc_port_addr; - dma_config.src.end_addr = adc_port_addr + 4; - } - - dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE; - dma_config.dst.addr_loop_en = DMA_ADDR_LOOP_ENABLE; - dma_config.dst.start_addr = (uint32_t)ring_buff_addr; - dma_config.dst.end_addr = (uint32_t)ring_buff_addr + ring_buff_size; - - /* init dma channel */ - ret = bk_dma_init(dma_id, &dma_config); - if (ret != BK_OK) - { - os_printf("cp1: audio adc dma channel init fail \r\n"); - return BK_FAIL; - } - - /* set dma transfer length */ - bk_dma_set_transfer_len(dma_id, transfer_len); - - //register isr - bk_dma_register_isr(dma_id, NULL, (void *)audio_dma_adc_finish_isr); - bk_dma_enable_finish_interrupt(dma_id); - - //bk_dma_set_transfer_len(dma_id, 0x20); - //bk_dma_start(dma_id); - - return BK_OK; -} - - -void audio_adc_start(void) -{ - int ret; - - LOGI("%s\n", __func__); - - ret = audio_adc_config(); - - if (ret != BK_OK) - { - os_printf("cp1: audio adc init fail \r\n"); - return; - } - - /* allocate free DMA channel */ - aud_adc_dma_id = bk_dma_alloc(DMA_DEV_AUDIO); - if ((aud_adc_dma_id < DMA_ID_0) || (aud_adc_dma_id >= DMA_ID_MAX)) - { - os_printf("malloc dma fail \r\n"); - return; - } - -#ifdef CONFIG_PSRAM - ret = audio_adc_dma_config(aud_adc_dma_id, (int32_t *)psram_map->aud_adc, AUD_8K_FRAME_SAMP_SIZE * 2, AUD_8K_FRAME_SAMP_SIZE); -#else - ret = audio_adc_dma_config(aud_adc_dma_id, (int32_t *)NULL, AUD_8K_FRAME_SAMP_SIZE * 2, AUD_8K_FRAME_SAMP_SIZE); -#endif - ret = bk_dma_start(aud_adc_dma_id); - if (ret != BK_OK) - { - os_printf("cp1: start dac dma fail \r\n"); - return; - } - - /* enable adc */ - /* wait receive data and then open adc */ - bk_aud_start_adc(); -} - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/aud/aud_act.c b/bk7235/liteos_m/bk_sdk_armino/components/media/aud/aud_act.c deleted file mode 100755 index 91a5f47..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/aud/aud_act.c +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "media_core.h" -#include "media_evt.h" -#include "aud_act.h" -#include "adc_ccb.h" -#include "dac_ccb.h" - -#include -#include -#include -#include - -#include - - -#define TAG "aud_act" - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - - -void audio_adc_open_handle(void) -{ - audio_adc_start(); -} - -void audio_dac_open_handle(void) -{ - audio_dac_start(); -} - - -void audio_event_handle(uint32_t event, uint32_t param) -{ - switch (event) - { - case EVENT_AUD_ADC_OPEN: - audio_adc_open_handle(); - break; - case EVENT_AUD_DAC_OPEN: - audio_dac_open_handle(); - break; - } -} - - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/aud/aud_api.c b/bk7235/liteos_m/bk_sdk_armino/components/media/aud/aud_api.c deleted file mode 100755 index 96f996f..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/aud/aud_api.c +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "media_core.h" -#include "media_evt.h" - -#include -#include -#include -#include - -#include - - -#define TAG "aud_act" - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - - -bk_err_t adc_open(void) -{ - media_msg_t msg; - msg.event = EVENT_AUD_ADC_OPEN; - - media_send_msg(&msg); - - return BK_OK; -} - -bk_err_t dac_open(void) -{ - media_msg_t msg; - msg.event = EVENT_AUD_DAC_OPEN; - - media_send_msg(&msg); - - return BK_OK; -} - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/aud/dac_ccb.c b/bk7235/liteos_m/bk_sdk_armino/components/media/aud/dac_ccb.c deleted file mode 100755 index 3e58499..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/aud/dac_ccb.c +++ /dev/null @@ -1,201 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "media_core.h" -#include "aud_act.h" - -#include -#include -#include -#include -#include -#include -#include "aud_hal.h" -#include "sys_driver.h" -#include "aud_driver.h" -#include -#include -#include -#include - -#include "gpio_driver.h" -#include -#include - -#include "dac_ccb.h" - -#define TAG "dac_ccb" - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - -#define AUD_8K_FRAME_SAMP_SIZE 160*2 - -dma_id_t aud_dac_dma_id = DMA_ID_MAX; - - -static bk_err_t audio_dac_config(void) -{ - bk_err_t ret = BK_OK; - aud_dac_config_t dac_config; - - dac_config.dac_enable = AUD_DAC_DISABLE; - dac_config.samp_rate = AUD_DAC_SAMP_RATE_SOURCE_8K; - dac_config.dac_hpf2_coef_B2 = 0x3A22; - dac_config.dac_hpf2_bypass_enable = AUD_DAC_HPF_BYPASS_ENABLE; - dac_config.dac_hpf1_bypass_enable = AUD_DAC_HPF_BYPASS_ENABLE; - dac_config.dac_set_gain = 0x2D; //default 2D 3F 15 - dac_config.dac_clk_invert = AUD_DAC_CLK_INVERT_RISING; - - dac_config.dac_hpf2_coef_B0 = 0x3A22; - dac_config.dac_hpf2_coef_B1 = 0x8BBF; - dac_config.dac_hpf2_coef_A1 = 0x751C; - dac_config.dac_hpf2_coef_A2 = 0xC9E6; - dac_config.dacr_rd_threshold = 0x4; - dac_config.dacl_rd_threshold = 0x4; - dac_config.dacr_int_enable = 0x0; - dac_config.dacl_int_enable = 0x0; - dac_config.dac_filt_enable = AUD_DAC_FILT_DISABLE; - dac_config.dac_fracmod_manual_enable = AUD_DAC_FRACMOD_MANUAL_DISABLE; - dac_config.dac_fracmode_value = 0x0; - - /* init audio driver and config dac */ - ret = bk_aud_driver_init(); - if (ret != BK_OK) - { - os_printf("cp1: init audio driver fail \r\n"); - goto aud_dac_exit; - } - - ret = bk_aud_dac_init(&dac_config); - if (ret != BK_OK) - { - os_printf("cp1: init audio dac fail \r\n"); - goto aud_dac_exit; - } - - return BK_OK; - -aud_dac_exit: - os_printf("cp1: audio dac config fail \r\n"); - bk_aud_driver_deinit(); - return BK_FAIL; -} - - - -static void audio_dma_dac_finish_isr(void) -{ - bk_gpio_pull_up(GPIO_3); - - bk_gpio_pull_down(GPIO_3); -} - -static bk_err_t audio_dac_dma_config(dma_id_t dma_id, int32_t *ring_buff_addr, uint32_t ring_buff_size, uint32_t transfer_len) -{ - bk_err_t ret = BK_OK; - dma_config_t dma_config; - uint32_t dac_port_addr; - - dma_config.mode = DMA_WORK_MODE_REPEAT; - dma_config.chan_prio = 1; - dma_config.src.dev = DMA_DEV_DTCM; - dma_config.dst.dev = DMA_DEV_AUDIO; - dma_config.src.width = DMA_DATA_WIDTH_32BITS; - dma_config.dst.width = DMA_DATA_WIDTH_32BITS; - /* get dac fifo address */ - if (bk_aud_get_dac_fifo_addr(&dac_port_addr) != BK_OK) - { - os_printf("get dac fifo address failed\r\n"); - return BK_FAIL; - } - else - { - dma_config.dst.addr_inc_en = DMA_ADDR_INC_ENABLE; - dma_config.dst.addr_loop_en = DMA_ADDR_LOOP_ENABLE; - dma_config.dst.start_addr = dac_port_addr; - dma_config.dst.end_addr = dac_port_addr + 4; - } - dma_config.src.addr_inc_en = DMA_ADDR_INC_ENABLE; - //dma_config.src.addr_loop_en = DMA_ADDR_LOOP_ENABLE; - dma_config.src.start_addr = (uint32_t)ring_buff_addr; - dma_config.src.end_addr = (uint32_t)(ring_buff_addr) + ring_buff_size; - - /* init dma channel */ - ret = bk_dma_init(dma_id, &dma_config); - if (ret != BK_OK) - { - os_printf("cp1: audio dac dma channel init fail \r\n"); - return BK_FAIL; - } - - /* set dma transfer length */ - bk_dma_set_transfer_len(dma_id, transfer_len); - - //register isr - bk_dma_register_isr(dma_id, NULL, (void *)audio_dma_dac_finish_isr); - bk_dma_enable_finish_interrupt(dma_id); - - //bk_dma_set_transfer_len(dma_id, 0x20); - //bk_dma_start(dma_id); - - return BK_OK; -} - -void audio_dac_start(void) -{ - int ret; - - LOGI("%s\n", __func__); - - ret = audio_dac_config(); - - if (ret != BK_OK) - { - os_printf("cp1: audio dac init fail \r\n"); - return; - } - - /* allocate free DMA channel */ - aud_dac_dma_id = bk_dma_alloc(DMA_DEV_AUDIO); - if ((aud_dac_dma_id < DMA_ID_0) || (aud_dac_dma_id >= DMA_ID_MAX)) - { - os_printf("malloc dma fail \r\n"); - return; - } - -#ifdef CONFIG_PSRAM - ret = audio_dac_dma_config(aud_dac_dma_id, (int32_t *)psram_map->aud_dac, AUD_8K_FRAME_SAMP_SIZE, AUD_8K_FRAME_SAMP_SIZE); -#else - ret = audio_dac_dma_config(aud_dac_dma_id, (int32_t *)NULL, AUD_8K_FRAME_SAMP_SIZE, AUD_8K_FRAME_SAMP_SIZE); -#endif - - ret = bk_dma_start(aud_dac_dma_id); - if (ret != BK_OK) - { - os_printf("cp1: start dac dma fail \r\n"); - return; - } - - /* enable dac */ - /* wait receive data and then open dac */ - bk_aud_start_dac(); - -} - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/camera/camera.h b/bk7235/liteos_m/bk_sdk_armino/components/media/camera/camera.h deleted file mode 100755 index c478df4..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/camera/camera.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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. - -#pragma once - -#include -#include "media_evt.h" -#include - -#ifdef __cplusplus -extern "C" { -#endif - -bk_err_t bk_dvp_camera_open(media_ppi_t ppi, dvp_mode_t mode); -bk_err_t bk_dvp_camera_close(void); -bk_err_t bk_uvc_camera_open(media_ppi_t ppi); -bk_err_t bk_uvc_camera_start(void); -bk_err_t bk_uvc_camera_stop(void); -bk_err_t bk_uvc_camera_close(void); -bk_err_t bk_uvc_camera_param_set(param_pak_t *param); - -#ifdef __cplusplus -} -#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/camera/camera_act.c b/bk7235/liteos_m/bk_sdk_armino/components/media/camera/camera_act.c deleted file mode 100755 index 833d610..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/camera/camera_act.c +++ /dev/null @@ -1,299 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "media_core.h" -#include "camera_act.h" -#include "media_evt.h" -#include "storage_act.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - -#include "camera.h" -#include "frame_buffer.h" - - -#include -#include - -#include - -#include - -#define TAG "cam_act" - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - -#define DEBUG_INTERVAL (1000 * 2) - -extern bk_err_t pm_core_bus_clock_ctrl(uint32_t cksel_core, uint32_t ckdiv_core, uint32_t ckdiv_bus, uint32_t ckdiv_cpu0, uint32_t ckdiv_cpu1); - -extern void transfer_dump(uint32_t ms); - -media_debug_t *media_debug = NULL; -media_debug_t *media_debug_cached = NULL; - -camera_info_t camera_info; - -static void camera_debug_dump(timer_id_t timer_id) -{ - transfer_dump(DEBUG_INTERVAL); - - uint16_t jpg = (media_debug->isr_jpeg - media_debug_cached->isr_jpeg) / 2; - uint16_t dec = (media_debug->isr_decoder - media_debug_cached->isr_decoder) / 2; - uint16_t lcd = (media_debug->isr_lcd - media_debug_cached->isr_lcd) / 2; - uint16_t fps = (media_debug->fps_lcd - media_debug_cached->fps_lcd) / 2; - uint16_t wifi = (media_debug->fps_wifi - media_debug_cached->fps_wifi) / 2; - uint16_t err_dec = (media_debug->err_dec - media_debug_cached->err_dec) / 2; - - media_debug_cached->isr_jpeg = media_debug->isr_jpeg; - media_debug_cached->isr_decoder = media_debug->isr_decoder; - media_debug_cached->isr_lcd = media_debug->isr_lcd; - media_debug_cached->fps_lcd = media_debug->fps_lcd; - media_debug_cached->fps_wifi = media_debug->fps_wifi; - media_debug_cached->err_dec = media_debug->err_dec; - - LOGI("jpg: %d[%d], dec: %d[%d, %d], lcd: %d[%d], fps: %d[%d], wifi: %d[%d]\n", - jpg, media_debug->isr_jpeg, - dec, media_debug->isr_decoder, err_dec, - lcd, media_debug->isr_lcd, - fps, media_debug->fps_lcd, - wifi, media_debug->fps_wifi); -} - -void camera_dvp_open_handle(param_pak_t *param, dvp_mode_t mode) -{ - int ret = 0; - - LOGI("%s\n", __func__); - - if (CAMERA_STATE_DISABLED != get_camera_state()) - { - LOGI("%s already opened\n", __func__); - ret = kNoErr; - goto out; - } - - //pm_core_bus_clock_ctrl(2, 0, 1, 0, 0); - - frame_buffer_enable(true); - - ret = bk_dvp_camera_open(param->param, mode); - - - if (ret != kNoErr) - { - LOGE("%s open failed\n", __func__); - goto out; - } - - set_camera_state(CAMERA_STATE_ENABLED); - - if (camera_info.debug) - { - bk_timer_start(TIMER_ID1, DEBUG_INTERVAL, camera_debug_dump); - } - -out: - MEDIA_EVT_RETURN(param, ret); -} - -void camera_dvp_close_handle(param_pak_t *param) -{ - int ret = 0; - - LOGI("%s\n", __func__); - - if (CAMERA_STATE_DISABLED == get_camera_state()) - { - LOGI("%s already close\n", __func__); - ret = kNoErr; - goto out; - } - - bk_dvp_camera_close(); - - set_camera_state(CAMERA_STATE_DISABLED); - - if (camera_info.debug) - { - bk_timer_stop(TIMER_ID1); - } - - - frame_buffer_enable(false); - - //pm_core_bus_clock_ctrl(3, 1, 1, 0, 0); - -out: - MEDIA_EVT_RETURN(param, ret); -} - -#ifdef CONFIG_USB_UVC - -void camera_uvc_open_handle(param_pak_t *param) -{ - int ret = 0; - - LOGI("%s\n", __func__); - - if (CAMERA_STATE_DISABLED != get_camera_state()) - { - LOGI("%s already opened\n", __func__); - ret = kNoErr; - goto out; - } - - if (bk_ble_get_env_state()) - { - LOGI("bluetooth is enabled, shutdown bluetooth\n"); - bk_ble_deinit(); - rtos_delay_milliseconds(900); - } - else - { - LOGI("bluetooth state: %d\n", bk_ble_get_env_state()); - } - - - //pm_core_bus_clock_ctrl(2, 0, 1, 0, 0); - - frame_buffer_enable(true); - - ret = bk_uvc_camera_open(param->param); - - if (ret != kNoErr) - { - LOGE("%s open failed\n", __func__); - goto out; - } - - set_camera_state(CAMERA_STATE_ENABLED); - - if (camera_info.debug) - { - bk_timer_start(TIMER_ID1, DEBUG_INTERVAL, camera_debug_dump); - } - -out: - MEDIA_EVT_RETURN(param, ret); -} - - -void camera_uvc_close_handle(param_pak_t *param) -{ - int ret = 0; - - LOGI("%s\n", __func__); - - if (CAMERA_STATE_DISABLED == get_camera_state()) - { - LOGI("%s already close\n", __func__); - ret = kNoErr; - goto out; - } - - if (camera_info.debug) - { - bk_timer_stop(TIMER_ID1); - } - - bk_uvc_camera_close(); - - set_camera_state(CAMERA_STATE_DISABLED); - - frame_buffer_enable(false); - - //pm_core_bus_clock_ctrl(3, 1, 1, 0, 0); - LOGI("uvc close success!\n"); - -out: - MEDIA_EVT_RETURN(param, ret); -} - -#endif - -void camera_event_handle(uint32_t event, uint32_t param) -{ - switch (event) - { - case EVENT_CAM_DVP_JPEG_OPEN_IND: - camera_dvp_open_handle((param_pak_t *)param, DVP_MODE_JPG); - break; - case EVENT_CAM_DVP_YUV_OPEN_IND: - camera_dvp_open_handle((param_pak_t *)param, DVP_MODE_YUV); - break; - case EVENT_CAM_DVP_CLOSE_IND: - camera_dvp_close_handle((param_pak_t *)param); - break; - -#ifdef CONFIG_USB_UVC - case EVENT_CAM_UVC_OPEN_IND: - camera_uvc_open_handle((param_pak_t *)param); - break; - case EVENT_CAM_UVC_CLOSE_IND: - camera_uvc_close_handle((param_pak_t *)param); - break; -#endif - } -} - -camera_state_t get_camera_state(void) -{ - return camera_info.state; -} - -void set_camera_state(camera_state_t state) -{ - camera_info.state = state; -} - -void camera_init(void) -{ - if (media_debug == NULL) - { - media_debug = (media_debug_t*)os_malloc(sizeof(media_debug_t)); - - if (media_debug == NULL) - { - LOGE("malloc media_debug fail\n"); - } - } - - if (media_debug_cached == NULL) - { - media_debug_cached = (media_debug_t*)os_malloc(sizeof(media_debug_t)); - if (media_debug_cached == NULL) - { - LOGE("malloc media_debug_cached fail\n"); - } - } - - camera_info.state = CAMERA_STATE_DISABLED; - camera_info.debug = true; -} - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/camera/dvp.c b/bk7235/liteos_m/bk_sdk_armino/components/media/camera/dvp.c deleted file mode 100755 index 869ecb9..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/camera/dvp.c +++ /dev/null @@ -1,100 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "media_core.h" -#include "camera_act.h" -#include "lcd_act.h" -#include "storage_act.h" - -#include -#include -#include -#include - -#include -#include -#include -#include - - -#include -#include - -#include "frame_buffer.h" - -#define TAG "dvp" - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - - -void frame_buffer_jpg_complete(frame_buffer_t *buffer) -{ - frame_buffer_generate_complete(buffer, FRAME_JPEG); -} - -frame_buffer_t *frame_buffer_jpg_alloc(void) -{ - return frame_buffer_alloc(FRAME_JPEG); -} - -void frame_buffer_yuv_complete(frame_buffer_t *buffer) -{ - frame_buffer_generate_complete(buffer, FRAME_DISPLAY); -} - -frame_buffer_t *frame_buffer_yuv_alloc(void) -{ - return frame_buffer_alloc(FRAME_DISPLAY); -} - -bk_err_t bk_dvp_camera_open(media_ppi_t ppi, dvp_mode_t mode) -{ - int ret = BK_OK; - dvp_camera_config_t config; - - if (DVP_MODE_JPG == mode) - { - config.ppi = ppi; - config.mode = DVP_MODE_JPG; - config.frame_set_ppi = frame_buffer_set_ppi; - config.frame_complete = frame_buffer_jpg_complete; - config.frame_alloc = frame_buffer_jpg_alloc; - - ret = bk_dvp_camera_driver_init(&config); - } - else if (DVP_MODE_YUV == mode) - { - config.ppi = ppi; - config.mode = DVP_MODE_YUV; - config.frame_set_ppi = frame_buffer_set_ppi; - config.frame_complete = frame_buffer_yuv_complete; - config.frame_alloc = frame_buffer_yuv_alloc; - - ret = bk_dvp_camera_driver_init(&config); - } - - return ret; -} - -bk_err_t bk_dvp_camera_close(void) -{ - bk_dvp_camera_driver_deinit(); - return 0; -} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/camera/uvc.c b/bk7235/liteos_m/bk_sdk_armino/components/media/camera/uvc.c deleted file mode 100755 index b51e1d1..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/camera/uvc.c +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "camera_act.h" -#include "media_evt.h" -#include "media_app.h" - -#include - -#include - -#include "frame_buffer.h" - -#define TAG "uvc" - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - -#ifdef CONFIG_USB_UVC - -uvc_camera_device_t uvc_camera_device = -{ - .width = 640, - .height = 480, - .fps = 25, -}; - -void frame_buffer_uvc_jpg_complete(frame_buffer_t *buffer) -{ - frame_buffer_generate_complete(buffer, FRAME_JPEG); -} - -frame_buffer_t *frame_buffer_uvc_jpg_alloc(void) -{ - return frame_buffer_alloc(FRAME_JPEG); -} - -void uvc_device_disconnect_callback(void) -{ - LOGI("%s\n", __func__); - - media_app_camera_close(APP_CAMERA_UVC); -} - -const uvc_camera_config_t uvc_camera_config = -{ - .device = &uvc_camera_device, - .frame_set_ppi = frame_buffer_set_ppi, - .frame_complete = frame_buffer_uvc_jpg_complete, - .frame_alloc = frame_buffer_uvc_jpg_alloc, - .uvc_disconnect = uvc_device_disconnect_callback, -}; - - -bk_err_t bk_uvc_camera_open(media_ppi_t ppi) -{ - if (ppi != 0) - { - uvc_camera_device.width = ppi >> 16; - uvc_camera_device.height = ppi & 0xFFFF; - } - - return bk_uvc_camera_driver_init(&uvc_camera_config); -} - -bk_err_t bk_uvc_camera_start(void) -{ - return bk_uvc_camera_driver_start(); -} - -bk_err_t bk_uvc_camera_stop(void) -{ - return bk_uvc_camera_driver_stop(); -} - -bk_err_t bk_uvc_camera_close(void) -{ - bk_uvc_camera_driver_deinit(); - return 0; -} - -bk_err_t bk_uvc_camera_param_set(param_pak_t *param) -{ - return bk_uvc_camera_set_config((uvc_camera_device_t *)param->param); -} - -#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/lcd/lcd_act.c b/bk7235/liteos_m/bk_sdk_armino/components/media/lcd/lcd_act.c deleted file mode 100755 index 83bb0d1..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/lcd/lcd_act.c +++ /dev/null @@ -1,799 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "media_core.h" -#include "media_evt.h" -#include "storage_act.h" -#include "lcd_act.h" -#include "frame_buffer.h" - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -//#include -#include -#include "modules/image_scale.h" -//#include "lcd_blend_config.h" -#include -#include - -#include -#include - - -#define TAG "lcd" - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - -extern media_debug_t *media_debug; - - -lcd_info_t lcd_info = {0}; -uint32_t decoder_size; - -void lcd_frame_pingpong_insert(frame_buffer_t *buffer) -{ - if (lcd_info.display_frame == NULL) - { - lcd_info.display_frame = buffer; - lcd_driver_set_display_base_addr((uint32_t)lcd_info.display_frame->frame); - lcd_driver_display_enable(); - LOGD("display start\n"); - } - else - { - GLOBAL_INT_DECLARATION(); - GLOBAL_INT_DISABLE(); - - if (lcd_info.pingpong_frame != NULL) - { - frame_buffer_free_request(lcd_info.pingpong_frame, MODULE_DISPLAY); - } - - lcd_info.pingpong_frame = buffer; - - GLOBAL_INT_RESTORE(); - } -} - - -static void lcd_act_complete_callback(void) -{ - media_debug->isr_lcd++; - - if (lcd_info.display_frame == NULL) - { - LOGW("display frame should not be NULL\n"); - return; - } - - if (lcd_info.pingpong_frame != NULL) - { - frame_buffer_free_request(lcd_info.display_frame, MODULE_DISPLAY); - lcd_info.display_frame = lcd_info.pingpong_frame; - lcd_info.pingpong_frame = NULL; - lcd_driver_set_display_base_addr((uint32_t)lcd_info.display_frame->frame); - media_debug->fps_lcd++; - } - //LOGI("rgb %p\n", lcd_info.display_frame->frame); - - lcd_driver_display_continue(); -} - -#if 0 -static void lcd_act_jpeg_dec_dump(uint8_t *src, uint32_t size) -{ - uint32_t i; - - LOGE("dump: "); - - for (i = 0; i < size; i++) - { - os_printf("%02X ", src[i]); - } - os_printf("\n"); -} -#endif - -static void jpeg_dec_eof_cb(jpeg_dec_res_t *result) -{ - media_debug->isr_decoder++; - - //bk_gpio_pull_up(GPIO_8); - - if (lcd_info.step_mode == false) - { - bk_timer_stop(TIMER_ID3); - } - else - { - if (lcd_info.step_trigger == true) - { - LOGI("decoder frame %u complete(%u:%u)\n", lcd_info.jpeg_frame->sequence, lcd_info.jpeg_frame->length, result->size); - lcd_info.step_trigger = false; - } - lcd_frame_pingpong_insert(lcd_info.decoder_frame); - return; - } - - decoder_size = result->size; - - if (result->ok == false) - { - media_msg_t msg; - - //LOGE("decoder failed, %u %u\n", result->size, lcd_info.jpeg_frame->length); - - //lcd_act_jpeg_dec_dump(lcd_info.jpeg_frame->frame + lcd_info.jpeg_frame->length - 15, 15); - - frame_buffer_free_request(lcd_info.decoder_frame, MODULE_DISPLAY); - msg.event = EVENT_COM_FRAME_DECODER_FREE_IND; - msg.param = (uint32_t)lcd_info.jpeg_frame; - media_send_msg(&msg); - lcd_info.jpeg_frame = NULL; - - media_debug->err_dec++; - - return; - } - - if (lcd_info.rotate == false) - { - lcd_frame_pingpong_insert(lcd_info.decoder_frame); - lcd_info.decoder_frame = NULL; - if (lcd_info.jpeg_frame && true == frame_buffer_get_state()) - { - media_msg_t msg; - - LOGD("free decoder frame: %u\n", lcd_info.jpeg_frame->sequence); - msg.event = EVENT_COM_FRAME_DECODER_FREE_IND; - msg.param = (uint32_t)lcd_info.jpeg_frame; - media_send_msg(&msg); - lcd_info.jpeg_frame = NULL; - } - else - { - LOGD("fjpgeof frame: %p, %d\n", lcd_info.jpeg_frame, frame_buffer_get_state()); - } - } - else - { - lcd_info.rotate_frame = frame_buffer_alloc(FRAME_DISPLAY); - lcd_info.rotate_frame->sequence = lcd_info.decoder_frame->sequence; - -#if 1 - - media_msg_t msg; - msg.event = EVENT_LCD_ROTATE_RIGHT_CMD; - msg.param = (uint32_t)&lcd_info; - media_send_msg(&msg); -#else - media_msg_t msg; - msg.event = EVENT_LCD_FRAME_LOCAL_ROTATE_IND; - msg.param = (uint32_t)&lcd_info; - media_send_msg(&msg); -#endif - } - - //bk_gpio_pull_down(GPIO_8); -} - -static void lcd_act_decoder_timeout(timer_id_t timer_id) -{ - bk_timer_stop(TIMER_ID3); - - LOGI("decoder timeout\n"); - bk_jpeg_dec_stop(); - - frame_buffer_free_request(lcd_info.decoder_frame, MODULE_DISPLAY); - lcd_info.decoder_frame = NULL; - - - if (lcd_info.jpeg_frame && true == frame_buffer_get_state()) - { - media_msg_t msg; - - LOGI("free decoder frame: %u\n", lcd_info.jpeg_frame->sequence); - msg.event = EVENT_COM_FRAME_DECODER_FREE_IND; - msg.param = (uint32_t)lcd_info.jpeg_frame; - media_send_msg(&msg); - lcd_info.jpeg_frame = NULL; - } -} - -void lcd_act_rotate_complete(frame_buffer_t *frame) -{ - frame_buffer_free_request(lcd_info.decoder_frame, MODULE_DISPLAY); - - if (frame != lcd_info.rotate_frame) - { - LOGE("frame not match\n"); - } - - lcd_frame_pingpong_insert(lcd_info.rotate_frame); - - if (lcd_info.jpeg_frame && true == frame_buffer_get_state()) - { - media_msg_t msg; - - LOGD("free decoder frame: %u\n", lcd_info.jpeg_frame->sequence); - msg.event = EVENT_COM_FRAME_DECODER_FREE_IND; - msg.param = (uint32_t)lcd_info.jpeg_frame; - media_send_msg(&msg); - lcd_info.jpeg_frame = NULL; - } -} - - -uint8_t lcd_frame_complete_callback(frame_buffer_t *buffer) -{ - bool lock = false; - - if (buffer->type == FRAME_JPEG) - { - media_msg_t msg; - - msg.event = EVENT_LCD_FRAME_COMPLETE_IND; - msg.param = (uint32_t)buffer; - - media_send_msg(&msg); - } - else if (buffer->type == FRAME_DISPLAY) - { - lcd_frame_pingpong_insert(buffer); - } - - return lock; -} - - -int lcd_act_driver_init(uint32_t lcd_ppi) -{ - int ret = BK_FAIL; - dvp_camera_device_t *dvp_device = NULL; - bool yuv_mode = false; - - LOGI("%s, ppi: %dX%d\n", __func__, lcd_ppi >> 16, lcd_ppi & 0xFFFF); - - if (lcd_info.state == LCD_STATE_ENABLED) - { - LOGE("alread enable\n", __func__); - return ret; - } - - dvp_device = bk_dvp_camera_get_device(); - - if (dvp_device == NULL || dvp_device->id == ID_UNKNOW) - { - LOGE("dvp camera was not init\n"); -#if (CONFIG_USB_UVC) - uvc_camera_device_t *uvc_device = NULL; - - uvc_device = bk_uvc_camera_get_device(); - - if (uvc_device == NULL) - { - LOGE("uvc camera was not init\n"); - return BK_FAIL; - } - - lcd_info.src_pixel_x = uvc_device->width; - lcd_info.src_pixel_y = uvc_device->height; - lcd_info.camera = UVC_CAMERA; -#else - return BK_FAIL; -#endif - } - else - { - lcd_info.src_pixel_x = ppi_to_pixel_x(dvp_device->ppi); - lcd_info.src_pixel_y = ppi_to_pixel_y(dvp_device->ppi); - - if (dvp_device->mode == DVP_MODE_YUV) - { - yuv_mode = true; - } - - lcd_info.camera = DVP_CAMERA; - } - - ret = bk_jpeg_dec_driver_init(); - - media_debug->fps_lcd = 0; - media_debug->isr_decoder = 0; - media_debug->isr_lcd = 0; - media_debug->err_dec = 0; - - if (ret != BK_OK) - { - LOGE("bk_jpeg_dec_driver_init failed\n"); - return ret; - } - - lcd_info.lcd_pixel_x = ppi_to_pixel_x(lcd_ppi); - lcd_info.lcd_pixel_y = ppi_to_pixel_y(lcd_ppi); - - lcd_info.display_frame = NULL; - lcd_info.pingpong_frame = NULL; - lcd_info.jpeg_frame = NULL; - lcd_info.decoder_frame = NULL; - lcd_info.step_mode = false; - lcd_info.step_trigger = false; - - LOGI("%s Camera PPI: %dX%d\n", __func__, lcd_info.src_pixel_x, lcd_info.src_pixel_y); - - lcd_config_t lcd_config; - - if (lcd_ppi == PPI_1024X600) - { - lcd_config.device = get_lcd_device_by_id(LCD_DEVICE_HX8282); - } - else if (lcd_ppi == PPI_320X480) - { - lcd_config.device = get_lcd_device_by_id(LCD_DEVICE_ST7796S); - } - else if (lcd_ppi == PPI_480X800) - { - lcd_config.device = get_lcd_device_by_id(LCD_DEVICE_GC9503V); - } - else - { - lcd_config.device = get_lcd_device_by_id(LCD_DEVICE_ST7282); - } - - lcd_config.complete_callback = lcd_act_complete_callback; - - if (lcd_info.rotate == false) - { - lcd_config.pixel_x = lcd_info.src_pixel_x; - lcd_config.pixel_y = lcd_info.src_pixel_y; - } - else - { - lcd_config.pixel_x = ppi_to_pixel_x(lcd_config.device->ppi); - lcd_config.pixel_y = ppi_to_pixel_y(lcd_config.device->ppi); - } - - lcd_info.pixel_size = get_ppi_size(lcd_config.device->ppi); - - if (yuv_mode) - { - lcd_config.fmt = LCD_FMT_ORGINAL_YUYV; - } - else - { - frame_buffer_display_frame_init(); - - if (lcd_info.rotate) - { - lcd_config.fmt = LCD_FMT_ORGINAL_YUYV; - } - else - { - lcd_config.fmt = LCD_FMT_VUYY; - } - bk_jpeg_dec_isr_register(DEC_END_OF_FRAME, jpeg_dec_eof_cb); - } - - lcd_driver_init(&lcd_config); -#if CONFIG_PWM - lcd_driver_set_backlight(100); -#endif - - lcd_info.state = LCD_STATE_ENABLED; - - if (yuv_mode) - { - frame_buffer_frame_register(MODULE_DISPLAY, lcd_frame_complete_callback); - } - else - { - frame_buffer_frame_register(MODULE_DECODER, lcd_frame_complete_callback); - } - - LOGI("%s successful\n", __func__); - return ret; -} - -void lcd_open_handle(param_pak_t *param) -{ - int ret = BK_OK; - //media_msg_t msg; - - LOGI("%s\n", __func__); - - if (LCD_STATE_ENABLED == get_lcd_state()) - { - LOGW("%s already open\n", __func__); - goto out; - } - - bk_pm_module_vote_cpu_freq(PM_DEV_ID_DISP, PM_CPU_FRQ_320M); - - ret = lcd_act_driver_init(param->param); - - set_lcd_state(LCD_STATE_ENABLED); - -out: - - MEDIA_EVT_RETURN(param, ret); -} - -void lcd_close_handle(param_pak_t *param) -{ - int ret = BK_OK; - dvp_camera_device_t *dvp_device = NULL; - bool yuv_mode = false; - - LOGI("%s\n", __func__); - - if (LCD_STATE_DISABLED == get_lcd_state()) - { - LOGW("%s already close\n", __func__); - goto out; - } - - dvp_device = bk_dvp_camera_get_device(); - - lcd_driver_deinit(); - - lcd_info.rotate = false; - - if (dvp_device != NULL - && dvp_device->id != ID_UNKNOW - && dvp_device->mode == DVP_MODE_YUV) - { - yuv_mode = true; - } - - if (yuv_mode) - { - frame_buffer_frame_deregister(MODULE_DISPLAY); - } - else - { - bk_timer_stop(TIMER_ID3); - bk_jpeg_dec_driver_deinit(); - frame_buffer_frame_deregister(MODULE_DECODER); - } - - if (lcd_info.jpeg_frame) - { - media_msg_t msg; - - msg.event = EVENT_COM_FRAME_DECODER_FREE_IND; - msg.param = (uint32_t)lcd_info.jpeg_frame; - media_send_msg(&msg); - lcd_info.jpeg_frame = NULL; - } - - if (lcd_info.decoder_frame) - { - frame_buffer_free_request(lcd_info.decoder_frame, MODULE_DISPLAY); - lcd_info.decoder_frame = NULL; - } - - if (lcd_info.pingpong_frame) - { - frame_buffer_free_request(lcd_info.pingpong_frame, MODULE_DISPLAY); - lcd_info.pingpong_frame = NULL; - } - - - if (lcd_info.display_frame) - { - frame_buffer_free_request(lcd_info.display_frame, MODULE_DISPLAY); - lcd_info.display_frame = NULL; - } - - set_lcd_state(LCD_STATE_DISABLED); - - bk_pm_module_vote_cpu_freq(PM_DEV_ID_DISP, PM_CPU_FRQ_DEFAULT); - - LOGI("%s complete\n", __func__); - -out: - - MEDIA_EVT_RETURN(param, ret); -} - -void lcd_set_backligth_handle(param_pak_t *param) -{ - int ret = BK_OK; - - LOGI("%s, levle: %d\n", __func__, param->param); - -#if CONFIG_PWM - lcd_driver_set_backlight(param->param); -#endif - - MEDIA_EVT_RETURN(param, ret); -} - - -void lcd_act_dump_decoder_frame(void) -{ - storage_frame_buffer_dump(lcd_info.decoder_frame, "decoder_vuyy.yuv"); -} - -void lcd_act_dump_jpeg_frame(void) -{ - LOGI("decoder size: %u, jpeg size: %d\n", decoder_size, lcd_info.jpeg_frame->length); - storage_frame_buffer_dump(lcd_info.jpeg_frame, "jpeg.jpg"); -} - -void lcd_act_dump_display_frame(void) -{ - storage_frame_buffer_dump(lcd_info.display_frame, "display_vuyy.yuv"); -} - - -bk_err_t lcd_frame_decoder(frame_buffer_t *buffer) -{ - int ret = BK_FAIL; - frame_buffer_t *frame = NULL; - - if (buffer->frame[0] != 0xFF || buffer->frame[1] != 0xD8) - { - ret = BK_FAIL; - LOGE("%s frame header error\n"); - goto error; - } - - if (lcd_info.jpeg_frame == NULL) - { - lcd_info.jpeg_frame = buffer; - frame = frame_buffer_alloc(FRAME_DISPLAY); - - if (frame == NULL) - { - LOGE("%s malloc decoder frame NULL\n"); - //TODO; - goto error; - } - - frame->length = lcd_info.src_pixel_x * lcd_info.src_pixel_y * 2; - frame->sequence = lcd_info.jpeg_frame->sequence; - - //bk_gpio_pull_up(GPIO_5); - - LOGD("decoder frame: %u, %p, %p\n", lcd_info.jpeg_frame->sequence, lcd_info.jpeg_frame->frame, frame->frame); - LOGD("frame: %u, %u, %u\n", lcd_info.jpeg_frame->sequence, lcd_info.jpeg_frame->length, lcd_info.jpeg_frame->length % 4); - - if (lcd_info.camera == UVC_CAMERA) - { - ret = bk_jpeg_dec_dma_start(lcd_info.jpeg_frame->length, lcd_info.jpeg_frame->frame, frame->frame); - } - else - { - ret = bk_jpeg_dec_hw_start(lcd_info.jpeg_frame->length, lcd_info.jpeg_frame->frame, frame->frame); - } - - if (lcd_info.step_mode == false) - { - bk_timer_start(TIMER_ID3, 200, lcd_act_decoder_timeout); - } - - //bk_gpio_pull_down(GPIO_5); - - LOGD("bk_jpeg_dec_hw_start, :%d\n", ret); - } - else - { - LOGI("decoder frame not NULL\n"); - } - - if (ret != BK_OK) - { - LOGE("%s frame decoder error\n", __func__); - goto error; - } - - lcd_info.decoder_frame = frame; - - return ret; - -error: - - LOGE("decoder error, free frame: %u\n", buffer->sequence); - - lcd_info.jpeg_frame = NULL; - - media_debug->err_dec++; - - if (frame != NULL) - { - frame_buffer_free_request(frame, MODULE_DISPLAY); - } - return ret; -} - - - -void lcd_frame_complete_handle(frame_buffer_t *buffer) -{ - int ret = BK_FAIL; - - if (lcd_info.debug == true) - { - bk_gpio_set_output_high(GPIO_2); - } - - if (buffer->type == FRAME_JPEG) - { - ret = lcd_frame_decoder(buffer); - } - else if (buffer->type == FRAME_DISPLAY) - { - //TODO - LOGE("%s frame error\n"); - } - - - if (ret != BK_OK) - { - media_msg_t msg; - - msg.event = EVENT_COM_FRAME_DECODER_FREE_IND; - msg.param = (uint32_t)buffer; - media_send_msg(&msg); - } - - - if (lcd_info.debug == true) - { - bk_gpio_set_output_low(GPIO_2); - } -} - -void lcd_event_handle(uint32_t event, uint32_t param) -{ - param_pak_t *param_pak = NULL; - - switch (event) - { - case EVENT_LCD_OPEN_IND: - lcd_open_handle((param_pak_t *)param); - break; - - case EVENT_LCD_ROTATE_ENABLE_IND: - { - LOGI("EVENT_LCD_ROTATE_ENABLE_IND\n"); - - param_pak = (param_pak_t *)param; - lcd_info.rotate = param_pak->param; - MEDIA_EVT_RETURN(param_pak, BK_OK); - } - break; - - case EVENT_LCD_FRAME_COMPLETE_IND: - lcd_frame_complete_handle((frame_buffer_t *)param); - break; - - case EVENT_LCD_FRAME_LOCAL_ROTATE_IND: -#if 0 - lcd_act_rotate_degree90(param); - lcd_act_rotate_complete(lcd_info.rotate_frame); -#endif - break; - - case EVENT_LCD_CLOSE_IND: - lcd_close_handle((param_pak_t *)param); - break; - case EVENT_LCD_SET_BACKLIGHT_IND: - lcd_set_backligth_handle((param_pak_t *)param); - break; - - case EVENT_LCD_DUMP_DECODER_IND: - lcd_act_dump_decoder_frame(); - param_pak = (param_pak_t *)param; - MEDIA_EVT_RETURN(param_pak, BK_OK); - break; - - case EVENT_LCD_DUMP_JPEG_IND: - lcd_act_dump_jpeg_frame(); - param_pak = (param_pak_t *)param; - MEDIA_EVT_RETURN(param_pak, BK_OK); - break; - - case EVENT_LCD_DUMP_DISPLAY_IND: - lcd_act_dump_display_frame(); - param_pak = (param_pak_t *)param; - MEDIA_EVT_RETURN(param_pak, BK_OK); - break; - - case EVENT_LCD_STEP_MODE_IND: - param_pak = (param_pak_t *)param; - - if (param_pak->param) - { - LOGI("step mode enable"); - lcd_info.step_mode = true; - bk_timer_stop(TIMER_ID3); - } - else - { - LOGI("step mode disable"); - lcd_info.step_mode = false; - } - MEDIA_EVT_RETURN(param_pak, BK_OK); - break; - - case EVENT_LCD_STEP_TRIGGER_IND: - param_pak = (param_pak_t *)param; - - LOGI("step trigger start"); - lcd_info.step_trigger = true; - - if (lcd_info.jpeg_frame && true == frame_buffer_get_state()) - { - media_msg_t msg; - - LOGI("free decoder frame: %u\n", lcd_info.jpeg_frame->sequence); - msg.event = EVENT_COM_FRAME_DECODER_FREE_IND; - msg.param = (uint32_t)lcd_info.jpeg_frame; - media_send_msg(&msg); - lcd_info.jpeg_frame = NULL; - } - - MEDIA_EVT_RETURN(param_pak, BK_OK); - break; - - - } -} - - -lcd_state_t get_lcd_state(void) -{ - return lcd_info.state; -} - -void set_lcd_state(lcd_state_t state) -{ - lcd_info.state = state; -} - -void lcd_init(void) -{ - os_memset(&lcd_info, 0, sizeof(lcd_info_t)); - - lcd_info.state = LCD_STATE_DISABLED; - lcd_info.debug = false; - lcd_info.rotate = false; -} - - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/lcd/lcd_calc.c b/bk7235/liteos_m/bk_sdk_armino/components/media/lcd/lcd_calc.c deleted file mode 100755 index 8eccef4..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/lcd/lcd_calc.c +++ /dev/null @@ -1,179 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "media_core.h" -#include "media_evt.h" -#include "lcd_act.h" -#include "frame_buffer.h" - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -//#include -#include -#include "modules/image_scale.h" -//#include "lcd_blend_config.h" -#include -#include - -#include -#include "modules/image_scale.h" - -#define TAG "rotate" -#include "cache.h" - -#if CONFIG_SLAVE_CORE -#define MINOOR_DTCM __attribute__((section(".dtcm_sec_data "))) -#else -#define MINOOR_DTCM -#endif - -#if CONFIG_SLAVE_CORE -#define MINOOR_ITCM __attribute__((section(".itcm_sec_code "))) -#else -#define MINOOR_ITCM -#endif - - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - -frame_buffer_t *rotate_frame = NULL; -frame_buffer_t *decoder_frame = NULL; - -uint32_t lcd_width = 0; -uint32_t lcd_height = 0; - -lcd_info_t *lcd_info_ptr = NULL; - - -#define BLOCK_WIDTH (40) -#define BLOCK_HEIGHT (80) -#define BLOCK_SIZE (BLOCK_WIDTH * BLOCK_HEIGHT * 2) - -MINOOR_DTCM uint8_t rx_block[BLOCK_SIZE]; -MINOOR_DTCM uint8_t tx_block[BLOCK_SIZE]; - - - -void rotate_complete(frame_buffer_t *frame) -{ - media_msg_t msg; - msg.event = EVENT_LCD_ROTATE_RIGHT_COMP_EVT; - msg.param = (uint32_t)frame; - media_send_msg(&msg); -} - - -MINOOR_ITCM void memcpy_word(uint32_t *dst, uint32_t *src, uint32_t size) -{ - uint32_t i = 0; - - for (i = 0; i < size; i++) - { - dst[i] = src[i]; - } -} - - -MINOOR_ITCM void lcd_act_rotate_degree90(uint32_t param) -{ - - lcd_info_ptr = (lcd_info_t *)param; - uint32_t i, j, k; - uint8_t *cp_ptr = NULL; - uint16_t src_width, src_height; - - decoder_frame = lcd_info_ptr->decoder_frame; - rotate_frame = lcd_info_ptr->rotate_frame; - - src_width = lcd_info_ptr->src_pixel_x; - src_height = lcd_info_ptr->src_pixel_y; - - lcd_width = lcd_info_ptr->lcd_pixel_x; - lcd_height = lcd_info_ptr->lcd_pixel_y; - -#if(1) // cpu1 cache enable - uint8_t * dst_frame_temp = rotate_frame->frame + 0x4000000; - uint8_t * src_frame_temp = decoder_frame->frame + 0x4000000; - - flush_dcache(src_frame_temp, JPEG_DEC_FRAME_SIZE); - flush_dcache(dst_frame_temp, JPEG_DEC_FRAME_SIZE); -#endif - LOGD("camera %d:%d, lcd %d:%d\n", src_width, src_height, lcd_width, lcd_height); - - if (lcd_width == src_width - && lcd_width == src_width) - { - LOGD("do not rotate\n"); - memcpy_word((uint32_t *)(rotate_frame->frame), (uint32_t *)decoder_frame->frame, decoder_frame->length / 4); - rotate_complete(rotate_frame); - return; - } - - for (j = 0; j < (src_height / BLOCK_HEIGHT); j++) - { - - for (i = 0; i < (src_width / BLOCK_WIDTH); i++) - { - for (k = 0; k < BLOCK_HEIGHT; k++) - { - #if(1) // cpu1 cache enable - cp_ptr = src_frame_temp + i * BLOCK_WIDTH * 2 + j * BLOCK_HEIGHT * src_width * 2 + k * src_width * 2; - #else - cp_ptr = decoder_frame->frame + i * BLOCK_WIDTH * 2 + j * BLOCK_HEIGHT * src_width * 2 + k * src_width * 2; - #endif - memcpy_word((uint32_t *)(rx_block + BLOCK_WIDTH * 2 * k), (uint32_t *)cp_ptr, BLOCK_WIDTH * 2 / 4); - } - - vuyy_rotate_degree90(rx_block, tx_block, BLOCK_WIDTH, BLOCK_HEIGHT); - - for (k = 0; k < BLOCK_WIDTH; k++) - { - #if(1) // cpu1 cache enable - cp_ptr = dst_frame_temp + (src_height / BLOCK_HEIGHT - j - 1) * BLOCK_HEIGHT * 2 + (i) * BLOCK_WIDTH * src_height * 2 + k * src_height * 2; - #else - cp_ptr = rotate_frame->frame + (src_height / BLOCK_HEIGHT - j - 1) * BLOCK_HEIGHT * 2 + (i) * BLOCK_WIDTH * src_height * 2 + k * src_height * 2; - #endif - memcpy_word((uint32_t *)cp_ptr, (uint32_t *)(tx_block + BLOCK_HEIGHT * 2 * k), BLOCK_HEIGHT * 2 / 4); - } - } - } - -#if CONFIG_SLAVE_CORE - rotate_complete(rotate_frame); -#endif -} - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/mb/mailbox_act.c b/bk7235/liteos_m/bk_sdk_armino/components/media/mb/mailbox_act.c deleted file mode 100755 index f19f38f..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/mb/mailbox_act.c +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "media_core.h" -#include "media_evt.h" -#include "mailbox_act.h" -#include "lcd_act.h" - -#include -#include -#include -#include - -#include - -#ifdef CONFIG_MASTER_CORE -#define TAG "mb_major" -#endif - -#ifdef CONFIG_SLAVE_CORE -#define TAG "mb_minor" -#endif - -#include - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - - - - - - - - - - - -#if CONFIG_SLAVE_CORE -void mailbox_cmd_handle(uint32_t event, uint32_t param) -{ - switch (event) - { - case EVENT_LCD_DEFAULT_CMD: - LOGI("EVENT_LCD_DEFAULT_CMD \n"); - media_msg_t msg; - msg.event = EVENT_LCD_DEFAULT_EVT; - msg.param = param; - media_send_msg(&msg); - - case EVENT_LCD_ROTATE_RIGHT_CMD: - //LOGI("EVENT_LCD_ROTATE_RIGHT_CMD \n"); - lcd_act_rotate_degree90(param); - break; - } -} -#endif - -#if CONFIG_MASTER_CORE -void mailbox_evt_handle(uint32_t event, uint32_t param) -{ - switch (event) - { - case EVENT_LCD_DEFAULT_EVT: - LOGI("EVENT_LCD_DEFAULT_EVT \n"); - - param_pak_t *param_pak = (param_pak_t *)param; - - - LOGI("param: %08X\n", param_pak->param); - - MEDIA_EVT_RETURN(param_pak, 0); - - break; - -#ifdef CONFIG_LCD - case EVENT_LCD_ROTATE_RIGHT_COMP_EVT: - //LOGI("EVENT_LCD_ROTATE_RIGHT_COMP_EVT\n"); - lcd_act_rotate_complete((frame_buffer_t *)param); - break; -#endif - - } -} -#endif diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/mb/mailbox_queue.c b/bk7235/liteos_m/bk_sdk_armino/components/media/mb/mailbox_queue.c deleted file mode 100755 index c2477d3..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/mb/mailbox_queue.c +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include - -#include "media_core.h" -#include "dvp_act.h" -#include "mailbox_channel.h" - -static struct list_head media_mb_list; - - -void mailbox_queue_init(void) -{ - INIT_LIST_HEAD(&media_mb_list); -} - -void mailbox_queue_enqueue(void *param) -{ - list_add_tail(param, &media_mb_list); -} - -void mailbox_queue_dequeue(void *param) -{ - list_add_tail(param, &media_mb_list); -} - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/storage/storage_act.c b/bk7235/liteos_m/bk_sdk_armino/components/media/storage/storage_act.c deleted file mode 100755 index 8e5249b..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/storage/storage_act.c +++ /dev/null @@ -1,336 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include -#include - -#include - -#include -#include -#include -#include - -#include - - -#include -#include -#include -#include - -#include "frame_buffer.h" - -#include "media_core.h" -#include "media_evt.h" -#include "storage_act.h" - -#if (CONFIG_SDCARD_HOST) -#include "ff.h" -#include "diskio.h" -#endif - -#define TAG "storage" - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - -static beken_queue_t storage_task_queue = NULL; -static beken_thread_t storage_task_thread = NULL; - -typedef struct -{ - uint8_t type; - uint32_t data; -} storages_task_msg_t; - - -typedef enum -{ - STORAGE_TASK_DATA, - STORAGE_TASK_EXIT, -} storage_task_evt_t; - -storage_info_t storage_info; - -char *capture_name = NULL; - -bk_err_t storage_task_send_msg(uint8_t msg_type, uint32_t data) -{ - bk_err_t ret; - storages_task_msg_t msg; - - if (storage_task_queue) - { - msg.type = msg_type; - msg.data = data; - - ret = rtos_push_to_queue(&storage_task_queue, &msg, BEKEN_NO_WAIT); - if (kNoErr != ret) - { - os_printf("video_transfer_cpu1_send_msg failed\r\n"); - return kOverrunErr; - } - - return ret; - } - return kNoResourcesErr; -} - - -void storage_task_stop(void) -{ - storage_task_send_msg(STORAGE_TASK_EXIT, 0); - while (storage_task_thread) - { - rtos_delay_milliseconds(10); - } -} - -void storage_frame_buffer_dump(frame_buffer_t *frame, char *name) -{ - LOGI("%s dump frame: %d, %p, %u, size: %d\n", __func__, frame->id, frame->frame, frame->sequence, frame->length); - -#if (CONFIG_SDCARD_HOST) - FIL fp1; - unsigned int uiTemp = 0; - char file_name[50] = {0}; - - sprintf(file_name, "%d:/No.%d_%s", DISK_NUMBER_SDIO_SD, frame->sequence, name); - - FRESULT fr = f_open(&fp1, file_name, FA_CREATE_ALWAYS | FA_WRITE); - if (fr != FR_OK) - { - LOGE("can not open file: %s, error: %d\n", file_name, fr); - return; - } - - LOGI("open file:%s!\n", file_name); - - fr = f_write(&fp1, (char *)frame->frame, frame->length, &uiTemp); - if (fr != FR_OK) - { - LOGE("f_write failed 1 fr = %d\r\n", fr); - } - - f_close(&fp1); - - LOGI("%s, complete\n", __func__); -#endif -} - - -static void storage_capture_save(frame_buffer_t *frame) -{ - media_msg_t msg; - - LOGI("%s save frame: %d, size: %d", __func__, frame->id, frame->length); - -#if (CONFIG_SDCARD_HOST) - FIL fp1; - unsigned int uiTemp = 0; - char file_name[50] = {0}; - - sprintf(file_name, "%d:/%s", DISK_NUMBER_SDIO_SD, capture_name); - - FRESULT fr = f_open(&fp1, file_name, FA_CREATE_ALWAYS | FA_WRITE); - if (fr != FR_OK) - { - LOGE("can not open file: %s, error: %d\n", file_name, fr); - goto error; - } - - LOGI("open file:%s!\n", file_name); - - fr = f_write(&fp1, (char *)frame->frame, frame->length, &uiTemp); - if (fr != FR_OK) - { - LOGE("f_write failed 1 fr = %d\r\n", fr); - } - - f_close(&fp1); - - LOGI("%s, complete\n", __func__); - -error: - -#endif - - msg.event = EVENT_COM_FRAME_CAPTURE_FREE_IND; - msg.param = (uint32_t)frame; - media_send_msg(&msg); - - storage_info.capture_state = STORAGE_STATE_DISABLED; -} - -static void storage_task_entry(beken_thread_arg_t data) -{ - bk_err_t ret = BK_OK; - storages_task_msg_t msg; - - while (1) - { - ret = rtos_pop_from_queue(&storage_task_queue, &msg, BEKEN_WAIT_FOREVER); - - if (kNoErr == ret) - { - switch (msg.type) - { - case STORAGE_TASK_DATA: - storage_capture_save((frame_buffer_t *)msg.data); - break; - - case STORAGE_TASK_EXIT: - goto exit; - default: - break; - } - } - } - -exit: - - rtos_deinit_queue(&storage_task_queue); - storage_task_queue = NULL; - - storage_task_thread = NULL; - rtos_delete_thread(NULL); -} - -int storage_task_start(void) -{ - int ret; - - if (storage_task_queue == NULL) - { - ret = rtos_init_queue(&storage_task_queue, "trs_task_queue", sizeof(storages_task_msg_t), 60); - - if (kNoErr != ret) - { - LOGE("%s trs_task_queue init failed\n"); - goto error; - } - } - - if (storage_task_thread == NULL) - { - ret = rtos_create_thread(&storage_task_thread, - 4, - "storage_task_thread", - (beken_thread_function_t)storage_task_entry, - 4 * 1024, - NULL); - - if (kNoErr != ret) - { - LOGE("%s trs_task_thread init failed\n"); - goto error; - } - } - - return kNoErr; - -error: - - if (storage_task_queue) - { - rtos_deinit_queue(&storage_task_queue); - storage_task_queue = NULL; - } - - if (storage_task_thread) - { - storage_task_thread = NULL; - rtos_delete_thread(NULL); - } - - return kGeneralErr; -} - - -void storage_open_handle(void) -{ - LOGI("%s\n", __func__); - - LOGI("%s register camera init\n", __func__); -} - -void storage_capture_frame_callback(frame_buffer_t *frame) -{ - storage_task_send_msg(STORAGE_TASK_DATA, (uint32_t)frame); -} - - -void storage_capture_handle(param_pak_t *param) -{ - LOGI("%s, %s\n", __func__, (char *)param->param); - - if (storage_info.capture_state == STORAGE_STATE_ENABLED) - { - LOGI("%s already capture\n", __func__); - goto out; - } - - if (capture_name == NULL) - { - capture_name = (char *)os_malloc(32); - } - - os_memcpy(capture_name, (char *)param->param, 31); - capture_name[31] = 0; - - frame_buffer_frame_register(MODULE_CAPTURE, storage_capture_frame_callback); - - storage_info.capture_state = STORAGE_STATE_ENABLED; - -out: - MEDIA_EVT_RETURN(param, kNoErr); -} - -void storage_event_handle(uint32_t event, uint32_t param) -{ - switch (event) - { - case EVENT_STORAGE_OPEN_IND: - storage_open_handle(); - break; - - case EVENT_STORAGE_CAPTURE_IND: - storage_capture_handle((param_pak_t *)param); - break; - } -} - -storage_state_t get_storage_state(void) -{ - return storage_info.state; -} - -void set_storage_state(storage_state_t state) -{ - storage_info.state = state; -} - -void storage_init(void) -{ - os_memset(&storage_info, 0, sizeof(storage_info_t)); - - storage_info.state = STORAGE_STATE_DISABLED; - storage_info.capture_state = STORAGE_STATE_DISABLED; - storage_task_start(); -} - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/media/transfer/transfer_act.c b/bk7235/liteos_m/bk_sdk_armino/components/media/transfer/transfer_act.c deleted file mode 100755 index bb99efc..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/media/transfer/transfer_act.c +++ /dev/null @@ -1,539 +0,0 @@ -// Copyright (C) 2022 Beken Corporation -// -// 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 -#include -#include - -#include "media_core.h" -#include -#include -#include -#include - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - - -#include "bk_general_dma.h" - -#include "transfer_act.h" -#include "media_evt.h" - -#include "frame_buffer.h" - -#include "wlan_ui_pub.h" - -#include "bk_misc.h" - -#define TAG "transfer" - -#define LOGI(...) BK_LOGI(TAG, ##__VA_ARGS__) -#define LOGW(...) BK_LOGW(TAG, ##__VA_ARGS__) -#define LOGE(...) BK_LOGE(TAG, ##__VA_ARGS__) -#define LOGD(...) BK_LOGD(TAG, ##__VA_ARGS__) - -typedef struct -{ - uint8_t type; - uint32_t data; -} trs_task_msg_t; - -typedef enum -{ - TRS_TRANSFER_DATA, - TRS_TRANSFER_EXIT, -} trs_task_msg_type_t; - -typedef struct -{ - uint8_t id; - uint8_t eof; - uint8_t cnt; - uint8_t size; - uint8_t data[]; -} transfer_data_t; - - - -transfer_info_t transfer_info; - - -#define MAX_TX_SIZE (1472) -#define MAX_COPY_SIZE (1472 - sizeof(transfer_data_t)) -#define MAX_RETRY (10000) -#define RETRANSMITS_TIME (5) - -static beken_queue_t trs_task_queue = NULL; -static beken_thread_t trs_task_thread = NULL; - -extern media_debug_t *media_debug; - -transfer_data_t *wifi_tranfer_data = NULL; - -uint8_t frame_id = 0; -bool runing = false; - - -frame_buffer_t *wifi_tranfer_frame = NULL; - - -video_setup_t vido_transfer_info = {0}; - -uint32_t lost_size = 0; -uint32_t complete_size = 0; -uint32_t transfer_timer_us = 0; // unit us - -extern void rwnxl_set_video_transfer_flag(uint32_t video_transfer_flag); - -int dvp_frame_send(uint8_t *data, uint32_t size, uint32_t retry_max, uint32_t ms_time, uint32_t us_delay_time) -{ - int ret = BK_FAIL; - - if (!vido_transfer_info.send_func) - { - return ret; - } - - do - { - ret = vido_transfer_info.send_func(data, size); - - if (ret == size) - { - //LOGI("size: %d\n", size); - complete_size += size; - delay_us(us_delay_time); - break; - } - - //LOGI("retry\n"); - lost_size += size; - rtos_delay_milliseconds(ms_time); - } - while (retry_max-- && runing); - - return ret == size ? BK_OK : BK_FAIL; -} - -static void dvp_frame_handle(frame_buffer_t *buffer) -{ - uint32_t i; - uint32_t count = buffer->length / MAX_COPY_SIZE; - uint32_t tail = buffer->length % MAX_COPY_SIZE; - uint8_t id = frame_id++; - int ret; - - uint32_t delay_time = (transfer_timer_us / (count + 1)); - if (delay_time > 500) - delay_time -= 500; - - LOGD("id: %u, seq: %u, length: %u, size: %u\n", buffer->id, buffer->sequence, buffer->length, buffer->size); - wifi_tranfer_data->id = id; - wifi_tranfer_data->size = 0; - wifi_tranfer_data->eof = 0; - wifi_tranfer_data->cnt = 0; - - for (i = 0; i < count && runing; i++) - { - if ((tail == 0) && (i == count - 1)) - { - wifi_tranfer_data->eof = 1; - wifi_tranfer_data->cnt = count; - } - - dma_memcpy(wifi_tranfer_data->data, buffer->frame + (MAX_COPY_SIZE * i), MAX_COPY_SIZE); - - ret = dvp_frame_send((uint8_t *)wifi_tranfer_data, MAX_TX_SIZE, MAX_RETRY, RETRANSMITS_TIME, delay_time); - - if (ret != BK_OK) - { - LOGE("send failed\n"); - } - } - - if (tail) - { - wifi_tranfer_data->eof = 1; - wifi_tranfer_data->cnt = count + 1; - - /* fix for psram 4bytes alignment */ - dma_memcpy(wifi_tranfer_data->data, buffer->frame + (MAX_COPY_SIZE * i), (tail % 4) ? ((tail / 4 + 1) * 4) : tail); - - ret = dvp_frame_send((uint8_t *)wifi_tranfer_data, tail + sizeof(transfer_data_t), MAX_RETRY, RETRANSMITS_TIME, delay_time); - - if (ret != BK_OK) - { - LOGE("send failed\n"); - } - } - - media_debug->fps_wifi++; - - LOGD("seq: %u, length: %u, tail: %u, count: %u\n", id, buffer->length, tail, count); - - if (wifi_tranfer_frame) - { - media_msg_t msg; - - msg.event = EVENT_COM_FRAME_WIFI_FREE_IND; - msg.param = (uint32_t)buffer; - media_send_msg(&msg); - wifi_tranfer_frame = NULL; - } -} - -void transfer_dump(uint32_t ms) -{ - uint32_t lost = lost_size, complete = complete_size, speed; - lost_size = 0; - complete_size = 0; - - if (transfer_info.state == TRS_STATE_DISABLED) - { - return; - } - - lost = lost / 1024 / (ms / 1000); - complete = complete / 1024 / (ms / 1000); - speed = (complete * 8) / 1024; - - LOGI("Lost: %uKB/s, Complete: %uKB/s, Speed: %uMb/s\n", lost, complete, speed); -} - - -static void trs_task_entry(beken_thread_arg_t data) -{ - bk_err_t ret = BK_OK; - trs_task_msg_t msg; - - dvp_camera_device_t *dvp_device = NULL; - - dvp_device = bk_dvp_camera_get_device(); - - if (dvp_device == NULL || dvp_device->id == ID_UNKNOW) - { - LOGE("dvp camera was not init\n"); -#if (CONFIG_USB_UVC) - uvc_camera_device_t *uvc_device = NULL; - - uvc_device = bk_uvc_camera_get_device(); - - if (uvc_device == NULL) - { - LOGE("uvc camera was not init\n"); - goto exit; - } - - transfer_timer_us = 1000 * 1000 / uvc_device->fps; //us - LOGI("transfer_timer_us: %d, fps:%d\r\n", transfer_timer_us, uvc_device->fps); -#else - goto exit; -#endif - } - else - { - uint32_t fps = 20; - switch (dvp_device->fps) - { - case FPS5: - fps = 5; - break; - case FPS10: - fps = 10; - break; - case FPS15: - fps = 15; - break; - case FPS20: - fps = 20; - break; - case FPS25: - fps = 25; - break; - case FPS30: - fps = 30; - break; - } - - transfer_timer_us = 1000 * 1000 / fps - 1000;//us - LOGI("transfer_timer_us: %d, fps:%d\r\n", transfer_timer_us, fps); - } - - while (1) - { - ret = rtos_pop_from_queue(&trs_task_queue, &msg, BEKEN_WAIT_FOREVER); - - if (BK_OK == ret) - { - switch (msg.type) - { - case TRS_TRANSFER_DATA: - if (false == frame_buffer_get_state() && runing) - { - break; - } - dvp_frame_handle((frame_buffer_t *)msg.data); - break; - - case TRS_TRANSFER_EXIT: - goto exit; - default: - break; - } - } - } - -exit: - - if (wifi_tranfer_data != NULL) - { - os_free(wifi_tranfer_data); - wifi_tranfer_data = NULL; - } - - frame_id = 0; - - rtos_deinit_queue(&trs_task_queue); - trs_task_queue = NULL; - - trs_task_thread = NULL; - rtos_delete_thread(NULL); -} - -int transfer_task_start(video_setup_t *setup_cfg) -{ - int ret; - - os_memcpy(&vido_transfer_info, setup_cfg, sizeof(video_setup_t)); - media_debug->fps_wifi = 0; - - runing = true; - - if (wifi_tranfer_data == NULL) - { - wifi_tranfer_data = (transfer_data_t *) os_malloc(MAX_TX_SIZE); - } - - frame_id = 0; - - if (trs_task_queue == NULL) - { - ret = rtos_init_queue(&trs_task_queue, "trs_task_queue", sizeof(trs_task_msg_t), 60); - - if (BK_OK != ret) - { - LOGE("%s trs_task_queue init failed\n"); - goto error; - } - } - - if (trs_task_thread == NULL) - { - ret = rtos_create_thread(&trs_task_thread, - 4, - "trs_task_thread", - (beken_thread_function_t)trs_task_entry, - 4 * 1024, - NULL); - - if (BK_OK != ret) - { - LOGE("%s trs_task_thread init failed\n"); - goto error; - } - } - - return BK_OK; - -error: - - if (wifi_tranfer_frame) - { - media_msg_t msg; - - msg.event = EVENT_COM_FRAME_WIFI_FREE_IND; - msg.param = (uint32_t)wifi_tranfer_frame; - media_send_msg(&msg); - wifi_tranfer_frame = NULL; - } - - if (trs_task_queue) - { - rtos_deinit_queue(&trs_task_queue); - trs_task_queue = NULL; - } - - if (trs_task_thread) - { - trs_task_queue = NULL; - rtos_delete_thread(NULL); - } - - return BK_FAIL; -} - -bk_err_t transfer_task_send_msg(uint8_t msg_type, uint32_t data) -{ - bk_err_t ret; - trs_task_msg_t msg; - - if (trs_task_queue) - { - msg.type = msg_type; - msg.data = data; - - ret = rtos_push_to_queue(&trs_task_queue, &msg, BEKEN_NO_WAIT); - if (BK_OK != ret) - { - LOGE("video_transfer_cpu1_send_msg failed\r\n"); - return BK_FAIL; - } - - return ret; - } - return kNoResourcesErr; -} - - -void transfer_task_stop(void) -{ - runing = false; - transfer_task_send_msg(TRS_TRANSFER_EXIT, 0); - while (trs_task_thread) - { - rtos_delay_milliseconds(10); - } -} - -frame_buffer_t *get_wifi_transfer_frame(void) -{ - return wifi_tranfer_frame; -} - - -void transfer_frame_complete_callback(frame_buffer_t *buffer) -{ - LOGD("%s\n", __func__); - wifi_tranfer_frame = buffer; - - if (transfer_info.pause) - { - frame_buffer_free_request(buffer, MODULE_WIFI); - return; - } - - transfer_task_send_msg(TRS_TRANSFER_DATA, (uint32_t)buffer); -} - - -void transfer_open_handle(param_pak_t *param) -{ - video_setup_t *setup_cfg = (video_setup_t *)param->param; - - LOGI("%s ++\n", __func__); - - frame_buffer_frame_register(MODULE_WIFI, transfer_frame_complete_callback); - - transfer_task_start(setup_cfg); - - set_transfer_state(TRS_STATE_ENABLED); - - MEDIA_EVT_RETURN(param, BK_OK); - - LOGI("%s --\n", __func__); -} - -void transfer_close_handle(param_pak_t *param) -{ - LOGI("%s\n", __func__); - - wifi_tranfer_frame = NULL; - - transfer_task_stop(); - set_transfer_state(TRS_STATE_DISABLED); - - frame_buffer_frame_deregister(MODULE_WIFI); - - rwnxl_set_video_transfer_flag(false); - - bk_wlan_ps_enable(); - - MEDIA_EVT_RETURN(param, BK_OK); -} - -void transfer_pause_handle(param_pak_t *param) -{ - LOGI("%s, %d\n", __func__, param->param); - - GLOBAL_INT_DECLARATION(); - GLOBAL_INT_DISABLE(); - - transfer_info.pause = param->param; - - GLOBAL_INT_RESTORE(); - - MEDIA_EVT_RETURN(param, BK_OK); -} - - -void transfer_event_handle(uint32_t event, uint32_t param) -{ - switch (event) - { - case EVENT_TRANSFER_OPEN_IND: - transfer_open_handle((param_pak_t *)param); - break; - case EVENT_TRANSFER_CLOSE_IND: - transfer_close_handle((param_pak_t *)param); - break; - case EVENT_TRANSFER_PAUSE_IND: - transfer_pause_handle((param_pak_t *)param); - break; - } -} - -trs_state_t get_transfer_state(void) -{ - return transfer_info.state; -} - -void set_transfer_state(trs_state_t state) -{ - transfer_info.state = state; -} - -void transfer_init(void) -{ - transfer_info.state = TRS_STATE_DISABLED; - transfer_info.debug = false; - transfer_info.pause = false; -} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/os_source/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/components/os_source/CMakeLists.txt deleted file mode 100755 index dc0017b..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/components/os_source/CMakeLists.txt +++ /dev/null @@ -1,326 +0,0 @@ -if(CONFIG_FREERTOS) - if(CONFIG_FREERTOS_V9) - - set(incs - freertos_v9/portable/Keil/ARM968es - freertos_v9/include - ) - - set(srcs - freertos_v9/croutine.c - freertos_v9/event_groups.c - freertos_v9/list.c - freertos_v9/portable/Keil/ARM968es/port.c - freertos_v9/queue.c - freertos_v9/tasks.c - freertos_v9/timers.c - freertos_v9/portable/MemMang/heap_4.c - ) - - if(CONFIG_FULLY_HOSTED) - list(REMOVE_ITEM srcs freertos_v9/portable/MemMang/heap_4.c) - endif() - set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/freertos_v9/portable/Keil/ARM968es/port.c" PROPERTIES COMPILE_FLAGS "-marm") - elseif(CONFIG_FREERTOS_V10) - set(incs freertos_v10/include) - set(srcs - freertos_v10/croutine.c - freertos_v10/event_groups.c - freertos_v10/list.c - freertos_v10/queue.c - freertos_v10/tasks.c - freertos_v10/stream_buffer.c - freertos_v10/timers.c - freertos_v10/portable/MemMang/heap_4.c - ) - - if(CONFIG_ARCH_RISCV) - list(APPEND incs - freertos_v10/portable/GCC/RISC-V - freertos_v10/portable/GCC/RISC-V/chip_specific_extensions/Andes_V5_RV32RV64 - ) - - list(APPEND srcs - freertos_v10/portable/GCC/RISC-V/port.c - freertos_v10/portable/GCC/RISC-V/portASM.S - ) - - elseif(CONFIG_ARCH_CM33) - list(APPEND incs - freertos_v10/portable/GCC/ARM_CM33_NTZ/non_secure - ) - - list(APPEND srcs - freertos_v10/portable/GCC/ARM_CM33_NTZ/non_secure/port.c - freertos_v10/portable/GCC/ARM_CM33_NTZ/non_secure/portasm.c - freertos_v10/portable/Common/mpu_wrappers.c - ) - else() - list(APPEND incs - freertos_v10/portable/Keil/ARM968es - ) - - list(APPEND srcs - freertos_v10/portable/Keil/ARM968es/port.c - ) - set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/freertos_v10/portable/Keil/ARM968es/port.c" PROPERTIES COMPILE_FLAGS "-marm") - endif() - - if(CONFIG_FULLY_HOSTED) - list(REMOVE_ITEM srcs freertos_v10/portable/MemMang/heap_4.c) - endif() - endif() -elseif(CONFIG_LITEOS_M) - set(incs - liteos_m/config/ - liteos_m/components/exchook - liteos_m/components/cpup - liteos_m/components/power - # liteos_m/components/port - liteos_m/components/bounds_checking_function/include/ - liteos_m/kernel/include/ - liteos_m/kernel/arch/include/ - liteos_m/targets/bk72xx/ - # liteos_m/port/ - liteos_m/utils/ - liteos_m/kernel/arch/arm/arm9/gcc/ - ) - set(srcs - liteos_m/kernel/src/mm/los_membox.c - liteos_m/kernel/src/mm/los_memory.c - liteos_m/kernel/src/los_event.c - liteos_m/kernel/src/los_init.c - liteos_m/kernel/src/los_mux.c - liteos_m/kernel/src/los_queue.c - liteos_m/kernel/src/los_sem.c - liteos_m/kernel/src/los_swtmr.c - liteos_m/kernel/src/los_task.c - liteos_m/kernel/src/los_tick.c - liteos_m/kernel/src/los_sched.c - liteos_m/kernel/src/los_sortlink.c - liteos_m/components/bounds_checking_function/src/fscanf_s.c - liteos_m/components/bounds_checking_function/src/fwscanf_s.c - liteos_m/components/bounds_checking_function/src/gets_s.c - liteos_m/components/bounds_checking_function/src/memcpy_s.c - liteos_m/components/bounds_checking_function/src/memmove_s.c - liteos_m/components/bounds_checking_function/src/memset_s.c - liteos_m/components/bounds_checking_function/src/scanf_s.c - liteos_m/components/bounds_checking_function/src/securecutil.c - liteos_m/components/bounds_checking_function/src/secureinput_a.c - liteos_m/components/bounds_checking_function/src/secureinput_w.c - liteos_m/components/bounds_checking_function/src/secureprintoutput_a.c - liteos_m/components/bounds_checking_function/src/secureprintoutput_w.c - liteos_m/components/bounds_checking_function/src/snprintf_s.c - liteos_m/components/bounds_checking_function/src/sprintf_s.c - liteos_m/components/bounds_checking_function/src/sscanf_s.c - liteos_m/components/bounds_checking_function/src/strcat_s.c - liteos_m/components/bounds_checking_function/src/strcpy_s.c - liteos_m/components/bounds_checking_function/src/strncat_s.c - liteos_m/components/bounds_checking_function/src/strncpy_s.c - liteos_m/components/bounds_checking_function/src/strtok_s.c - liteos_m/components/bounds_checking_function/src/swprintf_s.c - liteos_m/components/bounds_checking_function/src/swscanf_s.c - liteos_m/components/bounds_checking_function/src/vfscanf_s.c - liteos_m/components/bounds_checking_function/src/vfwscanf_s.c - liteos_m/components/bounds_checking_function/src/vscanf_s.c - liteos_m/components/bounds_checking_function/src/vsnprintf_s.c - liteos_m/components/bounds_checking_function/src/vsprintf_s.c - liteos_m/components/bounds_checking_function/src/vsscanf_s.c - liteos_m/components/bounds_checking_function/src/vswprintf_s.c - liteos_m/components/bounds_checking_function/src/vswscanf_s.c - liteos_m/components/bounds_checking_function/src/vwscanf_s.c - liteos_m/components/bounds_checking_function/src/wcscat_s.c - liteos_m/components/bounds_checking_function/src/wcscpy_s.c - liteos_m/components/bounds_checking_function/src/wcsncat_s.c - liteos_m/components/bounds_checking_function/src/wcsncpy_s.c - liteos_m/components/bounds_checking_function/src/wcstok_s.c - liteos_m/components/bounds_checking_function/src/wmemcpy_s.c - liteos_m/components/bounds_checking_function/src/wmemmove_s.c - liteos_m/components/bounds_checking_function/src/wscanf_s.c - liteos_m/components/power/los_pm.c - liteos_m/components/exchook/los_exc_info.c - liteos_m/utils/los_error.c - liteos_m/utils/los_debug.c - liteos_m/kernel/arch/arm/arm9/gcc/los_context.c - liteos_m/kernel/arch/arm/arm9/gcc/los_interrupt.c - liteos_m/kernel/arch/arm/arm9/gcc/los_timer.c - liteos_m/targets/bk72xx/bk_los_timer.c - liteos_m/kernel/arch/arm/arm9/gcc/los_dispatch.S - liteos_m/kernel/arch/arm/arm9/gcc/los_exc.S - ) - set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/liteos_m/kernel/arch/arm/arm9/gcc/los_context.c" PROPERTIES COMPILE_FLAGS "-marm") - set_source_files_properties("${CMAKE_CURRENT_LIST_DIR}/liteos_m/kernel/arch/arm/arm9/gcc/los_interrupt.c" PROPERTIES COMPILE_FLAGS "-marm") -elseif(CONFIG_LITEOS_M_V3) - if(CONFIG_ARCH_RISCV) - set(incs - liteos_m_v3/config/ - liteos_m_v3/components/exchook - liteos_m_v3/components/cpup - liteos_m_v3/components/power - liteos_m_v3/components/bounds_checking_function/include/ - liteos_m_v3/components/backtrace/ - liteos_m_v3/kernel/include/ - liteos_m_v3/kernel/arch/include/ - liteos_m_v3/targets/bk72xx/ - liteos_m_v3/utils/ - liteos_m_v3/kernel/arch/risc-v/riscv32/gcc/ - liteos_m_v3/kernel/arch/risc-v/riscv32/gcc/asm - ) - set(srcs - liteos_m_v3/kernel/src/mm/los_membox.c - liteos_m_v3/kernel/src/mm/los_memory.c - liteos_m_v3/kernel/src/los_event.c - liteos_m_v3/kernel/src/los_init.c - liteos_m_v3/kernel/src/los_mux.c - liteos_m_v3/kernel/src/los_queue.c - liteos_m_v3/kernel/src/los_sem.c - liteos_m_v3/kernel/src/los_swtmr.c - liteos_m_v3/kernel/src/los_task.c - liteos_m_v3/kernel/src/los_tick.c - liteos_m_v3/kernel/src/los_sched.c - liteos_m_v3/kernel/src/los_sortlink.c - liteos_m_v3/components/bounds_checking_function/src/fscanf_s.c - liteos_m_v3/components/bounds_checking_function/src/fwscanf_s.c - liteos_m_v3/components/bounds_checking_function/src/gets_s.c - liteos_m_v3/components/bounds_checking_function/src/memcpy_s.c - liteos_m_v3/components/bounds_checking_function/src/memmove_s.c - liteos_m_v3/components/bounds_checking_function/src/memset_s.c - liteos_m_v3/components/bounds_checking_function/src/scanf_s.c - liteos_m_v3/components/bounds_checking_function/src/securecutil.c - liteos_m_v3/components/bounds_checking_function/src/secureinput_a.c - liteos_m_v3/components/bounds_checking_function/src/secureinput_w.c - liteos_m_v3/components/bounds_checking_function/src/secureprintoutput_a.c - liteos_m_v3/components/bounds_checking_function/src/secureprintoutput_w.c - liteos_m_v3/components/bounds_checking_function/src/snprintf_s.c - liteos_m_v3/components/bounds_checking_function/src/sprintf_s.c - liteos_m_v3/components/bounds_checking_function/src/sscanf_s.c - liteos_m_v3/components/bounds_checking_function/src/strcat_s.c - liteos_m_v3/components/bounds_checking_function/src/strcpy_s.c - liteos_m_v3/components/bounds_checking_function/src/strncat_s.c - liteos_m_v3/components/bounds_checking_function/src/strncpy_s.c - liteos_m_v3/components/bounds_checking_function/src/strtok_s.c - liteos_m_v3/components/bounds_checking_function/src/swprintf_s.c - liteos_m_v3/components/bounds_checking_function/src/swscanf_s.c - liteos_m_v3/components/bounds_checking_function/src/vfscanf_s.c - liteos_m_v3/components/bounds_checking_function/src/vfwscanf_s.c - liteos_m_v3/components/bounds_checking_function/src/vscanf_s.c - liteos_m_v3/components/bounds_checking_function/src/vsnprintf_s.c - liteos_m_v3/components/bounds_checking_function/src/vsprintf_s.c - liteos_m_v3/components/bounds_checking_function/src/vsscanf_s.c - liteos_m_v3/components/bounds_checking_function/src/vswprintf_s.c - liteos_m_v3/components/bounds_checking_function/src/vswscanf_s.c - liteos_m_v3/components/bounds_checking_function/src/vwscanf_s.c - liteos_m_v3/components/bounds_checking_function/src/wcscat_s.c - liteos_m_v3/components/bounds_checking_function/src/wcscpy_s.c - liteos_m_v3/components/bounds_checking_function/src/wcsncat_s.c - liteos_m_v3/components/bounds_checking_function/src/wcsncpy_s.c - liteos_m_v3/components/bounds_checking_function/src/wcstok_s.c - liteos_m_v3/components/bounds_checking_function/src/wmemcpy_s.c - liteos_m_v3/components/bounds_checking_function/src/wmemmove_s.c - liteos_m_v3/components/bounds_checking_function/src/wscanf_s.c - liteos_m_v3/components/power/los_pm.c - liteos_m_v3/components/exchook/los_exc_info.c - liteos_m_v3/utils/los_error.c - liteos_m_v3/utils/los_debug.c - liteos_m_v3/components/backtrace/los_backtrace.c - liteos_m_v3/kernel/arch/risc-v/riscv32/gcc/los_context.c - liteos_m_v3/kernel/arch/risc-v/riscv32/gcc/los_interrupt.c - # liteos_m_v3/kernel/arch/risc-v/riscv32/gcc/los_timer.c - liteos_m_v3/targets/bk72xx/bk_los_timer.c - liteos_m_v3/kernel/arch/risc-v/riscv32/gcc/los_dispatch.S - liteos_m_v3/kernel/arch/risc-v/riscv32/gcc/los_exc.S - ) - endif() -elseif(CONFIG_LITEOS_M_MST) - if(CONFIG_ARCH_RISCV) - set(bounds_dir "../../../../../../../../third_party/bounds_checking_function") - #set(bounds_dir "liteos_m_mst/components/bounds_checking_function") - set(kernel_dir "../../../../../../../../kernel/liteos_m") - set(incs - ${kernel_dir}/config/ - ${kernel_dir}/components/exchook - ${kernel_dir}/components/cpup - ${kernel_dir}/components/power - ${bounds_dir}/include/ - ${kernel_dir}/components/backtrace/ - ${kernel_dir}/kernel/include/ - ${kernel_dir}/arch/include/ - ${kernel_dir}/targets/bk72xx/ - ${kernel_dir}/utils/ - ${kernel_dir}/arch/risc-v/riscv32/gcc/ - ${kernel_dir}/arch/risc-v/riscv32/gcc/asm - ) - - set(srcs - ${kernel_dir}/kernel/src/mm/los_membox.c - ${kernel_dir}/kernel/src/mm/los_memory.c - ${kernel_dir}/kernel/src/los_event.c - ${kernel_dir}/kernel/src/los_init.c - ${kernel_dir}/kernel/src/los_mux.c - ${kernel_dir}/kernel/src/los_queue.c - ${kernel_dir}/kernel/src/los_sem.c - ${kernel_dir}/kernel/src/los_swtmr.c - ${kernel_dir}/kernel/src/los_task.c - ${kernel_dir}/kernel/src/los_tick.c - ${kernel_dir}/kernel/src/los_sched.c - ${kernel_dir}/kernel/src/los_sortlink.c - ${bounds_dir}/src/fscanf_s.c - ${bounds_dir}/src/fwscanf_s.c - ${bounds_dir}/src/gets_s.c - ${bounds_dir}/src/memcpy_s.c - ${bounds_dir}/src/memmove_s.c - ${bounds_dir}/src/memset_s.c - ${bounds_dir}/src/scanf_s.c - ${bounds_dir}/src/securecutil.c - ${bounds_dir}/src/secureinput_a.c - ${bounds_dir}/src/secureinput_w.c - ${bounds_dir}/src/secureprintoutput_a.c - ${bounds_dir}/src/secureprintoutput_w.c - ${bounds_dir}/src/snprintf_s.c - ${bounds_dir}/src/sprintf_s.c - ${bounds_dir}/src/sscanf_s.c - ${bounds_dir}/src/strcat_s.c - ${bounds_dir}/src/strcpy_s.c - ${bounds_dir}/src/strncat_s.c - ${bounds_dir}/src/strncpy_s.c - ${bounds_dir}/src/strtok_s.c - ${bounds_dir}/src/swprintf_s.c - ${bounds_dir}/src/swscanf_s.c - ${bounds_dir}/src/vfscanf_s.c - ${bounds_dir}/src/vfwscanf_s.c - ${bounds_dir}/src/vscanf_s.c - ${bounds_dir}/src/vsnprintf_s.c - ${bounds_dir}/src/vsprintf_s.c - ${bounds_dir}/src/vsscanf_s.c - ${bounds_dir}/src/vswprintf_s.c - ${bounds_dir}/src/vswscanf_s.c - ${bounds_dir}/src/vwscanf_s.c - ${bounds_dir}/src/wcscat_s.c - ${bounds_dir}/src/wcscpy_s.c - ${bounds_dir}/src/wcsncat_s.c - ${bounds_dir}/src/wcsncpy_s.c - ${bounds_dir}/src/wcstok_s.c - ${bounds_dir}/src/wmemcpy_s.c - ${bounds_dir}/src/wmemmove_s.c - ${bounds_dir}/src/wscanf_s.c - ${kernel_dir}/components/power/los_pm.c - ${kernel_dir}/components/exchook/los_exc_info.c - ${kernel_dir}/utils/los_error.c - ${kernel_dir}/utils/los_debug.c - ${kernel_dir}/components/backtrace/los_backtrace.c - ${kernel_dir}/arch/risc-v/riscv32/gcc/los_context.c - ${kernel_dir}/arch/risc-v/riscv32/gcc/los_interrupt.c - # ${kernel_dir}/arch/risc-v/riscv32/gcc/los_timer.c - #${kernel_dir}/targets/bk72xx/bk_los_timer.c - ${kernel_dir}/arch/risc-v/riscv32/gcc/los_timer.c - ${kernel_dir}/arch/risc-v/riscv32/gcc/los_dispatch.S - ${kernel_dir}/arch/risc-v/riscv32/gcc/los_exc.S - ) - endif() -endif() - - -armino_component_register(SRCS "${srcs}" - INCLUDE_DIRS "${incs}" - PRIV_REQUIRES bk_common bk_os) - diff --git a/bk7235/liteos_m/bk_sdk_armino/components/saradc_intf/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/saradc_intf/BUILD.gn new file mode 100755 index 0000000..657b1e1 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/saradc_intf/BUILD.gn @@ -0,0 +1,31 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") + +static_library(module_name) { + sources = [ "saradc_intf.c" ] + public_configs = [ + ":public", + "${beken_sdk_dir}/components/bk_os:public", + "${beken_sdk_dir}/components/temp_detect:public", + "${beken_sdk_dir}/middleware/driver:public", + ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/saradc_intf/saradc_intf.c b/bk7235/liteos_m/bk_sdk_armino/components/saradc_intf/saradc_intf.c new file mode 100755 index 0000000..f975d84 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/saradc_intf/saradc_intf.c @@ -0,0 +1,648 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include +#include "bk_arm_arch.h" +#include "bk_gpio.h" +#include "bk_uart.h" +#include "bk_saradc.h" +#include "temp_detect_pub.h" +#include "temp_detect.h" +#include "sys_rtos.h" +#include +#include "saradc_intf.h" +#include +#include "bk_fake_clock.h" +#include +#include "bk_sys_ctrl.h" + +#define TURING_ADC_TAG "saradc_intf" +#define TURING_ADC_TASK_PRIORITY (18) +#define TURING_ADC_TASK_STACK_SIZE (1024 * 1) +#define TURING_ADC_QITEM_COUNT (3) + +volatile uint8_t step_flag = 1; +volatile uint8_t adctest_flag = 1; +volatile uint8_t adc_accuracy = 0; + +enum { + TADC_TIMER_POLL = 0, + TADC_EXIT, +}; + +typedef struct tadc_message { + UINT32 data; +} TADC_MSG_T; + +typedef struct _tadc_entity_ { + beken_thread_t tadc_thread; + beken_queue_t msg_que; + beken_timer_t check_timer; + beken_semaphore_t sema_wait_end; + + ADC_OBJ *adc_obj_list; + beken_mutex_t obj_list_mutex; + + DD_HANDLE adc_handle; + saradc_desc_t adc_cfg; + UINT16 adc_data[ADC_TEMP_BUFFER_SIZE]; +} TADC_ENTITY_T; + +void saradc_calculate_step1(void); +void saradc_calculate_step2(void); + +static TADC_ENTITY_T *tadc_entity = NULL; + +void adc_obj_init(ADC_OBJ *handle, adc_obj_callback cb, UINT32 channel, void *user_data) +{ + if (handle) { + adc_obj_stop(handle); + os_memset(handle, 0, sizeof(ADC_OBJ)); + handle->channel = channel; + handle->user_data = user_data; + handle->cb = cb; + } +} + +int adc_obj_start(ADC_OBJ *handle) +{ + ADC_OBJ *target; + + if (!tadc_entity || (!tadc_entity->obj_list_mutex)) { + TADC_WARNING_PRINTF("adc obj start with no initial\r\n"); + return -1; + } + + rtos_lock_mutex(&tadc_entity->obj_list_mutex); + target = tadc_entity->adc_obj_list; + while (target) { + if (target == handle) { + rtos_unlock_mutex(&tadc_entity->obj_list_mutex); + return -1; //already exist. + } + target = target->next; + } + handle->next = tadc_entity->adc_obj_list; + tadc_entity->adc_obj_list = handle; + rtos_unlock_mutex(&tadc_entity->obj_list_mutex); + return 0; +} + +void adc_obj_stop(ADC_OBJ *handle) +{ + ADC_OBJ **curr; + + rtos_lock_mutex(&tadc_entity->obj_list_mutex); + for (curr = &tadc_entity->adc_obj_list; *curr;) { + ADC_OBJ *entry = *curr; + if (entry == handle) + *curr = entry->next; + else + curr = &entry->next; + } + rtos_unlock_mutex(&tadc_entity->obj_list_mutex); +} + +static void sadc_detect_handler(void) +{ + saradc_desc_t *p_ADC_drv_desc = &tadc_entity->adc_cfg; + + if (!p_ADC_drv_desc) + return; + + if (p_ADC_drv_desc->current_sample_data_cnt >= p_ADC_drv_desc->data_buff_size) { + UINT32 sum = 0, sum1, sum2; + + ddev_close(tadc_entity->adc_handle); + tadc_entity->adc_handle = DD_HANDLE_UNVALID; + saradc_ensure_close(); + + sum1 = p_ADC_drv_desc->pData[1] + p_ADC_drv_desc->pData[2]; + sum2 = p_ADC_drv_desc->pData[3] + p_ADC_drv_desc->pData[4]; + sum = sum1 / 2 + sum2 / 2; + sum = sum / 2; + + adc_accuracy = (uint8_t)saradc_check_accuracy(); + if (adc_accuracy != 0) + sum = sum >> (adc_accuracy - 1); + + p_ADC_drv_desc->pData[0] = sum; + + rtos_set_semaphore(&tadc_entity->sema_wait_end); + } +} + +void tadc_obj_handler(ADC_OBJ *handle) +{ + saradc_desc_t *p_ADC_drv_desc = NULL; + UINT32 status, ret; + GLOBAL_INT_DECLARATION(); + + p_ADC_drv_desc = &tadc_entity->adc_cfg; + + saradc_config_param_init(p_ADC_drv_desc); + + p_ADC_drv_desc->channel = handle->channel; + p_ADC_drv_desc->data_buff_size = ADC_TEMP_BUFFER_SIZE; + p_ADC_drv_desc->current_read_data_cnt = 0; + p_ADC_drv_desc->current_sample_data_cnt = 0; + p_ADC_drv_desc->has_data = 0; + p_ADC_drv_desc->pData = &tadc_entity->adc_data[0]; + os_memset(p_ADC_drv_desc->pData, 0x00, p_ADC_drv_desc->data_buff_size * sizeof(UINT16)); + + p_ADC_drv_desc->p_Int_Handler = sadc_detect_handler; + + ret = 0; + do { + GLOBAL_INT_DISABLE(); + if (saradc_check_busy() == 0) { + tadc_entity->adc_handle = ddev_open(DD_DEV_TYPE_SARADC, &status, (UINT32)p_ADC_drv_desc); + if (DD_HANDLE_UNVALID != tadc_entity->adc_handle) { + GLOBAL_INT_RESTORE(); + break; + } + } + GLOBAL_INT_RESTORE(); + rtos_delay_milliseconds(5); + ret++; + } while (ret < 5); + + if (ret == 5) { + TADC_WARNING_PRINTF("adc timeout\r\n"); + return; + } + + status = TURING_ADC_SCAN_INTERVALV; + ret = rtos_get_semaphore(&tadc_entity->sema_wait_end, status * bk_get_ticks_per_second()); + if (step_flag == 0) + saradc_calculate_step1(); + else + saradc_calculate_step2(); + + if (ret == kNoErr) { + + float voltage = 0.0; + int mv; + + if (adctest_flag == 0) + mv = p_ADC_drv_desc->pData[0]; + else { + voltage = saradc_calculate(p_ADC_drv_desc->pData[0]); + mv = voltage * 1000; + } + + if (handle->cb) + handle->cb(mv, handle->user_data); + } else + + TADC_WARNING_PRINTF("sema_wait_end timeout:%d\r\n", status); +} + +static void tadc_check_timer_poll_handle(void) +{ + ADC_OBJ *target; + + rtos_lock_mutex(&tadc_entity->obj_list_mutex); + for (target = tadc_entity->adc_obj_list; target; target = target->next) + tadc_obj_handler(target); + rtos_unlock_mutex(&tadc_entity->obj_list_mutex); +} + +void tadc_entity_deinit(TADC_ENTITY_T **adc_entity) +{ + TADC_WARNING_PRINTF("tadc_entity_deinit\r\n"); + if (*adc_entity) { + if ((*adc_entity)->sema_wait_end) { + rtos_deinit_semaphore(&((*adc_entity)->sema_wait_end)); + (*adc_entity)->sema_wait_end = NULL; + } + + if ((*adc_entity)->obj_list_mutex) { + rtos_deinit_mutex(&((*adc_entity)->obj_list_mutex)); + (*adc_entity)->obj_list_mutex = NULL; + } + + os_free((*adc_entity)); + *adc_entity = NULL; + } +} + +TADC_ENTITY_T *tadc_entity_init(void) +{ + TADC_ENTITY_T *adc_entity = NULL; + bk_err_t ret = 0; + + adc_entity = (TADC_ENTITY_T *) os_malloc(sizeof(TADC_ENTITY_T)); + if (adc_entity == NULL) { + TADC_FATAL_PRINTF("malloc TADC_ENTITY_T failed\r\n"); + return NULL; + } + + os_memset(adc_entity, 0, sizeof(TADC_ENTITY_T)); + TADC_WARNING_PRINTF("tc_entity_init\r\n"); + + ret = rtos_init_mutex(&adc_entity->obj_list_mutex); + if (ret != 0) { + TADC_FATAL_PRINTF("tc_entity->mutex error\r\n"); + tadc_entity_deinit(&adc_entity); + return NULL; + } + + ret = rtos_init_semaphore(&adc_entity->sema_wait_end, 1); + if (ret != 0) { + TADC_FATAL_PRINTF("tc_entity->sema_wait_end error\r\n"); + tadc_entity_deinit(&adc_entity); + return NULL; + } + + return adc_entity; +} + +#if (!CONFIG_SOC_BK7231) && (!CONFIG_SOC_BK7231N) && (!CONFIG_SOC_BK7236A) && (!CONFIG_SOC_BK7256XX) +/* +vol: PSRAM_VDD_1_8V + PSRAM_VDD_2_5V + PSRAM_VDD_3_3V +*/ +void saradc_config_vddram_voltage(UINT32 vol) +{ + UINT32 param; + + param = BLK_BIT_MIC_QSPI_RAM_OR_FLASH; + sddev_control(DD_DEV_TYPE_SCTRL, CMD_SCTRL_BLK_ENABLE, ¶m); + + param = vol; + sddev_control(DD_DEV_TYPE_SCTRL, CMD_QSPI_VDDRAM_VOLTAGE, ¶m); +} + +void saradc_disable_vddram_voltage(void) +{ + UINT32 param; + + param = BLK_BIT_MIC_QSPI_RAM_OR_FLASH; + sddev_control(DD_DEV_TYPE_SCTRL, CMD_SCTRL_BLK_DISABLE, ¶m); + +} +#endif + +void tadc_send_msg(UINT32 new_msg) +{ + bk_err_t ret; + TADC_MSG_T msg; + + if (tadc_entity->msg_que) { + msg.data = new_msg; + ret = rtos_push_to_queue(&tadc_entity->msg_que, &msg, BEKEN_NO_WAIT); + if (kNoErr != ret) + TADC_PRINTF("tadc_send_msg failed\r\n"); + } +} + +static void tadc_check_timer_callback(void *arg) +{ + UINT32 data = TADC_TIMER_POLL; + tadc_send_msg(data); +} + +static void tadc_thread_entry(beken_thread_arg_t data) +{ + bk_err_t err; + + TADC_WARNING_PRINTF("tadc_thread_entry\r\n"); + + err = rtos_init_queue(&tadc_entity->msg_que, + "tadc_msg_queue", + sizeof(TADC_MSG_T), + TURING_ADC_QITEM_COUNT); + if (kNoErr != err) { + TADC_FATAL_PRINTF("tadc_entity->msg_que\r\n"); + goto tadc_exit; + } + + err = rtos_init_timer(&tadc_entity->check_timer, + TURING_ADC_SCAN_INTERVALV, + tadc_check_timer_callback, + (void *)0); + BK_ASSERT(kNoErr == err); + + err = rtos_start_timer(&tadc_entity->check_timer); + BK_ASSERT(kNoErr == err); + + while (1) { + TADC_MSG_T msg; + err = rtos_pop_from_queue(&tadc_entity->msg_que, &msg, BEKEN_WAIT_FOREVER); + if (kNoErr == err) { + switch (msg.data) { + case TADC_TIMER_POLL: { + tadc_check_timer_poll_handle(); + break; + } + case TADC_EXIT: { + goto tadc_exit; + } + break; + default: + break; + } + } + } + +tadc_exit: + if (tadc_entity->check_timer.handle) { + err = rtos_deinit_timer(&tadc_entity->check_timer); + BK_ASSERT(kNoErr == err); + } + + if (tadc_entity->msg_que) { + rtos_deinit_queue(&tadc_entity->msg_que); + tadc_entity->msg_que = NULL; + } + + tadc_entity_deinit(&tadc_entity); + tadc_entity = NULL; + rtos_delete_thread(NULL); +} + +void saradc_work_create(void) +{ + bk_err_t result; + + TADC_WARNING_PRINTF("turing_adc_create\r\n"); + + if (tadc_entity) { + TADC_WARNING_PRINTF("aready turing_adc_create\r\n"); + return; + } + + tadc_entity = tadc_entity_init(); + if (NULL == tadc_entity) { + TADC_FATAL_PRINTF("turing_adc_create exceptional\r\n"); + goto create_exit; + } + + result = rtos_create_thread(&tadc_entity->tadc_thread, + TURING_ADC_TASK_PRIORITY, + TURING_ADC_TAG, + (beken_thread_function_t)tadc_thread_entry, + TURING_ADC_TASK_STACK_SIZE, + NULL); + if (result != kNoErr) { + TADC_FATAL_PRINTF("turing_adc_create exceptional\r\n"); + goto create_exit; + } + + TADC_WARNING_PRINTF("turing_adc_create done\r\n"); + return; + +create_exit: + + tadc_entity_deinit(&tadc_entity); +} + +#if (CONFIG_SARADC_CALI && (CONFIG_RTT)) +static void adc_check(int argc, char **argv) +{ + UINT32 status, ret; +#if CONFIG_FLASH_ORIGIN_API + DD_HANDLE flash_handle; +#endif + DD_HANDLE saradc_handle; + saradc_cal_val_t p_ADC_cal; + float voltage = 0.0; + saradc_desc_t *p_ADC_drv_desc = NULL; + GLOBAL_INT_DECLARATION(); + + if (argc < 2) + goto IDLE_CMD_ERR; + + if (0 == strcmp(argv[1], "read")) { + status = manual_cal_load_adc_cali_flash(); + if (status != 0) { + os_printf("Can't read cali value, use default!\r\n"); + os_printf("calibrate low value:[%x]\r\n", saradc_val.low); + os_printf("calibrate high value:[%x]\r\n", saradc_val.high); + } + } else if (0 == strcmp(argv[1], "set")) { + p_ADC_drv_desc = (saradc_desc_t *)malloc(sizeof(saradc_desc_t)); + if (p_ADC_drv_desc == NULL) { + os_printf("malloc1 failed!\r\n"); + return; + } + + os_memset(p_ADC_drv_desc, 0x00, sizeof(saradc_desc_t)); + saradc_config_param_init(p_ADC_drv_desc); + + p_ADC_drv_desc->channel = 1; + p_ADC_drv_desc->data_buff_size = ADC_TEMP_BUFFER_SIZE; + p_ADC_drv_desc->p_Int_Handler = NULL; + + p_ADC_drv_desc->has_data = 0; + p_ADC_drv_desc->current_read_data_cnt = 0; + p_ADC_drv_desc->current_sample_data_cnt = 0; + p_ADC_drv_desc->pData = (UINT16 *)malloc(p_ADC_drv_desc->data_buff_size * sizeof(UINT16)); + os_memset(p_ADC_drv_desc->pData, 0x00, p_ADC_drv_desc->data_buff_size * sizeof(UINT16)); + + if (p_ADC_drv_desc->pData == NULL) { + os_printf("malloc1 failed!\r\n"); + free(p_ADC_drv_desc); + return; + } + + ret = 0; + do { + GLOBAL_INT_DISABLE(); + if (saradc_check_busy() == 0) { + saradc_handle = ddev_open(DD_DEV_TYPE_SARADC, &status, (UINT32)p_ADC_drv_desc); + if (DD_HANDLE_UNVALID != saradc_handle) { + GLOBAL_INT_RESTORE(); + break; + } + } + GLOBAL_INT_RESTORE(); + + rtos_delay_milliseconds(5); + ret++; + } while (ret < 5); + + if (ret == 5) { + os_printf("saradc open failed!\r\n"); + free(p_ADC_drv_desc->pData); + free(p_ADC_drv_desc); + return; + } + + while (1) { + if (p_ADC_drv_desc->current_sample_data_cnt >= + p_ADC_drv_desc->data_buff_size) { + ddev_close(saradc_handle); + saradc_ensure_close(); + break; + } + } + + { + UINT32 sum = 0, sum1, sum2; + UINT16 *pData = p_ADC_drv_desc->pData; + sum1 = pData[1] + pData[2]; + sum2 = pData[3] + pData[4]; + sum = sum1 / 2 + sum2 / 2; + sum = sum / 2; + sum = sum / 4; + p_ADC_drv_desc->pData[0] = sum; + } + + if (0 == strcmp(argv[2], "low")) + p_ADC_cal.mode = SARADC_CALIBRATE_LOW; + else if (0 == strcmp(argv[2], "high")) + p_ADC_cal.mode = SARADC_CALIBRATE_HIGH; + else { + os_printf("invalid parameter\r\n"); + return; + } + p_ADC_cal.val = p_ADC_drv_desc->pData[0]; + if (SARADC_FAILURE == ddev_control(saradc_handle, SARADC_CMD_SET_CAL_VAL, (VOID *)&p_ADC_cal)) { + os_printf("set calibrate value failture\r\n"); + free(p_ADC_drv_desc->pData); + free(p_ADC_drv_desc); + return; + } + os_printf("set calibrate success\r\n"); + os_printf("type:[%s] value:[0x%x]\r\n", (p_ADC_cal.mode ? "high" : "low"), p_ADC_cal.val); + free(p_ADC_drv_desc->pData); + free(p_ADC_drv_desc); + } else if (0 == strcmp(argv[1], "write")) { + manual_cal_save_chipinfo_tab_to_flash(); + os_printf("calibrate low value:[%x]\r\n", saradc_val.low); + os_printf("calibrate high value:[%x]\r\n", saradc_val.high); + } else if (0 == strcmp(argv[1], "get")) { + p_ADC_drv_desc = (saradc_desc_t *)malloc(sizeof(saradc_desc_t)); + if (p_ADC_drv_desc == NULL) { + os_printf("malloc1 failed!\r\n"); + return; + } + + os_memset(p_ADC_drv_desc, 0x00, sizeof(saradc_desc_t)); + saradc_config_param_init(p_ADC_drv_desc); + p_ADC_drv_desc->p_Int_Handler = NULL; + + p_ADC_drv_desc->channel = 1; + if (argc > 2) + p_ADC_drv_desc->channel = atoi(argv[2]); + p_ADC_drv_desc->data_buff_size = ADC_TEMP_BUFFER_SIZE; + p_ADC_drv_desc->has_data = 0; + p_ADC_drv_desc->current_read_data_cnt = 0; + p_ADC_drv_desc->current_sample_data_cnt = 0; + p_ADC_drv_desc->pData = (UINT16 *)malloc(p_ADC_drv_desc->data_buff_size * sizeof(UINT16)); + os_memset(p_ADC_drv_desc->pData, 0x00, p_ADC_drv_desc->data_buff_size * sizeof(UINT16)); + + if (p_ADC_drv_desc->pData == NULL) { + os_printf("malloc1 failed!\r\n"); + free(p_ADC_drv_desc); + return; + } + + ret = 0; + do { + GLOBAL_INT_DISABLE(); + if (saradc_check_busy() == 0) { + saradc_handle = ddev_open(DD_DEV_TYPE_SARADC, &status, (UINT32)p_ADC_drv_desc); + if (DD_HANDLE_UNVALID != saradc_handle) { + GLOBAL_INT_RESTORE(); + break; + } + } + GLOBAL_INT_RESTORE(); + + rtos_delay_milliseconds(5); + ret++; + } while (ret < 5); + + if (ret == 5) { + os_printf("saradc open failed!\r\n"); + free(p_ADC_drv_desc->pData); + free(p_ADC_drv_desc); + return; + } + + while (1) { + if (p_ADC_drv_desc->current_sample_data_cnt >= p_ADC_drv_desc->data_buff_size) { + ddev_close(saradc_handle); + saradc_ensure_close(); + break; + } + } + + { + UINT32 sum = 0, sum1, sum2; + UINT16 *pData = p_ADC_drv_desc->pData; +#if (CONFIG_SOC_BK7231N) || (CONFIG_SOC_BK7236A) || (CONFIG_SOC_BK7256XX) + sum1 = pData[6] + pData[7]; + sum2 = pData[8] + pData[9]; +#else + sum1 = pData[1] + pData[2]; + sum2 = pData[3] + pData[4]; +#endif + sum = sum1 / 2 + sum2 / 2; + sum = sum / 2; + sum = sum / 4; + p_ADC_drv_desc->pData[0] = sum; + } + +#if (CONFIG_SOC_BK7231N) || (CONFIG_SOC_BK7236A) || (CONFIG_SOC_BK7256XX) + os_printf("saradc[ch%d]=%d\r\n", (UINT32)p_ADC_drv_desc->channel, (UINT32)p_ADC_drv_desc->pData[0]); +#else + voltage = saradc_calculate(p_ADC_drv_desc->pData[0]); + os_printf("voltage is [%d] mv\r\n", (UINT32)(voltage * 1000)); +#endif + free(p_ADC_drv_desc->pData); + free(p_ADC_drv_desc); + return; + } else + goto IDLE_CMD_ERR; + + return; +IDLE_CMD_ERR: + os_printf("Usage:ps [func] [param]\r\n"); +} + +MSH_CMD_EXPORT(adc_check, adc check); +#endif // (CONFIG_SARADC_CALI && (CONFIG_RTT)) + +static ADC_OBJ adc_test = {0}; + +void adc_detect_callback(int new_mv, void *user_data) +{ + ADC_OBJ *cfg = (ADC_OBJ *)user_data; + + TADC_WARNING_PRINTF("new:%d, %d\r\n", new_mv, cfg->channel); +} + +void adc_detect_configuration(UINT32 channel) +{ + TADC_WARNING_PRINTF("adc_detect %d, %d\r\n", channel, adc_test.channel); + + if (channel == adc_test.channel) + return; + + saradc_work_create(); + + if (adc_test.cb) + adc_obj_stop(&adc_test); + + adc_obj_init(&adc_test, adc_detect_callback, channel, &adc_test); + adc_obj_start(&adc_test); +} + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/security/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/security/BUILD.gn new file mode 100755 index 0000000..22f3c66 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/security/BUILD.gn @@ -0,0 +1,31 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") + +static_library(module_name) { + sources = [ "security_func.c" ] + public_configs = [ + ":public", + "${beken_sdk_dir}/components/bk_os:public", + "${beken_sdk_dir}/components/temp_detect:public", + "${beken_sdk_dir}/middleware/driver:public", + ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/security/security_func.c b/bk7235/liteos_m/bk_sdk_armino/components/security/security_func.c new file mode 100755 index 0000000..cc68a18 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/security/security_func.c @@ -0,0 +1,178 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 "sys_rtos.h" +#include +#include + +#include +#include +#include "security_func.h" + +#include +#include "bk_uart.h" + +#if (CONFIG_SOC_BK7251) +#include "bk_security.h" +#endif + + +#if (CONFIG_SOC_BK7251) +void sec_Command(char *pcWriteBuffer, int xWriteBufferLen, int argc, char **argv) +#if USE_SEC_TEST_CMD +{ + int sec = 0; + + if (argc > 5 || argc < 2) { + os_printf("Usage: sec.\r\n"); + return; + } + + if (0 == os_strcmp(argv[1], "aes")) { + unsigned char aes256_key[32] = {0x27, 0x73, 0x1a, 0xe6, 0x23, 0x4e, 0xd5, 0xab, 0xfb, 0x07, 0xd5, 0xc8, 0x69, 0x5f, 0x4a, 0x30, + 0x1c, 0x38, 0x2a, 0x09, 0x5b, 0x6f, 0x47, 0xd0, 0x2c, 0x9e, 0x1a, 0xf3, 0x0b, 0x54, 0x6d, 0x82 + }; + unsigned char aes256_block[16] = {0xa1, 0x2e, 0x84, 0x5c, 0x10, 0x93, 0xa6, 0x9f, 0x4e, 0xb0, 0x6d, 0xa4, 0x85, 0xa3, 0x8f, 0x5d}; + unsigned char aes256_ex_enc_expected[16] = {0x1b, 0x1e, 0x55, 0x4e, 0x65, 0xcb, 0x8d, 0x10, 0x9d, 0x95, 0x4e, 0xd4, 0x8d, 0xc2, 0xad, 0x6f}; + + + unsigned char aes256_enc_expected[16]; + unsigned char ex_aes256_block[16]; + void *ctx; + int i, key_len; + + if (argc == 3) { + key_len = os_strtoul(argv[2], NULL, 10);; + } else if (argc == 5) { + key_len = os_strtoul(argv[2], NULL, 10);; + + os_memset(aes256_block, 0, 16); + os_memset(aes256_key, 0, 32); + os_memcpy(aes256_block, argv[4], os_strlen(argv[4])); + os_memcpy(aes256_key, argv[3], os_strlen(argv[3])); + } else { + os_printf("Usage: sec aes_en key block\r\n"); + return; + } + + os_printf("key len%d: ", key_len); + for (i = 0; i < 32; i++) + os_printf("%x ", aes256_key[i]); + os_printf("\r\n"); + + os_printf("block: "); + for (i = 0; i < 16; i++) + os_printf("%x ", aes256_block[i]); + os_printf("\r\n"); + + os_printf("hw encrypt\r\n"); + ctx = hal_aes_init(aes256_key, key_len); + hal_aes_encrypt(ctx, aes256_block, aes256_enc_expected); + os_printf("en: "); + for (i = 0; i < 16; i++) + os_printf("%x ", aes256_enc_expected[i]); + os_printf("\r\n"); + + hal_aes_deinit(ctx); + + + os_printf("sw decrypt\r\n"); + ctx = aes_decrypt_init(aes256_key, key_len); + aes_decrypt(ctx, aes256_enc_expected, ex_aes256_block); + os_printf("de: "); + for (i = 0; i < 16; i++) + os_printf("%x ", ex_aes256_block[i]); + os_printf("\r\n"); + + aes_decrypt_deinit(ctx); + + if (0 != os_memcmp(aes256_block, ex_aes256_block, 16)) + os_printf("encrypt decrypt err\r\n"); + + + os_memset(aes256_enc_expected, 0, 16); + os_memset(ex_aes256_block, 0, 16); + + os_printf("sw encrypt\r\n"); + ctx = aes_encrypt_init(aes256_key, key_len); + aes_encrypt(ctx, aes256_block, aes256_enc_expected); + os_printf("en: "); + for (i = 0; i < 16; i++) + os_printf("%x ", aes256_enc_expected[i]); + os_printf("\r\n"); + + aes_encrypt_deinit(ctx); + + + os_printf("hw decrypt\r\n"); + ctx = hal_aes_init(aes256_key, key_len); + hal_aes_decrypt(ctx, aes256_enc_expected, ex_aes256_block); + os_printf("de: "); + for (i = 0; i < 16; i++) + os_printf("%x ", ex_aes256_block[i]); + os_printf("\r\n"); + hal_aes_deinit(ctx); + + } else if (0 == os_strcmp(argv[1], "sha1")) { + int i; + unsigned long sha_digst[16]; + void *ctx; + + os_memset(sha_digst, 0, 16 * 4); + + if (argc == 2) + argv[2] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; + + ctx = hal_sha1_init(); + + hal_sha1_update(ctx, argv[2], os_strlen(argv[2])); + hal_sha1_finish(ctx, (UINT8 *)sha_digst); + + os_printf("RESULT:"); + for (i = 0; i < 16 * 4; i++) + os_printf("%x ", ((UINT8 *)sha_digst)[i]); + os_printf("\r\n"); + + } else if (0 == os_strcmp(argv[1], "sha256")) { + int i; + unsigned long sha_digst[16]; + void *ctx; + + os_memset(sha_digst, 0, 16 * 4); + + if (argc == 2) + argv[2] = "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"; + + ctx = hal_sha256_init(); + + hal_sha256_update(ctx, argv[2], os_strlen(argv[2])); + hal_sha256_finish(ctx, (UINT8 *)sha_digst); + + os_printf("RESULT:"); + for (i = 0; i < 16 * 4; i++) + os_printf("%x ", ((UINT8 *)sha_digst)[i]); + os_printf("\r\n"); + + + } else if (0 == os_strcmp(argv[1], "sha256_st")) + hal_sha256_self_test(1); +} +#else +{ +} +#endif + +#endif + diff --git a/bk7235/liteos_m/bk_sdk_armino/components/temp_detect/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/temp_detect/BUILD.gn new file mode 100755 index 0000000..de190e1 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/temp_detect/BUILD.gn @@ -0,0 +1,31 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ "temp_detect.c" ] + public_configs = [ + ":public", + "${beken_sdk_dir}/components/bk_os:public", + "${beken_sdk_dir}/components/bk_wifi:public", + "${beken_sdk_dir}/middleware/driver:public", + "${beken_sdk_dir}/middleware/soc:public", + ] +} + +config("public") { + include_dirs = [ "." ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/components/utf8/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/components/utf8/BUILD.gn new file mode 100755 index 0000000..907b1bb --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/components/utf8/BUILD.gn @@ -0,0 +1,23 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ "conv_utf8.c" ] +} +config("public") { + include_dirs = [ "." ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/middleware/BUILD.gn new file mode 100755 index 0000000..383ad5e --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/BUILD.gn @@ -0,0 +1,18 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +module_name = get_path_info(rebase_path("."), "name") +module_group(module_name) { + modules = [] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/BUILD.gn new file mode 100755 index 0000000..31d6488 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/BUILD.gn @@ -0,0 +1,52 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +lite_component(module_name) { + features = [ ":riscv" ] +} + +static_library("riscv") { + sources = [ + "riscv/arch_interrupt.c", + "riscv/boot_handlers_base.S", + "riscv/boot_vectors_liteos_m.S", + "riscv/cache.c", + "riscv/initfini.c", + "riscv/pmp.c", + "riscv/reset.c", + "riscv/riscv.c", + "riscv/riscv_utility.S", + "riscv/stack_base.c", + "riscv/trap_base.c", + ] + include_dirs = [ + ".", + "riscv", + "${beken_sdk_dir}/middleware/driver/include/bk_private", + ] + public_configs = [ + ":public", + "${beken_sdk_dir}/components/bk_os:public", + ] +} +config("public") { + include_dirs = [ + "riscv/include", + "riscv/include/bk_private", + ] + ldflags = [ "-mstrict-align" ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/CMakeLists.txt index 3bdb93b..98f7130 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/CMakeLists.txt +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/CMakeLists.txt @@ -7,41 +7,41 @@ set(incs include/bk_private) set(srcs - boot_handlers_base.S - riscv_utility.S - stack_base.c - trap_base.c - arch_interrupt.c - reset.c - pmp.c - initfini.c - riscv.c - ) + boot_handlers_base.S + riscv_utility.S + stack_base.c + trap_base.c + arch_interrupt.c + reset.c + pmp.c + initfini.c + riscv.c + ) #if(CONFIG_CACHE_ENABLE) - list(APPEND srcs - cache.c - ) + list(APPEND srcs + cache.c + ) #endif() if(CONFIG_FREERTOS) - list(APPEND incs os/freertos) - list(APPEND srcs - os/freertos/cpu.c - boot_vectors_base.S - ) + list(APPEND incs os/freertos) + list(APPEND srcs + os/freertos/cpu.c + boot_vectors_base.S + ) endif() if(CONFIG_LITEOS_M_V3) - list(APPEND srcs - boot_vectors_liteos_m.S - ) + list(APPEND srcs + boot_vectors_liteos_m.S + ) endif() if(CONFIG_LITEOS_M_MST) - list(APPEND srcs - boot_vectors_liteos_m.S - ) + list(APPEND srcs + boot_vectors_liteos_m.S + ) endif() endif() diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/arch_interrupt.c b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/arch_interrupt.c index 1ac562d..b3707b9 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/arch_interrupt.c +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/arch_interrupt.c @@ -23,16 +23,16 @@ #define INT_PRIORITY_PLIC 0x01 #define INT_PRIORITY_MASK 0x07 - -#define REG_PLIC_PENDING_STATUS_GROUP1 (0xe4001000) //we can optimize this code with PLIC driver. + +#define REG_PLIC_PENDING_STATUS_GROUP1 (0xe4001000) //we can optimize this code with PLIC driver. #define REG_PLIC_PENDING_STATUS_GROUP2 (0xe4001004) #define NESTED_VPLIC_COMPLETE_INTERRUPT(irq) \ do { \ - clear_csr(NDS_MIE, MIP_MEIP); \ - __nds__plic_complete_interrupt(irq); \ - __asm volatile("fence io, io"); \ - set_csr(NDS_MIE, MIP_MEIP); \ + clear_csr(NDS_MIE, MIP_MEIP); \ + __nds__plic_complete_interrupt(irq); \ + __asm volatile("fence io, io"); \ + set_csr(NDS_MIE, MIP_MEIP); \ } while(0) #define CONFIG_NEST_INT_TEST 0 @@ -50,12 +50,12 @@ static volatile char trigger_pit_uart_msg_flag = 0; volatile unsigned int g_enter_interrupt_nest = 0; unsigned int arch_get_interrupt_nest_cnt(void) { - return g_enter_interrupt_nest; + return g_enter_interrupt_nest; } #if (CONFIG_NEST_INT_TEST) #define INT_SRC_UART0 (4) -#define SYS_DELAY_TIME_1MS (17000UL) +#define SYS_DELAY_TIME_1MS (17000UL) volatile unsigned int g_test_nest_count = 1; extern void sys_delay_sync(uint32_t time_count ); @@ -67,494 +67,494 @@ version that does not enable interrupts is provided below. THIS INTERRUPT HANDLER IS SPECIFIC TO FREERTOS WHICH USES PLIC! */ void mext_interrupt(void) { - unsigned int irq_source = __nds__plic_claim_interrupt(); - g_enter_interrupt_nest++; + unsigned int irq_source = __nds__plic_claim_interrupt(); + g_enter_interrupt_nest++; #if (CONFIG_NEST_INT_TEST) - if (g_enter_interrupt_nest > 1 && g_test_nest_count > 0) - { - os_printf("mext_interrupt: nest count %d, irq_source = %u.\r\n", g_enter_interrupt_nest, irq_source); - g_test_nest_count--; - } + if (g_enter_interrupt_nest > 1 && g_test_nest_count > 0) + { + os_printf("mext_interrupt: nest count %d, irq_source = %u.\r\n", g_enter_interrupt_nest, irq_source); + g_test_nest_count--; + } #endif //#if (CONFIG_NEST_INT_TEST) - + #if (CONFIG_NEST_INT_SUPPORT) - /* Disable the timer interrupts before - Enable interrupts in general to allow nested - */ - clear_csr(NDS_MIE, MIP_MTIP); + /* Disable the timer interrupts before + Enable interrupts in general to allow nested + */ + clear_csr(NDS_MIE, MIP_MTIP); - /* Enable interrupts in general to allow nested */ - set_csr(NDS_MSTATUS, MSTATUS_MIE); + /* Enable interrupts in general to allow nested */ + set_csr(NDS_MSTATUS, MSTATUS_MIE); #endif // #if (CONFIG_NEST_INT_SUPPORT) - if (irq_source != 0 && irq_source < INT_NUMBER_MAX - && p_intn_func_handle[irq_source] != NULL) { + if (irq_source != 0 && irq_source < INT_NUMBER_MAX + && p_intn_func_handle[irq_source] != NULL) { - #if( configUSE_ANDES_TRACER == 1 ) - traceISR_ENTER(irq_source); - #endif + #if( configUSE_ANDES_TRACER == 1 ) + traceISR_ENTER(irq_source); + #endif - /* Do interrupt handler */ - p_intn_func_handle[irq_source](); + /* Do interrupt handler */ + p_intn_func_handle[irq_source](); #if (CONFIG_NEST_INT_TEST) - if (irq_source != INT_SRC_UART0 && g_test_nest_count != 0) - { - sys_delay_sync(SYS_DELAY_TIME_1MS); - } + if (irq_source != INT_SRC_UART0 && g_test_nest_count != 0) + { + sys_delay_sync(SYS_DELAY_TIME_1MS); + } #endif //#if (CONFIG_NEST_INT_TEST) - #if( configUSE_ANDES_TRACER == 1 ) - traceISR_EXIT(); - #endif + #if( configUSE_ANDES_TRACER == 1 ) + traceISR_EXIT(); + #endif - } else { - //print irq status - os_printf("ERROR: func %s, irq_source = %u.\r\n", __func__, irq_source); - if (irq_source < INT_NUMBER_MAX) { - os_printf("ERROR: func %s, p_intn_func_handle = %p.\r\n", __func__, p_intn_func_handle[irq_source]); - } - } + } else { + //print irq status + os_printf("ERROR: func %s, irq_source = %u.\r\n", __func__, irq_source); + if (irq_source < INT_NUMBER_MAX) { + os_printf("ERROR: func %s, p_intn_func_handle = %p.\r\n", __func__, p_intn_func_handle[irq_source]); + } + } #if (CONFIG_NEST_INT_SUPPORT) - /* Disable interrupt in general to restore context */ - clear_csr(NDS_MSTATUS, MSTATUS_MIE); + /* Disable interrupt in general to restore context */ + clear_csr(NDS_MSTATUS, MSTATUS_MIE); - /* Restore the timer interrupts after - interrupts complete handle - */ - if (g_enter_interrupt_nest == 1) { - set_csr(NDS_MIE, MIP_MTIP); - } + /* Restore the timer interrupts after + interrupts complete handle + */ + if (g_enter_interrupt_nest == 1) { + set_csr(NDS_MIE, MIP_MTIP); + } #endif // #if (CONFIG_NEST_INT_SUPPORT) - g_enter_interrupt_nest--; - __nds__plic_complete_interrupt(irq_source); + g_enter_interrupt_nest--; + __nds__plic_complete_interrupt(irq_source); } void arch_interrupt_enable(void) { - volatile unsigned int i = 0; - for (i = 1; i < INT_NUMBER_MAX; i++) - { - HAL_INTERRUPT_SET_LEVEL(i, INT_PRIORITY_PLIC); //set default Priority. Priority level must be set > 0 - HAL_INTERRUPT_ENABLE(i); // Enable PLIC interrupt source - } + volatile unsigned int i = 0; + for (i = 1; i < INT_NUMBER_MAX; i++) + { + HAL_INTERRUPT_SET_LEVEL(i, INT_PRIORITY_PLIC); //set default Priority. Priority level must be set > 0 + HAL_INTERRUPT_ENABLE(i); // Enable PLIC interrupt source + } #if (CONFIG_NEST_INT_TEST) - arch_interrupt_set_priority(INT_SRC_UART0, 2); + arch_interrupt_set_priority(INT_SRC_UART0, 2); #endif //#if (CONFIG_NEST_INT_TEST) } void arch_interrupt_set_priority(arch_int_src_t int_number, uint32_t int_priority) { - if(int_number > 0 && int_number < INT_NUMBER_MAX) { - //set Priority for int. Priority level must be set > 0 and <=7 - HAL_INTERRUPT_SET_LEVEL(int_number, int_priority & INT_PRIORITY_MASK); - } + if(int_number > 0 && int_number < INT_NUMBER_MAX) { + //set Priority for int. Priority level must be set > 0 and <=7 + HAL_INTERRUPT_SET_LEVEL(int_number, int_priority & INT_PRIORITY_MASK); + } - return; + return; } void arch_interrupt_register_int(arch_int_src_t int_number, int_group_isr_t isr_callback) { if((int_number > (INT_ID_MAX-1))|| isr_callback == NULL) { - return; + return; } - - p_intn_func_handle[int_number] = isr_callback; + + p_intn_func_handle[int_number] = isr_callback; } void arch_interrupt_unregister_int(arch_int_src_t int_number) { if(int_number > (INT_ID_MAX-1)) { - return; + return; } - - p_intn_func_handle[int_number] = NULL; + + p_intn_func_handle[int_number] = NULL; } void setup_mtimer(void) { - HAL_MTIMER_INITIAL(); + HAL_MTIMER_INITIAL(); - /* Active machine timer */ - DEV_PLMT->MTIMECMP = DEV_PLMT->MTIME + MACHINE_TIMER_PERIOD; + /* Active machine timer */ + DEV_PLMT->MTIMECMP = DEV_PLMT->MTIME + MACHINE_TIMER_PERIOD; - HAL_MTIME_ENABLE(); + HAL_MTIME_ENABLE(); } void setup_mswi(void) { - HAL_MSWI_INITIAL(); - HAL_MSWI_ENABLE(); + HAL_MSWI_INITIAL(); + HAL_MSWI_ENABLE(); } void trigger_mswi(void) { - /* Trigger Machine software interrupt */ - HAL_MSWI_PENDING(); + /* Trigger Machine software interrupt */ + HAL_MSWI_PENDING(); } /////////////////////////////msi///////////////////////////////////////////////////////////// void mswi_handler(void) { - HAL_MSWI_CLEAR(); + HAL_MSWI_CLEAR(); - /* - * It is triggered by Machine mtime interrupt handler. - * Output messgaes to indicate Machine mtime is alive. - */ - if(trigger_mswi_uart_msg_flag) { - /* Clear UART output message trigger flag */ - trigger_mswi_uart_msg_flag = 0; + /* + * It is triggered by Machine mtime interrupt handler. + * Output messgaes to indicate Machine mtime is alive. + */ + if(trigger_mswi_uart_msg_flag) { + /* Clear UART output message trigger flag */ + trigger_mswi_uart_msg_flag = 0; - //printf("Message triggered from machine time interrupt\n"); - } + //printf("Message triggered from machine time interrupt\n"); + } - /* - * It is triggered by PIT interrupt handler. - * Output messgaes to indicate PLIC PIT is alive. - */ - if(trigger_pit_uart_msg_flag) { - /* Clear UART output message trigger flag */ - trigger_pit_uart_msg_flag = 0; + /* + * It is triggered by PIT interrupt handler. + * Output messgaes to indicate PLIC PIT is alive. + */ + if(trigger_pit_uart_msg_flag) { + /* Clear UART output message trigger flag */ + trigger_pit_uart_msg_flag = 0; - //printf("Message triggered from PLIC PIT interrupt\n"); - } + //printf("Message triggered from PLIC PIT interrupt\n"); + } } /////////////////////////mti//////////////////////////// void mtime_handler(void) { - /* Disable the timer interrupt to prevent reentry */ - HAL_MTIME_DISABLE(); + /* Disable the timer interrupt to prevent reentry */ + HAL_MTIME_DISABLE(); - /* Reset the timer to specified period */ - DEV_PLMT->MTIMECMP = DEV_PLMT->MTIME + MACHINE_TIMER_PERIOD; + /* Reset the timer to specified period */ + DEV_PLMT->MTIMECMP = DEV_PLMT->MTIME + MACHINE_TIMER_PERIOD; - /* Enable interrupts in general to allow nested */ - set_csr(NDS_MSTATUS, MSTATUS_MIE); + /* Enable interrupts in general to allow nested */ + set_csr(NDS_MSTATUS, MSTATUS_MIE); - /* - * Set the flag to trigger Machine software interrupt. - * The Machine SWI interrupt handler will output message to indicate - * Machine mtime is alive. - */ - // trigger_mswi_flag = 1; - trigger_mswi_uart_msg_flag = 1; + /* + * Set the flag to trigger Machine software interrupt. + * The Machine SWI interrupt handler will output message to indicate + * Machine mtime is alive. + */ + // trigger_mswi_flag = 1; + trigger_mswi_uart_msg_flag = 1; - /* Re-enable the timer interrupt. */ - HAL_MTIME_ENABLE(); + /* Re-enable the timer interrupt. */ + HAL_MTIME_ENABLE(); } //specify:low voltage process can't be interrupt or the system can't response external interrupt after wakeup. -void mtimer_reset_next_tick(uint32_t minimum_offset) -{ - if(DEV_PLMT->MTIMECMP < DEV_PLMT->MTIME + minimum_offset) - { - DEV_PLMT->MTIMECMP = DEV_PLMT->MTIME + minimum_offset; - } -} - -bool mtimer_is_timeout() -{ - return (DEV_PLMT->MTIMECMP <= DEV_PLMT->MTIME); -} +void mtimer_reset_next_tick(uint32_t minimum_offset) +{ + if(DEV_PLMT->MTIMECMP < DEV_PLMT->MTIME + minimum_offset) + { + DEV_PLMT->MTIMECMP = DEV_PLMT->MTIME + minimum_offset; + } +} + +bool mtimer_is_timeout() +{ + return (DEV_PLMT->MTIMECMP <= DEV_PLMT->MTIME); +} void arch_interrupt_init(void) { /* Disable the Machine external, timer and software interrupts until setup is done */ - clear_csr(NDS_MIE, MIP_MEIP | MIP_MTIP | MIP_MSIP); - clear_csr(NDS_MSTATUS, MSTATUS_MIE); /* Disable interrupts in general. */ + clear_csr(NDS_MIE, MIP_MEIP | MIP_MTIP | MIP_MSIP); + clear_csr(NDS_MSTATUS, MSTATUS_MIE); /* Disable interrupts in general. */ - /* Setup Machine mtime and software interrupt */ - setup_mtimer(); - setup_mswi(); - arch_interrupt_enable() ; //irq enabler + /* Setup Machine mtime and software interrupt */ + setup_mtimer(); + setup_mswi(); + arch_interrupt_enable() ; //irq enabler /* Disable the Machine external, timer and software interrupts until setup is done */ - clear_csr(NDS_MIE, MIP_MEIP | MIP_MTIP | MIP_MSIP); - clear_csr(NDS_MSTATUS, MSTATUS_MIE); /* Enable interrupts in general. */ + clear_csr(NDS_MIE, MIP_MEIP | MIP_MTIP | MIP_MSIP); + clear_csr(NDS_MSTATUS, MSTATUS_MIE); /* Enable interrupts in general. */ - // set_csr(NDS_MIE, MIP_MEIP | MIP_MTIP | MIP_MSIP); /* Enable the Machine External/Timer/Sofware interrupt bit in MIE. */ - //set_csr(NDS_MSTATUS, MSTATUS_MIE); /* Enable interrupts in general. */ + // set_csr(NDS_MIE, MIP_MEIP | MIP_MTIP | MIP_MSIP); /* Enable the Machine External/Timer/Sofware interrupt bit in MIE. */ + //set_csr(NDS_MSTATUS, MSTATUS_MIE); /* Enable interrupts in general. */ } bk_err_t arch_isr_entry_init(void) { // arch_interrupt_enable(); - arch_interrupt_init(); - return BK_OK; + arch_interrupt_init(); + return BK_OK; +} + +uint64_t arch_get_plic_pending_status(void) +{ + uint64_t plic_pend1 = *(volatile uint32 *)(REG_PLIC_PENDING_STATUS_GROUP1); + uint64_t plic_pend2 = *(volatile uint32 *)(REG_PLIC_PENDING_STATUS_GROUP2); + uint64_t plic_pending_status = (plic_pend2 << 32) | plic_pend1; + + return plic_pending_status; } - -uint64_t arch_get_plic_pending_status(void) -{ - uint64_t plic_pend1 = *(volatile uint32 *)(REG_PLIC_PENDING_STATUS_GROUP1); - uint64_t plic_pend2 = *(volatile uint32 *)(REG_PLIC_PENDING_STATUS_GROUP2); - uint64_t plic_pending_status = (plic_pend2 << 32) | plic_pend1; - - return plic_pending_status; -} #ifdef INT_VECTOR_EN void __attribute__ ((interrupt)) entry_irq1(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[1] != NULL) - (*(p_intn_func_handle[1]))() ; + (*(p_intn_func_handle[1]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(1); + NESTED_VPLIC_COMPLETE_INTERRUPT(1); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq2(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[2] != NULL) - (*(p_intn_func_handle[2]))() ; + (*(p_intn_func_handle[2]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(2); + NESTED_VPLIC_COMPLETE_INTERRUPT(2); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq3(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[3] != NULL) - (*(p_intn_func_handle[3]))() ; + (*(p_intn_func_handle[3]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(3); + NESTED_VPLIC_COMPLETE_INTERRUPT(3); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq4(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[4] != NULL) - (*(p_intn_func_handle[4]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(4); + (*(p_intn_func_handle[4]))() ; + NESTED_VPLIC_COMPLETE_INTERRUPT(4); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq5(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[5] != NULL) - (*(p_intn_func_handle[5]))() ; + (*(p_intn_func_handle[5]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(5); + NESTED_VPLIC_COMPLETE_INTERRUPT(5); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq6(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[6] != NULL) - (*(p_intn_func_handle[6]))() ; + (*(p_intn_func_handle[6]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(6); + NESTED_VPLIC_COMPLETE_INTERRUPT(6); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq7(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[7] != NULL) - (*(p_intn_func_handle[7]))() ; + (*(p_intn_func_handle[7]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(7); + NESTED_VPLIC_COMPLETE_INTERRUPT(7); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq8(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[8] != NULL) - (*(p_intn_func_handle[8]))() ; + (*(p_intn_func_handle[8]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(8); - NESTED_IRQ_EXIT(); + NESTED_VPLIC_COMPLETE_INTERRUPT(8); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq9(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[9] != NULL) - (*(p_intn_func_handle[9]))() ; + (*(p_intn_func_handle[9]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(9); + NESTED_VPLIC_COMPLETE_INTERRUPT(9); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq10(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[10] != NULL) - (*(p_intn_func_handle[10]))() ; + (*(p_intn_func_handle[10]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(10); + NESTED_VPLIC_COMPLETE_INTERRUPT(10); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq11(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[11] != NULL) - (*(p_intn_func_handle[11]))() ; + (*(p_intn_func_handle[11]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(11); + NESTED_VPLIC_COMPLETE_INTERRUPT(11); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq12(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[12] != NULL) - (*(p_intn_func_handle[12]))() ; + (*(p_intn_func_handle[12]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(12); + NESTED_VPLIC_COMPLETE_INTERRUPT(12); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq13(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[13] != NULL) - (*(p_intn_func_handle[13]))() ; + (*(p_intn_func_handle[13]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(13); + NESTED_VPLIC_COMPLETE_INTERRUPT(13); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq14(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[14] != NULL) - (*(p_intn_func_handle[14]))() ; + (*(p_intn_func_handle[14]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(14); + NESTED_VPLIC_COMPLETE_INTERRUPT(14); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq15(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[15] != NULL) - (*(p_intn_func_handle[15]))() ; + (*(p_intn_func_handle[15]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(15); + NESTED_VPLIC_COMPLETE_INTERRUPT(15); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq16(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[16] != NULL) - (*(p_intn_func_handle[16]))() ; + (*(p_intn_func_handle[16]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(16); + NESTED_VPLIC_COMPLETE_INTERRUPT(16); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq17(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[17] != NULL) - (*(p_intn_func_handle[17]))() ; + (*(p_intn_func_handle[17]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(17); + NESTED_VPLIC_COMPLETE_INTERRUPT(17); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq18(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[18] != NULL) - (*(p_intn_func_handle[18]))() ; + (*(p_intn_func_handle[18]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(18); + NESTED_VPLIC_COMPLETE_INTERRUPT(18); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq19(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[19] != NULL) - (*(p_intn_func_handle[19]))() ; + (*(p_intn_func_handle[19]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(19); + NESTED_VPLIC_COMPLETE_INTERRUPT(19); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq20(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[20] != NULL) - (*(p_intn_func_handle[20]))() ; + (*(p_intn_func_handle[20]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(20); + NESTED_VPLIC_COMPLETE_INTERRUPT(20); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq21(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[21] != NULL) - (*(p_intn_func_handle[21]))() ; + (*(p_intn_func_handle[21]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(21); + NESTED_VPLIC_COMPLETE_INTERRUPT(21); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } @@ -562,524 +562,524 @@ void __attribute__ ((interrupt)) entry_irq21(void) void __attribute__ ((interrupt)) entry_irq22(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[22] != NULL) - (*(p_intn_func_handle[22]))() ; + (*(p_intn_func_handle[22]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(22); + NESTED_VPLIC_COMPLETE_INTERRUPT(22); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq23(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[23] != NULL) - (*(p_intn_func_handle[23]))() ; + (*(p_intn_func_handle[23]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(23); + NESTED_VPLIC_COMPLETE_INTERRUPT(23); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq24(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[24] != NULL) - (*(p_intn_func_handle[24]))() ; + (*(p_intn_func_handle[24]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(24); + NESTED_VPLIC_COMPLETE_INTERRUPT(24); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq25(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[25] != NULL) - (*(p_intn_func_handle[25]))() ; + (*(p_intn_func_handle[25]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(25); + NESTED_VPLIC_COMPLETE_INTERRUPT(25); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq26(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[26] != NULL) - (*(p_intn_func_handle[26]))() ; + (*(p_intn_func_handle[26]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(26); + NESTED_VPLIC_COMPLETE_INTERRUPT(26); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq27(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[27] != NULL) - (*(p_intn_func_handle[27]))() ; + (*(p_intn_func_handle[27]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(27); + NESTED_VPLIC_COMPLETE_INTERRUPT(27); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq28(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[28] != NULL) - (*(p_intn_func_handle[28]))() ; + (*(p_intn_func_handle[28]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(28); + NESTED_VPLIC_COMPLETE_INTERRUPT(28); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq29(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[29] != NULL) - (*(p_intn_func_handle[29]))() ; + (*(p_intn_func_handle[29]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(29); + NESTED_VPLIC_COMPLETE_INTERRUPT(29); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq30(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[30] != NULL) - (*(p_intn_func_handle[30]))() ; + (*(p_intn_func_handle[30]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(30); + NESTED_VPLIC_COMPLETE_INTERRUPT(30); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq31(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[31] != NULL) - (*(p_intn_func_handle[31]))() ; + (*(p_intn_func_handle[31]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(31); + NESTED_VPLIC_COMPLETE_INTERRUPT(31); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq32(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[32] != NULL) - (*(p_intn_func_handle[32]))() ; + (*(p_intn_func_handle[32]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(32); + NESTED_VPLIC_COMPLETE_INTERRUPT(32); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq33(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[33] != NULL) - (*(p_intn_func_handle[33]))() ; + (*(p_intn_func_handle[33]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(33); + NESTED_VPLIC_COMPLETE_INTERRUPT(33); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq34(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[34] != NULL) - (*(p_intn_func_handle[34]))() ; + (*(p_intn_func_handle[34]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(34); + NESTED_VPLIC_COMPLETE_INTERRUPT(34); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq35(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[35] != NULL) - (*(p_intn_func_handle[35]))() ; + (*(p_intn_func_handle[35]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(35); + NESTED_VPLIC_COMPLETE_INTERRUPT(35); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq36(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[36] != NULL) - (*(p_intn_func_handle[36]))() ; + (*(p_intn_func_handle[36]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(36); + NESTED_VPLIC_COMPLETE_INTERRUPT(36); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq37(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[37] != NULL) - (*(p_intn_func_handle[37]))() ; + (*(p_intn_func_handle[37]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(37); + NESTED_VPLIC_COMPLETE_INTERRUPT(37); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq38(void) { - NESTED_IRQ_ENTER(); - + NESTED_IRQ_ENTER(); + if(p_intn_func_handle[38] != NULL) - (*(p_intn_func_handle[38]))() ; + (*(p_intn_func_handle[38]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(38); + NESTED_VPLIC_COMPLETE_INTERRUPT(38); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq39(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[39] != NULL) - (*(p_intn_func_handle[39]))() ; + (*(p_intn_func_handle[39]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(39); + NESTED_VPLIC_COMPLETE_INTERRUPT(39); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq40(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[40] != NULL) - (*(p_intn_func_handle[40]))() ; + (*(p_intn_func_handle[40]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(40); + NESTED_VPLIC_COMPLETE_INTERRUPT(40); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq41(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[41] != NULL) - (*(p_intn_func_handle[41]))() ; + (*(p_intn_func_handle[41]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(41); + NESTED_VPLIC_COMPLETE_INTERRUPT(41); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq42(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[42] != NULL) - (*(p_intn_func_handle[42]))() ; + (*(p_intn_func_handle[42]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(42); + NESTED_VPLIC_COMPLETE_INTERRUPT(42); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq43(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[43] != NULL) - (*(p_intn_func_handle[43]))() ; + (*(p_intn_func_handle[43]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(43); + NESTED_VPLIC_COMPLETE_INTERRUPT(43); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq44(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[44] != NULL) - (*(p_intn_func_handle[44]))() ; + (*(p_intn_func_handle[44]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(44); + NESTED_VPLIC_COMPLETE_INTERRUPT(44); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq45(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[45] != NULL) - (*(p_intn_func_handle[45]))() ; + (*(p_intn_func_handle[45]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(45); + NESTED_VPLIC_COMPLETE_INTERRUPT(45); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq46(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[46] != NULL) - (*(p_intn_func_handle[46]))() ; + (*(p_intn_func_handle[46]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(46); + NESTED_VPLIC_COMPLETE_INTERRUPT(46); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq47(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[47] != NULL) - (*(p_intn_func_handle[47]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(47); + (*(p_intn_func_handle[47]))() ; + NESTED_VPLIC_COMPLETE_INTERRUPT(47); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq48(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[48] != NULL) - (*(p_intn_func_handle[48]))() ; + (*(p_intn_func_handle[48]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(48); + NESTED_VPLIC_COMPLETE_INTERRUPT(48); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq49(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[49] != NULL) - (*(p_intn_func_handle[49]))() ; + (*(p_intn_func_handle[49]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(49); + NESTED_VPLIC_COMPLETE_INTERRUPT(49); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq50(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[50] != NULL) - (*(p_intn_func_handle[50]))() ; + (*(p_intn_func_handle[50]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(50); + NESTED_VPLIC_COMPLETE_INTERRUPT(50); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq51(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[51] != NULL) - (*(p_intn_func_handle[51]))() ; + (*(p_intn_func_handle[51]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(51); + NESTED_VPLIC_COMPLETE_INTERRUPT(51); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq52(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[52] != NULL) - (*(p_intn_func_handle[52]))() ; + (*(p_intn_func_handle[52]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(52); + NESTED_VPLIC_COMPLETE_INTERRUPT(52); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq53(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[53] != NULL) - (*(p_intn_func_handle[53]))() ; + (*(p_intn_func_handle[53]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(53); + NESTED_VPLIC_COMPLETE_INTERRUPT(53); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq54(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[54] != NULL) - (*(p_intn_func_handle[54]))() ; + (*(p_intn_func_handle[54]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(54); + NESTED_VPLIC_COMPLETE_INTERRUPT(54); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq55(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[55] != NULL) - (*(p_intn_func_handle[55]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(55); + (*(p_intn_func_handle[55]))() ; + NESTED_VPLIC_COMPLETE_INTERRUPT(55); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq56(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[56] != NULL) - (*(p_intn_func_handle[56]))() ; + (*(p_intn_func_handle[56]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(56); + NESTED_VPLIC_COMPLETE_INTERRUPT(56); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq57(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[57] != NULL) - (*(p_intn_func_handle[57]))() ; + (*(p_intn_func_handle[57]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(57); + NESTED_VPLIC_COMPLETE_INTERRUPT(57); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq58(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[58] != NULL) - (*(p_intn_func_handle[58]))() ; + (*(p_intn_func_handle[58]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(58); + NESTED_VPLIC_COMPLETE_INTERRUPT(58); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq59(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[59] != NULL) - (*(p_intn_func_handle[59]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(59); + (*(p_intn_func_handle[59]))() ; + NESTED_VPLIC_COMPLETE_INTERRUPT(59); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq60(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[60] != NULL) - (*(p_intn_func_handle[60]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(60); + (*(p_intn_func_handle[60]))() ; + NESTED_VPLIC_COMPLETE_INTERRUPT(60); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq61(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[61] != NULL) - (*(p_intn_func_handle[61]))() ; + (*(p_intn_func_handle[61]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(61); + NESTED_VPLIC_COMPLETE_INTERRUPT(61); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq62(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[62] != NULL) - (*(p_intn_func_handle[62]))() ; + (*(p_intn_func_handle[62]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(62); + NESTED_VPLIC_COMPLETE_INTERRUPT(62); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } void __attribute__ ((interrupt)) entry_irq63(void) { - NESTED_IRQ_ENTER(); + NESTED_IRQ_ENTER(); if(p_intn_func_handle[63] != NULL) - (*(p_intn_func_handle[63]))() ; + (*(p_intn_func_handle[63]))() ; - NESTED_VPLIC_COMPLETE_INTERRUPT(63); + NESTED_VPLIC_COMPLETE_INTERRUPT(63); - NESTED_IRQ_EXIT(); + NESTED_IRQ_EXIT(); } #endif diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_handlers_base.S b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_handlers_base.S index 342541e..bdb961b 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_handlers_base.S +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_handlers_base.S @@ -18,9 +18,9 @@ .globl boot_reset boot_reset: - //Clear Registers + //Clear Registers - /* start main entry*/ - call entry_main - call . + /* start main entry*/ + call entry_main + call . diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_vectors_base.S b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_vectors_base.S index be60830..a11aef1 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_vectors_base.S +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_vectors_base.S @@ -15,99 +15,99 @@ #include "core_v5.h" - .section .nds_vector, "ax" + .section .nds_vector, "ax" .option push .option norelax - .global reset_vector + .global reset_vector reset_vector: - /* Decide whether this is an NMI or cold reset */ - csrr t0, mcause - bnez t0, nmi_handler - .global _start - .type _start,@function + /* Decide whether this is an NMI or cold reset */ + csrr t0, mcause + bnez t0, nmi_handler + .global _start + .type _start,@function _start: #ifndef CACHE_DISABLE /* enable icache */ - csrr a5,mcache_ctl - ori a5,a5,1 - csrw mcache_ctl,a5 + csrr a5,mcache_ctl + ori a5,a5,1 + csrw mcache_ctl,a5 /* enable dcache */ - csrr a5,mcache_ctl - ori a5,a5,2 - csrw mcache_ctl,a5 + csrr a5,mcache_ctl + ori a5,a5,2 + csrw mcache_ctl,a5 #endif - /* Initialize global pointer */ - .option push - .option norelax - la gp, __global_pointer$ - .option pop + /* Initialize global pointer */ + .option push + .option norelax + la gp, __global_pointer$ + .option pop - /* Initialize stack pointer */ - la t0, _stack - mv sp, t0 + /* Initialize stack pointer */ + la t0, _stack + mv sp, t0 #ifdef __nds_execit - /* Initialize EXEC.IT table */ - la t0, _ITB_BASE_ - csrw uitb, t0 + /* Initialize EXEC.IT table */ + la t0, _ITB_BASE_ + csrw uitb, t0 #endif #ifdef __riscv_flen - /* Enable FPU */ - li t0, MSTATUS_FS - csrrs t0, mstatus, t0 + /* Enable FPU */ + li t0, MSTATUS_FS + csrrs t0, mstatus, t0 - /* Initialize FCSR */ - fscsr zero + /* Initialize FCSR */ + fscsr zero #endif - /* Initial machine trap-vector Base. Use FreeRTOS trap function. */ + /* Initial machine trap-vector Base. Use FreeRTOS trap function. */ #ifdef INT_VECTOR_EN - la t0, __vectors - #else - la t0, freertos_risc_v_trap_handler + la t0, __vectors + #else + la t0, freertos_risc_v_trap_handler #endif - csrw mtvec, t0 + csrw mtvec, t0 - /* Enable vectored external PLIC interrupt */ - #ifdef INT_VECTOR_EN - csrsi mmisc_ctl, 2 - #endif + /* Enable vectored external PLIC interrupt */ + #ifdef INT_VECTOR_EN + csrsi mmisc_ctl, 2 + #endif #ifndef CACHE_DISABLE - /* Enable I/D cache with HW prefetcher and D-cache write-around (threshold: 4 cache lines) */ - li t0, (0x3 << 13) - csrc mcache_ctl, t0 - li t0, (1 << 13) | (1 << 10) | (1 << 9) | (0x3) - csrs mcache_ctl, t0 + /* Enable I/D cache with HW prefetcher and D-cache write-around (threshold: 4 cache lines) */ + li t0, (0x3 << 13) + csrc mcache_ctl, t0 + li t0, (1 << 13) | (1 << 10) | (1 << 9) | (0x3) + csrs mcache_ctl, t0 #endif - /* Do system low level setup. It must be a leaf function */ - call __platform_init + /* Do system low level setup. It must be a leaf function */ + call __platform_init - /* System reset handler */ - call reset_handler + /* System reset handler */ + call reset_handler - /* Infinite loop, if returned accidently */ -1: j 1b + /* Infinite loop, if returned accidently */ +1: j 1b - .weak __platform_init + .weak __platform_init __platform_init: - ret + ret - .weak nmi_handler + .weak nmi_handler nmi_handler: - csrr a0, mcause - mv a1, ra - call user_nmi_handler - li t0, TRAP_M_USER_NP - csrw mcause, t0 - j freertos_risc_v_trap_handler - ret + csrr a0, mcause + mv a1, ra + call user_nmi_handler + li t0, TRAP_M_USER_NP + csrw mcause, t0 + j freertos_risc_v_trap_handler + ret .org 0x100 .word 0x32374B42 @@ -125,53 +125,53 @@ nmi_handler: .word 0x00000000 .word 0x00000000 .option pop - .section .text + .section .text - .global trap_entry - .align 2 + .global trap_entry + .align 2 trap_entry: - li t0, TRAP_M_USER_ASSERT - csrw mcause, t0 - j freertos_risc_v_trap_handler - ret + li t0, TRAP_M_USER_ASSERT + csrw mcause, t0 + j freertos_risc_v_trap_handler + ret #ifdef INT_VECTOR_EN - .text + .text - .global default_irq_entry - .align 2 + .global default_irq_entry + .align 2 default_irq_entry: -1: j 1b +1: j 1b .macro INTERRUPT num - .weak entry_irq\num - .set entry_irq\num, default_irq_entry - .long entry_irq\num - .endm + .weak entry_irq\num + .set entry_irq\num, default_irq_entry + .long entry_irq\num + .endm - /* Vector table - * NOTE: - * The Vector Table base alignment requirement has to be : - * " 2^ceiling(log2(N)) x 4 " bytes, - * if the PLIC device supports N interrupt sources. - */ + /* Vector table + * NOTE: + * The Vector Table base alignment requirement has to be : + * " 2^ceiling(log2(N)) x 4 " bytes, + * if the PLIC device supports N interrupt sources. + */ #define VECTOR_NUMINTRS 63 - .section .vector_table, "a" + .section .vector_table, "a" - .global __vectors -// .balign 4096 + .global __vectors +// .balign 4096 .balign 128 __vectors: - /* Trap vector */ - .long trap_entry + /* Trap vector */ + .long trap_entry - /* PLIC interrupt vector */ - .altmacro - .set irqno, 1 - .rept VECTOR_NUMINTRS - INTERRUPT %irqno - .set irqno, irqno+1 - .endr + /* PLIC interrupt vector */ + .altmacro + .set irqno, 1 + .rept VECTOR_NUMINTRS + INTERRUPT %irqno + .set irqno, irqno+1 + .endr #endif diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_vectors_liteos_m.S b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_vectors_liteos_m.S index 0c2534e..bbfe11e 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_vectors_liteos_m.S +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/boot_vectors_liteos_m.S @@ -15,106 +15,106 @@ #include "core_v5.h" - .section .nds_vector, "ax" + .section .nds_vector, "ax" .extern liteos_m_risc_v_trap_handler .extern HalTrapVector .option push .option norelax - .global reset_vector + .global reset_vector reset_vector: - /* Decide whether this is an NMI or cold reset */ - csrr t0, mcause - bnez t0, nmi_handler - .global _start - .type _start,@function + /* Decide whether this is an NMI or cold reset */ + csrr t0, mcause + bnez t0, nmi_handler + .global _start + .type _start,@function _start: #ifndef CACHE_DISABLE /* enable icache */ - csrr a5,mcache_ctl - ori a5,a5,1 - csrw mcache_ctl,a5 + csrr a5,mcache_ctl + ori a5,a5,1 + csrw mcache_ctl,a5 /* enable dcache */ - csrr a5,mcache_ctl - ori a5,a5,2 - csrw mcache_ctl,a5 + csrr a5,mcache_ctl + ori a5,a5,2 + csrw mcache_ctl,a5 #endif - /* Initialize global pointer */ - .option push - .option norelax - la gp, __global_pointer$ - .option pop + /* Initialize global pointer */ + .option push + .option norelax + la gp, __global_pointer$ + .option pop - /* Initialize stack pointer */ - la t0, _stack - mv sp, t0 + /* Initialize stack pointer */ + la t0, _stack + mv sp, t0 #ifdef __nds_execit - /* Initialize EXEC.IT table */ - la t0, _ITB_BASE_ - csrw uitb, t0 + /* Initialize EXEC.IT table */ + la t0, _ITB_BASE_ + csrw uitb, t0 #endif #ifdef __riscv_flen - /* Enable FPU */ - li t0, MSTATUS_FS - csrrs t0, mstatus, t0 + /* Enable FPU */ + li t0, MSTATUS_FS + csrrs t0, mstatus, t0 - /* Initialize FCSR */ - fscsr zero + /* Initialize FCSR */ + fscsr zero #endif - /* Initial machine trap-vector Base. Use FreeRTOS trap function. */ - la t0, HalTrapVector - csrw mtvec, t0 + /* Initial machine trap-vector Base. Use FreeRTOS trap function. */ + la t0, HalTrapVector + csrw mtvec, t0 #ifdef CFG_CACHE_ENABLE - /* Enable I/D cache with HW prefetcher and D-cache write-around (threshold: 4 cache lines) */ - li t0, (0x3 << 13) - csrc mcache_ctl, t0 - li t0, (1 << 13) | (1 << 10) | (1 << 9) | (0x3) - csrs mcache_ctl, t0 + /* Enable I/D cache with HW prefetcher and D-cache write-around (threshold: 4 cache lines) */ + li t0, (0x3 << 13) + csrc mcache_ctl, t0 + li t0, (1 << 13) | (1 << 10) | (1 << 9) | (0x3) + csrs mcache_ctl, t0 #endif - /* Do system low level setup. It must be a leaf function */ - call __platform_init + /* Do system low level setup. It must be a leaf function */ + call __platform_init - /* System reset handler */ - call reset_handler + /* System reset handler */ + call reset_handler - /* Infinite loop, if returned accidently */ -1: j 1b + /* Infinite loop, if returned accidently */ +1: j 1b - .weak __platform_init + .weak __platform_init __platform_init: - ret + ret - .weak nmi_handler + .weak nmi_handler nmi_handler: - csrr a0, mcause - call user_nmi_handler - li t0, TRAP_M_USER_NP - csrw mcause, t0 - j HalTrapVector - ret + csrr a0, mcause + call user_nmi_handler + li t0, TRAP_M_USER_NP + csrw mcause, t0 + j HalTrapVector + ret .org 0x100 .word 0x32374B42 .word 0x00003635 .option pop - .section .text + .section .text - .global trap_entry - .align 2 + .global trap_entry + .align 2 trap_entry: - li t0, TRAP_M_USER_ASSERT - csrw mcause, t0 - j HalTrapVector - ret + li t0, TRAP_M_USER_ASSERT + csrw mcause, t0 + j HalTrapVector + ret diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/BK7256_RegList.h b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/BK7256_RegList.h index 7cad69c..162672e 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/BK7256_RegList.h +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/BK7256_RegList.h @@ -33,11 +33,11 @@ #define addSYSTEM_Reg0x1 *((volatile unsigned long *) (0x44010000+0x1*4)) -#define BASEADDR_PWM0 0x44840000 +#define BASEADDR_PWM0 0x44840000 -#define BASEADDR_PWM1 0x44840040 +#define BASEADDR_PWM1 0x44840040 -#define BASEADDR_PWM2 0x44840080 +#define BASEADDR_PWM2 0x44840080 //addSYSTEM_Reg0x2 #define addSYSTEM_Reg0x2 *((volatile unsigned long *) (0x44010000+0x2*4)) diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/arch_interrupt.h b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/arch_interrupt.h index 973b3a1..7433f28 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/arch_interrupt.h +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/arch_interrupt.h @@ -130,63 +130,63 @@ extern void default_irq_entry(void); /*Define INT ID */ typedef enum { - INT_ID_NULL0_INT = 0, - INT_ID_EIP130_0_IRQ , - INT_ID_EIP130_0_SEC_IRQ , - INT_ID_TIMER , - INT_ID_UART0 , - INT_ID_PWM , - INT_ID_I2C , - INT_ID_SPI , - INT_ID_SADC , - INT_ID_IRDA , - INT_ID_SDIO , - INT_ID_GDMA , - INT_ID_LA , - INT_ID_TIMER1 , - INT_ID_I2C1 , - INT_ID_UART1 , - INT_ID_UART2 , - INT_ID_SPI1 , - INT_ID_CAN , - INT_ID_USB , - INT_ID_QSPI , - INT_ID_FFT , - INT_ID_SBC , - INT_ID_AUD , - INT_ID_I2S , - INT_ID_JPEGENC , - INT_ID_JPEGDEC , - INT_ID_LCD , - INT_ID_NULL1_INT , - INT_ID_INT_PHY , - INT_ID_MAC_TX_RX_TIMER_N , - INT_ID_MAC_TX_RX_MISC_N , - INT_ID_MAC_RX_TRIGGER_N , - INT_ID_MAC_TX_TRIGGER_N , - INT_ID_MAC_PORT_TRIGGER_N , - INT_ID_MAC_GEN_N , - INT_ID_HSU_IRQ , - INT_ID_INT_MAC_WAKEUP , - INT_ID_NULL2_INT , - INT_ID_DM , - INT_ID_BLE , - INT_ID_BT , - INT_ID_NULL3_INT , - INT_ID_NULL4_INT , - INT_ID_NULL5_INT , - INT_ID_NULL6_INT , - INT_ID_NULL7_INT , - INT_ID_NULL8_INT , - INT_ID_MBOX0 , - INT_ID_MBOX1 , - INT_ID_BMC64 , - INT_ID_NULL9_INT , - INT_ID_TOUCHED , - INT_ID_USBPLUG , - INT_ID_RTC , - INT_ID_GPIO , - INT_ID_MAX + INT_ID_NULL0_INT = 0, + INT_ID_EIP130_0_IRQ , + INT_ID_EIP130_0_SEC_IRQ , + INT_ID_TIMER , + INT_ID_UART0 , + INT_ID_PWM , + INT_ID_I2C , + INT_ID_SPI , + INT_ID_SADC , + INT_ID_IRDA , + INT_ID_SDIO , + INT_ID_GDMA , + INT_ID_LA , + INT_ID_TIMER1 , + INT_ID_I2C1 , + INT_ID_UART1 , + INT_ID_UART2 , + INT_ID_SPI1 , + INT_ID_CAN , + INT_ID_USB , + INT_ID_QSPI , + INT_ID_FFT , + INT_ID_SBC , + INT_ID_AUD , + INT_ID_I2S , + INT_ID_JPEGENC , + INT_ID_JPEGDEC , + INT_ID_LCD , + INT_ID_NULL1_INT , + INT_ID_INT_PHY , + INT_ID_MAC_TX_RX_TIMER_N , + INT_ID_MAC_TX_RX_MISC_N , + INT_ID_MAC_RX_TRIGGER_N , + INT_ID_MAC_TX_TRIGGER_N , + INT_ID_MAC_PORT_TRIGGER_N , + INT_ID_MAC_GEN_N , + INT_ID_HSU_IRQ , + INT_ID_INT_MAC_WAKEUP , + INT_ID_NULL2_INT , + INT_ID_DM , + INT_ID_BLE , + INT_ID_BT , + INT_ID_NULL3_INT , + INT_ID_NULL4_INT , + INT_ID_NULL5_INT , + INT_ID_NULL6_INT , + INT_ID_NULL7_INT , + INT_ID_NULL8_INT , + INT_ID_MBOX0 , + INT_ID_MBOX1 , + INT_ID_BMC64 , + INT_ID_NULL9_INT , + INT_ID_TOUCHED , + INT_ID_USBPLUG , + INT_ID_RTC , + INT_ID_GPIO , + INT_ID_MAX } arch_int_src_t; @@ -200,8 +200,8 @@ void arch_interrupt_unregister_int(arch_int_src_t int_number); unsigned int arch_get_interrupt_nest_cnt(void); unsigned int arch_is_enter_exception(void); void mext_interrupt(void); -bool mtimer_is_timeout(); -uint64_t arch_get_plic_pending_status(void); +bool mtimer_is_timeout(); +uint64_t arch_get_plic_pending_status(void); -#endif /* __ARCH_INTERRUPT_H__ */ +#endif /* __ARCH_INTERRUPT_H__ */ diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/core_v5.h b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/core_v5.h new file mode 100755 index 0000000..85dd647 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/core_v5.h @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 __CORE_V5_H__ +#define __CORE_V5_H__ + +#define MSTATUS_UIE 0x00000001 +#define MSTATUS_SIE 0x00000002 +#define MSTATUS_HIE 0x00000004 +#define MSTATUS_MIE 0x00000008 +#define MSTATUS_UPIE 0x00000010 +#define MSTATUS_SPIE 0x00000020 +#define MSTATUS_HPIE 0x00000040 +#define MSTATUS_MPIE 0x00000080 +#define MSTATUS_SPP 0x00000100 +#define MSTATUS_HPP 0x00000600 +#define MSTATUS_MPP 0x00001800 +#define MSTATUS_FS 0x00006000 +#define MSTATUS_XS 0x00018000 +#define MSTATUS_MPRV 0x00020000 +#define MSTATUS_PUM 0x00040000 +#define MSTATUS_MXR 0x00080000 +#define MSTATUS_VM 0x1F000000 +#define MSTATUS32_SD 0x80000000 +#define MSTATUS64_SD 0x8000000000000000 + +#if __riscv_xlen == 64 +#define MCAUSE_INT 0x8000000000000000UL +#define MCAUSE_CAUSE 0x7FFFFFFFFFFFFFFFUL +#else +#define MCAUSE_INT 0x80000000UL +#define MCAUSE_CAUSE 0x7FFFFFFFUL +#endif + +#define IRQ_S_SOFT 1 +#define IRQ_H_SOFT 2 +#define IRQ_M_SOFT 3 +#define IRQ_S_TIMER 5 +#define IRQ_H_TIMER 6 +#define IRQ_M_TIMER 7 +#define IRQ_S_EXT 9 +#define IRQ_H_EXT 10 +#define IRQ_M_EXT 11 +#define IRQ_COP 12 +#define IRQ_HOST 13 + +/* Machine mode MCAUSE */ +#define TRAP_M_I_ACC_FAULT 1 /* Instruction access fault */ +#define TRAP_M_L_ACC_FAULT 5 /* Data load access fault */ +#define TRAP_M_S_ACC_FAULT 7 /* Data store access fault */ +#define TRAP_U_ECALL 8 +#define TRAP_S_ECALL 9 +#define TRAP_H_ECALL 10 +#define TRAP_M_ECALL 11 +#define TRAP_M_I_PAGE_FAULT 12 /* Instruction page fault */ +#define TRAP_M_L_PAGE_FAULT 13 /* Data load page fault */ +#define TRAP_M_S_PAGE_FAULT 15 /* Data store page fault */ +#define TRAP_M_STACKOVF 32 +#define TRAP_M_STACKUDF 33 +#define TRAP_M_USER_ASSERT 0x77 +#define TRAP_M_USER_NP 0x88 +#define TRAP_M_USER_OTHER 0x99 + + +/* Supervisor mode SCAUSE */ +#define TRAP_S_I_ACC_FAULT 1 /* Instruction access fault */ +#define TRAP_S_L_ACC_FAULT 5 /* Data load access fault */ +#define TRAP_S_S_ACC_FAULT 7 /* Data store access fault */ +#define TRAP_S_I_PAGE_FAULT 12 /* Instruction page fault */ +#define TRAP_S_L_PAGE_FAULT 13 /* Data load page fault */ +#define TRAP_S_S_PAGE_FAULT 15 /* Data store page fault */ + +#define MIP_SSIP (1 << IRQ_S_SOFT) +#define MIP_HSIP (1 << IRQ_H_SOFT) +#define MIP_MSIP (1 << IRQ_M_SOFT) +#define MIP_STIP (1 << IRQ_S_TIMER) +#define MIP_HTIP (1 << IRQ_H_TIMER) +#define MIP_MTIP (1 << IRQ_M_TIMER) +#define MIP_SEIP (1 << IRQ_S_EXT) +#define MIP_HEIP (1 << IRQ_H_EXT) +#define MIP_MEIP (1 << IRQ_M_EXT) + +#if __riscv_xlen == 64 +# define SLL32 sllw +# define STORE sd +# define LOAD ld +# define LWU lwu +# define LOG_REGBYTES 3 +#else +# define SLL32 sll +# define STORE sw +# define LOAD lw +# define LWU lw +# define LOG_REGBYTES 2 +#endif +#ifndef REGBYTES +#define REGBYTES (1 << LOG_REGBYTES) +#endif + +#if __riscv_flen == 64 +# define FPSTORE fsd +# define FPLOAD fld +# define LOG_FPREGBYTES 3 +#else +# define FPSTORE fsw +# define FPLOAD flw +# define LOG_FPREGBYTES 2 +#endif +#define FPREGBYTES (1 << LOG_FPREGBYTES) + +#define STR(S) #S +#define XSTR(S) STR(S) + +#define PUSH XSTR(STORE) +#define POP XSTR(LOAD) +#define REGSIZE XSTR(REGBYTES) +#define FPPUSH XSTR(FPSTORE) +#define FPPOP XSTR(FPLOAD) +#define FPREGSIZE XSTR(FPREGBYTES) + +#ifndef __ASSEMBLER__ + +#include + +#define read_csr(reg) __nds__csrr(reg) +#define write_csr(reg, val) __nds__csrw(val, reg) +#define swap_csr(reg, val) __nds__csrrw(val, reg) +#define set_csr(reg, bit) __nds__csrrs(bit, reg) +#define clear_csr(reg, bit) __nds__csrrc(bit, reg) + +#endif + +#endif // __CORE_V5_H__ diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/mcu_ip.h b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/mcu_ip.h index 4c0ea2b..ad6b0a0 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/mcu_ip.h +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/mcu_ip.h @@ -32,7 +32,7 @@ extern "C" { * Device Specific Peripheral Registers structures ****************************************************************************/ -#define __I volatile const /* 'read only' permissions */ +#define __I volatile const /* 'read only' permissions */ #define __O volatile /* 'write only' permissions */ #define __IO volatile /* 'read / write' permissions */ @@ -48,23 +48,23 @@ extern "C" { * PLMT ****************************************************************************/ typedef struct { - __IO unsigned long long MTIME; /* 0x00 Machine Time */ - __IO unsigned long long MTIMECMP; /* 0x08 Machine Time Compare */ + __IO unsigned long long MTIME; /* 0x00 Machine Time */ + __IO unsigned long long MTIMECMP; /* 0x08 Machine Time Compare */ } PLMT_RegDef; typedef struct { - __I unsigned int SYSTEMVER; /* 0x00 SYSTEM ID and Revision Register */ - unsigned int RESERVED0[3]; /* 0x04 ~ 0x0C Reserved */ - __IO unsigned int WRSR; /* 0x10 Wakeup and Reset Status Register */ - __IO unsigned int SMUCR; /* 0x14 SMU Command Register */ - unsigned int RESERVED1[1]; /* 0x18 Reserved */ - __IO unsigned int WRMASK; /* 0x1C Wake up Mask Register */ - __IO unsigned int CER; /* 0x20 Clock Enable Register */ - __IO unsigned int CRR; /* 0x24 Clock Ratio Register */ - unsigned int RESERVED2[6]; /* 0x28 ~ 0x3C Reserved Register */ - __IO unsigned int SCRATCH; /* 0x40 Scratch Register */ - unsigned int RESERVED3[3]; /* 0x44 ~ 0x4C Reserved */ - __IO unsigned int RESET_VECTOR; /* 0x50 CPU Reset Vector Register */ + __I unsigned int SYSTEMVER; /* 0x00 SYSTEM ID and Revision Register */ + unsigned int RESERVED0[3]; /* 0x04 ~ 0x0C Reserved */ + __IO unsigned int WRSR; /* 0x10 Wakeup and Reset Status Register */ + __IO unsigned int SMUCR; /* 0x14 SMU Command Register */ + unsigned int RESERVED1[1]; /* 0x18 Reserved */ + __IO unsigned int WRMASK; /* 0x1C Wake up Mask Register */ + __IO unsigned int CER; /* 0x20 Clock Enable Register */ + __IO unsigned int CRR; /* 0x24 Clock Ratio Register */ + unsigned int RESERVED2[6]; /* 0x28 ~ 0x3C Reserved Register */ + __IO unsigned int SCRATCH; /* 0x40 Scratch Register */ + unsigned int RESERVED3[3]; /* 0x44 ~ 0x4C Reserved */ + __IO unsigned int RESET_VECTOR; /* 0x50 CPU Reset Vector Register */ } SMU_RegDef; /***************************************************************************** * Peripheral device declaration @@ -76,4 +76,4 @@ typedef struct { } #endif -#endif /* __MCU_IP_H__ */ +#endif /* __MCU_IP_H__ */ diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/platform.h b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/platform.h index 1b1fdb4..5c6369a 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/platform.h +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/platform.h @@ -44,4 +44,4 @@ extern "C" { } #endif -#endif /* __PLATFORM_H__ */ +#endif /* __PLATFORM_H__ */ diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/riscv_hal.h b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/riscv_hal.h index 9a7b6db..a81e338 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/riscv_hal.h +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/include/riscv_hal.h @@ -26,7 +26,7 @@ #define MTIMERCMP (0xE6000008) #endif -#define HalIrqDisable(irq_no) clear_csr(NDS_MIE, (1< -#define USE_LIBC_INITFINI 0 +#define USE_LIBC_INITFINI 0 #if USE_LIBC_INITFINI @@ -52,16 +52,16 @@ extern void (*__init_array_end []) (void) __attribute__((weak)); //void __libc_init_array (void) __attribute__((no_profile_instrument_function)); void __libc_init_array (void) { - size_t count; - size_t i; + size_t count; + size_t i; - count = __preinit_array_end - __preinit_array_start; - for (i = 0; i < count; i++) - __preinit_array_start[i] (); + count = __preinit_array_end - __preinit_array_start; + for (i = 0; i < count; i++) + __preinit_array_start[i] (); - count = __init_array_end - __init_array_start; - for (i = 0; i < count; i++) - __init_array_start[i] (); + count = __init_array_end - __init_array_start; + for (i = 0; i < count; i++) + __init_array_start[i] (); } extern void (*__fini_array_start []) (void) __attribute__((weak)); @@ -71,12 +71,12 @@ extern void (*__fini_array_end []) (void) __attribute__((weak)); void __libc_fini_array (void) __attribute__((no_profile_instrument_function)); void __libc_fini_array (void) { - size_t count; - size_t i; + size_t count; + size_t i; - count = __fini_array_end - __fini_array_start; - for (i = count; i > 0; i--) - __fini_array_start[i-1] (); + count = __fini_array_end - __fini_array_start; + for (i = count; i > 0; i--) + __fini_array_start[i-1] (); } #endif diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/pmp.c b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/pmp.c index 33074c9..ec54da0 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/pmp.c +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/pmp.c @@ -16,11 +16,11 @@ #include #include "platform.h" -#include "pmp.h" #include +#include "pmp.h" -#define SYS_DELAY_TIME_10US (170UL) +#define SYS_DELAY_TIME_10US (170UL) /* bk7256 */ #define MEM_MAPPING_MAX 0xFFFFFFF0 @@ -51,13 +51,13 @@ extern char _dtcm_ema_start; #if (!CONFIG_SLAVE_CORE) const pmp_config_t pmp_tor_config_table[] = {\ - {ENTRY_PMPADDR0, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON), (void*)(&_start + 4)}, \ - {ENTRY_PMPADDR1, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON), (void*)(&_data_lmastart + 4) }, \ - {ENTRY_PMPADDR2, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON), (void*)(FLASH_END + 4) }, \ - {ENTRY_PMPADDR3, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_OFF, PMP_R_OFF), (void*)(&_itcm_ema_start + 4) }, \ - {ENTRY_PMPADDR4, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON), (void*)(&_dtcm_ema_start + 4) }, \ - {ENTRY_PMPADDR5, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON), (void*)(SRAM_END +4) }, \ - {ENTRY_PMPADDR6, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON), (void*)(ADDR_MAPPING_MAX+4) } \ + {ENTRY_PMPADDR0, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON), (void*)(&_start + 4)}, \ + {ENTRY_PMPADDR1, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON), (void*)(&_data_lmastart + 4) }, \ + {ENTRY_PMPADDR2, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON), (void*)(FLASH_END + 4) }, \ + {ENTRY_PMPADDR3, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_OFF, PMP_R_OFF), (void*)(&_itcm_ema_start + 4) }, \ + {ENTRY_PMPADDR4, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON), (void*)(&_dtcm_ema_start + 4) }, \ + {ENTRY_PMPADDR5, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON), (void*)(SRAM_END +4) }, \ + {ENTRY_PMPADDR6, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON), (void*)(ADDR_MAPPING_MAX+4) } \ }; #else const pmp_config_t pmp_tor_config_table[] = {\ @@ -68,251 +68,251 @@ extern void sys_delay_sync(uint32_t time_count ); void pmp_tor_config(char entry, void* address, char pmp_cfg) { - long pmpcfg = pmp_cfg & 0xFF; + long pmpcfg = pmp_cfg & 0xFF; - void * va = (void *)((((uint32)(address)+3)/4) * 4); - - os_printf("pmp_tor_config[%d]: addr(0x%08x),TOR(0x%08x) cfg(0x%02x).\n", entry, va, TOR(va), pmpcfg); - switch (entry) { - case ENTRY_PMPADDR0: - write_csr(NDS_PMPADDR0, TOR(va)); - break; - case ENTRY_PMPADDR1: - write_csr(NDS_PMPADDR1, TOR(va)); - break; - case ENTRY_PMPADDR2: - write_csr(NDS_PMPADDR2, TOR(va)); - break; - case ENTRY_PMPADDR3: - write_csr(NDS_PMPADDR3, TOR(va)); - break; - case ENTRY_PMPADDR4: - write_csr(NDS_PMPADDR4, TOR(va)); - break; - case ENTRY_PMPADDR5: - write_csr(NDS_PMPADDR5, TOR(va)); - break; - case ENTRY_PMPADDR6: - write_csr(NDS_PMPADDR6, TOR(va)); - break; - case ENTRY_PMPADDR7: - write_csr(NDS_PMPADDR7, TOR(va)); - break; - case ENTRY_PMPADDR8: - write_csr(NDS_PMPADDR8, TOR(va)); - break; - case ENTRY_PMPADDR9: - write_csr(NDS_PMPADDR9, TOR(va)); - break; - case ENTRY_PMPADDR10: - write_csr(NDS_PMPADDR10, TOR(va)); - break; - case ENTRY_PMPADDR11: - write_csr(NDS_PMPADDR11, TOR(va)); - break; - case ENTRY_PMPADDR12: - write_csr(NDS_PMPADDR12, TOR(va)); - break; - case ENTRY_PMPADDR13: - write_csr(NDS_PMPADDR13, TOR(va)); - break; - case ENTRY_PMPADDR14: - write_csr(NDS_PMPADDR14, TOR(va)); - break; - case ENTRY_PMPADDR15: - write_csr(NDS_PMPADDR15, TOR(va)); - break; - } + void * va = (void *)((((uint32)(address)+3)/4) * 4); + + os_printf("pmp_tor_config[%d]: addr(0x%08x),TOR(0x%08x) cfg(0x%02x).\n", entry, va, TOR(va), pmpcfg); + switch (entry) { + case ENTRY_PMPADDR0: + write_csr(NDS_PMPADDR0, TOR(va)); + break; + case ENTRY_PMPADDR1: + write_csr(NDS_PMPADDR1, TOR(va)); + break; + case ENTRY_PMPADDR2: + write_csr(NDS_PMPADDR2, TOR(va)); + break; + case ENTRY_PMPADDR3: + write_csr(NDS_PMPADDR3, TOR(va)); + break; + case ENTRY_PMPADDR4: + write_csr(NDS_PMPADDR4, TOR(va)); + break; + case ENTRY_PMPADDR5: + write_csr(NDS_PMPADDR5, TOR(va)); + break; + case ENTRY_PMPADDR6: + write_csr(NDS_PMPADDR6, TOR(va)); + break; + case ENTRY_PMPADDR7: + write_csr(NDS_PMPADDR7, TOR(va)); + break; + case ENTRY_PMPADDR8: + write_csr(NDS_PMPADDR8, TOR(va)); + break; + case ENTRY_PMPADDR9: + write_csr(NDS_PMPADDR9, TOR(va)); + break; + case ENTRY_PMPADDR10: + write_csr(NDS_PMPADDR10, TOR(va)); + break; + case ENTRY_PMPADDR11: + write_csr(NDS_PMPADDR11, TOR(va)); + break; + case ENTRY_PMPADDR12: + write_csr(NDS_PMPADDR12, TOR(va)); + break; + case ENTRY_PMPADDR13: + write_csr(NDS_PMPADDR13, TOR(va)); + break; + case ENTRY_PMPADDR14: + write_csr(NDS_PMPADDR14, TOR(va)); + break; + case ENTRY_PMPADDR15: + write_csr(NDS_PMPADDR15, TOR(va)); + break; + } #if __riscv_xlen == 64 - switch (entry >> 3){ - case ENTRY_PMPCFG0: - write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3)))); - break; - case ENTRY_PMPCFG1: - write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3)))); - break; - } + switch (entry >> 3){ + case ENTRY_PMPCFG0: + write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3)))); + break; + case ENTRY_PMPCFG1: + write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3)))); + break; + } #else - switch (entry >> 2) { - case ENTRY_PMPCFG0: - write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); - break; - case ENTRY_PMPCFG1: - write_csr(NDS_PMPCFG1, ((read_csr(NDS_PMPCFG1) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); - break; - case ENTRY_PMPCFG2: - write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); - break; - case ENTRY_PMPCFG3: - write_csr(NDS_PMPCFG3, ((read_csr(NDS_PMPCFG3) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); - break; - } + switch (entry >> 2) { + case ENTRY_PMPCFG0: + write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); + break; + case ENTRY_PMPCFG1: + write_csr(NDS_PMPCFG1, ((read_csr(NDS_PMPCFG1) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); + break; + case ENTRY_PMPCFG2: + write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); + break; + case ENTRY_PMPCFG3: + write_csr(NDS_PMPCFG3, ((read_csr(NDS_PMPCFG3) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); + break; + } #endif } void pmp_napot_config(char entry, void* va, unsigned long size, char pmpcfg) { - switch (entry) { - case ENTRY_PMPADDR0: - write_csr(NDS_PMPADDR0, NAPOT(va, size)); - break; - case ENTRY_PMPADDR1: - write_csr(NDS_PMPADDR1, NAPOT(va, size)); - break; - case ENTRY_PMPADDR2: - write_csr(NDS_PMPADDR2, NAPOT(va, size)); - break; - case ENTRY_PMPADDR3: - write_csr(NDS_PMPADDR3, NAPOT(va, size)); - break; - case ENTRY_PMPADDR4: - write_csr(NDS_PMPADDR4, NAPOT(va, size)); - break; - case ENTRY_PMPADDR5: - write_csr(NDS_PMPADDR5, NAPOT(va, size)); - break; - case ENTRY_PMPADDR6: - write_csr(NDS_PMPADDR6, NAPOT(va, size)); - break; - case ENTRY_PMPADDR7: - write_csr(NDS_PMPADDR7, NAPOT(va, size)); - break; - case ENTRY_PMPADDR8: - write_csr(NDS_PMPADDR8, NAPOT(va, size)); - break; - case ENTRY_PMPADDR9: - write_csr(NDS_PMPADDR9, NAPOT(va, size)); - break; - case ENTRY_PMPADDR10: - write_csr(NDS_PMPADDR10, NAPOT(va, size)); - break; - case ENTRY_PMPADDR11: - write_csr(NDS_PMPADDR11, NAPOT(va, size)); - break; - case ENTRY_PMPADDR12: - write_csr(NDS_PMPADDR12, NAPOT(va, size)); - break; - case ENTRY_PMPADDR13: - write_csr(NDS_PMPADDR13, NAPOT(va, size)); - break; - case ENTRY_PMPADDR14: - write_csr(NDS_PMPADDR14, NAPOT(va, size)); - break; - case ENTRY_PMPADDR15: - write_csr(NDS_PMPADDR15, NAPOT(va, size)); - break; - } + switch (entry) { + case ENTRY_PMPADDR0: + write_csr(NDS_PMPADDR0, NAPOT(va, size)); + break; + case ENTRY_PMPADDR1: + write_csr(NDS_PMPADDR1, NAPOT(va, size)); + break; + case ENTRY_PMPADDR2: + write_csr(NDS_PMPADDR2, NAPOT(va, size)); + break; + case ENTRY_PMPADDR3: + write_csr(NDS_PMPADDR3, NAPOT(va, size)); + break; + case ENTRY_PMPADDR4: + write_csr(NDS_PMPADDR4, NAPOT(va, size)); + break; + case ENTRY_PMPADDR5: + write_csr(NDS_PMPADDR5, NAPOT(va, size)); + break; + case ENTRY_PMPADDR6: + write_csr(NDS_PMPADDR6, NAPOT(va, size)); + break; + case ENTRY_PMPADDR7: + write_csr(NDS_PMPADDR7, NAPOT(va, size)); + break; + case ENTRY_PMPADDR8: + write_csr(NDS_PMPADDR8, NAPOT(va, size)); + break; + case ENTRY_PMPADDR9: + write_csr(NDS_PMPADDR9, NAPOT(va, size)); + break; + case ENTRY_PMPADDR10: + write_csr(NDS_PMPADDR10, NAPOT(va, size)); + break; + case ENTRY_PMPADDR11: + write_csr(NDS_PMPADDR11, NAPOT(va, size)); + break; + case ENTRY_PMPADDR12: + write_csr(NDS_PMPADDR12, NAPOT(va, size)); + break; + case ENTRY_PMPADDR13: + write_csr(NDS_PMPADDR13, NAPOT(va, size)); + break; + case ENTRY_PMPADDR14: + write_csr(NDS_PMPADDR14, NAPOT(va, size)); + break; + case ENTRY_PMPADDR15: + write_csr(NDS_PMPADDR15, NAPOT(va, size)); + break; + } #if __riscv_xlen == 64 - switch (entry >> 3){ - case ENTRY_PMPCFG0: - write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3)))); - break; - case ENTRY_PMPCFG1: - write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3)))); - break; - } + switch (entry >> 3){ + case ENTRY_PMPCFG0: + write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3)))); + break; + case ENTRY_PMPCFG1: + write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3)))); + break; + } #else - switch (entry >> 2) { - case ENTRY_PMPCFG0: - write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); - break; - case ENTRY_PMPCFG1: - write_csr(NDS_PMPCFG1, ((read_csr(NDS_PMPCFG1) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); - break; - case ENTRY_PMPCFG2: - write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); - break; - case ENTRY_PMPCFG3: - write_csr(NDS_PMPCFG3, ((read_csr(NDS_PMPCFG3) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); - break; - } + switch (entry >> 2) { + case ENTRY_PMPCFG0: + write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); + break; + case ENTRY_PMPCFG1: + write_csr(NDS_PMPCFG1, ((read_csr(NDS_PMPCFG1) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); + break; + case ENTRY_PMPCFG2: + write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); + break; + case ENTRY_PMPCFG3: + write_csr(NDS_PMPCFG3, ((read_csr(NDS_PMPCFG3) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3)))); + break; + } #endif } void init_pmp_config() { - int i = 0; - int config_count = 0; - /* - * Check whether the CPU configured with PMP feature. - * Write 0x3 to the pmpcfg0 register, and read it back - * to check the number of PMP entries. - */ - write_csr(NDS_PMPCFG0, 0x3); - if (!read_csr(NDS_PMPCFG0)) { - os_printf("PMP entries is 0, CPU does NOT support PMP.\n"); - while(1); - } + int i = 0; + int config_count = 0; + /* + * Check whether the CPU configured with PMP feature. + * Write 0x3 to the pmpcfg0 register, and read it back + * to check the number of PMP entries. + */ + write_csr(NDS_PMPCFG0, 0x3); + if (!read_csr(NDS_PMPCFG0)) { + os_printf("PMP entries is 0, CPU does NOT support PMP.\n"); + while(1); + } - /* Disable global interrupt but allow exception */ - clear_csr(NDS_MSTATUS, MSTATUS_MIE); + /* Disable global interrupt but allow exception */ + clear_csr(NDS_MSTATUS, MSTATUS_MIE); #if USE_NAPOT - os_printf("PMP uses NAPOT scheme!.\n"); + os_printf("PMP uses NAPOT scheme!.\n"); -#else /* USE_TOR */ +#else /* USE_TOR */ - os_printf("PMP uses TOR scheme!.\n"); - config_count = sizeof(pmp_tor_config_table)/sizeof(pmp_config_t); + os_printf("PMP uses TOR scheme!.\n"); + config_count = sizeof(pmp_tor_config_table)/sizeof(pmp_config_t); - os_printf("PMP config count(%d).\n", config_count); - for (i = 0; i < config_count; i++) - { - pmp_tor_config(pmp_tor_config_table[i].pmp_entry, - pmp_tor_config_table[i].pmp_addr, - pmp_tor_config_table[i].pmp_config); + os_printf("PMP config count(%d).\n", config_count); + for (i = 0; i < config_count; i++) + { + pmp_tor_config(pmp_tor_config_table[i].pmp_entry, + pmp_tor_config_table[i].pmp_addr, + pmp_tor_config_table[i].pmp_config); - sys_delay_sync(SYS_DELAY_TIME_10US); - } + sys_delay_sync(SYS_DELAY_TIME_10US); + } #endif } void show_pmp_config() { - os_printf("==========PMP config info===============\r\n"); + os_printf("==========PMP config info===============\r\n"); - int i = 0; - int config_count = 0; - long pmp_config0 = read_csr(NDS_PMPCFG0); - if (!pmp_config0) { - os_printf("PMP entries is 0, CPU does NOT support PMP.\n"); - } + int i = 0; + int config_count = 0; + long pmp_config0 = read_csr(NDS_PMPCFG0); + if (!pmp_config0) { + os_printf("PMP entries is 0, CPU does NOT support PMP.\n"); + } #if USE_NAPOT - os_printf("PMP uses NAPOT scheme!.\n"); + os_printf("PMP uses NAPOT scheme!.\n"); -#else /* USE_TOR */ +#else /* USE_TOR */ - os_printf("PMP uses TOR scheme!.\n"); - config_count = sizeof(pmp_tor_config_table)/sizeof(pmp_config_t); + os_printf("PMP uses TOR scheme!.\n"); + config_count = sizeof(pmp_tor_config_table)/sizeof(pmp_config_t); - os_printf("PMP user config count(%d).\n", config_count); - for (i = 0; i < config_count; i++) - { - os_printf("PMP config[%d], 0x%08x, 0x%0x.\r\n", i, - (void *)pmp_tor_config_table[i].pmp_addr, - pmp_tor_config_table[i].pmp_config); + os_printf("PMP user config count(%d).\n", config_count); + for (i = 0; i < config_count; i++) + { + os_printf("PMP config[%d], 0x%08x, 0x%0x.\r\n", i, + (void *)pmp_tor_config_table[i].pmp_addr, + pmp_tor_config_table[i].pmp_config); - } + } #endif - os_printf("==========PMP actural config:\r\n"); - os_printf("==========NDS_PMPCFG0: 0x%08x.\r\n", pmp_config0); - os_printf("==========NDS_PMPCFG1: 0x%08x.\r\n", read_csr(NDS_PMPCFG1)); + os_printf("==========PMP actural config:\r\n"); + os_printf("==========NDS_PMPCFG0: 0x%08x.\r\n", pmp_config0); + os_printf("==========NDS_PMPCFG1: 0x%08x.\r\n", read_csr(NDS_PMPCFG1)); - os_printf("==========NDS_PMPADDR0: 0x%08x.\r\n", read_csr(NDS_PMPADDR0)); - os_printf("==========NDS_PMPADDR1: 0x%08x.\r\n", read_csr(NDS_PMPADDR1)); - os_printf("==========NDS_PMPADDR2: 0x%08x.\r\n", read_csr(NDS_PMPADDR2)); - os_printf("==========NDS_PMPADDR3: 0x%08x.\r\n", read_csr(NDS_PMPADDR3)); - os_printf("==========NDS_PMPADDR4: 0x%08x.\r\n", read_csr(NDS_PMPADDR4)); - os_printf("==========NDS_PMPADDR5: 0x%08x.\r\n", read_csr(NDS_PMPADDR5)); - os_printf("==========NDS_PMPADDR6: 0x%08x.\r\n", read_csr(NDS_PMPADDR6)); - os_printf("==========NDS_PMPADDR7: 0x%08x.\r\n", read_csr(NDS_PMPADDR7)); + os_printf("==========NDS_PMPADDR0: 0x%08x.\r\n", read_csr(NDS_PMPADDR0)); + os_printf("==========NDS_PMPADDR1: 0x%08x.\r\n", read_csr(NDS_PMPADDR1)); + os_printf("==========NDS_PMPADDR2: 0x%08x.\r\n", read_csr(NDS_PMPADDR2)); + os_printf("==========NDS_PMPADDR3: 0x%08x.\r\n", read_csr(NDS_PMPADDR3)); + os_printf("==========NDS_PMPADDR4: 0x%08x.\r\n", read_csr(NDS_PMPADDR4)); + os_printf("==========NDS_PMPADDR5: 0x%08x.\r\n", read_csr(NDS_PMPADDR5)); + os_printf("==========NDS_PMPADDR6: 0x%08x.\r\n", read_csr(NDS_PMPADDR6)); + os_printf("==========NDS_PMPADDR7: 0x%08x.\r\n", read_csr(NDS_PMPADDR7)); } diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/pmp.h b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/pmp.h index 6b1847c..cf548c7 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/pmp.h +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/pmp.h @@ -62,51 +62,51 @@ enum { ENTRY_PMPADDR0 = 0, - ENTRY_PMPADDR1, - ENTRY_PMPADDR2, - ENTRY_PMPADDR3, - ENTRY_PMPADDR4, - ENTRY_PMPADDR5, - ENTRY_PMPADDR6, - ENTRY_PMPADDR7, - ENTRY_PMPADDR8, - ENTRY_PMPADDR9, - ENTRY_PMPADDR10, - ENTRY_PMPADDR11, - ENTRY_PMPADDR12, - ENTRY_PMPADDR13, - ENTRY_PMPADDR14, - ENTRY_PMPADDR15, - ENTRY_PMPADDR_COUNT + ENTRY_PMPADDR1, + ENTRY_PMPADDR2, + ENTRY_PMPADDR3, + ENTRY_PMPADDR4, + ENTRY_PMPADDR5, + ENTRY_PMPADDR6, + ENTRY_PMPADDR7, + ENTRY_PMPADDR8, + ENTRY_PMPADDR9, + ENTRY_PMPADDR10, + ENTRY_PMPADDR11, + ENTRY_PMPADDR12, + ENTRY_PMPADDR13, + ENTRY_PMPADDR14, + ENTRY_PMPADDR15, + ENTRY_PMPADDR_COUNT }; enum { ENTRY_PMPCFG0 = 0, - ENTRY_PMPCFG1, - ENTRY_PMPCFG2, - ENTRY_PMPCFG3, + ENTRY_PMPCFG1, + ENTRY_PMPCFG2, + ENTRY_PMPCFG3, }; typedef struct { - uint8_t pmp_entry; - uint8_t pmp_config; - /* - union - { - struct - { - volatile uint8_t R : 1; //[0], Read Access Control - volatile uint8_t W : 1; //[1], Write Access Control - volatile uint8_t X : 1; //[2], Instruction execution Control - volatile uint8_t A : 2; //[4:3], Address matching mode - volatile uint8_t reserved : 2; //[6:5], - volatile uint8_t L : 1; //[7], Write Lock and permission enforcement bit for Machine mode - }; - uint8_t value; - }pmp_config; + uint8_t pmp_entry; + uint8_t pmp_config; + /* + union + { + struct + { + volatile uint8_t R : 1; //[0], Read Access Control + volatile uint8_t W : 1; //[1], Write Access Control + volatile uint8_t X : 1; //[2], Instruction execution Control + volatile uint8_t A : 2; //[4:3], Address matching mode + volatile uint8_t reserved : 2; //[6:5], + volatile uint8_t L : 1; //[7], Write Lock and permission enforcement bit for Machine mode + }; + uint8_t value; + }pmp_config; */ - void *pmp_addr; + void *pmp_addr; } pmp_config_t; #endif // __PMP_H__ diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/reset.c b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/reset.c index 3d49be7..a3487a3 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/reset.c +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/reset.c @@ -32,49 +32,49 @@ extern int print_str(char * st); void close_wdt(void) { - /*close the wdt*/ - *((volatile unsigned long *) (0x44000600)) = 0x5A0000; - *((volatile unsigned long *) (0x44000600)) = 0xA50000; - *((volatile unsigned long *) (0x44800000)) = 0x5A0000; - *((volatile unsigned long *) (0x44800000)) = 0xA50000; + /*close the wdt*/ + *((volatile unsigned long *) (0x44000600)) = 0x5A0000; + *((volatile unsigned long *) (0x44000600)) = 0xA50000; + *((volatile unsigned long *) (0x44800000)) = 0x5A0000; + *((volatile unsigned long *) (0x44800000)) = 0xA50000; } //volatile int g_debug_mode=1; void reset_handler(void) { /// TODO: DEBUG VERSION close the wdt - close_wdt(); + close_wdt(); - //while(g_test_mode); + //while(g_test_mode); #if (!CONFIG_SLAVE_CORE) - sram_dcache_map(); + sram_dcache_map(); #endif - /* - * Initialize LMA/VMA sections. - * Relocation for any sections that need to be copied from LMA to VMA. - */ - c_startup(); + /* + * Initialize LMA/VMA sections. + * Relocation for any sections that need to be copied from LMA to VMA. + */ + c_startup(); - /*power manager init*/ - pm_hardware_init(); + /*power manager init*/ + pm_hardware_init(); #if (CONFIG_SOC_BK7256XX) - //clear mannully reboot flag - set_reboot_tag(0); + //clear mannully reboot flag + set_reboot_tag(0); #endif - /* Call platform specific hardware initialization */ - system_init(); + /* Call platform specific hardware initialization */ + system_init(); //while(g_debug_mode){}; - /* Do global constructors */ - __libc_init_array(); + /* Do global constructors */ + __libc_init_array(); - /*Init pmp configuration*/ - init_pmp_config(); - - /* Entry function */ - entry_main(); + /*Init pmp configuration*/ + init_pmp_config(); + + /* Entry function */ + entry_main(); } diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/riscv.c b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/riscv.c index 2517075..626462a 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/riscv.c +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/riscv.c @@ -25,92 +25,92 @@ extern unsigned int g_sram_addr_map[SRAM_BLOCK_COUNT]; void __platform_init (void) __attribute__((naked)); void __platform_init(void) { - /* Do your platform low-level initial */ + /* Do your platform low-level initial */ - __asm("ret"); + __asm("ret"); } void c_startup(void) { #define MEMCPY(des, src, n) __builtin_memcpy ((des), (src), (n)) #define MEMSET(s, c, n) __builtin_memset ((s), (c), (n)) - /* Data section initialization */ - extern char _edata, _end; - unsigned int size; + /* Data section initialization */ + extern char _edata, _end; + unsigned int size; #if !CONFIG_SLAVE_CORE - int i = 0; + int i = 0; - /* Init all sram block */ - for(i = 0; i < SRAM_BLOCK_COUNT; i++) - { - MEMSET((void *)g_sram_addr_map[i], 0x0, SRAM_BLOCK_SIZE); - } + /* Init all sram block */ + for(i = 0; i < SRAM_BLOCK_COUNT; i++) + { + MEMSET((void *)g_sram_addr_map[i], 0x0, SRAM_BLOCK_SIZE); + } #endif #ifdef CFG_XIP - extern char _data_lmastart, _data_start; - extern char _itcm_lma_start, _itcm_ema_start, _itcm_lma_end; - extern char _dtcm_lma_start, _dtcm_ema_start, _dtcm_lma_end; - extern char _dtcm_bss_start, _dtcm_bss_end; + extern char _data_lmastart, _data_start; + extern char _itcm_lma_start, _itcm_ema_start, _itcm_lma_end; + extern char _dtcm_lma_start, _dtcm_ema_start, _dtcm_lma_end; + extern char _dtcm_bss_start, _dtcm_bss_end; - /*Copy ITCM section from LMA to VMA*/ + /*Copy ITCM section from LMA to VMA*/ - size = &_itcm_lma_end - &_itcm_lma_start; - if(size!=0) - { - MEMCPY(&_itcm_ema_start, &_itcm_lma_start, size); - } - /*Copy DTCM section from LMA to VMA*/ - size = &_dtcm_lma_end - &_dtcm_lma_start; - if(size!=0) - { - MEMCPY(&_dtcm_ema_start, &_dtcm_lma_start, size); - } + size = &_itcm_lma_end - &_itcm_lma_start; + if(size!=0) + { + MEMCPY(&_itcm_ema_start, &_itcm_lma_start, size); + } + /*Copy DTCM section from LMA to VMA*/ + size = &_dtcm_lma_end - &_dtcm_lma_start; + if(size!=0) + { + MEMCPY(&_dtcm_ema_start, &_dtcm_lma_start, size); + } - /* Clear DTCM bss section */ - size = &_dtcm_bss_end - &_dtcm_bss_start; - if(size!=0) - { - MEMSET(&_dtcm_bss_start, 0, size); - } + /* Clear DTCM bss section */ + size = &_dtcm_bss_end - &_dtcm_bss_start; + if(size!=0) + { + MEMSET(&_dtcm_bss_start, 0, size); + } #endif - /* Copy data section from LMA to VMA */ - size = &_edata - &_data_start; - MEMCPY(&_data_start, &_data_lmastart, size); + /* Copy data section from LMA to VMA */ + size = &_edata - &_data_start; + MEMCPY(&_data_start, &_data_lmastart, size); - /* Clear bss section */ - size = &_end - &_edata; - MEMSET(&_edata, 0, size); + /* Clear bss section */ + size = &_end - &_edata; + MEMSET(&_edata, 0, size); #if CONFIG_SAVE_BOOT_TIME_POINT - save_mtime_point(CPU_INIT_MEM_TIME); + save_mtime_point(CPU_INIT_MEM_TIME); #endif } void system_init(void) { - /* - * Do your system reset handling here - */ - /* Reset the CPU reset vector for this program. */ - MCUIP_SMU->RESET_VECTOR = (unsigned int)(long)reset_vector; + /* + * Do your system reset handling here + */ + /* Reset the CPU reset vector for this program. */ + MCUIP_SMU->RESET_VECTOR = (unsigned int)(long)reset_vector; - /* Enable PLIC features */ - if (read_csr(NDS_MMISC_CTL) & (1 << 1)) { - /* External PLIC interrupt is vectored */ - __nds__plic_set_feature(NDS_PLIC_FEATURE_PREEMPT | NDS_PLIC_FEATURE_VECTORED); - } else { - /* External PLIC interrupt is NOT vectored */ - __nds__plic_set_feature(NDS_PLIC_FEATURE_PREEMPT); - } + /* Enable PLIC features */ + if (read_csr(NDS_MMISC_CTL) & (1 << 1)) { + /* External PLIC interrupt is vectored */ + __nds__plic_set_feature(NDS_PLIC_FEATURE_PREEMPT | NDS_PLIC_FEATURE_VECTORED); + } else { + /* External PLIC interrupt is NOT vectored */ + __nds__plic_set_feature(NDS_PLIC_FEATURE_PREEMPT); + } - /* Enable misaligned access and non-blocking load. */ - set_csr(NDS_MMISC_CTL, (1 << 8) | (1 << 6)); + /* Enable misaligned access and non-blocking load. */ + set_csr(NDS_MMISC_CTL, (1 << 8) | (1 << 6)); } void arch_init(void) { - //arch_enable_align_fault(); + //arch_enable_align_fault(); } diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/riscv_utility.S b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/riscv_utility.S index 3cc0a81..2e2425f 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/riscv_utility.S +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/riscv_utility.S @@ -57,7 +57,7 @@ arch_enable_irq: */ arch_int_lock: csrr a0, mstatus // return value - csrci mstatus, MSTATUS_MIE + csrci mstatus, MSTATUS_MIE ret /* @@ -65,7 +65,7 @@ arch_int_lock: */ arch_int_unlock: csrr a0, mstatus // return value - csrsi mstatus, MSTATUS_MIE + csrsi mstatus, MSTATUS_MIE ret /* @@ -87,27 +87,27 @@ arch_get_int_status: * void arch_fence(void); */ arch_fence: - fence iorw, iorw - ret + fence iorw, iorw + ret #if 0 /* * void arch_atomic_clear(u32 * lock_addr); */ arch_atomic_clear: - amoswap.w.rl x0, x0, (a0) - ret + amoswap.w.rl x0, x0, (a0) + ret /* * u32 arch_atomic_set(u32 * lock_addr); */ arch_atomic_set: - addi t0, x0, 1 + addi t0, x0, 1 //swap_again: - amoswap.w.aq t0, t0, (a0) - c.mv a0, t0 -// bnez t0, swap_again - ret + amoswap.w.aq t0, t0, (a0) + c.mv a0, t0 +// bnez t0, swap_again + ret #endif @@ -115,45 +115,45 @@ arch_atomic_set: * u64 riscv_get_mtimer(void); */ riscv_get_mtimer: - li t0, MTIMER + li t0, MTIMER read_mtimer: - lw a1, 4(t0) - lw a0, 0(t0) - lw t1, 4(t0) - bne a1, t1, read_mtimer - ret + lw a1, 4(t0) + lw a0, 0(t0) + lw t1, 4(t0) + bne a1, t1, read_mtimer + ret /* * void riscv_set_mtimercmp(u64 new_time); */ riscv_set_mtimercmp: - li t0, MTIMERCMP - li t1, -1 - sw t1, 4(t0) - fence - sw a0, 0(t0) - sw a1, 4(t0) - ret + li t0, MTIMERCMP + li t1, -1 + sw t1, 4(t0) + fence + sw a0, 0(t0) + sw a1, 4(t0) + ret /* * u64 riscv_get_cycle(void); */ riscv_get_cycle: read_cycle: - csrrs a1, mcycleh, x0 - csrrs a0, mcycle, x0 - csrrs t0, mcycleh, x0 - bne a1, t0, read_cycle - ret + csrrs a1, mcycleh, x0 + csrrs a0, mcycle, x0 + csrrs t0, mcycleh, x0 + bne a1, t0, read_cycle + ret /* * u64 riscv_get_instruct_cnt(void); */ riscv_get_instruct_cnt: read_instr_cnt: - csrrs a1, minstreth, x0 - csrrs a0, minstret, x0 - csrrs t0, minstreth, x0 - bne a1, t0, read_instr_cnt - ret + csrrs a1, minstreth, x0 + csrrs a0, minstret, x0 + csrrs t0, minstreth, x0 + bne a1, t0, read_instr_cnt + ret diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/stack_base.c b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/stack_base.c index e475db1..8e14758 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/stack_base.c +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/stack_base.c @@ -29,39 +29,39 @@ extern char _itcm_ema_start, _itcm_ema_end; static int addr_is_in_flash_txt(uint32_t addr) { - return ((addr > 0x100) && (addr < (uint32_t)&__etext)); + return ((addr > 0x100) && (addr < (uint32_t)&__etext)); } static int addr_is_in_itcm_txt(uint32_t addr) { - return ((addr > (uint32_t)&_itcm_ema_start) && (addr < (uint32_t)&_itcm_ema_end)); + return ((addr > (uint32_t)&_itcm_ema_start) && (addr < (uint32_t)&_itcm_ema_end)); } static int code_addr_is_valid(uint32_t addr) { - return (addr_is_in_flash_txt(addr) || addr_is_in_itcm_txt(addr)); + return (addr_is_in_flash_txt(addr) || addr_is_in_itcm_txt(addr)); } void stack_mem_dump(uint32_t stack_top, uint32_t stack_bottom) { - unsigned char *data; - uint32_t cnt = 0; - uint32_t sp = stack_top; - uint32_t fp = stack_bottom; + unsigned char *data; + uint32_t cnt = 0; + uint32_t sp = stack_top; + uint32_t fp = stack_bottom; - BK_DUMP_OUT(">>>>stack mem dump begin, stack_top=%08x, stack end=%08x\r\n", stack_top, stack_bottom); - for (; sp < fp; sp += sizeof(size_t)) { - data = ((unsigned char *) sp); + BK_DUMP_OUT(">>>>stack mem dump begin, stack_top=%08x, stack end=%08x\r\n", stack_top, stack_bottom); + for (; sp < fp; sp += sizeof(size_t)) { + data = ((unsigned char *) sp); - if ((cnt++ & 0x7) == 0) { - BK_DUMP_OUT("\r\n"); - } + if ((cnt++ & 0x7) == 0) { + BK_DUMP_OUT("\r\n"); + } - BK_DUMP_OUT("%02x %02x %02x %02x ", data[0], data[1], data[2], data[3]); - } - BK_DUMP_OUT("\r\n"); - BK_DUMP_OUT("<<< 0) { - int index; + if (call_stack_index > 0) { + int index; - BK_DUMP_OUT("%-16s [0x%-6x ~ 0x%-6x] 0x%-6x %-4d %-8d ", - str_type, stack_minimum, stack_bottom, init_stack_top, stack_size, init_stack_top < stack_minimum); + BK_DUMP_OUT("%-16s [0x%-6x ~ 0x%-6x] 0x%-6x %-4d %-8d ", + str_type, stack_minimum, stack_bottom, init_stack_top, stack_size, init_stack_top < stack_minimum); - for (index = 0; index < call_stack_index; index++) - BK_DUMP_OUT("%lx ", call_stack_buf[index]); - BK_DUMP_OUT("\r\n"); - } else if (init_stack_top < stack_minimum) { - BK_DUMP_OUT("%-16s [0x%-6x ~ 0x%-6x] 0x%-6x %-4d %-8d ", - str_type, stack_minimum, stack_bottom, init_stack_top, stack_size, init_stack_top < stack_minimum); - } + for (index = 0; index < call_stack_index; index++) + BK_DUMP_OUT("%lx ", call_stack_buf[index]); + BK_DUMP_OUT("\r\n"); + } else if (init_stack_top < stack_minimum) { + BK_DUMP_OUT("%-16s [0x%-6x ~ 0x%-6x] 0x%-6x %-4d %-8d ", + str_type, stack_minimum, stack_bottom, init_stack_top, stack_size, init_stack_top < stack_minimum); + } } diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/trap_base.c b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/trap_base.c index 1ff5803..f3cc90d 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/trap_base.c +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/arch/riscv/trap_base.c @@ -34,97 +34,97 @@ #include #if (CONFIG_CACHE_ENABLE) - #define SRAM_BLOCK_COUNT 4 - extern unsigned int g_sram_addr_map[SRAM_BLOCK_COUNT]; + #define SRAM_BLOCK_COUNT 4 + extern unsigned int g_sram_addr_map[SRAM_BLOCK_COUNT]; #else - #if (CONFIG_SLAVE_CORE) - #define RAM_BASE_ADDR 0x30060000 - #else - #define RAM_BASE_ADDR 0x30000000 - #endif + #if (CONFIG_SLAVE_CORE) + #define RAM_BASE_ADDR 0x30060000 + #else + #define RAM_BASE_ADDR 0x30000000 + #endif #endif -#define SYS_DELAY_TIME_5S (85000000UL) +#define SYS_DELAY_TIME_5S (85000000UL) #if CONFIG_LITEOS_M_V3 || CONFIG_LITEOS_M_MST typedef struct { - union { - struct { - long x2; //sp - long x4; //tp - long x31; //t6 - long x30; //t5 - long x29; //t4 - long x28; //t3 - long x7; //t2 - long x6; //t1 - long x5; //t0 - long x27; //s11 - long x26; //s10 - long x25; //s9 - long x24; //s8 - long x23; //s7 - long x22; //s6 - long x21; //s5 - long mstatus; - long mepc; - long x17; //a7 - long x16; //a6 - long x15; //a5 - long x14; //a4 - long x13; //a3 - long x12; //a2 - long x11; //a1 - long x10; //a0 - long x20; //s4 - long x19; //s3 - long x18; //s2 - long x9; //s1 - long x8; //s0 - long x1; //ra - }; - long riscv_regs[32]; - }; + union { + struct { + long x2; //sp + long x4; //tp + long x31; //t6 + long x30; //t5 + long x29; //t4 + long x28; //t3 + long x7; //t2 + long x6; //t1 + long x5; //t0 + long x27; //s11 + long x26; //s10 + long x25; //s9 + long x24; //s8 + long x23; //s7 + long x22; //s6 + long x21; //s5 + long mstatus; + long mepc; + long x17; //a7 + long x16; //a6 + long x15; //a5 + long x14; //a4 + long x13; //a3 + long x12; //a2 + long x11; //a1 + long x10; //a0 + long x20; //s4 + long x19; //s3 + long x18; //s2 + long x9; //s1 + long x8; //s0 + long x1; //ra + }; + long riscv_regs[32]; + }; } SAVED_CONTEXT; #else // CONFIG_FREERTOS typedef struct { - union { - struct { - long mepc; - long x1; - long x5; - long x6; - long x7; - long x8; - long x9; - long x10; - long x11; - long x12; - long x13; - long x14; - long x15; - long x16; - long x17; - long x18; - long x19; - long x20; - long x21; - long x22; - long x23; - long x24; - long x25; - long x26; - long x27; - long x28; - long x29; - long x30; - long x31; - long mstatus; - }; - long riscv_regs[30]; - }; + union { + struct { + long mepc; + long x1; + long x5; + long x6; + long x7; + long x8; + long x9; + long x10; + long x11; + long x12; + long x13; + long x14; + long x15; + long x16; + long x17; + long x18; + long x19; + long x20; + long x21; + long x22; + long x23; + long x24; + long x25; + long x26; + long x27; + long x28; + long x29; + long x30; + long x31; + long mstatus; + }; + long riscv_regs[30]; + }; } SAVED_CONTEXT; #endif @@ -146,42 +146,42 @@ static hook_func s_ble_dump_func = NULL; volatile unsigned int g_enter_exception = 0; unsigned int arch_is_enter_exception(void) { - return g_enter_exception; + return g_enter_exception; } void rtos_regist_wifi_dump_hook(hook_func wifi_func) { - s_wifi_dump_func = wifi_func; + s_wifi_dump_func = wifi_func; } void rtos_regist_ble_dump_hook(hook_func ble_func) { - s_ble_dump_func = ble_func; + s_ble_dump_func = ble_func; } void trap_handler(unsigned long mcause, SAVED_CONTEXT *context) { - if (0 == g_enter_exception) { - // Make sure the interrupt is disable - uint32_t int_level = rtos_disable_int(); - uint32_t mie_status = rtos_disable_mie_int(); + if (0 == g_enter_exception) { + // Make sure the interrupt is disable + uint32_t int_level = rtos_disable_int(); + uint32_t mie_status = rtos_disable_mie_int(); #if CONFIG_INT_WDT - close_wdt(); - bk_task_wdt_stop(); + close_wdt(); + bk_task_wdt_stop(); #endif - /* Handled Trap */ - g_enter_exception = 1; - BK_LOG_FLUSH(); - bk_set_printf_sync(true); - - user_except_handler(mcause, context); - BK_DUMP_OUT("Unhandled Trap : mcause = 0x%x, mepc = 0x%x\r\n", mcause, context->mepc); - while(g_enter_exception); + /* Handled Trap */ + g_enter_exception = 1; + BK_LOG_FLUSH(); + bk_set_printf_sync(true); + + user_except_handler(mcause, context); + BK_DUMP_OUT("Unhandled Trap : mcause = 0x%x, mepc = 0x%x\r\n", mcause, context->mepc); + while(g_enter_exception); - rtos_enable_mie_int(mie_status); - rtos_enable_int(int_level); - } + rtos_enable_mie_int(mie_status); + rtos_enable_int(int_level); + } } @@ -195,145 +195,145 @@ void trap_handler(unsigned long mcause, SAVED_CONTEXT *context) void arch_dump_cpu_registers (unsigned long mcause, SAVED_CONTEXT *context) { - BK_DUMP_OUT("Current regs:\r\n"); + BK_DUMP_OUT("Current regs:\r\n"); - BK_DUMP_OUT("1 ra x 0x%lx\r\n", context->x1); - BK_DUMP_OUT("2 sp x 0x%lx\r\n", context + 1); - BK_DUMP_OUT("5 t0 x 0x%lx\r\n", context->x5); - BK_DUMP_OUT("6 t1 x 0x%lx\r\n", context->x6); - BK_DUMP_OUT("7 t2 x 0x%lx\r\n", context->x7); - BK_DUMP_OUT("8 fp x 0x%lx\r\n", context->x8); - BK_DUMP_OUT("9 s1 x 0x%lx\r\n", context->x9); - BK_DUMP_OUT("10 a0 x 0x%lx\r\n", context->x10); - BK_DUMP_OUT("11 a1 x 0x%lx\r\n", context->x11); - BK_DUMP_OUT("12 a2 x 0x%lx\r\n", context->x12); - BK_DUMP_OUT("13 a3 x 0x%lx\r\n", context->x13); - BK_DUMP_OUT("14 a4 x 0x%lx\r\n", context->x14); - BK_DUMP_OUT("15 a5 x 0x%lx\r\n", context->x15); - BK_DUMP_OUT("16 a6 x 0x%lx\r\n", context->x16); - BK_DUMP_OUT("17 a7 x 0x%lx\r\n", context->x17); - BK_DUMP_OUT("18 s2 x 0x%lx\r\n", context->x18); - BK_DUMP_OUT("19 s3 x 0x%lx\r\n", context->x19); - BK_DUMP_OUT("20 s4 x 0x%lx\r\n", context->x20); - BK_DUMP_OUT("21 s5 x 0x%lx\r\n", context->x21); - BK_DUMP_OUT("22 s6 x 0x%lx\r\n", context->x22); - BK_DUMP_OUT("23 s7 x 0x%lx\r\n", context->x23); - BK_DUMP_OUT("24 s8 x 0x%lx\r\n", context->x24); - BK_DUMP_OUT("25 s9 x 0x%lx\r\n", context->x25); - BK_DUMP_OUT("26 s10 x 0x%lx\r\n", context->x26); - BK_DUMP_OUT("27 s11 x 0x%lx\r\n", context->x27); - BK_DUMP_OUT("28 t3 x 0x%lx\r\n", context->x28); - BK_DUMP_OUT("29 t4 x 0x%lx\r\n", context->x29); - BK_DUMP_OUT("30 t5 x 0x%lx\r\n", context->x30); - BK_DUMP_OUT("31 t6 x 0x%lx\r\n", context->x31); + BK_DUMP_OUT("1 ra x 0x%lx\r\n", context->x1); + BK_DUMP_OUT("2 sp x 0x%lx\r\n", context + 1); + BK_DUMP_OUT("5 t0 x 0x%lx\r\n", context->x5); + BK_DUMP_OUT("6 t1 x 0x%lx\r\n", context->x6); + BK_DUMP_OUT("7 t2 x 0x%lx\r\n", context->x7); + BK_DUMP_OUT("8 fp x 0x%lx\r\n", context->x8); + BK_DUMP_OUT("9 s1 x 0x%lx\r\n", context->x9); + BK_DUMP_OUT("10 a0 x 0x%lx\r\n", context->x10); + BK_DUMP_OUT("11 a1 x 0x%lx\r\n", context->x11); + BK_DUMP_OUT("12 a2 x 0x%lx\r\n", context->x12); + BK_DUMP_OUT("13 a3 x 0x%lx\r\n", context->x13); + BK_DUMP_OUT("14 a4 x 0x%lx\r\n", context->x14); + BK_DUMP_OUT("15 a5 x 0x%lx\r\n", context->x15); + BK_DUMP_OUT("16 a6 x 0x%lx\r\n", context->x16); + BK_DUMP_OUT("17 a7 x 0x%lx\r\n", context->x17); + BK_DUMP_OUT("18 s2 x 0x%lx\r\n", context->x18); + BK_DUMP_OUT("19 s3 x 0x%lx\r\n", context->x19); + BK_DUMP_OUT("20 s4 x 0x%lx\r\n", context->x20); + BK_DUMP_OUT("21 s5 x 0x%lx\r\n", context->x21); + BK_DUMP_OUT("22 s6 x 0x%lx\r\n", context->x22); + BK_DUMP_OUT("23 s7 x 0x%lx\r\n", context->x23); + BK_DUMP_OUT("24 s8 x 0x%lx\r\n", context->x24); + BK_DUMP_OUT("25 s9 x 0x%lx\r\n", context->x25); + BK_DUMP_OUT("26 s10 x 0x%lx\r\n", context->x26); + BK_DUMP_OUT("27 s11 x 0x%lx\r\n", context->x27); + BK_DUMP_OUT("28 t3 x 0x%lx\r\n", context->x28); + BK_DUMP_OUT("29 t4 x 0x%lx\r\n", context->x29); + BK_DUMP_OUT("30 t5 x 0x%lx\r\n", context->x30); + BK_DUMP_OUT("31 t6 x 0x%lx\r\n", context->x31); - if (mcause == TRAP_M_USER_ASSERT) { - BK_DUMP_OUT("32 pc x 0x%lx\r\n", context->x1 - 4); - } else { - BK_DUMP_OUT("32 pc x 0x%lx\r\n", context->mepc - 4); - } + if (mcause == TRAP_M_USER_ASSERT) { + BK_DUMP_OUT("32 pc x 0x%lx\r\n", context->x1 - 4); + } else { + BK_DUMP_OUT("32 pc x 0x%lx\r\n", context->mepc - 4); + } - BK_DUMP_OUT("833 mstatus x 0x%lx\r\n", context->mstatus); + BK_DUMP_OUT("833 mstatus x 0x%lx\r\n", context->mstatus); - BK_DUMP_OUT("838 mtvec x 0x%lx\r\n", read_csr(NDS_MTVEC)); - BK_DUMP_OUT("897 mscratch x 0x%lx\r\n", read_csr(NDS_MSCRATCH)); - BK_DUMP_OUT("898 mepc x 0x%lx\r\n", context->mepc); - BK_DUMP_OUT("899 mcause x 0x%lx\r\n", mcause); - BK_DUMP_OUT("900 mtval x 0x%lx\r\n", read_csr(NDS_MTVAL)); - BK_DUMP_OUT("2058 mdcause x 0x%lx\r\n", read_csr(NDS_MDCAUSE)); + BK_DUMP_OUT("838 mtvec x 0x%lx\r\n", read_csr(NDS_MTVEC)); + BK_DUMP_OUT("897 mscratch x 0x%lx\r\n", read_csr(NDS_MSCRATCH)); + BK_DUMP_OUT("898 mepc x 0x%lx\r\n", context->mepc); + BK_DUMP_OUT("899 mcause x 0x%lx\r\n", mcause); + BK_DUMP_OUT("900 mtval x 0x%lx\r\n", read_csr(NDS_MTVAL)); + BK_DUMP_OUT("2058 mdcause x 0x%lx\r\n", read_csr(NDS_MDCAUSE)); - BK_DUMP_OUT("\r\n"); + BK_DUMP_OUT("\r\n"); - if (mcause == 0x2) { - stack_mem_dump((uint32_t)(context->mepc - 32), (uint32_t)(context->mepc + 32)); - } + if (mcause == 0x2) { + stack_mem_dump((uint32_t)(context->mepc - 32), (uint32_t)(context->mepc + 32)); + } } void sys_delay_sync(uint32_t time_count ) { - volatile UINT32 i = 0; + volatile UINT32 i = 0; - for (i = 0; i < time_count; i ++) - ; + for (i = 0; i < time_count; i ++) + ; } void user_except_handler (unsigned long mcause, SAVED_CONTEXT *context) { - BK_DUMP_OUT("***********************************************************************************************\r\n"); - BK_DUMP_OUT("***********************************user except handler begin***********************************\r\n"); - BK_DUMP_OUT("***********************************************************************************************\r\n"); + BK_DUMP_OUT("***********************************************************************************************\r\n"); + BK_DUMP_OUT("***********************************user except handler begin***********************************\r\n"); + BK_DUMP_OUT("***********************************************************************************************\r\n"); - arch_dump_cpu_registers(mcause, context); + arch_dump_cpu_registers(mcause, context); - if(NULL != s_wifi_dump_func) { - s_wifi_dump_func(); - } + if(NULL != s_wifi_dump_func) { + s_wifi_dump_func(); + } - if(NULL != s_ble_dump_func) { - s_ble_dump_func(); - } + if(NULL != s_ble_dump_func) { + s_ble_dump_func(); + } - BK_DUMP_OUT("System will dump memory in 5s, please ready to save whole log.........\r\n"); + BK_DUMP_OUT("System will dump memory in 5s, please ready to save whole log.........\r\n"); - sys_delay_sync(SYS_DELAY_TIME_5S); + sys_delay_sync(SYS_DELAY_TIME_5S); #if CONFIG_MEMDUMP_ALL - stack_mem_dump((uint32_t)&_dtcm_ema_start, (uint32_t)&_dtcm_bss_end); + stack_mem_dump((uint32_t)&_dtcm_ema_start, (uint32_t)&_dtcm_bss_end); #if CONFIG_CACHE_ENABLE && (!CONFIG_SLAVE_CORE) - for (int i = 0; i < SRAM_BLOCK_COUNT; i++) { - stack_mem_dump(g_sram_addr_map[i], g_sram_addr_map[i] + 0x20000); - } + for (int i = 0; i < SRAM_BLOCK_COUNT; i++) { + stack_mem_dump(g_sram_addr_map[i], g_sram_addr_map[i] + 0x20000); + } #else - stack_mem_dump(RAM_BASE_ADDR, (uint32_t)&_end); + stack_mem_dump(RAM_BASE_ADDR, (uint32_t)&_end); #endif #endif - rtos_dump_backtrace(); - rtos_dump_task_list(); + rtos_dump_backtrace(); + rtos_dump_task_list(); #if CONFIG_FREERTOS - rtos_dump_task_runtime_stats(); + rtos_dump_task_runtime_stats(); #endif #if CONFIG_FREERTOS && CONFIG_MEM_DEBUG - os_dump_memory_stats(0, 0, NULL); + os_dump_memory_stats(0, 0, NULL); #endif - arch_dump_cpu_registers(mcause, context); + arch_dump_cpu_registers(mcause, context); - BK_DUMP_OUT("***********************************************************************************************\r\n"); - BK_DUMP_OUT("************************************user except handler end************************************\r\n"); - BK_DUMP_OUT("***********************************************************************************************\r\n"); + BK_DUMP_OUT("***********************************************************************************************\r\n"); + BK_DUMP_OUT("************************************user except handler end************************************\r\n"); + BK_DUMP_OUT("***********************************************************************************************\r\n"); - bk_reboot(); + bk_reboot(); } void set_reboot_tag(uint32_t tag) { - uint32_t p_tag = REBOOT_TAG_ADDR; - *((uint32_t *)p_tag) = tag; + uint32_t p_tag = REBOOT_TAG_ADDR; + *((uint32_t *)p_tag) = tag; } inline uint32_t get_reboot_tag(void) { - return *((uint32_t *)REBOOT_TAG_ADDR); + return *((uint32_t *)REBOOT_TAG_ADDR); } void user_nmi_handler(unsigned long mcause, unsigned long ra) { - if(mcause == MCAUSE_CAUSE_WATCHDOG) { - if( REBOOT_TAG_REQ == get_reboot_tag() ) { - BK_DUMP_OUT("Wait reboot.\r\n"); - while(1); - } - } + if(mcause == MCAUSE_CAUSE_WATCHDOG) { + if( REBOOT_TAG_REQ == get_reboot_tag() ) { + BK_DUMP_OUT("Wait reboot.\r\n"); + while(1); + } + } #if CONFIG_INT_WDT - close_wdt(); - bk_task_wdt_stop(); + close_wdt(); + bk_task_wdt_stop(); #endif - BK_DUMP_OUT("========Call NULL func pointer/WDT, please check the code near ra reg.========\r\n"); - BK_DUMP_OUT("1 ra x 0x%lx\r\n", ra); - BK_DUMP_OUT("========Call NULL func pointer/WDT, please check the code near ra reg.========\r\n"); + BK_DUMP_OUT("========Call NULL func pointer/WDT, please check the code near ra reg.========\r\n"); + BK_DUMP_OUT("1 ra x 0x%lx\r\n", ra); + BK_DUMP_OUT("========Call NULL func pointer/WDT, please check the code near ra reg.========\r\n"); } #if CONFIG_SAVE_BOOT_TIME_POINT @@ -344,84 +344,84 @@ extern uint64_t riscv_get_mtimer(void); extern uint64_t riscv_get_instruct_cnt(void); static uint32_t get_saved_time_info_addr(uint32_t time_point) { - uint32_t addr = 0; + uint32_t addr = 0; - if (CPU_BOOT_TIME == time_point) { - //The BSS section not ready at cpu boot time point - addr = CPU_BOOT_TIME_ADDR; - } else if (time_point < CPU_SAVED_TIME_MAX){ - addr = (uint32_t)&s_saved_boot_info[2*time_point]; - } + if (CPU_BOOT_TIME == time_point) { + //The BSS section not ready at cpu boot time point + addr = CPU_BOOT_TIME_ADDR; + } else if (time_point < CPU_SAVED_TIME_MAX){ + addr = (uint32_t)&s_saved_boot_info[2*time_point]; + } - return addr; + return addr; } void save_mtime_point(uint32_t time_point) { - uint32_t addr = get_saved_time_info_addr(time_point); + uint32_t addr = get_saved_time_info_addr(time_point); - if (0 != addr) { - *((uint64_t *)addr) = riscv_get_mtimer(); - *((uint64_t *)addr + 1) = riscv_get_instruct_cnt(); - } + if (0 != addr) { + *((uint64_t *)addr) = riscv_get_mtimer(); + *((uint64_t *)addr + 1) = riscv_get_instruct_cnt(); + } } void show_saved_mtime_point(uint32_t time_point) { - uint32_t addr = get_saved_time_info_addr(time_point); + uint32_t addr = get_saved_time_info_addr(time_point); - if (0 != addr) { - uint64_t saved_time = *((uint64_t *)addr); - uint64_t saved_inst_cnt = *((uint64_t *)addr + 1); - uint32_t saved_time_ms = (u32)(saved_time & 0xFFFFFFFF) / 26000; - BK_DUMP_OUT("saved time: 0x%x:0x%08x\r\n", (u32)(saved_time >> 32), (u32)(saved_time & 0xFFFFFFFF)); - BK_DUMP_OUT("saved time: %ldms\r\n", saved_time_ms); - BK_DUMP_OUT("saved inst_cnt: 0x%x:0x%08x\r\n", (u32)(saved_inst_cnt >> 32), (u32)(saved_inst_cnt & 0xFFFFFFFF)); - } + if (0 != addr) { + uint64_t saved_time = *((uint64_t *)addr); + uint64_t saved_inst_cnt = *((uint64_t *)addr + 1); + uint32_t saved_time_ms = (u32)(saved_time & 0xFFFFFFFF) / 26000; + BK_DUMP_OUT("saved time: 0x%x:0x%08x\r\n", (u32)(saved_time >> 32), (u32)(saved_time & 0xFFFFFFFF)); + BK_DUMP_OUT("saved time: %ldms\r\n", saved_time_ms); + BK_DUMP_OUT("saved inst_cnt: 0x%x:0x%08x\r\n", (u32)(saved_inst_cnt >> 32), (u32)(saved_inst_cnt & 0xFFFFFFFF)); + } } void show_saved_mtime_info(void) { - BK_DUMP_OUT("==============Show Boot Time===================\r\n"); - show_saved_mtime_point(CPU_BOOT_TIME); + BK_DUMP_OUT("==============Show Boot Time===================\r\n"); + show_saved_mtime_point(CPU_BOOT_TIME); - BK_DUMP_OUT("==============Show Init Mem Time===================\r\n"); - show_saved_mtime_point(CPU_INIT_MEM_TIME); + BK_DUMP_OUT("==============Show Init Mem Time===================\r\n"); + show_saved_mtime_point(CPU_INIT_MEM_TIME); - BK_DUMP_OUT("==============Show MAIN Emtry Time===================\r\n"); - show_saved_mtime_point(CPU_MAIN_ENTRY_TIME); + BK_DUMP_OUT("==============Show MAIN Emtry Time===================\r\n"); + show_saved_mtime_point(CPU_MAIN_ENTRY_TIME); - BK_DUMP_OUT("==============Show INIT Driver Time===================\r\n"); - show_saved_mtime_point(CPU_INIT_DRIVER_TIME); + BK_DUMP_OUT("==============Show INIT Driver Time===================\r\n"); + show_saved_mtime_point(CPU_INIT_DRIVER_TIME); - BK_DUMP_OUT("==============Show App Entry Time===================\r\n"); - show_saved_mtime_point(CPU_APP_ENTRY_TIME); + BK_DUMP_OUT("==============Show App Entry Time===================\r\n"); + show_saved_mtime_point(CPU_APP_ENTRY_TIME); - BK_DUMP_OUT("==============Show Start Sche Time===================\r\n"); - show_saved_mtime_point(CPU_START_SCHE_TIME); + BK_DUMP_OUT("==============Show Start Sche Time===================\r\n"); + show_saved_mtime_point(CPU_START_SCHE_TIME); - BK_DUMP_OUT("==============Show Start Wifi init Time===================\r\n"); - show_saved_mtime_point(CPU_START_WIFI_INIT_TIME); + BK_DUMP_OUT("==============Show Start Wifi init Time===================\r\n"); + show_saved_mtime_point(CPU_START_WIFI_INIT_TIME); - BK_DUMP_OUT("==============Show Finish Wifi init Time===================\r\n"); - show_saved_mtime_point(CPU_FINISH_WIFI_INIT_TIME); + BK_DUMP_OUT("==============Show Finish Wifi init Time===================\r\n"); + show_saved_mtime_point(CPU_FINISH_WIFI_INIT_TIME); - BK_DUMP_OUT("==============Show App Finish Time===================\r\n"); - show_saved_mtime_point(CPU_APP_FINISH_TIME); + BK_DUMP_OUT("==============Show App Finish Time===================\r\n"); + show_saved_mtime_point(CPU_APP_FINISH_TIME); - BK_DUMP_OUT("==============Show Main Finish Time===================\r\n"); - show_saved_mtime_point(CPU_MIAN_FINISH_TIME); + BK_DUMP_OUT("==============Show Main Finish Time===================\r\n"); + show_saved_mtime_point(CPU_MIAN_FINISH_TIME); - BK_DUMP_OUT("==============Show Start Connect Time===================\r\n"); - show_saved_mtime_point(CPU_START_CONNECT_TIME); + BK_DUMP_OUT("==============Show Start Connect Time===================\r\n"); + show_saved_mtime_point(CPU_START_CONNECT_TIME); - BK_DUMP_OUT("==============Show Wifi Connected Time===================\r\n"); - show_saved_mtime_point(CPU_CONNECTED_TIME); + BK_DUMP_OUT("==============Show Wifi Connected Time===================\r\n"); + show_saved_mtime_point(CPU_CONNECTED_TIME); } void show_current_time_point(const char *info) { - uint64_t current_time = riscv_get_mtimer();; - uint32_t current_time_ms = (u32) (current_time/26000); - BK_DUMP_OUT("%s: current time: %ldms\r\n", info, current_time_ms); + uint64_t current_time = riscv_get_mtimer();; + uint32_t current_time_ms = (u32) (current_time/26000); + BK_DUMP_OUT("%s: current time: %ldms\r\n", info, current_time_ms); } #endif diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/middleware/boards/BUILD.gn new file mode 100755 index 0000000..6b03261 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/boards/BUILD.gn @@ -0,0 +1,38 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +module_name = get_path_info(rebase_path("."), "name") +lite_component(module_name) { + features = [ ":vnd" ] +} + +static_library("vnd") { + sources = [ + "bk7235/vnd_cal/vnd_cal.c", + "bk7235/vnd_flash/vnd_flash.c", + ] + public_configs = [ + ":public", + "${beken_sdk_dir}/middleware/driver:public", + ] +} + +config("public") { + include_dirs = [ + "bk7235/vnd_cal", + "bk7235/vnd_cal/include", + "bk7235/vnd_flash", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/CMakeLists.txt deleted file mode 100755 index c02eabe..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -armino_component_register_call_subdirs() \ No newline at end of file diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/bk7235.wrapper b/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/bk7235.wrapper deleted file mode 100755 index 8b13789..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/bk7235.wrapper +++ /dev/null @@ -1 +0,0 @@ - diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/configuration.json b/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/configuration.json deleted file mode 100755 index 2ad43e9..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/configuration.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "magic": "FreeRTOS", - "version": "0.1", - "count": 2, - "section": [ - { - "firmware": "bootloader.bin", - "version": "2M.1220", - "partition": "bootloader", - "start_addr": "0x00000000", - "size": "68k" - }, - { - "firmware": "app.bin", - "version": "2M.1220", - "partition": "app", - "start_addr": "0x00011000", - "size": "2312K" - } - ] -} \ No newline at end of file diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_cal/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_cal/CMakeLists.txt deleted file mode 100755 index 52fa9ee..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_cal/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -if (CONFIG_VND_CAL) - -set(incs - . - include - ) -set(srcs - vnd_cal.c - ) -endif() - -armino_component_register(SRCS "${srcs}" INCLUDE_DIRS "${incs}" PRIV_REQUIRES bk_libs) diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_cal/Kconfig b/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_cal/Kconfig deleted file mode 100755 index a48f5f5..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_cal/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -menu "VENDOR CAL CONFIG" - config VND_CAL - bool "Enable vendor cal" - default n - - config BLE_USE_HIGH_POWER_LEVEL - bool "Enable high power level" - default y -endmenu diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_flash/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_flash/CMakeLists.txt deleted file mode 100755 index 16e78a1..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_flash/CMakeLists.txt +++ /dev/null @@ -1,10 +0,0 @@ -if (NOT CONFIG_OVERRIDE_FLASH_PARTITION) - -set(incs . - ) -set(srcs - vnd_flash.c - ) -endif() - -armino_component_register(SRCS "${srcs}" INCLUDE_DIRS "${incs}" PRIV_REQUIRES bk_libs user_driver) diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_flash/Kconfig b/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_flash/Kconfig deleted file mode 100755 index 93efe4b..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/boards/bk7235/vnd_flash/Kconfig +++ /dev/null @@ -1,5 +0,0 @@ -menu "VENDOR FLASH CONFIG" - config OVERRIDE_FLASH_PARTITION - bool "Override flash partition" - default n -endmenu diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/compal/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/middleware/compal/BUILD.gn new file mode 100755 index 0000000..935e6b4 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/compal/BUILD.gn @@ -0,0 +1,20 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") + +config("public") { + include_dirs = [ "common_io/include" ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/compal/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/middleware/compal/CMakeLists.txt index 5eabe52..fc537eb 100644 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/compal/CMakeLists.txt +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/compal/CMakeLists.txt @@ -2,8 +2,8 @@ set(incs homekit matter) set(srcs - homekit/key_value.c - homekit/func_convert.c + #homekit/key_value.c + #homekit/func_convert.c ) if(CONFIG_SUPPORT_MATTER) diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/compal/common_io/include/iot_adc.h b/bk7235/liteos_m/bk_sdk_armino/middleware/compal/common_io/include/iot_adc.h new file mode 100755 index 0000000..f3981d6 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/compal/common_io/include/iot_adc.h @@ -0,0 +1,359 @@ +/* + * FreeRTOS Common IO V0.1.3 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * http://aws.amazon.com/freertos + * http://www.FreeRTOS.org + */ + +/** + * @file iot_adc.h + * @brief File for the HAL APIs of ADC called by application layer. + */ +#ifndef _IOT_ADC_H_ +#define _IOT_ADC_H_ + +/** + * @brief Error code returned by ADC driver + */ +#define IOT_ADC_SUCCESS ( 0 ) /*!< ADC operation completed successfully. */ +#define IOT_ADC_FAILED ( 1 ) /*!< ADC operation failed. */ +#define IOT_ADC_INVALID_VALUE ( 2 ) /*!< At least one parameter is invalid. */ +#define IOT_ADC_NOT_OPEN ( 3 ) /*!< ADC operation not possible unless ADC instance is opened. */ +#define IOT_ADC_FUNCTION_NOT_SUPPORTED ( 4 ) /*!< ADC operation not supported. */ +#define IOT_ADC_CH_BUSY ( 5 ) /*!< ADC channel is busy at current time. */ + +/** + * @brief The handle for a ADC peripheral, defined in the source file. + * This is an anonymous struct that is vendor/driver specific. + */ +struct IotAdcDescriptor; + +/** + * @brief IotAdcHandle_t is the handle type returned by calling iot_adc_open(). + * This is initialized in open and returned to caller. The caller must pass + * this pointer to the rest of the ADC APIs. + */ +typedef struct IotAdcDescriptor * IotAdcHandle_t; + +/** + * @brief ADC notification callback type + * + * @param[in] pvUserContext User Context passed when setting the callback. + * This is not used or modified by the driver. The context is + * provided by the caller when setting the callback, and is + * passed back to the caller in the callback. + * @param[out] pusConvertedData pointer to converted ADC sample data. + */ +typedef void ( * IotAdcCallback_t )( uint16_t * pusConvertedData, + void * pvUserContext ); + +/** + * @brief Initializes ADC controller with default configuration. + * init ADC controller, enable ADC clock, reset HW FIFO, set default + * configuration parameters, etc. Also allocate all required resources + * for ADC operation such as software data buffer etc. + * + * @warning Must be called prior to any other ADC api's so that a valid handle is obtained. + * @warning Once opened, the same ADC instance must be closed before calling open again. + * + * @param[in] lAdc The instance of ADC controller to initialize. + * + * @return + * - handle to the ADC controller on success + * - NULL, if + * - invalid instance number + * - open same instance more than once before closing it. + */ +IotAdcHandle_t iot_adc_open( int32_t lAdc ); + +/** + * @brief Close ADC controller. + * All pending operation will be cancelled, put ADC module in reset state or low + * power state if possible. Release all resources claimed during open call + * + * @param[in] pxAdc handle to ADC controller returned from iot_adc_open() call. + * + * @return + * - IOT_ADC_SUCCESS, on success; + * - IOT_I2C_INVALID_VALUE, if pxAdc is NULL + * - IOT_ADC_NOT_OPEN, if is not in open state (already closed). + */ +int32_t iot_adc_close( IotAdcHandle_t const pxAdc ); + +/** + * @brief Sets channel callback on availability of channel scan data. + * On availability of ADC scan data, the application is notified with a + * function callback. The callback function and user context for callback + * are set using iot_adc_set_callback. + * + * @note This callback is per AdcChannel for each handle. + * @note If input handle or AdcChannel is invalid, or if callback function is NULL, + * this function silently takes no action. + * + * @param[in] pxAdc The ADC handle returned in the open() call. + * @param[in] ucAdcChannel The ADC channel for which the callback is set + * @param[in] xAdcCallback The callback function to be called on availability of ADC channel data. + * @param[in] pvUserContext The user context to be passed when callback is called. + * + * Example Callback Function + * For asychronous ADC calls, a callback function is used to signal when the async + * task is complete. This example uses a Semaphore to signal the completion. + * @code{c} + * static void prvAdcChCallback( uint16_t * pusConvertedData, + * void * pvUserContext ) + * { + * BaseType_t xHigherPriorityTaskWoken; + * xSemaphoreGiveFromISR( xIotAdcSemaphore, &xHigherPriorityTaskWoken ); + * } + * @endcode + */ +void iot_adc_set_callback( IotAdcHandle_t const pxAdc, + uint8_t ucAdcChannel, + IotAdcCallback_t xAdcCallback, + void * pvUserContext ); + +/** + * @brief Start data acquisition for ADC channel until iot_adc_stop API is called. + * Data will be passed back to client using callback function. + * By default each callback will pass back one data sample, however if client has + * used ioctl to pass in data buffer, only when buffer is full will callback + * be triggered. + * + * @warning iot_adc_set_callback() must be called prior to this in order to get notification + * when ADC scan is complete and data is available. + * + * @note iot_adc_set_callback() must be called prior to iot_adc_start(). + * + * @param[in] pxAdc. The ADC handle returned in the open() call + * @param[in] ucAdcChannel. The ADC channel to start data acquisition + * + * @return + * - IOT_ADC_SUCCESS on success + * - IOT_ADC_INVALID_VALUE, on NULL handle or invalid AdcChannel + * - IOT_ADC_NOT_OPEN if ADC has not been opened yet. + * - IOT_ADC_CH_BUSY if ADC operation has started but is not complete + * - IOT_ADC_FAILED if not callback function has been set. + * Example Asynchronous read + * @code{c} + * // ADC Instance to open + * int32_t lAdcInstance = 0; + * + * // Return value of ADC functions + * int32_t lRetVal; + * + * // ADC Channel to read + * int32_t lAdcChannel = 0; + * + * // User/Driver context; if necessary + * void xUserContext = NULL; + * + * // Open the ADC instance and get a handle. + * xAdcHandle = iot_adc_open( lAdcInstance ); + * // assert(lRetVal == IOT_ADC_SUCCESS); + * + * // set the callback function + * iot_adc_set_callback( xAdcHandle, lAdcChannel, prvAdcChCallback, &xUserCntx ); + * + * // start channel data scan on channel + * lRetVal = iot_adc_start( xAdcHandle, lAdcChannel ); + * // assert( IOT_ADC_SUCCESS == lRetVal ); + * + * // wait for the ADC operation to complete + * lRetVal = xSemaphoreTake( xIotAdcSemaphore, lIotAdcChWaitTime ); + * // assert ( pdTRUE == lRetVal ); + * + * // stop channel data scan + * lRetVal = iot_adc_stop( xAdcHandle, lAdcChannel ); + * assert( IOT_ADC_SUCCESS == lRetVal ); + * + * // close ADC module + * lRetVal = iot_adc_close( xAdcHandle ); + * // assert( IOT_ADC_SUCCESS == lRetVal ); + * @endcode + */ +int32_t iot_adc_start( IotAdcHandle_t const pxAdc, + uint8_t ucAdcChannel ); + +/** + * @brief Stop data acquisition for ADC channel + * + * @param[in] pxAdc. The ADC handle returned in the open() call + * @param[in] ucAdcChannel. The ADC channel to stop data acquisition + * + * @return + * - IOT_ADC_SCUCCESS on success + * - IOT_ADC_INVALID_VALUE, on NULL handle or invalid AdcChannel + * - IOT_ADC_NOT_OPEN if ADC has been closed without re-opening. + */ +int32_t iot_adc_stop( IotAdcHandle_t const pxAdc, + uint8_t ucAdcChannel ); + +/** + * @brief read one ADC data sample. This API will return one ADC sample. + * + * @param[in] pxAdc. The ADC handle returned in the open() call. + * @param[in] ucAdcChannel. The ADC channel to read data from. + * @param[out] pusAdcSample. ADC channel read sample value. + * + * @return + * - IOT_ADC_SCUCCESS on success. + * - IOT_ADC_INVALID_VALUE, on NULL handle or invalid AdcChannel. + * - IOT_ADC_CH_BUSY if ADC operation not complete. + * - IOT_ADC_NOT_OPEN if ADC has been closed without re-opening. + * Example Synchronous read + * @code{c} + * // ADC Instance to open + * int32_t lAdcInstance = 0; + * + * // ADC Channel to read + * int32_t lAdcChannel = 0; + * + * // Declare and ADC handle + * IotAdcHandle_t xAdcHandle; + * + * // Return value of ADC functions + * int32_t lRetVal; + * + * // ADC value read + * uint16_t usSample; + * + * // Open the ADC instance and get a handle. + * xAdcHandle = iot_adc_open( lAdcInstance ); + * // assert(lRetVal == IOT_ADC_SUCCESS); + * + * // Read sample from ADC channel + * lRetVal = iot_adc_read_sample( xAdcHandle, lAdcChannel, &usSample); + * // assert(lRetVal == IOT_ADC_SUCCESS); + * + * // Close the ADC instance and get a handle. + * lRetVal = iot_adc_close( xAdcHandle ); + * // assert(lRetVal == IOT_ADC_SUCCESS); + * @endcode + * + */ +int32_t iot_adc_read_sample( IotAdcHandle_t const pxAdc, + uint8_t ucAdcChannel, + uint16_t * pusAdcSample ); + +/** + * @brief data structures for ioctl request + */ + +/** + * @brief data structure for ioctl SetAdcConfig and GetAdcConfig + */ +typedef struct IotAdcConfig_s +{ + uint32_t ulAdcSampleTime; /*!< Sample time in ADC clock cycles, apply to all channels. + *!< Shortest sample time maximize conversion speed for lower impedance input + *!< Extending sample time improve sample accuracy for higher impedance input. + *!< Sample time is reported as the closest possible value, rounded up, the hardware can support. */ + uint8_t ucAdcResolution; /*!< ADC channel resolution, reported as the closest possible value, rounded up. + *!< value = resolution bits; 12 = 12bit, 13 = 13bit, etc */ +} IotAdcConfig_t; + +typedef enum +{ + eChStateIdle, /*!< ADC channel is idle. */ + eChStateBusy, /*!< ADC channel is busy. */ +} IotAdcChState_t; + +/** + * @brief data structure for ioctl GetChStatus + */ +typedef struct IotAdcChStatus_s +{ + uint8_t ucAdcChannel; /*!< ADC Channel number */ + IotAdcChState_t xAdcChState; /*!< ADC Channel State */ +} IotAdcChStatus_t; + +/** + * @brief data structure for ioctl SetChBuffer + * setting channel data buffer is optional using this ioctl + * if client doesn't pass in data buffer for driver to use, callback is triggered + * for every ADC sample to pass data back to client as driver doesn't have buffer + * to accumulate data. As soon as callback returns, xConverted_Data becomes invalid. + * On the other hand however if client does pass a buffer for driver to use, + * callback is triggered only after driver has filled buffer with xBufLen samples, + * client buffer is passed back in callback as XConverted_Data whose life span is + * controlled by the client even after callback returns. + */ +typedef struct IotAdcChBuffer_s +{ + uint8_t ucAdcChannel; /*!< Adc Channel number */ + void * pvBuffer; /*!< Buffer to store adc results in */ + uint8_t ucBufLen; /*!< Max buffer length to write into pvBuffer */ +} IotAdcChBuffer_t; + +/** + * @brief Some ADC host controller supports grouping multiple ADC channels into a chain. + * When the chain is triggered to sample ADC data, all ADC channels in the group + * are sampled in sequence so that client doesn't need to trigger each channel + * individually. Converted ADC samples from such chain group can be passed back + * to the client with a single callback. + * This data structure is used for ioctl to define ADC chain setting. + */ +typedef struct IoTAdcChain_s +{ + uint8_t ucAdcChannel; /*!< logical ADC channel number as input to ioctl. It is recommended + *!< that client uses the first ADC channel number in the group as its + *!< logical number which client can use later to trigger group sampling */ + void * pvBuffer; /*!< data buffer used by driver to save converted sample data. + *!< The buffer is allocated by client and passed to driver to use. */ + uint8_t ucBufLen; /*!< Data buffer length, shall be large enough to hold group sample data. */ + uint16_t usChainMask; /*!< Define which ADC channels are in the chain group. + *!< e.g. 'x' bit set to 1 means ADC channel x is included in the group. + *!< Client shall manage potential ADC channel use conflict. */ +} IotAdcChain_t; + +/** + * @brief adc ioctl request types. + */ +typedef enum IotAdcIoctlRequest_s +{ + eSetAdcConfig, /*!< Set the ADC Configuration. Takes IotAdcConfig_t parameter. */ + eGetAdcConfig, /*!< Get the ADC Configuration. Returns results in IotAdcConfig_t parameter. */ + eGetChStatus, /*!< Get the Channel Status. Returns results in IotAdcChStatus_t parameter. */ + eSetChBuffer, /*!< Set the buffer for ADC values to be stored in. Takes IotAdcChBuffer_t parameter. */ + eSetAdcChain, /*!< ADC Chain for multiple ADC channels. Takes IotAdcChain_t parameter. */ +} IotAdcIoctlRequest_t; + +/** + * @brief Used for various ADC control functions. + * + * @param[in] pxAdc The ADC handle returned in the open() call. + * @param[in] xRequest ioctl request defined by IotAdcIoctlRequest_s enums. + * @param[in/out] pvBuffer data buffer for ioctl request. + * @param[in] pvBuffer size. + * + * @return + * - IOT_ADC_SCUCCESS on success + * - IOT_ADC_INVALID_VALUE, on NULL handle or invalid request or NULL or invalid buffer pointer + * - IOT_ADC_CH_BUSY if ADC operation not complete. + * - IOT_ADC_NOT_OPEN if ADC has been closed without re-opening. + * - IOT_ADC_FAILED if invalid ADC chain is requested. + * - IOT_ADC_FUNCTION_NOT_SUPPORTED only valid for eSetAdcChain, if feature is not supported. + */ +int32_t iot_adc_ioctl( IotAdcHandle_t const pxAdc, + IotAdcIoctlRequest_t xRequest, + void * const pvBuffer ); + +#endif /* _IOT_ADC_H_ */ diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/driver/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/middleware/driver/BUILD.gn new file mode 100755 index 0000000..6de4d5c --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/driver/BUILD.gn @@ -0,0 +1,105 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +static_library(module_name) { + sources = [ + "bk7235/gpio_driver.c", + "bk7235/interrupt.c", + "bk7235/interrupt_statis.c", + "common/dd.c", + "common/driver.c", + "common/drv_model.c", + "efuse/efuse_driver.c", + "flash/flash_bypass.c", + "flash/flash_driver.c", + "flash/flash_partition.c", + "general_dma/dma_driver.c", + "gpio/gpio_driver_base.c", + "icu/icu_driver.c", + "icu/interrupt_base.c", + "pmu/aon_pmu_driver.c", + "reset_reason/reset_reason.c", + "rtc/aon_rtc_driver.c", + "saradc/adc_driver.c", + "saradc/adc_statis.c", + "security/hal_aes.c", + "security/security.c", + "spi/spi_driver.c", + "spi/spi_statis.c", + "spinlock/amp_res_lock.c", + "sys_ctrl/sys_audio_driver.c", + "sys_ctrl/sys_bt_driver.c", + "sys_ctrl/sys_clock_driver.c", + "sys_ctrl/sys_ctrl.c", + "sys_ctrl/sys_driver.c", + "sys_ctrl/sys_driver_common.c", + "sys_ctrl/sys_int_driver.c", + "sys_ctrl/sys_ps_driver.c", + "sys_ctrl/sys_psram_driver.c", + "sys_ctrl/sys_touch_driver.c", + "sys_ctrl/sys_video_driver.c", + "sys_ctrl/sys_wifi_driver.c", + "timer/timer_driver.c", + "trng/trng_driver.c", + "uart/printf.c", + "uart/uart_driver.c", + "uart/uart_statis.c", + "wdt/wdt_driver.c", + ] + + public_configs = [ + ":public", + "${beken_sdk_dir}/middleware/compal:public", + "${beken_sdk_dir}/middleware/arch:public", + "${beken_sdk_dir}/middleware/soc:public", + "${beken_sdk_dir}/components/bk_os:public", + ] +} + +config("public") { + include_dirs = [ + ".", + "bk7235", + "include", + "common", + "reset_reason", + "pwm", + "flash", + "uart", + "sys_ctrl", + "gpio", + "general_dma", + "icu", + "i2c", + "sdcard", + "saradc", + "pmu", + "mailbox", + "spinlock", + "touch", + "sbc", + "rtc", + "i2s", + "fft", + "chip_support", + "spi", + "jpeg_enc", + "sdcard", + "include/bk_private", + "include/bk_private/legacy", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/driver/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/middleware/driver/CMakeLists.txt index 6066b61..084adf1 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/driver/CMakeLists.txt +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/driver/CMakeLists.txt @@ -65,7 +65,7 @@ set(srcs saradc/adc_statis.c security/security.c security/hal_aes.c - security/hal_sha.c + #security/hal_sha.c spinlock/amp_res_lock.c ) if (CONFIG_AON_WDT) @@ -360,7 +360,7 @@ if (NOT CONFIG_FULLY_HOSTED) ) list(APPEND srcs - "dsp/dsp.c" + #"dsp/dsp.c" ) if (CONFIG_SOC_BK7271) @@ -372,7 +372,7 @@ endif() #if (NOT CONFIG_FULLY_HOSTED) if (CONFIG_SOC_BK7256XX) list(APPEND srcs - "bk7256/mailbox_driver.c" + #"bk7256/mailbox_driver.c" ) endif() diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/driver/uart/printf.c b/bk7235/liteos_m/bk_sdk_armino/middleware/driver/uart/printf.c new file mode 100755 index 0000000..fa2f93f --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/driver/uart/printf.c @@ -0,0 +1,1250 @@ +/* + * Copyright (c) 1995 Patrick Powell. + * + * This code is based on code written by Patrick Powell . + * It may be used for any purpose as long as this notice remains intact on all + * source code distributions. + */ + +/* + * Copyright (c) 2008 Holger Weiss. + * + * This version of the code is maintained by Holger Weiss . + * My changes to the code may freely be used, modified and/or redistributed for + * any purpose. It would be nice if additions and fixes to this file (including + * trivial code cleanups) would be sent back in order to let me include them in + * the version available at . + * However, this is not a requirement for using or redistributing (possibly + * modified) versions of this file, nor is leaving this notice intact mandatory. + */ + +#include +#include /* For *_MAX. */ +#include /* For intmax_t (if not defined in ). */ +#include /* For ptrdiff_t. */ +#include /* For intmax_t. */ +#include /* For pow(3), NAN, and INFINITY. */ +#include /* For strcmp(3). */ +#include +#include "bk_uart.h" +#include + +#define VA_START(ap, last) va_start(ap, last) +#define VA_SHIFT(ap, value, type) /* No-op for ANSI C. */ + +/* Support for unsigned long long int. We may also need ULLONG_MAX. */ +#ifndef ULONG_MAX /* We may need ULONG_MAX as a fallback. */ +#ifdef UINT_MAX +#define ULONG_MAX UINT_MAX +#else +#define ULONG_MAX INT_MAX +#endif /* defined(UINT_MAX) */ +#endif /* !defined(ULONG_MAX) */ +#ifdef ULLONG +#undef ULLONG +#endif /* defined(ULLONG) */ +#if HAVE_UNSIGNED_LONG_LONG_INT +#define ULLONG unsigned long long int +#ifndef ULLONG_MAX +#define ULLONG_MAX ULONG_MAX +#endif /* !defined(ULLONG_MAX) */ +#else +#define ULLONG unsigned long int +#ifdef ULLONG_MAX +#undef ULLONG_MAX +#endif /* defined(ULLONG_MAX) */ +#define ULLONG_MAX ULONG_MAX +#endif /* HAVE_LONG_LONG_INT */ + +/* Support for uintmax_t. We also need UINTMAX_MAX. */ +#ifdef UINTMAX_T +#undef UINTMAX_T +#endif /* defined(UINTMAX_T) */ +#if HAVE_UINTMAX_T || defined(uintmax_t) +#define UINTMAX_T uintmax_t +#ifndef UINTMAX_MAX +#define UINTMAX_MAX ULLONG_MAX +#endif /* !defined(UINTMAX_MAX) */ +#else +#define UINTMAX_T ULLONG +#ifdef UINTMAX_MAX +#undef UINTMAX_MAX +#endif /* defined(UINTMAX_MAX) */ +#define UINTMAX_MAX ULLONG_MAX +#endif /* HAVE_UINTMAX_T || defined(uintmax_t) */ + +/* Support for long double. */ +#ifndef LDOUBLE +#if HAVE_LONG_DOUBLE +#define LDOUBLE long double +#else +#define LDOUBLE double +#endif /* HAVE_LONG_DOUBLE */ +#endif /* !defined(LDOUBLE) */ + +/* Support for long long int. */ +#ifndef LLONG +#if HAVE_LONG_LONG_INT +#define LLONG long long int +#else +#define LLONG long int +#endif /* HAVE_LONG_LONG_INT */ +#endif /* !defined(LLONG) */ + +/* Support for intmax_t. */ +#ifndef INTMAX_T +#if HAVE_INTMAX_T || defined(intmax_t) +#define INTMAX_T intmax_t +#else +#define INTMAX_T LLONG +#endif /* HAVE_INTMAX_T || defined(intmax_t) */ +#endif /* !defined(INTMAX_T) */ + +/* Support for uintptr_t. */ +#ifndef UINTPTR_T +#if HAVE_UINTPTR_T || defined(uintptr_t) +#define UINTPTR_T uintptr_t +#else +#define UINTPTR_T unsigned long int +#endif /* HAVE_UINTPTR_T || defined(uintptr_t) */ +#endif /* !defined(UINTPTR_T) */ + +/* Support for ptrdiff_t. */ +#ifndef PTRDIFF_T +#if HAVE_PTRDIFF_T || defined(ptrdiff_t) +#define PTRDIFF_T ptrdiff_t +#else +#define PTRDIFF_T long int +#endif /* HAVE_PTRDIFF_T || defined(ptrdiff_t) */ +#endif /* !defined(PTRDIFF_T) */ + +/* + * We need an unsigned integer type corresponding to ptrdiff_t (cf. C99: + * 7.19.6.1, 7). However, we'll simply use PTRDIFF_T and convert it to an + * unsigned type if necessary. This should work just fine in practice. + */ +#ifndef UPTRDIFF_T +#define UPTRDIFF_T PTRDIFF_T +#endif /* !defined(UPTRDIFF_T) */ + +/* + * We need a signed integer type corresponding to size_t (cf. C99: 7.19.6.1, 7). + * However, we'll simply use size_t and convert it to a signed type if + * necessary. This should work just fine in practice. + */ +#ifndef SSIZE_T +#define SSIZE_T size_t +#endif /* !defined(SSIZE_T) */ + +/* + * Buffer size to hold the octal string representation of UINT128_MAX without + * nul-termination ("3777777777777777777777777777777777777777777"). + */ +#ifdef MAX_CONVERT_LENGTH +#undef MAX_CONVERT_LENGTH +#endif /* defined(MAX_CONVERT_LENGTH) */ +#define MAX_CONVERT_LENGTH 43 + +/* Format read states. */ +#define PRINT_S_DEFAULT 0 +#define PRINT_S_FLAGS 1 +#define PRINT_S_WIDTH 2 +#define PRINT_S_DOT 3 +#define PRINT_S_PRECISION 4 +#define PRINT_S_MOD 5 +#define PRINT_S_CONV 6 + +/* Format flags. */ +#define PRINT_F_MINUS (1 << 0) +#define PRINT_F_PLUS (1 << 1) +#define PRINT_F_SPACE (1 << 2) +#define PRINT_F_NUM (1 << 3) +#define PRINT_F_ZERO (1 << 4) +#define PRINT_F_QUOTE (1 << 5) +#define PRINT_F_UP (1 << 6) +#define PRINT_F_UNSIGNED (1 << 7) +#define PRINT_F_TYPE_G (1 << 8) +#define PRINT_F_TYPE_E (1 << 9) + +/* Conversion flags. */ +#define PRINT_C_CHAR 1 +#define PRINT_C_SHORT 2 +#define PRINT_C_LONG 3 +#define PRINT_C_LLONG 4 +#define PRINT_C_LDOUBLE 5 +#define PRINT_C_SIZE 6 +#define PRINT_C_PTRDIFF 7 +#define PRINT_C_INTMAX 8 + +#ifndef MAX +#define MAX(x, y) ((x >= y) ? x : y) +#endif /* !defined(MAX) */ +#ifndef CHARTOINT +#define CHARTOINT(ch) (ch - '0') +#endif /* !defined(CHARTOINT) */ +#ifndef ISDIGIT +#define ISDIGIT(ch) ('0' <= (unsigned char)ch && (unsigned char)ch <= '9') +#endif /* !defined(ISDIGIT) */ +#ifndef ISNAN +#define ISNAN(x) (x != x) +#endif /* !defined(ISNAN) */ +#ifndef ISINF +#define ISINF(x) (x != 0.0 && x + x == x) +#endif /* !defined(ISINF) */ + +#ifdef OUTCHAR +#undef OUTCHAR +#endif /* defined(OUTCHAR) */ +#define OUTCHAR(str, len, size, ch) \ + do { \ + if (len + 1 < size) \ + str[len] = ch; \ + (len)++; \ + } while (/* CONSTCOND */ 0) + +static void fmtstr(char *, size_t *, size_t, const char *, int, int, int); +static void fmtint(char *, size_t *, size_t, INTMAX_T, int, int, int, int); +static void fmtflt(char *, size_t *, size_t, LDOUBLE, int, int, int, int *); +static void printsep(char *, size_t *, size_t); +static int getnumsep(int); +static int getexponent(LDOUBLE); +static int convert(UINTMAX_T, char *, size_t, int, int); +static UINTMAX_T cast(LDOUBLE); +static UINTMAX_T myround(LDOUBLE); +static LDOUBLE mypow10(int); +static void fmtmac(char *buf, size_t *len, size_t size, const unsigned char *mac, int caps); +static void fmtip(char *buf, size_t *len, size_t size, unsigned int value); + +int __wrap_vsnprintf(char *str, size_t size, const char *format, va_list args) +{ + LDOUBLE fvalue; + INTMAX_T value; + unsigned char cvalue; + const char *strvalue; + INTMAX_T *intmaxptr; + PTRDIFF_T *ptrdiffptr; + SSIZE_T *sizeptr; + LLONG *llongptr; + long int *longptr; + int *intptr; + short int *shortptr; + signed char *charptr; + size_t len = 0; + int overflow = 0; + int base = 0; + int cflags = 0; + int flags = 0; + int width = 0; + int precision = -1; + int state = PRINT_S_DEFAULT; + char ch = *format++; + + /* + * C99 says: "If `n' is zero, nothing is written, and `s' may be a null + * pointer." (7.19.6.5, 2) We're forgiving and allow a NULL pointer + * even if a size larger than zero was specified. At least NetBSD's + * snprintf(3) does the same, as well as other versions of this file. + * (Though some of these versions will write to a non-NULL buffer even + * if a size of zero was specified, which violates the standard.) + */ + if (str == NULL && size != 0) + size = 0; + + while (ch != '\0') { + switch (state) { + case PRINT_S_DEFAULT: + if (ch == '%') + state = PRINT_S_FLAGS; + else + OUTCHAR(str, len, size, ch); + ch = *format++; + break; + case PRINT_S_FLAGS: + switch (ch) { + case '-': + flags |= PRINT_F_MINUS; + ch = *format++; + break; + case '+': + flags |= PRINT_F_PLUS; + ch = *format++; + break; + case ' ': + flags |= PRINT_F_SPACE; + ch = *format++; + break; + case '#': + flags |= PRINT_F_NUM; + ch = *format++; + break; + case '0': + flags |= PRINT_F_ZERO; + ch = *format++; + break; + case '\'': /* SUSv2 flag (not in C99). */ + flags |= PRINT_F_QUOTE; + ch = *format++; + break; + default: + state = PRINT_S_WIDTH; + break; + } + break; + case PRINT_S_WIDTH: + if (ISDIGIT(ch)) { + ch = CHARTOINT(ch); + if (width > (INT_MAX - ch) / 10) { + overflow = 1; + goto out; + } + width = 10 * width + ch; + ch = *format++; + } else if (ch == '*') { + /* + * C99 says: "A negative field width argument is + * taken as a `-' flag followed by a positive + * field width." (7.19.6.1, 5) + */ + if ((width = va_arg(args, int)) < 0) { + flags |= PRINT_F_MINUS; + width = -width; + } + ch = *format++; + state = PRINT_S_DOT; + } else + state = PRINT_S_DOT; + break; + case PRINT_S_DOT: + if (ch == '.') { + state = PRINT_S_PRECISION; + ch = *format++; + } else + state = PRINT_S_MOD; + break; + case PRINT_S_PRECISION: + if (precision == -1) + precision = 0; + if (ISDIGIT(ch)) { + ch = CHARTOINT(ch); + if (precision > (INT_MAX - ch) / 10) { + overflow = 1; + goto out; + } + precision = 10 * precision + ch; + ch = *format++; + } else if (ch == '*') { + /* + * C99 says: "A negative precision argument is + * taken as if the precision were omitted." + * (7.19.6.1, 5) + */ + if ((precision = va_arg(args, int)) < 0) + precision = -1; + ch = *format++; + state = PRINT_S_MOD; + } else + state = PRINT_S_MOD; + break; + case PRINT_S_MOD: + switch (ch) { + case 'h': + ch = *format++; + if (ch == 'h') { /* It's a char. */ + ch = *format++; + cflags = PRINT_C_CHAR; + } else + cflags = PRINT_C_SHORT; + break; + case 'l': + ch = *format++; + if (ch == 'l') { /* It's a long long. */ + ch = *format++; + cflags = PRINT_C_LLONG; + } else + cflags = PRINT_C_LONG; + break; + case 'L': + cflags = PRINT_C_LDOUBLE; + ch = *format++; + break; + case 'j': + cflags = PRINT_C_INTMAX; + ch = *format++; + break; + case 't': + cflags = PRINT_C_PTRDIFF; + ch = *format++; + break; + case 'z': + cflags = PRINT_C_SIZE; + ch = *format++; + break; + } + state = PRINT_S_CONV; + break; + case PRINT_S_CONV: + switch (ch) { + case 'd': + /* FALLTHROUGH */ + case 'i': + switch (cflags) { + case PRINT_C_CHAR: + value = (signed char)va_arg(args, int); + break; + case PRINT_C_SHORT: + value = (short int)va_arg(args, int); + break; + case PRINT_C_LONG: + value = va_arg(args, long int); + break; + case PRINT_C_LLONG: + value = va_arg(args, LLONG); + break; + case PRINT_C_SIZE: + value = va_arg(args, SSIZE_T); + break; + case PRINT_C_INTMAX: + value = va_arg(args, INTMAX_T); + break; + case PRINT_C_PTRDIFF: + value = va_arg(args, PTRDIFF_T); + break; + default: + value = va_arg(args, int); + break; + } + fmtint(str, &len, size, value, 10, width, + precision, flags); + break; + case 'X': + flags |= PRINT_F_UP; + /* FALLTHROUGH */ + case 'x': + base = 16; + /* FALLTHROUGH */ + case 'o': + if (base == 0) + base = 8; + /* FALLTHROUGH */ + case 'u': + if (base == 0) + base = 10; + flags |= PRINT_F_UNSIGNED; + switch (cflags) { + case PRINT_C_CHAR: + value = (unsigned char)va_arg(args, + unsigned int); + break; + case PRINT_C_SHORT: + value = (unsigned short int)va_arg(args, + unsigned int); + break; + case PRINT_C_LONG: + value = va_arg(args, unsigned long int); + break; + case PRINT_C_LLONG: + value = va_arg(args, ULLONG); + break; + case PRINT_C_SIZE: + value = va_arg(args, size_t); + break; + case PRINT_C_INTMAX: + value = va_arg(args, UINTMAX_T); + break; + case PRINT_C_PTRDIFF: + value = va_arg(args, UPTRDIFF_T); + break; + default: + value = va_arg(args, unsigned int); + break; + } + fmtint(str, &len, size, (UINTMAX_T)value, base, width, + precision, flags); + break; + case 'A': + /* Not yet supported, we'll use "%F". */ + /* FALLTHROUGH */ + case 'F': + flags |= PRINT_F_UP; + case 'a': + /* Not yet supported, we'll use "%f". */ + /* FALLTHROUGH */ + case 'f': + if (cflags == PRINT_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + fmtflt(str, &len, size, fvalue, width, + precision, flags, &overflow); + if (overflow) + goto out; + break; + case 'E': + flags |= PRINT_F_UP; + /* FALLTHROUGH */ + case 'e': + flags |= PRINT_F_TYPE_E; + if (cflags == PRINT_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + fmtflt(str, &len, size, fvalue, width, + precision, flags, &overflow); + if (overflow) + goto out; + break; + case 'G': + flags |= PRINT_F_UP; + /* FALLTHROUGH */ + case 'g': + flags |= PRINT_F_TYPE_G; + if (cflags == PRINT_C_LDOUBLE) + fvalue = va_arg(args, LDOUBLE); + else + fvalue = va_arg(args, double); + /* + * If the precision is zero, it is treated as + * one (cf. C99: 7.19.6.1, 8). + */ + if (precision == 0) + precision = 1; + fmtflt(str, &len, size, fvalue, width, + precision, flags, &overflow); + if (overflow) + goto out; + break; + case 'c': + cvalue = va_arg(args, int); + OUTCHAR(str, len, size, cvalue); + break; + case 's': + strvalue = va_arg(args, char *); + fmtstr(str, &len, size, strvalue, width, + precision, flags); + break; + case 'p': + /* + * C99 says: "The value of the pointer is + * converted to a sequence of printing + * characters, in an implementation-defined + * manner." (C99: 7.19.6.1, 8) + */ + if (*format == 'm' || *format == 'M') { + unsigned char *macstr; + if (*format == 'M') + flags |= PRINT_F_UP; + format++; + if ((macstr = va_arg(args, unsigned char *)) == NULL) + macstr = (unsigned char *)"\x00\x00\x00\x00\x00\x00"; + fmtmac(str, &len, size, macstr, flags & PRINT_F_UP); + + break; + } else if (*format == 'i' || *format == 'I') { + format++; + value = va_arg(args, unsigned int); + fmtip(str, &len, size, (unsigned int)value); + break; + } else { + if ((strvalue = va_arg(args, void *)) == NULL) { + /* + * We use the glibc format. BSD prints + * "0x0", SysV "0". + */ + fmtstr(str, &len, size, "(nil)", width, + -1, flags); + } else { + /* + * We use the BSD/glibc format. SysV + * omits the "0x" prefix (which we emit + * using the PRINT_F_NUM flag). + */ + flags |= PRINT_F_NUM; + flags |= PRINT_F_UNSIGNED; + fmtint(str, &len, size, + (UINTPTR_T)strvalue, 16, width, + precision, flags); + } + } + break; + case 'n': + switch (cflags) { + case PRINT_C_CHAR: + charptr = va_arg(args, signed char *); + *charptr = len; + break; + case PRINT_C_SHORT: + shortptr = va_arg(args, short int *); + *shortptr = len; + break; + case PRINT_C_LONG: + longptr = va_arg(args, long int *); + *longptr = len; + break; + case PRINT_C_LLONG: + llongptr = va_arg(args, LLONG *); + *llongptr = len; + break; + case PRINT_C_SIZE: + /* + * C99 says that with the "z" length + * modifier, "a following `n' conversion + * specifier applies to a pointer to a + * signed integer type corresponding to + * size_t argument." (7.19.6.1, 7) + */ + sizeptr = va_arg(args, SSIZE_T *); + *sizeptr = len; + break; + case PRINT_C_INTMAX: + intmaxptr = va_arg(args, INTMAX_T *); + *intmaxptr = len; + break; + case PRINT_C_PTRDIFF: + ptrdiffptr = va_arg(args, PTRDIFF_T *); + *ptrdiffptr = len; + break; + default: + intptr = va_arg(args, int *); + *intptr = len; + break; + } + break; + case '%': /* Print a "%" character verbatim. */ + OUTCHAR(str, len, size, ch); + break; + default: /* Skip other characters. */ + break; + } + ch = *format++; + state = PRINT_S_DEFAULT; + base = cflags = flags = width = 0; + precision = -1; + break; + } + } +out: + if (len < size) + str[len] = '\0'; + else if (size > 0) + str[size - 1] = '\0'; + + if (overflow || len >= INT_MAX) { + //errno = overflow ? EOVERFLOW : ERANGE; + return -1; + } + return (int)len; +} + +static void fmtstr(char *str, size_t *len, size_t size, const char *value, int width, + int precision, int flags) +{ + int padlen, strln; /* Amount to pad. */ + int noprecision = (precision == -1); + + if (value == NULL) /* We're forgiving. */ + value = "(null)"; + + /* If a precision was specified, don't read the string past it. */ + for (strln = 0; value[strln] != '\0' && + (noprecision || strln < precision); strln++) + continue; + + if ((padlen = width - strln) < 0) + padlen = 0; + if (flags & PRINT_F_MINUS) /* Left justify. */ + padlen = -padlen; + + while (padlen > 0) { /* Leading spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen--; + } + while (*value != '\0' && (noprecision || precision-- > 0)) { + OUTCHAR(str, *len, size, *value); + value++; + } + while (padlen < 0) { /* Trailing spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen++; + } +} + +static void fmtint(char *str, size_t *len, size_t size, INTMAX_T value, int base, int width, + int precision, int flags) +{ + UINTMAX_T uvalue; + char iconvert[MAX_CONVERT_LENGTH]; + char sign = 0; + char hexprefix = 0; + int spadlen = 0; /* Amount to space pad. */ + int zpadlen = 0; /* Amount to zero pad. */ + int pos; + int separators = (flags & PRINT_F_QUOTE); + int noprecision = (precision == -1); + + if (flags & PRINT_F_UNSIGNED) + uvalue = value; + else { + uvalue = (value >= 0) ? value : -value; + if (value < 0) + sign = '-'; + else if (flags & PRINT_F_PLUS) /* Do a sign. */ + sign = '+'; + else if (flags & PRINT_F_SPACE) + sign = ' '; + } + + pos = convert(uvalue, iconvert, sizeof(iconvert), base, + flags & PRINT_F_UP); + + if (flags & PRINT_F_NUM && uvalue != 0) { + /* + * C99 says: "The result is converted to an `alternative form'. + * For `o' conversion, it increases the precision, if and only + * if necessary, to force the first digit of the result to be a + * zero (if the value and precision are both 0, a single 0 is + * printed). For `x' (or `X') conversion, a nonzero result has + * `0x' (or `0X') prefixed to it." (7.19.6.1, 6) + */ + switch (base) { + case 8: + if (precision <= pos) + precision = pos + 1; + break; + case 16: + hexprefix = (flags & PRINT_F_UP) ? 'X' : 'x'; + break; + } + } + + if (separators) /* Get the number of group separators we'll print. */ + separators = getnumsep(pos); + + zpadlen = precision - pos - separators; + spadlen = width /* Minimum field width. */ + - separators /* Number of separators. */ + - MAX(precision, pos) /* Number of integer digits. */ + - ((sign != 0) ? 1 : 0) /* Will we print a sign? */ + - ((hexprefix != 0) ? 2 : 0); /* Will we print a prefix? */ + + if (zpadlen < 0) + zpadlen = 0; + if (spadlen < 0) + spadlen = 0; + + /* + * C99 says: "If the `0' and `-' flags both appear, the `0' flag is + * ignored. For `d', `i', `o', `u', `x', and `X' conversions, if a + * precision is specified, the `0' flag is ignored." (7.19.6.1, 6) + */ + if (flags & PRINT_F_MINUS) /* Left justify. */ + spadlen = -spadlen; + else if (flags & PRINT_F_ZERO && noprecision) { + zpadlen += spadlen; + spadlen = 0; + } + while (spadlen > 0) { /* Leading spaces. */ + OUTCHAR(str, *len, size, ' '); + spadlen--; + } + if (sign != 0) /* Sign. */ + OUTCHAR(str, *len, size, sign); + if (hexprefix != 0) { /* A "0x" or "0X" prefix. */ + OUTCHAR(str, *len, size, '0'); + OUTCHAR(str, *len, size, hexprefix); + } + while (zpadlen > 0) { /* Leading zeros. */ + OUTCHAR(str, *len, size, '0'); + zpadlen--; + } + while (pos > 0) { /* The actual digits. */ + pos--; + OUTCHAR(str, *len, size, iconvert[pos]); + if (separators > 0 && pos > 0 && pos % 3 == 0) + printsep(str, len, size); + } + while (spadlen < 0) { /* Trailing spaces. */ + OUTCHAR(str, *len, size, ' '); + spadlen++; + } +} + +static void fmtflt(char *str, size_t *len, size_t size, LDOUBLE fvalue, int width, + int precision, int flags, int *overflow) +{ + LDOUBLE ufvalue; + UINTMAX_T intpart; + UINTMAX_T fracpart; + UINTMAX_T mask; + const char *infnan = NULL; + char iconvert[MAX_CONVERT_LENGTH]; + char fconvert[MAX_CONVERT_LENGTH]; + char econvert[4]; /* "e-12" (without nul-termination). */ + char esign = 0; + char sign = 0; + int leadfraczeros = 0; + int exponent = 0; + int emitpoint = 0; + int omitzeros = 0; + int omitcount = 0; + int padlen = 0; + int epos = 0; + int fpos = 0; + int ipos = 0; + int separators = (flags & PRINT_F_QUOTE); + int estyle = (flags & PRINT_F_TYPE_E); + + /* + * AIX' man page says the default is 0, but C99 and at least Solaris' + * and NetBSD's man pages say the default is 6, and sprintf(3) on AIX + * defaults to 6. + */ + if (precision == -1) + precision = 6; + + if (fvalue < 0.0) + sign = '-'; + else if (flags & PRINT_F_PLUS) /* Do a sign. */ + sign = '+'; + else if (flags & PRINT_F_SPACE) + sign = ' '; + + if (ISNAN(fvalue)) + infnan = (flags & PRINT_F_UP) ? "NAN" : "nan"; + else if (ISINF(fvalue)) + infnan = (flags & PRINT_F_UP) ? "INF" : "inf"; + + if (infnan != NULL) { + if (sign != 0) + iconvert[ipos++] = sign; + while (*infnan != '\0') + iconvert[ipos++] = *infnan++; + fmtstr(str, len, size, iconvert, width, ipos, flags); + return; + } + + /* "%e" (or "%E") or "%g" (or "%G") conversion. */ + if (flags & PRINT_F_TYPE_E || flags & PRINT_F_TYPE_G) { + if (flags & PRINT_F_TYPE_G) { + /* + * For "%g" (and "%G") conversions, the precision + * specifies the number of significant digits, which + * includes the digits in the integer part. The + * conversion will or will not be using "e-style" (like + * "%e" or "%E" conversions) depending on the precision + * and on the exponent. However, the exponent can be + * affected by rounding the converted value, so we'll + * leave this decision for later. Until then, we'll + * assume that we're going to do an "e-style" conversion + * (in order to get the exponent calculated). For + * "e-style", the precision must be decremented by one. + */ + precision--; + /* + * For "%g" (and "%G") conversions, trailing zeros are + * removed from the fractional portion of the result + * unless the "#" flag was specified. + */ + if (!(flags & PRINT_F_NUM)) + omitzeros = 1; + } + exponent = getexponent(fvalue); + estyle = 1; + } + +again: + /* + * Sorry, we only support 9, 19, or 38 digits (that is, the number of + * digits of the 32-bit, the 64-bit, or the 128-bit UINTMAX_MAX value + * minus one) past the decimal point due to our conversion method. + */ + switch (sizeof(UINTMAX_T)) { + case 16: + if (precision > 38) + precision = 38; + break; + case 8: + if (precision > 19) + precision = 19; + break; + default: + if (precision > 9) + precision = 9; + break; + } + + ufvalue = (fvalue >= 0.0) ? fvalue : -fvalue; + if (estyle) /* We want exactly one integer digit. */ + ufvalue /= mypow10(exponent); + + if ((intpart = cast(ufvalue)) == UINTMAX_MAX) { + *overflow = 1; + return; + } + + /* + * Factor of ten with the number of digits needed for the fractional + * part. For example, if the precision is 3, the mask will be 1000. + */ + mask = mypow10(precision); + /* + * We "cheat" by converting the fractional part to integer by + * multiplying by a factor of ten. + */ + if ((fracpart = myround(mask * (ufvalue - intpart))) >= mask) { + /* + * For example, ufvalue = 2.99962, intpart = 2, and mask = 1000 + * (because precision = 3). Now, myround(1000 * 0.99962) will + * return 1000. So, the integer part must be incremented by one + * and the fractional part must be set to zero. + */ + intpart++; + fracpart = 0; + if (estyle && intpart == 10) { + /* + * The value was rounded up to ten, but we only want one + * integer digit if using "e-style". So, the integer + * part must be set to one and the exponent must be + * incremented by one. + */ + intpart = 1; + exponent++; + } + } + + /* + * Now that we know the real exponent, we can check whether or not to + * use "e-style" for "%g" (and "%G") conversions. If we don't need + * "e-style", the precision must be adjusted and the integer and + * fractional parts must be recalculated from the original value. + * + * C99 says: "Let P equal the precision if nonzero, 6 if the precision + * is omitted, or 1 if the precision is zero. Then, if a conversion + * with style `E' would have an exponent of X: + * + * - if P > X >= -4, the conversion is with style `f' (or `F') and + * precision P - (X + 1). + * + * - otherwise, the conversion is with style `e' (or `E') and precision + * P - 1." (7.19.6.1, 8) + * + * Note that we had decremented the precision by one. + */ + if (flags & PRINT_F_TYPE_G && estyle && + precision + 1 > exponent && exponent >= -4) { + precision -= exponent; + estyle = 0; + goto again; + } + + if (estyle) { + if (exponent < 0) { + exponent = -exponent; + esign = '-'; + } else + esign = '+'; + + /* + * Convert the exponent. The sizeof(econvert) is 4. So, the + * econvert buffer can hold e.g. "e+99" and "e-99". We don't + * support an exponent which contains more than two digits. + * Therefore, the following stores are safe. + */ + epos = convert(exponent, econvert, 2, 10, 0); + /* + * C99 says: "The exponent always contains at least two digits, + * and only as many more digits as necessary to represent the + * exponent." (7.19.6.1, 8) + */ + if (epos == 1) + econvert[epos++] = '0'; + econvert[epos++] = esign; + econvert[epos++] = (flags & PRINT_F_UP) ? 'E' : 'e'; + } + + /* Convert the integer part and the fractional part. */ + ipos = convert(intpart, iconvert, sizeof(iconvert), 10, 0); + if (fracpart != 0) /* convert() would return 1 if fracpart == 0. */ + fpos = convert(fracpart, fconvert, sizeof(fconvert), 10, 0); + + leadfraczeros = precision - fpos; + + if (omitzeros) { + if (fpos > 0) /* Omit trailing fractional part zeros. */ + while (omitcount < fpos && fconvert[omitcount] == '0') + omitcount++; + else { /* The fractional part is zero, omit it completely. */ + omitcount = precision; + leadfraczeros = 0; + } + precision -= omitcount; + } + + /* + * Print a decimal point if either the fractional part is non-zero + * and/or the "#" flag was specified. + */ + if (precision > 0 || flags & PRINT_F_NUM) + emitpoint = 1; + if (separators) /* Get the number of group separators we'll print. */ + separators = getnumsep(ipos); + + padlen = width /* Minimum field width. */ + - ipos /* Number of integer digits. */ + - epos /* Number of exponent characters. */ + - precision /* Number of fractional digits. */ + - separators /* Number of group separators. */ + - (emitpoint ? 1 : 0) /* Will we print a decimal point? */ + - ((sign != 0) ? 1 : 0); /* Will we print a sign character? */ + + if (padlen < 0) + padlen = 0; + + /* + * C99 says: "If the `0' and `-' flags both appear, the `0' flag is + * ignored." (7.19.6.1, 6) + */ + if (flags & PRINT_F_MINUS) /* Left justifty. */ + padlen = -padlen; + else if (flags & PRINT_F_ZERO && padlen > 0) { + if (sign != 0) { /* Sign. */ + OUTCHAR(str, *len, size, sign); + sign = 0; + } + while (padlen > 0) { /* Leading zeros. */ + OUTCHAR(str, *len, size, '0'); + padlen--; + } + } + while (padlen > 0) { /* Leading spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen--; + } + if (sign != 0) /* Sign. */ + OUTCHAR(str, *len, size, sign); + while (ipos > 0) { /* Integer part. */ + ipos--; + OUTCHAR(str, *len, size, iconvert[ipos]); + if (separators > 0 && ipos > 0 && ipos % 3 == 0) + printsep(str, len, size); + } + if (emitpoint) /* Decimal point. */ + OUTCHAR(str, *len, size, '.'); + while (leadfraczeros > 0) { /* Leading fractional part zeros. */ + OUTCHAR(str, *len, size, '0'); + leadfraczeros--; + } + while (fpos > omitcount) { /* The remaining fractional part. */ + fpos--; + OUTCHAR(str, *len, size, fconvert[fpos]); + } + while (epos > 0) { /* Exponent. */ + epos--; + OUTCHAR(str, *len, size, econvert[epos]); + } + while (padlen < 0) { /* Trailing spaces. */ + OUTCHAR(str, *len, size, ' '); + padlen++; + } +} + +static void printsep(char *str, size_t *len, size_t size) +{ + OUTCHAR(str, *len, size, ','); +} + +static int getnumsep(int digits) +{ + int separators = (digits - ((digits % 3 == 0) ? 1 : 0)) / 3; + + return separators; +} + +static int getexponent(LDOUBLE value) +{ + LDOUBLE tmp = (value >= 0.0) ? value : -value; + int exponent = 0; + + /* + * We check for 99 > exponent > -99 in order to work around possible + * endless loops which could happen (at least) in the second loop (at + * least) if we're called with an infinite value. However, we checked + * for infinity before calling this function using our ISINF() macro, so + * this might be somewhat paranoid. + */ + while (tmp < 1.0 && tmp > 0.0 && --exponent > -99) + tmp *= 10; + while (tmp >= 10.0 && ++exponent < 99) + tmp /= 10; + + return exponent; +} + +static int convert(UINTMAX_T value, char *buf, size_t size, int base, int caps) +{ + const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef"; + size_t pos = 0; + + /* We return an unterminated buffer with the digits in reverse order. */ + do { + buf[pos++] = digits[value % base]; + value /= base; + } while (value != 0 && pos < size); + + return (int)pos; +} + +static int convert_ip(unsigned int value, char *buf, size_t size) +{ + const char *digits = "0123456789"; + int i; + unsigned char c; + size_t pos = 0; + + for (i = 0; i < 4; i++) { + c = (value >> (i * 8)) & 0xff; + + /* We return an unterminated buffer with the digits in reverse order. */ + do { + buf[pos++] = digits[c % 10]; + c /= 10; + } while (c != 0 && pos < size); + + if (i != 3 && pos < size) + buf[pos++] = '.'; + } + + return (int)pos; +} + +/* TODO: IPv6 */ +static void fmtip(char *buf, size_t *len, size_t size, unsigned int value) +{ + int pos; + char ip_buf[18]; + + pos = convert_ip(value, ip_buf, sizeof(ip_buf)); + if (pos > 0) pos--; + for (; pos >= 0; pos--) + OUTCHAR(buf, *len, size, ip_buf[pos]); +} + +static void fmtmac(char *buf, size_t *len, size_t size, const unsigned char *mac, int caps) +{ + const char *digits = caps ? "0123456789ABCDEF" : "0123456789abcdef"; + int i; + unsigned char c; + + for (i = 0; i < 6; i++) { + c = mac[i]; + OUTCHAR(buf, *len, size, digits[(c >> 4) & 0xf]); + OUTCHAR(buf, *len, size, digits[c & 0xf]); + if (i != 5) + OUTCHAR(buf, *len, size, ':'); + } +} + +static UINTMAX_T cast(LDOUBLE value) +{ + UINTMAX_T result; + + /* + * We check for ">=" and not for ">" because if UINTMAX_MAX cannot be + * represented exactly as an LDOUBLE value (but is less than LDBL_MAX), + * it may be increased to the nearest higher representable value for the + * comparison (cf. C99: 6.3.1.4, 2). It might then equal the LDOUBLE + * value although converting the latter to UINTMAX_T would overflow. + */ + if (value >= UINTMAX_MAX) + return UINTMAX_MAX; + + result = value; + /* + * At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to + * an integer type converts e.g. 1.9 to 2 instead of 1 (which violates + * the standard). Sigh. + */ + return (result <= value) ? result : result - 1; +} + +static UINTMAX_T myround(LDOUBLE value) +{ + UINTMAX_T intpart = cast(value); + + return ((value -= intpart) < 0.5) ? intpart : intpart + 1; +} + +static LDOUBLE mypow10(int exponent) +{ + LDOUBLE result = 1; + + while (exponent > 0) { + result *= 10; + exponent--; + } + while (exponent < 0) { + result /= 10; + exponent++; + } + return result; +} + +int __wrap_vasprintf(char **ret, const char *format, va_list ap) +{ + size_t size; + int len; + va_list aq; + + va_copy(aq, ap); + len = __wrap_vsnprintf(NULL, 0, format, aq); + va_end(aq); + + if (len < 0 || (*ret = os_malloc(size = len + 1)) == NULL) + return -1; + + return __wrap_vsnprintf(*ret, size, format, ap); +} + +int __wrap_snprintf(char *str, size_t size, const char *format, ...) +{ + va_list ap; + int len; + + va_start(ap, format); + len = __wrap_vsnprintf(str, size, format, ap); + va_end(ap); + + return len; +} + +int __wrap_asprintf(char **ret, const char *format, ...) +{ + va_list ap; + int len; + + va_start(ap, format); + len = __wrap_vasprintf(ret, format, ap); + va_end(ap); + return len; +} + +int __wrap_sprintf(char *str, const char *format, ...) +{ + va_list ap; + int len; + + va_start(ap, format); + len = __wrap_vsnprintf(str, INT_MAX, format, ap); + va_end(ap); + + return len; +} + + + +int __wrap_puts(const char *s) +{ + uart_write_string(bk_get_printf_port(), s); + + return 1; /* non-negative value returned */ +} + diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/soc/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/middleware/soc/BUILD.gn new file mode 100755 index 0000000..4fdcf10 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/soc/BUILD.gn @@ -0,0 +1,99 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +lite_component(module_name) { + features = [ + ":bk7235", + ":common", + ] +} + +static_library("bk7235") { + sources = [ + "bk7235/hal/adc_hal_debug.c", + "bk7235/hal/adc_ll.c", + "bk7235/hal/aon_pmu_hal.c", + "bk7235/hal/aon_rtc_hal_debug.c", + "bk7235/hal/aon_rtc_ll.c", + "bk7235/hal/dma_hal_debug.c", + "bk7235/hal/dma_ll.c", + "bk7235/hal/efuse_hal_debug.c", + "bk7235/hal/efuse_ll.c", + "bk7235/hal/fft_hal_debug.c", + "bk7235/hal/flash_hal_debug.c", + "bk7235/hal/gpio_hal_debug.c", + "bk7235/hal/gpio_ll.c", + "bk7235/hal/i2c_hal_debug.c", + "bk7235/hal/i2c_ll.c", + "bk7235/hal/i2s_hal_debug.c", + "bk7235/hal/icu_hal_debug.c", + "bk7235/hal/icu_ll.c", + "bk7235/hal/jpeg_dec_hal.c", + "bk7235/hal/jpeg_hal_debug.c", + "bk7235/hal/jpeg_ll.c", + "bk7235/hal/pwm_hal_debug.c", + "bk7235/hal/pwm_ll.c", + "bk7235/hal/spi_hal_debug.c", + "bk7235/hal/spi_ll.c", + "bk7235/hal/sys_hal.c", + "bk7235/hal/timer_hal_debug.c", + "bk7235/hal/timer_ll.c", + "bk7235/hal/trng_hal_debug.c", + "bk7235/hal/trng_ll.c", + "bk7235/hal/uart_hal_debug.c", + "bk7235/hal/uart_ll.c", + "bk7235/hal/wdt_hal_debug.c", + "bk7235/hal/wdt_ll.c", + "bk7235/stub.c", + ] + public_configs = [ + ":public", + "${beken_sdk_dir}/middleware/driver:public", + ] +} + +static_library("common") { + sources = [ + "common/hal/adc_hal.c", + "common/hal/aon_rtc_hal.c", + "common/hal/dma_hal.c", + "common/hal/efuse_hal.c", + "common/hal/flash_hal.c", + "common/hal/gpio_hal.c", + "common/hal/i2c_hal.c", + "common/hal/icu_hal.c", + "common/hal/pwm_hal.c", + "common/hal/spi_hal.c", + "common/hal/timer_hal.c", + "common/hal/trng_hal.c", + "common/hal/uart_hal.c", + "common/hal/wdt_hal.c", + ] + public_configs = [ + ":public", + "${beken_sdk_dir}/middleware/driver:public", + ] +} + +config("public") { + include_dirs = [ + "bk7235/soc", + "bk7235/hal", + "common/soc/include", + "common/hal/include", + ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/middleware/soc/bk7235/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/middleware/soc/bk7235/CMakeLists.txt index 58efa5f..e36d186 100755 --- a/bk7235/liteos_m/bk_sdk_armino/middleware/soc/bk7235/CMakeLists.txt +++ b/bk7235/liteos_m/bk_sdk_armino/middleware/soc/bk7235/CMakeLists.txt @@ -45,7 +45,7 @@ list(APPEND srcs "hal/fft_hal_debug.c" "hal/i2s_hal_debug.c" "hal/flash_hal_debug.c" - "hal/flash_ll.c" + #"hal/flash_ll.c" "hal/jpeg_dec_hal.c" ) diff --git a/bk7235/liteos_m/bk_sdk_armino/projects/BUILD.gn b/bk7235/liteos_m/bk_sdk_armino/projects/BUILD.gn new file mode 100755 index 0000000..776bb79 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/projects/BUILD.gn @@ -0,0 +1,25 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") +module_name = get_path_info(rebase_path("."), "name") +lite_component(module_name) { + features = [ ":main" ] +} + +static_library("main") { + sources = [ "bk7235/main/harmony_main.c" ] + public_configs = [ "${beken_sdk_dir}/components/bk_init:public" ] +} diff --git a/bk7235/liteos_m/bk_sdk_armino/projects/openharmony/.gitignore b/bk7235/liteos_m/bk_sdk_armino/projects/bk7235/.gitignore similarity index 100% rename from bk7235/liteos_m/bk_sdk_armino/projects/openharmony/.gitignore rename to bk7235/liteos_m/bk_sdk_armino/projects/bk7235/.gitignore diff --git a/bk7235/liteos_m/bk_sdk_armino/projects/openharmony/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/projects/bk7235/CMakeLists.txt similarity index 100% rename from bk7235/liteos_m/bk_sdk_armino/projects/openharmony/CMakeLists.txt rename to bk7235/liteos_m/bk_sdk_armino/projects/bk7235/CMakeLists.txt diff --git a/bk7235/liteos_m/bk_sdk_armino/projects/openharmony/config/bk7235.config b/bk7235/liteos_m/bk_sdk_armino/projects/bk7235/config/bk7235.config similarity index 100% rename from bk7235/liteos_m/bk_sdk_armino/projects/openharmony/config/bk7235.config rename to bk7235/liteos_m/bk_sdk_armino/projects/bk7235/config/bk7235.config diff --git a/bk7235/liteos_m/bk_sdk_armino/projects/openharmony/config/common.config b/bk7235/liteos_m/bk_sdk_armino/projects/bk7235/config/common.config similarity index 71% rename from bk7235/liteos_m/bk_sdk_armino/projects/openharmony/config/common.config rename to bk7235/liteos_m/bk_sdk_armino/projects/bk7235/config/common.config index 60f41c1..5b7bc26 100755 --- a/bk7235/liteos_m/bk_sdk_armino/projects/openharmony/config/common.config +++ b/bk7235/liteos_m/bk_sdk_armino/projects/bk7235/config/common.config @@ -6,6 +6,15 @@ CONFIG_LITEOS_M_BK=y CONFIG_EASY_FLASH=y CONFIG_MDNS=n CONFIG_HARMONY_LWIP=y +CONFIG_JPEG_ENCODE=n +CONFIG_CLI=y +CONFIG_I2C=n +CONFIG_I2S=n +CONFIG_SUPPORT_MATTER=n +CONFIG_AT_CMD=n +CONFIG_PWM=n +CONFIG_SECURITYIP=n + # FreeRTOS CONFIG_FREERTOS=n diff --git a/bk7235/liteos_m/bk_sdk_armino/projects/openharmony/main/CMakeLists.txt b/bk7235/liteos_m/bk_sdk_armino/projects/bk7235/main/CMakeLists.txt similarity index 100% rename from bk7235/liteos_m/bk_sdk_armino/projects/openharmony/main/CMakeLists.txt rename to bk7235/liteos_m/bk_sdk_armino/projects/bk7235/main/CMakeLists.txt diff --git a/bk7235/liteos_m/bk_sdk_armino/projects/openharmony/main/harmony_main.c b/bk7235/liteos_m/bk_sdk_armino/projects/bk7235/main/harmony_main.c similarity index 75% rename from bk7235/liteos_m/bk_sdk_armino/projects/openharmony/main/harmony_main.c rename to bk7235/liteos_m/bk_sdk_armino/projects/bk7235/main/harmony_main.c index 7517b82..6ead3d3 100755 --- a/bk7235/liteos_m/bk_sdk_armino/projects/openharmony/main/harmony_main.c +++ b/bk7235/liteos_m/bk_sdk_armino/projects/bk7235/main/harmony_main.c @@ -18,19 +18,24 @@ void __attribute__((weak)) OHOS_SystemInit(void) { - os_printf("@NOOS@"); - return; + os_printf("@NOOS@"); + return; } void __attribute__((weak)) OHOS_TEST(void) { } +extern void bk_set_printf_sync(uint8_t enable); +extern void shell_set_log_level(int level); + int main(void) { - legacy_init(); - OHOS_SystemInit(); - OHOS_TEST(); + bk_set_printf_sync(1); + shell_set_log_level(2); + legacy_init(); + OHOS_SystemInit(); + OHOS_TEST(); - return 0; + return 0; } diff --git a/bk7235/liteos_m/bk_sdk_armino/requirements.txt b/bk7235/liteos_m/bk_sdk_armino/requirements.txt deleted file mode 120000 index 935dd21..0000000 --- a/bk7235/liteos_m/bk_sdk_armino/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -tools/build_tools/build_files/requirements.txt \ No newline at end of file diff --git a/bk7235/liteos_m/bk_sdk_armino/sdkconfig.gni b/bk7235/liteos_m/bk_sdk_armino/sdkconfig.gni new file mode 100755 index 0000000..4d666d7 --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/sdkconfig.gni @@ -0,0 +1,603 @@ +# +# Automatically generated file. DO NOT EDIT. +# Beken IoT Development Framework (BEKEN-ARMINO) Project Configuration +# + +# +# SOC_CONFIG +# +# CONFIG_SOC_BK7231N is not set +# CONFIG_SOC_BK7231U is not set +# CONFIG_SOC_BK7251 is not set +# CONFIG_SOC_BK7271 is not set +# CONFIG_SOC_BK7236 is not set +# CONFIG_SOC_BK7236A is not set +# CONFIG_SOC_BK7256 is not set +# CONFIG_SOC_BK7256_CP1 is not set +CONFIG_SOC_BK7235 = true + +# CONFIG_SOC_BK7237 is not set +CONFIG_SOC_STR = "bk7235" +CONFIG_SOC_ARCH = "riscv" +CONFIG_SOC_BK7256XX = true + +# end of SOC_CONFIG + +# +# ARMINO Configuration +# + +# +# Common Configuration +# + +# +# Compile/Build +# +CONFIG_TOOLCHAIN_PATH = "/opt/risc-v/nds32le-elf-mculib-v5/bin" +CONFIG_TOOLCHAIN_PREFIX = "riscv32-elf-" + +# end of Compile/Build + +# +# Debug +# +CONFIG_DEBUG_FIRMWARE = true +CONFIG_ASSERT_IGNORE = true + +# CONFIG_ASSERT_HALT is not set +# CONFIG_ASSERT_REBOOT is not set +# CONFIG_JTAG is not set +# end of Debug +# end of Common Configuration + +# +# Features Configuration +# +CONFIG_LWIP = true + +# CONFIG_LWIP_V2_0 is not set +CONFIG_LWIP_V2_1 = true +CONFIG_NO_HOSTED = true + +# CONFIG_SEMI_HOSTED is not set +# CONFIG_FULLY_HOSTED is not set +# CONFIG_WIFI_SENSOR is not set +CONFIG_BLUETOOTH = true + +# end of Features Configuration + +# +# Components Configuration +# +# CONFIG_AT_CMD is not set + +# +# ATE +# +CONFIG_ATE = true +CONFIG_ATE_GPIO_ID = 0 +CONFIG_ATE_GPIO_PULL_UP = true + +# CONFIG_ATE_TEST is not set +# end of ATE + +# +# BLE +# +# CONFIG_BT is not set +CONFIG_BLE = true + +# CONFIG_BLE_5_X is not set +# CONFIG_BLE_4_2 is not set +CONFIG_BTDM_5_2 = true + +# CONFIG_BTDM_5_2_MINDTREE is not set +# end of BLE + +# +# Cli +# +CONFIG_CLI = true +CONFIG_BKREG = true +CONFIG_MAX_COMMANDS = 320 + +# CONFIG_IPERF_TEST is not set +# CONFIG_TCP_SERVER_TEST is not set +# CONFIG_AIRKISS_TEST is not set +# CONFIG_WIFI_RAW_TX_TEST is not set +# CONFIG_I2C1_TEST is not set +CONFIG_I2C2_TEST = true + +# CONFIG_UART_TEST is not set +CONFIG_SPI_TEST = true +CONFIG_PERI_TEST = true + +# CONFIG_RF_OTA_TEST is not set +CONFIG_SHELL_ASYNCLOG = true + +# CONFIG_TOUCH is not set +# CONFIG_SBC_TEST is not set +# CONFIG_AUDIO is not set +CONFIG_EFUSE = true + +# CONFIG_ICU is not set +# CONFIG_SECURITYIP is not set +# CONFIG_KEYVALUE is not set +CONFIG_IDLE_UART_OUT_TEST = true + +# CONFIG_COMPONENTS_WPA2_ENTERPRISE is not set +CONFIG_COMPONENTS_WPA_TWT_TEST = true + +# CONFIG_COMPONENTS_WFA_CA is not set +CONFIG_ENABLE_WIFI_DEFAULT_CONNECT = true + +# end of Cli + +# +# DUAL_CORE +# +# CONFIG_DUAL_CORE is not set +# end of DUAL_CORE + +# +# Internal Kconfig +# +CONFIG_MCU_PS = true + +# CONFIG_DEEP_PS is not set +CONFIG_TICK_CALI = true +CONFIG_STA_PS = true + +# end of Internal Kconfig + +# +# BK_NETIF_CONFIG +# +CONFIG_BK_NETIF = true + +# end of BK_NETIF_CONFIG + +# +# FreeRTOS +# +# CONFIG_FREERTOS is not set + +# +# Memory Debug +# +# CONFIG_MALLOC_STATIS is not set +CONFIG_MEM_DEBUG = true +CONFIG_MEM_DEBUG_FUNC_NAME = true +CONFIG_MEM_DEBUG_FUNC_NAME_LEN = 16 +CONFIG_MEM_DEBUG_TASK_NAME = true +CONFIG_MEM_DEBUG_TASK_NAME_LEN = 8 + +# end of Memory Debug +# end of FreeRTOS + +# +# LITEOS_M +# +# CONFIG_LITEOS_M is not set +# CONFIG_LITEOS_M_V3 is not set +CONFIG_LITEOS_M_MST = true +CONFIG_LITEOS_M_BK = true + +# end of LITEOS_M + +# +# NON_OS +# +# CONFIG_NON_OS is not set +# end of NON_OS + +CONFIG_CUSTOMIZE_HEAP_SIZE = 163840 + +# +# Startup +# +CONFIG_APP_MAIN_TASK_PRIO = 4 +CONFIG_APP_MAIN_TASK_STACK_SIZE = 4096 + +# CONFIG_MATTER_START is not set +# end of Startup + +# +# System +# +# CONFIG_BASE_MAC_FROM_EFUSE is not set +CONFIG_BASE_MAC_FROM_RF_OTP_FLASH = true + +# CONFIG_BASE_MAC_FROM_NVS is not set +CONFIG_RANDOM_MAC_ADDR = true + +# end of System + +# +# USB configuration +# +# CONFIG_USB is not set +# end of USB configuration + +# +# WiFi +# +CONFIG_WIFI_ENABLE = true +CONFIG_WIFI6_CODE_STACK = true +CONFIG_WIFI6 = true +CONFIG_WIFI4 = true +CONFIG_MSDU_RESV_HEAD_LENGTH = 96 +CONFIG_MSDU_RESV_TAIL_LENGTH = 16 +CONFIG_TASK_RECONNECT_PRIO = 4 + +# CONFIG_AP_MONITOR_COEXIST is not set +# CONFIG_WIFI_FAST_CONNECT is not set +# CONFIG_BSSID_CONNECT is not set +# CONFIG_WFA_CERT is not set +# CONFIG_LESS_MEMERY_IN_RWNX is not set +# CONFIG_AP_PROBEREQ_CB is not set +CONFIG_WIFI6_IP_DEBUG = true +CONFIG_MAC_BSSID = true + +# CONFIG_BK_COMPONENTS_P2P_GO is not set +# CONFIG_COMPONENTS_STA_VSIE is not set +# end of WiFi + +CONFIG_EASY_FLASH = true + +# +# key +# +# CONFIG_COMPONENTS_TX_BUFING is not set +# end of key + +# +# LwIP 2.1.2 +# +# CONFIG_IPV6 is not set +CONFIG_DHCP = true + +# CONFIG_AUTOIP is not set +# CONFIG_MDNS is not set +CONFIG_TASK_LWIP_PRIO = 4 + +# CONFIG_MIDEA is not set +# CONFIG_LWIP_FAST_DHCP is not set +CONFIG_HARMONY_LWIP = true + +# CONFIG_LWIP_MEM_DEFAULT is not set +CONFIG_LWIP_MEM_REDUCE = true + +# end of LwIP 2.1.2 + +# +# MEDIA +# +CONFIG_MEDIA = true + +# end of MEDIA + +CONFIG_SARADC_CALI = true + +# CONFIG_SECURITY is not set +CONFIG_TEMP_DETECT = true + +# +# FLASH SIZE +# +# CONFIG_FLASH_SIZE_4M is not set +# end of FLASH SIZE + +# +# ARCH_RISCV +# +CONFIG_ARCH_RISCV = true +CONFIG_NEST_INT_SUPPORT = true +CONFIG_MEMDUMP_ALL = true + +# CONFIG_SAVE_BOOT_TIME_POINT is not set +# CONFIG_CACHE_ENABLE is not set +# end of ARCH_RISCV + +# +# HOME SYSTEM +# +# CONFIG_SUPPORT_MATTER is not set +# end of HOME SYSTEM + +# +# Driver +# + +# +# SOFTWARE_SUPPORT_CHIP +# +# CONFIG_CHIP_SUPPORT is not set +# end of SOFTWARE_SUPPORT_CHIP + +# +# Watchdog +# +CONFIG_INT_WDT = true +CONFIG_INT_WDT_PERIOD_MS = 20000 +CONFIG_TASK_WDT = true +CONFIG_TASK_WDT_PERIOD_MS = 60000 +CONFIG_NMI_WDT_EN = true + +# end of Watchdog + +# +# AON_Watchdog +# +# CONFIG_AON_WDT is not set +CONFIG_INT_AON_WDT = true +CONFIG_INT_AON_WDT_PERIOD_MS = 1000 + +# end of AON_Watchdog + +# +# UART +# +CONFIG_UART1 = true + +# CONFIG_UART1_FLOW_CTRL is not set +CONFIG_UART2 = true + +# CONFIG_UART3 is not set +CONFIG_PRINT_PORT_UART1 = true + +# CONFIG_PRINT_PORT_UART2 is not set +# CONFIG_PRINT_PORT_UART3 is not set +CONFIG_UART_PRINT_PORT = 0 +CONFIG_UART_ATE_PORT = 0 +CONFIG_PRINTF_BUF_SIZE = 128 + +# CONFIG_BACKGROUND_PRINT is not set +CONFIG_KFIFO_SIZE = 128 + +# CONFIG_UART_STATIS is not set +# end of UART + +# +# TRNG +# +CONFIG_TRNG_SUPPORT = true + +# end of TRNG + +# +# SDIO_HOST +# +# CONFIG_SDIO_HOST is not set +CONFIG_SDIO_HOST_DEFAULT_CLOCK_FREQ = 200000 + +# end of SDIO_HOST + +# +# SDCARD +# +# CONFIG_SDCARD_HOST is not set +CONFIG_SDCARD_V2P0 = true + +# CONFIG_SDCARD_V1P0 is not set +# CONFIG_SDCARD_BUSWIDTH_4LINE is not set +# end of SDCARD + +# +# FATFS +# +# CONFIG_FATFS is not set +# CONFIG_FATFS_SDCARD is not set +# end of FATFS + +CONFIG_MAC_PHY_BYPASS = true + +# +# SDIO +# +# CONFIG_SDIO is not set +# end of SDIO + +# +# SPI +# +CONFIG_SPI_DMA = true +CONFIG_SPI_SLAVE = true +CONFIG_SPI_MASTER = true +CONFIG_SPI_STATIS = true +CONFIG_SPI_SUPPORT_TX_FIFO_WR_READY = true + +# CONFIG_HSLAVE_SPI is not set +# CONFIG_SPI_MST_FLASH is not set +# CONFIG_SPI_MST_PSRAM is not set +# end of SPI + +# +# QSPI +# +# CONFIG_QSPI is not set +CONFIG_QSPI_STATIS = true + +# end of QSPI + +# +# AON_RTC +# +CONFIG_AON_RTC = true +CONFIG_AON_RTC_MANY_USERS = true +CONFIG_AON_RTC_TEST = true + +# CONFIG_AON_RTC_DEBUG is not set +# end of AON_RTC + +# +# GPIO +# +CONFIG_GPIO_WAKEUP_SUPPORT = true +CONFIG_GPIO_DYNAMIC_WAKEUP_SUPPORT = true + +# CONFIG_GPIO_WAKEUP_DEBUG is not set +CONFIG_GPIO_DYNAMIC_WAKEUP_SOURCE_MAX_CNT = 4 +CONFIG_GPIO_SIMULATE_UART_WRITE = true + +# end of GPIO + +# +# AON_PMU +# +CONFIG_AON_PMU = true + +# end of AON_PMU + +# +# DMA +# +CONFIG_GENERAL_DMA = true + +# end of DMA + +# +# TOUCH +# +# end of TOUCH + +# +# SBC +# +# CONFIG_SBC is not set +# end of SBC + +# +# JPEG_ENCODE +# +# CONFIG_JPEG_ENCODE is not set +# end of JPEG_ENCODE + +# +# PSRAM +# +# CONFIG_PSRAM is not set +# end of PSRAM + +# +# CALENDAR +# +# CONFIG_CALENDAR is not set +# end of CALENDAR + +# +# MPC +# +# CONFIG_MPC is not set +# end of MPC + +# +# PRRO +# +# CONFIG_PRRO is not set +# end of PRRO + +# +# System control +# +# CONFIG_SYS_REDUCE_NORMAL_POWER is not set +# CONFIG_XTAL_FREQ_40M is not set +CONFIG_XTAL_FREQ_26M = true +CONFIG_XTAL_FREQ = 26000000 +CONFIG_DCO_FREQ = 120000000 +CONFIG_SYSTEM_CTRL = true +CONFIG_POWER_CLOCK_RF = true + +# end of System control + +# +# PHY +# +# CONFIG_PTA is not set +# end of PHY + +# +# I2S +# +# CONFIG_I2S is not set +# end of I2S + +# +# I2C +# +# CONFIG_I2C is not set +CONFIG_I2C_SUPPORT_ID_BITS = 1 + +# CONFIG_FM_I2C is not set +# end of I2C + +# +# PWM +# +# CONFIG_PWM is not set +# CONFIG_PWM_HAS_TWO_INT is not set +# end of PWM + +# +# ICU +# +# CONFIG_ICU_GPIO is not set +# end of ICU + +# +# TIMER +# +CONFIG_TIMER = true +CONFIG_TIMER_COUNTER = true +CONFIG_TIMER_SUPPORT_ID_BITS = 63 + +# end of TIMER + +# +# SARADC +# +CONFIG_SARADC = true + +# CONFIG_SARADC_NEED_FLUSH is not set +CONFIG_SARADC_RANGE_DIVIDE = true + +# end of SARADC + +# +# FLASH +# +CONFIG_FLASH = true +CONFIG_FLASH_QUAD_ENABLE = true +CONFIG_FLASH_SRC_CLK_60M = true + +# CONFIG_FLASH_ORIGIN_API is not set +# end of FLASH + +# CONFIG_SUPPORT_IRDA is not set +# CONFIG_MAILBOX is not set +# CONFIG_LCD is not set +# CONFIG_DMA2D is not set +# CONFIG_JPEG_DEC is not set +# CONFIG_FFT is not set +# CONFIG_AUDIO_RISCV_IP_V1_0 is not set +# CONFIG_AUDIO_DSP_IP_V1_0 is not set +CONFIG_CHANGE_JTAG_GPIO = true + +# end of Driver + +# +# VENDOR CAL CONFIG +# +CONFIG_VND_CAL = true +CONFIG_BLE_USE_HIGH_POWER_LEVEL = true + +# end of VENDOR CAL CONFIG + +# +# VENDOR FLASH CONFIG +# +# CONFIG_OVERRIDE_FLASH_PARTITION is not set +# end of VENDOR FLASH CONFIG +# end of Components Configuration +# end of ARMINO Configuration diff --git a/bk7235/liteos_m/bk_sdk_armino/sdkconfig.h b/bk7235/liteos_m/bk_sdk_armino/sdkconfig.h new file mode 100755 index 0000000..de0c7ba --- /dev/null +++ b/bk7235/liteos_m/bk_sdk_armino/sdkconfig.h @@ -0,0 +1,119 @@ +/* + * Automatically generated file. DO NOT EDIT. + * Beken IoT Development Framework (BEKEN-ARMINO) Configuration Header + */ +#pragma once +#define CONFIG_SOC_BK7235 1 +#define CONFIG_SOC_STR "bk7235" +#define CONFIG_SOC_ARCH "riscv" +#define CONFIG_SOC_BK7256XX 1 +#define CONFIG_TOOLCHAIN_PATH "/opt/risc-v/nds32le-elf-mculib-v5/bin" +#define CONFIG_TOOLCHAIN_PREFIX "riscv32-elf-" +#define CONFIG_DEBUG_FIRMWARE 1 +#define CONFIG_ASSERT_IGNORE 1 +#define CONFIG_LWIP 1 +#define CONFIG_LWIP_V2_1 1 +#define CONFIG_NO_HOSTED 1 +#define CONFIG_BLUETOOTH 1 +#define CONFIG_ATE 1 +#define CONFIG_ATE_GPIO_ID 0 +#define CONFIG_ATE_GPIO_PULL_UP 1 +#define CONFIG_BLE 1 +#define CONFIG_BTDM_5_2 1 +#define CONFIG_CLI 1 +#define CONFIG_BKREG 1 +#define CONFIG_MAX_COMMANDS 320 +#define CONFIG_I2C2_TEST 1 +#define CONFIG_SPI_TEST 1 +#define CONFIG_PERI_TEST 1 +#define CONFIG_SHELL_ASYNCLOG 1 +#define CONFIG_EFUSE 1 +#define CONFIG_IDLE_UART_OUT_TEST 1 +#define CONFIG_COMPONENTS_WPA_TWT_TEST 1 +#define CONFIG_ENABLE_WIFI_DEFAULT_CONNECT 1 +#define CONFIG_MCU_PS 1 +#define CONFIG_TICK_CALI 1 +#define CONFIG_STA_PS 1 +#define CONFIG_BK_NETIF 1 +#define CONFIG_MEM_DEBUG 1 +#define CONFIG_MEM_DEBUG_FUNC_NAME 1 +#define CONFIG_MEM_DEBUG_FUNC_NAME_LEN 16 +#define CONFIG_MEM_DEBUG_TASK_NAME 1 +#define CONFIG_MEM_DEBUG_TASK_NAME_LEN 8 +#define CONFIG_LITEOS_M_MST 1 +#define CONFIG_LITEOS_M_BK 1 +#define CONFIG_CUSTOMIZE_HEAP_SIZE 163840 +#define CONFIG_APP_MAIN_TASK_PRIO 4 +#define CONFIG_APP_MAIN_TASK_STACK_SIZE 4096 +#define CONFIG_BASE_MAC_FROM_RF_OTP_FLASH 1 +#define CONFIG_RANDOM_MAC_ADDR 1 +#define CONFIG_WIFI_ENABLE 1 +#define CONFIG_WIFI6_CODE_STACK 1 +#define CONFIG_WIFI6 1 +#define CONFIG_WIFI4 1 +#define CONFIG_MSDU_RESV_HEAD_LENGTH 96 +#define CONFIG_MSDU_RESV_TAIL_LENGTH 16 +#define CONFIG_TASK_RECONNECT_PRIO 4 +#define CONFIG_WIFI6_IP_DEBUG 1 +#define CONFIG_MAC_BSSID 1 +#define CONFIG_EASY_FLASH 1 +#define CONFIG_DHCP 1 +#define CONFIG_TASK_LWIP_PRIO 4 +#define CONFIG_HARMONY_LWIP 1 +#define CONFIG_LWIP_MEM_REDUCE 1 +#define CONFIG_MEDIA 1 +#define CONFIG_SARADC_CALI 1 +#define CONFIG_TEMP_DETECT 1 +#define CONFIG_ARCH_RISCV 1 +#define CONFIG_NEST_INT_SUPPORT 1 +#define CONFIG_MEMDUMP_ALL 1 +#define CONFIG_INT_WDT 1 +#define CONFIG_INT_WDT_PERIOD_MS 20000 +#define CONFIG_TASK_WDT 1 +#define CONFIG_TASK_WDT_PERIOD_MS 60000 +#define CONFIG_NMI_WDT_EN 1 +#define CONFIG_INT_AON_WDT 1 +#define CONFIG_INT_AON_WDT_PERIOD_MS 1000 +#define CONFIG_UART1 1 +#define CONFIG_UART2 1 +#define CONFIG_PRINT_PORT_UART1 1 +#define CONFIG_UART_PRINT_PORT 0 +#define CONFIG_UART_ATE_PORT 0 +#define CONFIG_PRINTF_BUF_SIZE 128 +#define CONFIG_KFIFO_SIZE 128 +#define CONFIG_TRNG_SUPPORT 1 +#define CONFIG_SDIO_HOST_DEFAULT_CLOCK_FREQ 200000 +#define CONFIG_SDCARD_V2P0 1 +#define CONFIG_MAC_PHY_BYPASS 1 +#define CONFIG_SPI_DMA 1 +#define CONFIG_SPI_SLAVE 1 +#define CONFIG_SPI_MASTER 1 +#define CONFIG_SPI_STATIS 1 +#define CONFIG_SPI_SUPPORT_TX_FIFO_WR_READY 1 +#define CONFIG_QSPI_STATIS 1 +#define CONFIG_AON_RTC 1 +#define CONFIG_AON_RTC_MANY_USERS 1 +#define CONFIG_AON_RTC_TEST 1 +#define CONFIG_GPIO_WAKEUP_SUPPORT 1 +#define CONFIG_GPIO_DYNAMIC_WAKEUP_SUPPORT 1 +#define CONFIG_GPIO_DYNAMIC_WAKEUP_SOURCE_MAX_CNT 4 +#define CONFIG_GPIO_SIMULATE_UART_WRITE 1 +#define CONFIG_AON_PMU 1 +#define CONFIG_GENERAL_DMA 1 +#define CONFIG_XTAL_FREQ_26M 1 +#define CONFIG_XTAL_FREQ 26000000 +#define CONFIG_DCO_FREQ 120000000 +#define CONFIG_SYSTEM_CTRL 1 +#define CONFIG_POWER_CLOCK_RF 1 +#define CONFIG_I2C_SUPPORT_ID_BITS 1 +#define CONFIG_TIMER 1 +#define CONFIG_TIMER_COUNTER 1 +#define CONFIG_TIMER_SUPPORT_ID_BITS 63 +#define CONFIG_SARADC 1 +#define CONFIG_SARADC_RANGE_DIVIDE 1 +#define CONFIG_FLASH 1 +#define CONFIG_FLASH_QUAD_ENABLE 1 +#define CONFIG_FLASH_SRC_CLK_60M 1 +#define CONFIG_CHANGE_JTAG_GPIO 1 +#define CONFIG_VND_CAL 1 +#define CONFIG_BLE_USE_HIGH_POWER_LEVEL 1 diff --git a/bk7235/liteos_m/inc/soc.h b/bk7235/liteos_m/inc/soc.h index 693e585..ade774e 100755 --- a/bk7235/liteos_m/inc/soc.h +++ b/bk7235/liteos_m/inc/soc.h @@ -16,16 +16,12 @@ #include "soc_common.h" -#define MCAUSE_INT_ID_MASK (0xF) -#define __start_and_irq_stack_top _stack -#define __except_stack_top _stack - #define RISCV_PLIC_VECTOR_CNT (63) #define RISCV_SYS_MAX_IRQ (0) #ifndef MTIMER -#define MTIMER 0xE6000000 +#define MTIMER 0xE6000000 #endif #ifndef MTIMERCMP -#define MTIMERCMP 0xE6000008 +#define MTIMERCMP 0xE6000008 #endif #endif diff --git a/bk7235/liteos_m/components/BUILD.gn b/bk7235/liteos_m/third_party_adapter/arch/BUILD.gn similarity index 79% rename from bk7235/liteos_m/components/BUILD.gn rename to bk7235/liteos_m/third_party_adapter/arch/BUILD.gn index ab4b072..f3a8d8a 100755 --- a/bk7235/liteos_m/components/BUILD.gn +++ b/bk7235/liteos_m/third_party_adapter/arch/BUILD.gn @@ -11,10 +11,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -import("//drivers/hdf_core/adapter/khdf/liteos_m/hdf.gni") +import("//kernel/liteos_m/liteos.gni") -module_group("components") { -# modules = [ "net/lwip-2.1" ] - modules = [ "mbedtls" ] - +module_name = "arch_adapter" +kernel_module(module_name) { + sources = [ "los_exc.S" ] } diff --git a/bk7235/liteos_m/third_party_adapter/arch/los_exc.S b/bk7235/liteos_m/third_party_adapter/arch/los_exc.S new file mode 100755 index 0000000..c28949a --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/arch/los_exc.S @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2013-2020, Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _BK_LOS_EXC_S +#define _BK_LOS_EXC_S +#include "soc_common.h" + +.macro PUSH_CALLER_REG + addi sp, sp, -(32 * REGBYTES) + SREG t6, 2 * REGBYTES(sp) + SREG t5, 3 * REGBYTES(sp) + SREG t4, 4 * REGBYTES(sp) + SREG t3, 5 * REGBYTES(sp) + SREG t2, 6 * REGBYTES(sp) + SREG t1, 7 * REGBYTES(sp) + SREG t0, 8 * REGBYTES(sp) + SREG a7, 18 * REGBYTES(sp) + SREG a6, 19 * REGBYTES(sp) + SREG a5, 20 * REGBYTES(sp) + SREG a4, 21 * REGBYTES(sp) + SREG a3, 22 * REGBYTES(sp) + SREG a2, 23 * REGBYTES(sp) + SREG a1, 24 * REGBYTES(sp) + SREG a0, 25 * REGBYTES(sp) + SREG ra, 31 * REGBYTES(sp) + csrr t0, mstatus + SREG t0, 16 * REGBYTES(sp) + csrr t0, mepc + SREG t0, 17 * REGBYTES(sp) +.endm + +.macro POP_CALLER_REG + LREG t0, 16 * REGBYTES(sp) + csrw mstatus, t0 + LREG t0, 17 * REGBYTES(sp) + csrw mepc, t0 + LREG t6, 2 * REGBYTES(sp) + LREG t5, 3 * REGBYTES(sp) + LREG t4, 4 * REGBYTES(sp) + LREG t3, 5 * REGBYTES(sp) + LREG t2, 6 * REGBYTES(sp) + LREG t1, 7 * REGBYTES(sp) + LREG t0, 8 * REGBYTES(sp) + LREG a7, 18 * REGBYTES(sp) + LREG a6, 19 * REGBYTES(sp) + LREG a5, 20 * REGBYTES(sp) + LREG a4, 21 * REGBYTES(sp) + LREG a3, 22 * REGBYTES(sp) + LREG a2, 23 * REGBYTES(sp) + LREG a1, 24 * REGBYTES(sp) + LREG a0, 25 * REGBYTES(sp) + LREG ra, 31 * REGBYTES(sp) + addi sp, sp, 32 * REGBYTES +.endm + +.macro PUSH_CALLEE_REG + SREG s11, 9 * REGBYTES(sp) + SREG s10, 10 * REGBYTES(sp) + SREG s9, 11 * REGBYTES(sp) + SREG s8, 12 * REGBYTES(sp) + SREG s7, 13 * REGBYTES(sp) + SREG s6, 14 * REGBYTES(sp) + SREG s5, 15 * REGBYTES(sp) + SREG s4, 26 * REGBYTES(sp) + SREG s3, 27 * REGBYTES(sp) + SREG s2, 28 * REGBYTES(sp) + SREG s1, 29 * REGBYTES(sp) + SREG s0, 30 * REGBYTES(sp) +.endm + +.macro POP_ALL_REG + LREG t6, 2 * REGBYTES(sp) + LREG t5, 3 * REGBYTES(sp) + LREG t4, 4 * REGBYTES(sp) + LREG t3, 5 * REGBYTES(sp) + LREG t2, 6 * REGBYTES(sp) + LREG t1, 7 * REGBYTES(sp) + LREG t0, 8 * REGBYTES(sp) + LREG s11, 9 * REGBYTES(sp) + LREG s10, 10 * REGBYTES(sp) + LREG s9, 11 * REGBYTES(sp) + LREG s8, 12 * REGBYTES(sp) + LREG s7, 13 * REGBYTES(sp) + LREG s6, 14 * REGBYTES(sp) + LREG s5, 15 * REGBYTES(sp) + LREG a7, 18 * REGBYTES(sp) + LREG a6, 19 * REGBYTES(sp) + LREG a5, 20 * REGBYTES(sp) + LREG a4, 21 * REGBYTES(sp) + LREG a3, 22 * REGBYTES(sp) + LREG a2, 23 * REGBYTES(sp) + LREG a1, 24 * REGBYTES(sp) + LREG a0, 25 * REGBYTES(sp) + LREG s4, 26 * REGBYTES(sp) + LREG s3, 27 * REGBYTES(sp) + LREG s2, 28 * REGBYTES(sp) + LREG s1, 29 * REGBYTES(sp) + LREG s0, 30 * REGBYTES(sp) + LREG ra, 31 * REGBYTES(sp) + addi sp, sp, 32 * REGBYTES +.endm + +/* .section .interrupt.text */ +.extern HalExcEntry +.extern g_excInfo +.global __wrap_HalTrapEntry +.align 4 +__wrap_HalTrapEntry: + PUSH_CALLEE_REG + addi sp, sp, -(4 * REGBYTES) + sw a0, 0 * REGBYTES(sp) + csrr t0, mtval + sw t0, 1 * REGBYTES(sp) + csrr t0, medeleg + sw t0, 2 * REGBYTES(sp) + sw gp, 3 * REGBYTES(sp) + mv a0, sp + csrw mscratch, sp + la t0, g_excInfo + lh t1, 0(t0) + bnez t1, 1f + la sp, __except_stack_top +1: + addi t1, t1, 0x1 + sh t1, 0(t0) + call HalExcEntry + la t0, g_excInfo + sh zero, 0(t0) + csrr sp, mscratch + addi sp, sp, 4 * REGBYTES + lw t0, 16 * REGBYTES(sp) + csrw mstatus, t0 + lw t0, 17 * REGBYTES(sp) + csrw mepc, t0 + POP_ALL_REG + mret + + +/*.section .interrupt.HalTrapVector.text */ +.extern __wrap_HalTrapEntry +.extern HalIrqEndCheckNeedSched +.global __wrap_HalTrapVector +.equ TRAP_INTERRUPT_MODE_MASK, 0x80000000 +.align 4 +__wrap_HalTrapVector: + PUSH_CALLER_REG + csrr a0, mcause + li a1, TRAP_INTERRUPT_MODE_MASK + li a2, MCAUSE_INT_ID_MASK + and a1, a0, a1 + and a0, a2, a0 + beqz a1, __wrap_HalTrapEntry + csrw mscratch, sp + la sp, __start_and_irq_stack_top + jal HalHwiInterruptDone + csrr sp, mscratch + call HalIrqEndCheckNeedSched + + POP_CALLER_REG + mret +#endif /* _LOS_TRAP_S */ diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/BUILD.gn b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/BUILD.gn new file mode 100755 index 0000000..d4f7122 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/BUILD.gn @@ -0,0 +1,68 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("$LITEOSTHIRDPARTY/lwip/lwip.gni") +import("$LITEOSTOPDIR/components/net/lwip-2.1/lwip_porting.gni") +import("${beken_sdk_dir}/sdkconfig.gni") +import("${board_adapter_dir}/hals/sdk_dir.gni") + +kernel_module("lwip") { + sources = LWIPNOAPPSFILES + MDNSFILES - PPPFILES - SIXLOWPAN - [ + "$LWIPDIR/api/sockets.c", + "$LWIPDIR/api/if_api.c", + "$LWIPDIR/core/altcp.c", + "$LWIPDIR/core/altcp_alloc.c", + "$LWIPDIR/core/altcp_tcp.c", + "$LWIPDIR/netif/bridgeif.c", + "$LWIPDIR/netif/bridgeif_fdb.c", + "$LWIPDIR/netif/slipif.c", + ] + sources += [ + "dhcpd/dhcp-server-main.c", + "dhcpd/dhcp-server.c", + "lwip-2.1.2/port/ethernetif.c", + "lwip-2.1.2/port/net.c", + "lwip-2.1.2/port/sockets.c", + "lwip-2.1.2/port/sys_arch.c", + ] + + include_dirs = [] + deps = [] + public_configs = [ + ":public", + "${beken_sdk_dir}/components/bk_os:public", + "${beken_sdk_dir}/components/bk_wifi:public", + "${beken_sdk_dir}/middleware/driver:public", + ] +} + +config("public") { + include_dirs = [ + "lwip-2.1.2/port", + "$LWIPDIR", + "$LWIPDIR/include", + "$LWIPDIR/include/netif", + "$LWIPDIR/include/lwip", + "$LITEOSTOPDIR/arch/risc-v/riscv32/gcc", + "$LITEOSTOPDIR/arch/risc-v/riscv32/gcc/asm", + "$LITEOSTOPDIR/arch/include", + "$LITEOSTOPDIR/kernel/include", + "$LITEOSTOPDIR/kal/cmsis", + "$LITEOSTOPDIR/kal/posix/include", + "$LITEOSTOPDIR/components/power", + "$LITEOSTOPDIR/components/signal", + "$LITEOSTOPDIR/utils", + "$extra_include_dir", + ] +} diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/CMakeLists.txt b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/CMakeLists.txt new file mode 100755 index 0000000..4607f8e --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/CMakeLists.txt @@ -0,0 +1,91 @@ +set(incs) +set(srcs) + +if(CONFIG_HARMONY_LWIP) + set(lwip_dir "../../../../../../../../third_party/lwip") + set(liteos_dir "../../../../../../../../kernel/liteos_m") + set(extra_dir "../../../../../../../../device/soc/beken/bk7235/liteos_m") +else() + set(lwip_dir "lwip-2.1.2") +endif() + +if (CONFIG_LWIP_V2_1) + list(APPEND incs + ${lwip_dir}/src + lwip-2.1.2/port + ${lwip_dir}/src/include + ${lwip_dir}/src/include/netif + ${lwip_dir}/src/include/lwip + ${liteos_dir}/arch/risc-v/riscv32/gcc + ${liteos_dir}/arch/risc-v/riscv32/gcc/asm + ${liteos_dir}/arch/include + ${liteos_dir}/kernel/include + ${liteos_dir}/kal/cmsis + ${liteos_dir}/kal/posix/include + ${liteos_dir}/components/power + ${liteos_dir}/components/signal + ${liteos_dir}/utils + ${extra_dir}/inc + ) + + list(APPEND srcs + lwip-2.1.2/port/ethernetif.c + lwip-2.1.2/port/net.c + lwip-2.1.2/port/sys_arch.c + lwip-2.1.2/port/sockets.c + #lwip-2.1.2/port/ping.c + ${lwip_dir}/src/api/api_lib.c + ${lwip_dir}/src/api/api_msg.c + ${lwip_dir}/src/api/err.c + ${lwip_dir}/src/api/netbuf.c + ${lwip_dir}/src/api/netdb.c + ${lwip_dir}/src/api/netifapi.c + #${lwip_dir}/src/api/sockets.c + ${lwip_dir}/src/api/tcpip.c + ${lwip_dir}/src/apps/mdns/mdns.c + #lwip-2.1.2/src/apps/ping/ping.c + ${lwip_dir}/src/core/def.c + ${lwip_dir}/src/core/dns.c + ${lwip_dir}/src/core/inet_chksum.c + ${lwip_dir}/src/core/init.c + ${lwip_dir}/src/core/ip.c + ${lwip_dir}/src/core/ipv4/autoip.c + ${lwip_dir}/src/core/ipv4/dhcp.c + ${lwip_dir}/src/core/ipv4/etharp.c + ${lwip_dir}/src/core/ipv4/icmp.c + ${lwip_dir}/src/core/ipv4/igmp.c + ${lwip_dir}/src/core/ipv4/ip4_addr.c + ${lwip_dir}/src/core/ipv4/ip4.c + ${lwip_dir}/src/core/ipv4/ip4_frag.c + ${lwip_dir}/src/core/ipv6/dhcp6.c + ${lwip_dir}/src/core/ipv6/ethip6.c + ${lwip_dir}/src/core/ipv6/icmp6.c + ${lwip_dir}/src/core/ipv6/inet6.c + ${lwip_dir}/src/core/ipv6/ip6_addr.c + ${lwip_dir}/src/core/ipv6/ip6.c + ${lwip_dir}/src/core/ipv6/ip6_frag.c + ${lwip_dir}/src/core/ipv6/mld6.c + ${lwip_dir}/src/core/ipv6/nd6.c + ${lwip_dir}/src/core/mem.c + ${lwip_dir}/src/core/memp.c + ${lwip_dir}/src/core/netif.c + ${lwip_dir}/src/core/pbuf.c + ${lwip_dir}/src/core/raw.c + ${lwip_dir}/src/core/stats.c + ${lwip_dir}/src/core/sys.c + ${lwip_dir}/src/core/tcp.c + ${lwip_dir}/src/core/tcp_in.c + ${lwip_dir}/src/core/tcp_out.c + ${lwip_dir}/src/core/timeouts.c + ${lwip_dir}/src/core/udp.c + ${lwip_dir}/src/netif/ethernet.c + dhcpd/dhcp-server.c + dhcpd/dhcp-server-main.c + ) +endif() + +armino_component_register(SRCS "${srcs}" + INCLUDE_DIRS "${incs}" + REQUIRES driver + PRIV_REQUIRES bk_common bk_wifi + ) diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/Kconfig b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/Kconfig new file mode 100755 index 0000000..95b574c --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/Kconfig @@ -0,0 +1,57 @@ +#TODO add depens for CONFIG_HOST (bk7231u) +menu "LwIP 2.1.2" + config LWIP + bool "Enable LWIP" + default y + + config IPV6 + bool "Enable IPV6" + default n + + config DHCP + bool "Enable DHCP" + depends on LWIP + default y + + config AUTOIP + bool "Enable AUTOIP" + depends on LWIP + default n + + config MDNS + bool "Enable MDNS" + depends on LWIP + default n + + config TASK_LWIP_PRIO + int "Priority of LwIP task" + depends on LWIP + range 1 10 + default 4 + + config MIDEA + bool "Enable MIDEA" + depends on LWIP + default n + + config LWIP_FAST_DHCP + bool "Enable Fast DHCP(use previous IP)" + default n + + config HARMONY_LWIP + bool "Enable harmony lwip" + default n + + #TODO optimize it + choice LWIP_MEM + depends on LWIP + prompt "LWIP Memory Policy" + default LWIP_MEM_DEFAULT + + config LWIP_MEM_DEFAULT + bool "Default Memory Policy" + config LWIP_MEM_REDUCE + bool "Reduced Memory Policy" + endchoice + +endmenu diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-bootp.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-bootp.h new file mode 100755 index 0000000..83c2452 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-bootp.h @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 __DHCP_BOOTP_H_ +#define __DHCP_BOOTP_H_ + +#define DHCP_SERVER_PORT 67 +#define DHCP_CLIENT_PORT 68 + +#define NAMESERVER_PORT 53 + +#define CTRL_PORT 12679 + +#define BOOTP_OP_REQUEST 1 +#define BOOTP_OP_RESPONSE 2 + +#define BOOTP_OPTION_SUBNET_MASK 1 +#define BOOTP_OPTION_ROUTER 3 +#define BOOTP_OPTION_NAMESERVER 6 +#define BOOTP_OPTION_REQUESTED_IP 50 +#define BOOTP_OPTION_ADDRESS_TIME 51 +#define BOOTP_OPTION_DHCP_MESSAGE 53 +#define BOOTP_OPTION_DHCP_SERVER_ID 54 +#define BOOTP_END_OPTION 0xFF + +enum dhcp_message_type { + DHCP_MESSAGE_DISCOVER = 1, + DHCP_MESSAGE_OFFER = 2, + DHCP_MESSAGE_REQUEST = 3, + DHCP_MESSAGE_DECLINE = 4, + DHCP_MESSAGE_ACK = 5, + DHCP_MESSAGE_NAK = 6, + DHCP_MESSAGE_RELEASE = 7, + DHCP_MESSAGE_INFORM = 8, + DHCP_NO_RESPONSE = 255 +}; + +struct bootp_header { + uint8_t op; /* message type */ + uint8_t htype; /* hardware type (1 = ethernet) */ + uint8_t hlen; /* hardware address length (6) */ + uint8_t hops; /* (0) */ + uint32_t xid; /* transaction ID */ + uint16_t secs; /* seconds elapsed */ + uint16_t flags; /* bootp flags */ + uint32_t ciaddr; /* client IP address */ + uint32_t yiaddr; /* your IP address */ + uint32_t siaddr; /* next server IP address */ + uint32_t riaddr; /* relay agent IP address */ + uint8_t chaddr[6]; /* client MAC address */ + uint8_t pad[10 + 192]; /* 10 octets of padding, 192 octets of + padding */ + uint32_t cookie; /* magic cookie */ +} __attribute__((packed)); + +struct bootp_option { + uint8_t type; + uint8_t length; + char value[0]; +} __attribute__((packed)); +#define ETH_P_RARP 0x8035 + +#define ETH_HW_ADDR_LEN 6 +#define IP_ADDR_LEN 4 +#define ARP_FRAME_TYPE 0x0806 +#define ETHER_HW_TYPE 1 +#define IP_PROTO_TYPE 0x0800 +#define OP_ARP_REQUEST 2 +#define SOCK_PACKET 10 + +struct arp_packet { + uint8_t targ_hw_addr[ETH_HW_ADDR_LEN]; + uint8_t src_hw_addr[ETH_HW_ADDR_LEN]; + uint16_t frame_type; + uint16_t hw_type; + uint16_t prot_type; + uint8_t hw_addr_size; + uint8_t prot_addr_size; + uint16_t op; + uint8_t sndr_hw_addr[ETH_HW_ADDR_LEN]; + char sndr_ip_addr[IP_ADDR_LEN]; + uint8_t rcpt_hw_addr[ETH_HW_ADDR_LEN]; + char rcpt_ip_addr[IP_ADDR_LEN]; + uint8_t padding[18]; +}; + +#endif diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-priv.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-priv.h new file mode 100755 index 0000000..9f4f753 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-priv.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 __DHCP_PRIV_H__ +#define __DHCP_PRIV_H__ + +#include "lwip/sockets.h" + +#if 0 +#define dhcp_e(...) \ + LWIP_LOGI("dhcp: %s\r\n", ##__VA_ARGS__) +#define dhcp_w(...) \ + LWIP_LOGI("dhcp: %s\r\n", ##__VA_ARGS__) + +#define dhcp_d(...) \ + LWIP_LOGI("dhcp: %s\r\n", ##__VA_ARGS__) +#else +#define dhcp_d(...) //LWIP_LOGI +#define dhcp_e(...) //LWIP_LOGI +#define dhcp_w(...) //LWIP_LOGI +#endif + +#define SERVER_BUFFER_SIZE 1024 +#define MAC_IP_CACHE_SIZE 8 + +#if CONFIG_MALLOC_STATIS +#define DHCP_SERVER_TASK_STACK_SIZE 2048 +#else +#define DHCP_SERVER_TASK_STACK_SIZE 1536 +#endif + +struct client_mac_cache { + uint8_t client_mac[6]; /* mac address of the connected device */ + uint32_t client_ip; /* ip address of the connected device */ +}; + +struct dhcp_server_data { + int sock; + int dnssock; + int ctrlsock; + int count_clients; /* to keep count of cached devices */ + char *msg; + struct sockaddr_in saddr; /* dhcp server address */ + struct sockaddr_in dnsaddr; /* dns server address */ + struct sockaddr_in uaddr; /* unicast address */ + struct sockaddr_in baddr; /* broadcast address */ + struct sockaddr_in ctrladdr; + struct client_mac_cache ip_mac_mapping[MAC_IP_CACHE_SIZE]; + uint32_t netmask; /* network order */ + uint32_t my_ip; /* network order */ + uint32_t client_ip; /* last address that was requested, network + * order */ + uint32_t current_ip; /* keep track of assigned IP addresses */ + uint32_t router_ip; /* router IP addresses */ + void *prv; +}; + +void dhcp_enable_nack_dns_server(void); +int dhcp_server_init(void *intrfc_handle); +void dhcp_server(void* data); +int dhcp_send_halt(void); +int dhcp_free_allocations(void); + +#endif diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-server-main.c b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-server-main.c new file mode 100755 index 0000000..f90ae01 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-server-main.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include +#include "dhcp-priv.h" + +static beken_thread_t dhcpd_thread; +static bool dhcpd_running; + +int dhcp_server_start(void *intrfc_handle) +{ + int ret; + + dhcp_d("DHCP server start request \r\n"); + + dhcp_enable_nack_dns_server(); + + if (dhcpd_running || dhcp_server_init(intrfc_handle)) { + return -1; + } + + ret = rtos_create_thread(&dhcpd_thread, + BEKEN_APPLICATION_PRIORITY, + "dhcp-server", + (beken_thread_function_t)dhcp_server, + DHCP_SERVER_TASK_STACK_SIZE, + 0); + if (ret) { + dhcp_free_allocations(); + return -1; + } + + dhcpd_running = 1; + return 0; +} + +void dhcp_server_stop(void) +{ + dhcp_d("DHCP server stop request\r\n"); + if (dhcpd_running) + { + if (dhcp_send_halt() != 0) + { + dhcp_w("failed to send halt to DHCP thread\r\n"); + return; + } + + if (rtos_delete_thread(&dhcpd_thread) != 0) + dhcp_w("failed to delete thread\r\n"); + dhcpd_running = 0; + } + else + { + dhcp_w("server not dhcpd_running.\r\n"); + } +} +// eof + diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-server.c b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-server.c new file mode 100755 index 0000000..b2f5e43 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dhcp-server.c @@ -0,0 +1,906 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include +#include "dhcp-bootp.h" +#include "dns.h" +#include "dhcp-priv.h" +#include +#include +#include "lwip/etharp.h" +#include "lwip/sockets.h" +#include "opt.h" + +#define os_mem_alloc os_malloc +#define os_mem_free os_free +#define SEND_RESPONSE(w,x,y,z) send_response(w,x,y,z) + +#define DEFAULT_DHCP_ADDRESS_TIMEOUT (60U*60U*1U) /* 1 hour */ +#define CLIENT_IP_NOT_FOUND 0x00000000 + +uint32_t dhcp_address_timeout = DEFAULT_DHCP_ADDRESS_TIMEOUT; +static beken_mutex_t dhcpd_mutex; +static int (*dhcp_nack_dns_server_handler)(char *msg, int len, + struct sockaddr_in *fromaddr); + +struct dhcp_server_data dhcps; + +extern int net_get_if_macaddr(void *macaddr, void *intrfc_handle); +extern int net_get_if_ip_addr(uint32_t *ip, void *intrfc_handle); +extern int net_get_if_ip_mask(uint32_t *nm, void *intrfc_handle); +extern int net_get_if_gw_addr(uint32_t *ip, void *intrfc_handle); +static void get_broadcast_addr(struct sockaddr_in *addr); +static int get_ip_addr_from_interface(uint32_t *ip, void *interface_handle); +static int get_netmask_from_interface(uint32_t *nm, void *interface_handle); +static int get_mac_addr_from_interface(void *mac, void *interface_handle); +static int get_gateway_from_interface(uint32_t *gw, void *interface_handle); +static int send_gratuitous_arp(uint32_t ip); +static bool ac_add(uint8_t *chaddr, uint32_t client_ip); +static uint32_t ac_lookup_mac(uint8_t *chaddr); +static uint8_t *ac_lookup_ip(uint32_t client_ip); +static bool ac_not_full(); + +static bool ac_add(uint8_t *chaddr, uint32_t client_ip) +{ + /* adds ip-mac mapping in cache */ + if (ac_not_full()) { + dhcps.ip_mac_mapping[dhcps.count_clients].client_mac[0] + = chaddr[0]; + dhcps.ip_mac_mapping[dhcps.count_clients].client_mac[1] + = chaddr[1]; + dhcps.ip_mac_mapping[dhcps.count_clients].client_mac[2] + = chaddr[2]; + dhcps.ip_mac_mapping[dhcps.count_clients].client_mac[3] + = chaddr[3]; + dhcps.ip_mac_mapping[dhcps.count_clients].client_mac[4] + = chaddr[4]; + dhcps.ip_mac_mapping[dhcps.count_clients].client_mac[5] + = chaddr[5]; + dhcps.ip_mac_mapping[dhcps.count_clients].client_ip = client_ip; + dhcps.count_clients++; + return 0; + } + return -1; +} + +static uint32_t ac_lookup_mac(uint8_t *chaddr) +{ + /* returns ip address, if mac address is present in cache */ + int i; + for (i = 0; i < dhcps.count_clients && i < MAC_IP_CACHE_SIZE; i++) { + if ((dhcps.ip_mac_mapping[i].client_mac[0] == chaddr[0]) && + (dhcps.ip_mac_mapping[i].client_mac[1] == chaddr[1]) && + (dhcps.ip_mac_mapping[i].client_mac[2] == chaddr[2]) && + (dhcps.ip_mac_mapping[i].client_mac[3] == chaddr[3]) && + (dhcps.ip_mac_mapping[i].client_mac[4] == chaddr[4]) && + (dhcps.ip_mac_mapping[i].client_mac[5] == chaddr[5])) { + return dhcps.ip_mac_mapping[i].client_ip; + } + } + return CLIENT_IP_NOT_FOUND; +} + +static uint8_t *ac_lookup_ip(uint32_t client_ip) +{ + /* returns mac address, if ip address is present in cache */ + int i; + for (i = 0; i < dhcps.count_clients && i < MAC_IP_CACHE_SIZE; i++) { + if ((dhcps.ip_mac_mapping[i].client_ip) == client_ip) { + return dhcps.ip_mac_mapping[i].client_mac; + } + } + return NULL; +} + +static bool ac_not_full() +{ + /* returns true if cache is not full */ + return (dhcps.count_clients < MAC_IP_CACHE_SIZE); +} + +static bool ac_valid_ip(uint32_t requested_ip) +{ + /* skip over our own address, the network address or the + * broadcast address + */ + if (requested_ip == ntohl(dhcps.my_ip) || + (requested_ip == ntohl(dhcps.my_ip & + dhcps.netmask)) || + (requested_ip == ntohl((dhcps.my_ip | + (0xffffffff & ~dhcps.netmask))))) { + return false; + } + if (ac_lookup_ip(htonl(requested_ip)) != NULL) + return false; + return true; +} + +static void write_u32(char *dest, uint32_t be_value) +{ + *dest++ = be_value & 0xFF; + *dest++ = (be_value >> 8) & 0xFF; + *dest++ = (be_value >> 16) & 0xFF; + *dest = be_value >> 24; +} + +/* Configure the DHCP dynamic IP lease time*/ +int dhcp_server_lease_timeout(uint32_t val) +{ + if ((val == 0) || (val > (60U*60U*24U*49700U))) { + return -EINVAL; + } else { + dhcp_address_timeout = val; + return 0; + } +} + +/* calculate the address to give out to the next DHCP DISCOVER request + * + * DHCP clients will be assigned addresses in sequence in the subnet's address space. + */ +static unsigned int next_yiaddr() +{ +#ifdef CONFIG_DHCP_SERVER_DEBUG + struct in_addr ip; +#endif + uint32_t new_ip; + struct bootp_header *hdr = (struct bootp_header *)dhcps.msg; + + /* if device requesting for ip address is already registered, + * if yes, assign previous ip address to it + */ + new_ip = ac_lookup_mac(hdr->chaddr); + if (new_ip == (CLIENT_IP_NOT_FOUND)) { + /* next IP address in the subnet */ + dhcps.current_ip = ntohl(dhcps.my_ip & dhcps.netmask) | + ((dhcps.current_ip + 1) & ntohl(~dhcps.netmask)); + while (!ac_valid_ip(dhcps.current_ip)) { + dhcps.current_ip = ntohl(dhcps.my_ip & dhcps.netmask) | + ((dhcps.current_ip + 1) & + ntohl(~dhcps.netmask)); + } + + new_ip = htonl(dhcps.current_ip); + + if (ac_add(hdr->chaddr, new_ip) != + 0) + dhcp_w("No space to store new mapping..\r\n"); + } + +#ifdef CONFIG_DHCP_SERVER_DEBUG + ip.s_addr = new_ip; + dhcp_d("New client IP will be %s\r\n", inet_ntoa(ip)); + ip.s_addr = dhcps.my_ip & dhcps.netmask; +#endif + + return new_ip; +} + +static unsigned int make_response(char *msg, enum dhcp_message_type type) +{ + struct bootp_header *hdr; + struct bootp_option *opt; + char *offset = msg; + + hdr = (struct bootp_header *)offset; + hdr->op = BOOTP_OP_RESPONSE; + hdr->htype = 1; + hdr->hlen = 6; + hdr->hops = 0; + hdr->ciaddr = 0; + hdr->yiaddr = (type == DHCP_MESSAGE_ACK) ? dhcps.client_ip : 0; + hdr->yiaddr = (type == DHCP_MESSAGE_OFFER) ? + next_yiaddr() : hdr->yiaddr; + hdr->siaddr = 0; + hdr->riaddr = 0; + offset += sizeof(struct bootp_header); + + opt = (struct bootp_option *)offset; + opt->type = BOOTP_OPTION_DHCP_MESSAGE; + *(uint8_t *) opt->value = type; + opt->length = 1; + offset += sizeof(struct bootp_option) + opt->length; + + if (type == DHCP_MESSAGE_NAK) + return (unsigned int)(offset - msg); + + opt = (struct bootp_option *)offset; + opt->type = BOOTP_OPTION_SUBNET_MASK; + write_u32(opt->value, dhcps.netmask); + opt->length = 4; + offset += sizeof(struct bootp_option) + opt->length; + + opt = (struct bootp_option *)offset; + opt->type = BOOTP_OPTION_ADDRESS_TIME; + write_u32(opt->value, htonl(dhcp_address_timeout)); + opt->length = 4; + offset += sizeof(struct bootp_option) + opt->length; + + opt = (struct bootp_option *)offset; + opt->type = BOOTP_OPTION_DHCP_SERVER_ID; + write_u32(opt->value, dhcps.my_ip); + opt->length = 4; + offset += sizeof(struct bootp_option) + opt->length; + + opt = (struct bootp_option *)offset; + opt->type = BOOTP_OPTION_ROUTER; + write_u32(opt->value, dhcps.router_ip); + opt->length = 4; + offset += sizeof(struct bootp_option) + opt->length; + + opt = (struct bootp_option *)offset; + opt->type = BOOTP_OPTION_NAMESERVER; + if (dhcp_nack_dns_server_handler) + write_u32(opt->value, dhcps.router_ip); + else + write_u32(opt->value, 0); + opt->length = 4; + offset += sizeof(struct bootp_option) + opt->length; + + opt = (struct bootp_option *)offset; + opt->type = BOOTP_END_OPTION; + offset++; + + return (unsigned int)(offset - msg); +} + +int dhcp_get_ip_from_mac(uint8_t *client_mac, uint32_t *client_ip) +{ + *client_ip = ac_lookup_mac(client_mac); + if (*client_ip == CLIENT_IP_NOT_FOUND) { + return -1; + } + return 0; +} + +extern void ap_set_default_netif(void); +extern void reset_default_netif(void); + +static int send_response(int sock, struct sockaddr *addr, char *msg, int len) +{ + int nb; + unsigned int sent = 0; + // // in AP+STA mode, should set ap-netif as default + int dest_ip = ((struct sockaddr_in *)addr)->sin_addr.s_addr; + if ((dest_ip == IPADDR_ANY) || (dest_ip == IPADDR_BROADCAST)) + ap_set_default_netif(); + + while (sent < len) { + nb = lwip_sendto(sock, msg + sent, len - sent, 0, addr, + sizeof(struct sockaddr_in)); + if (nb < 0) { + dhcp_e("failed to send response, addr %p:%d\r\n", + ((struct sockaddr_in *)addr)->sin_addr, + ((struct sockaddr_in *)addr)->sin_port); + return -1; + } + sent += nb; + } + + // rest default netif to sta's netif + //if((dest_ip == IPADDR_ANY) || (dest_ip == IPADDR_BROADCAST)) + //reset_default_netif(); + + dhcp_d("sent response, %d bytes %s\r\n", sent, + inet_ntoa(((struct sockaddr_in *)addr)->sin_addr)); + return 0; +} + +#define ERROR_REFUSED 5 +static int process_dns_message(char *msg, int len, struct sockaddr_in *fromaddr) +{ + struct dns_header *hdr; + char *endp = msg + len; + int nq; + + if (len < sizeof(struct dns_header)) { + dhcp_e("DNS request is not complete, hence ignoring it\r\n"); + return -1; + } + + hdr = (struct dns_header *)msg; + + dhcp_d("DNS transaction id: 0x%x\r\n", htons(hdr->id)); + + if (hdr->flags.fields.qr) { + dhcp_e("ignoring this dns message (not a query)\r\n"); + return -1; + } + + nq = ntohs(hdr->num_questions); + dhcp_d("we were asked %d questions\r\n", nq); + + if (nq <= 0) { + dhcp_e("ignoring this dns msg (not a query or 0 questions)\r\n"); + return -1; + } + + /* make the header represent a response */ + hdr->flags.fields.qr = 1; + hdr->flags.fields.opcode = 0; + /* Errors are never authoritative (unless they are + NXDOMAINS, which this is not) */ + hdr->flags.fields.aa = 0; + hdr->flags.fields.tc = 0; + hdr->flags.fields.rd = 1; + hdr->flags.fields.ra = 0; + hdr->flags.fields.rcode = ERROR_REFUSED; + hdr->flags.num = htons(hdr->flags.num); + /* number of entries in questions section */ + hdr->num_questions = htons(0x01); + hdr->answer_rrs = 0; /* number of resource records in answer section */ + hdr->authority_rrs = 0; + hdr->additional_rrs = 0; + SEND_RESPONSE(dhcps.dnssock, (struct sockaddr *)fromaddr, + msg, endp - msg); + + return -1; +} + +static int process_dhcp_message(char *msg, int len) +{ + struct bootp_header *hdr; + struct bootp_option *opt; + uint8_t response_type = DHCP_NO_RESPONSE; + unsigned int consumed = 0; + bool got_ip = 0; + bool need_ip = 0; + bool got_client_ip = 0; + uint32_t new_ip; + + if (!msg || + len < sizeof(struct bootp_header) + sizeof(struct bootp_option) + 1) + return -1; + + hdr = (struct bootp_header *)msg; + + switch (hdr->op) { + case BOOTP_OP_REQUEST: + dhcp_d("bootp request\r\n"); + break; + case BOOTP_OP_RESPONSE: + dhcp_d("bootp response\r\n"); + break; + default: + dhcp_e("invalid op code: %d\r\n", hdr->op); + return -1; + } + + if (hdr->htype != 1 || hdr->hlen != 6) { + dhcp_e("invalid htype or hlen\r\n"); + return -1; + } + + dhcp_d("client MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", hdr->chaddr[0], + hdr->chaddr[1], hdr->chaddr[2], hdr->chaddr[3], hdr->chaddr[4], + hdr->chaddr[5]); + + dhcp_d("magic cookie: 0x%X\r\n", hdr->cookie); + + len -= sizeof(struct bootp_header); + opt = (struct bootp_option *)(msg + sizeof(struct bootp_header)); + while (len > 0 && opt->type != BOOTP_END_OPTION) { + if (opt->type == BOOTP_OPTION_DHCP_MESSAGE && opt->length == 1) { + dhcp_d("found DHCP message option\r\n"); + switch (*(uint8_t *) opt->value) { + case DHCP_MESSAGE_DISCOVER: + LWIP_LOGI("DHCP discover\r\n"); + response_type = DHCP_MESSAGE_OFFER; + break; + + case DHCP_MESSAGE_REQUEST: + LWIP_LOGI("DHCP request\r\n"); + need_ip = 1; + if (hdr->ciaddr != 0x0000000) { + dhcps.client_ip = hdr->ciaddr; + got_client_ip = 1; + } + break; + + default: + LWIP_LOGI("ignoring message type %d\r\n", + *(uint8_t *) opt->value); + break; + } + } + if (opt->type == BOOTP_OPTION_REQUESTED_IP && opt->length == 4) { + dhcp_d("found REQUESTED IP option %hhu.%hhu.%hhu.%hhu\r\n", + (uint8_t)opt->value[0], + (uint8_t)opt->value[1], + (uint8_t)opt->value[2], + (uint8_t)opt->value[3]); + memcpy((uint8_t *) &dhcps.client_ip, (uint8_t *) opt->value, 4); + got_client_ip = 1; + } + + if (got_client_ip) { + /* requested address outside of subnet */ + if ((dhcps.client_ip & dhcps.netmask) == + (dhcps.my_ip & dhcps.netmask)) { + + /* When client requests an IP address, + * DHCP-server checks if the valid + * IP-MAC entry is present in the + * ip-mac cache, if yes, also checks + * if the requested IP is same as the + * IP address present in IP-MAC entry, + * if yes, it allows the device to + * continue with the requested IP + * address. + */ + new_ip = ac_lookup_mac(hdr->chaddr); + if (new_ip != (CLIENT_IP_NOT_FOUND)) { + /* if new_ip is equal to requested ip */ + if (new_ip == dhcps.client_ip) { + got_ip = 1; + } else { + got_ip = 0; + } + } else if (ac_valid_ip + (ntohl(dhcps.client_ip))) { + /* When client requests with an IP + * address that is within subnet range + * and not assigned to any other client, + * then dhcp-server allows that device + * to continue with that IP address. + * And if IP-MAC cache is not full then + * adds this entry in cache. + */ + if (ac_not_full()) { + ac_add(hdr->chaddr, + dhcps.client_ip); + } else { + dhcp_w("No space to store new \r\n" + "mapping..\r\n"); + } + got_ip = 1; + } + } + } + + /* look at the next option (if any) */ + consumed = sizeof(struct bootp_option) + opt->length; + len -= consumed; + opt = (struct bootp_option *)((char *)opt + consumed); + if (need_ip) + response_type = got_ip ? DHCP_MESSAGE_ACK : + DHCP_MESSAGE_NAK; + } + + if (response_type != DHCP_NO_RESPONSE) { + uint32_t dst_ip = 0, retry = 0; + int send_byte; + struct bootp_header *hdr; + if (response_type == DHCP_MESSAGE_OFFER) + LWIP_LOGI("DHCP should send offer\r\n"); + else if (response_type == DHCP_MESSAGE_ACK) + LWIP_LOGI("DHCP should send ack\r\n"); + send_byte = make_response(msg, (enum dhcp_message_type)response_type); + hdr = (struct bootp_header *)msg; + + dst_ip = hdr->yiaddr; + + if(dst_ip != 0) { + dhcps.uaddr.sin_addr.s_addr = dst_ip; + + //dhcps.baddr.sin_addr.s_addr = dst_ip; + dhcp_d("change dhcps.uaddr: %s\r\n", inet_ntoa(dhcps.uaddr.sin_addr)); + + etharp_add_static_entry((ip4_addr_t *)&dst_ip, (struct eth_addr *)hdr->chaddr); + + retry = 0; + + dhcp_d("this pkt resp is unicast\r\n"); + hdr->flags &= ~(htons(1<<15)); + while(1) { + SEND_RESPONSE(dhcps.sock, + (struct sockaddr *)&dhcps.uaddr, msg, send_byte); + + if(++retry == 1) + break; + } + etharp_remove_static_entry((ip4_addr_t *)&dst_ip); + } + + dhcp_d("this pkt resp is broadcast\r\n"); + hdr->flags |= (htons(1<<15)); + retry = 0; + while(1) { + SEND_RESPONSE(dhcps.sock, + (struct sockaddr *)&dhcps.baddr, msg, send_byte); + + if(++retry == 3) + break; + } + + if (response_type == DHCP_MESSAGE_ACK) + send_gratuitous_arp(dhcps.my_ip); + return 0; + } + + dhcp_d("ignoring DHCP packet\r\n"); + return 0; +} + +static void dhcp_clean_sockets(void) +{ + int ret; + + if (dhcps.sock != -1) + { + ret = lwip_close(dhcps.sock); + if (ret != 0) { + dhcp_w("Failed to close dhcp socket\r\n"); + } + dhcps.sock = -1; + } + + if ( dhcp_nack_dns_server_handler ) + { + if ( dhcps.dnssock != -1 ) + { + ret = lwip_close(dhcps.dnssock); + if ( ret != 0 ) + { + dhcp_w("Failed to close dns socket\r\n"); + } + dhcps.dnssock = -1; + } + } + + if ( dhcps.ctrlsock != -1 ) + { + ret = lwip_close(dhcps.ctrlsock); + if ( ret != 0 ) + { + dhcp_w("Failed to close ctrol port socket\r\n"); + } + dhcps.ctrlsock = -1; + } +} + +void dhcp_server(void* data) +{ + int ret, len; + struct sockaddr_in caddr; + int max_sock; + socklen_t flen = sizeof(caddr); + fd_set rfds; + + rtos_lock_mutex(&dhcpd_mutex); + + while (1) { + FD_ZERO(&rfds); + FD_SET(dhcps.sock, &rfds); + max_sock = dhcps.sock; + + if (dhcp_nack_dns_server_handler) { + FD_SET(dhcps.dnssock, &rfds); + max_sock = (dhcps.sock > dhcps.dnssock ? + dhcps.sock : dhcps.dnssock); + } + + FD_SET(dhcps.ctrlsock, &rfds); + max_sock = (dhcps.sock > dhcps.ctrlsock ? + dhcps.sock : dhcps.ctrlsock); + + ret = lwip_select(max_sock + 1, &rfds, NULL, NULL, NULL); + + /* Error in select? */ + if (ret < 0) { + dhcp_e("select failed\r\n", -1); + goto done; + } + + if (FD_ISSET(dhcps.sock, &rfds)) { + len = lwip_recvfrom(dhcps.sock, dhcps.msg, + SERVER_BUFFER_SIZE, + 0, (struct sockaddr *)&caddr, &flen); + if (len > 0) { + dhcp_d("recved msg on dhcp sock len: %d\r\n", len); + process_dhcp_message(dhcps.msg, len); + } + } + + if ( dhcp_nack_dns_server_handler ) + { + if (FD_ISSET(dhcps.dnssock, &rfds)) { + len = lwip_recvfrom(dhcps.dnssock, dhcps.msg, + SERVER_BUFFER_SIZE, + 0, (struct sockaddr *)&caddr, &flen); + if (len > 0) { + dhcp_d("recved msg on dns sock len: %d\r\n", len); + dhcp_nack_dns_server_handler(dhcps.msg, len, + &caddr); + } + } + } + + if ( FD_ISSET(dhcps.ctrlsock, &rfds) ) + { + len = lwip_recvfrom(dhcps.ctrlsock, dhcps.msg, + SERVER_BUFFER_SIZE, + 0, (struct sockaddr *)&caddr, &flen); + if ( len > 0 ) + { + if ( os_strcmp(dhcps.msg, "HALT") == 0 ) + { + goto done; + } + } + } + } + +done: + dhcp_clean_sockets(); + rtos_unlock_mutex(&dhcpd_mutex); + rtos_delete_thread(NULL); +} + +static int create_and_bind_udp_socket(struct sockaddr_in *address, + void *intrfc_handle) +{ + int one = 1; + int ret; + + int sock = lwip_socket(PF_INET, SOCK_DGRAM, 0); + if (sock == -1) { + dhcp_e("failed to create a socket\r\n"); + return -1; + } + + ret = setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, + sizeof(int)); + if (ret == -1) { + /* This is unimplemented in lwIP, hence do not return */ + dhcp_e("failed to set SO_REUSEADDR\r\n"); + } + + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, + (char *)&one, sizeof(one)) == -1) { + dhcp_e("failed to set SO_BROADCAST\r\n"); + lwip_close(sock); + return -1; + } + + ret = lwip_bind(sock, (struct sockaddr *)address, + sizeof(struct sockaddr)); + + if (ret) { + dhcp_e("failed to bind server socket\r\n"); + dhcp_e("socket err: %d\r\n", errno); + lwip_close(sock); + return -1; + } + return sock; +} + +int dhcp_server_init(void *intrfc_handle) +{ + int ret = 0; + + memset(&dhcps, 0, sizeof(dhcps)); + dhcps.msg = (char*)os_mem_alloc(SERVER_BUFFER_SIZE); + if (dhcps.msg == NULL) + return -1; + ret = rtos_init_mutex(&dhcpd_mutex); + if (ret != 0) + return -1; + + get_broadcast_addr(&dhcps.baddr); + dhcps.baddr.sin_port = htons(DHCP_CLIENT_PORT); + + get_broadcast_addr(&dhcps.uaddr); + dhcps.uaddr.sin_port = htons(DHCP_CLIENT_PORT); + + if (get_ip_addr_from_interface(&dhcps.my_ip, intrfc_handle) < 0) { + dhcp_e("failed to look up our IP address from interface\r\n"); + ret = -1; + goto out; + } + + if (get_netmask_from_interface(&dhcps.netmask, intrfc_handle) < 0) { + dhcp_e("failed to look up our netmask from interface\r\n"); + ret = -1; + goto out; + } + + if (get_gateway_from_interface(&dhcps.router_ip, intrfc_handle) < 0) { + dhcp_e("failed to look up our netmask from interface\r\n"); + ret = -1; + goto out; + } + + + dhcps.saddr.sin_family = AF_INET; + dhcps.saddr.sin_addr.s_addr = INADDR_ANY; + dhcps.saddr.sin_port = htons(DHCP_SERVER_PORT); + dhcps.sock = create_and_bind_udp_socket(&dhcps.saddr, intrfc_handle); + + if (dhcps.sock < 0) { + ret = -1; + goto out; + } + + if (dhcp_nack_dns_server_handler) { + dhcps.dnsaddr.sin_family = AF_INET; + dhcps.dnsaddr.sin_addr.s_addr = INADDR_ANY; + dhcps.dnsaddr.sin_port = htons(NAMESERVER_PORT); + dhcps.dnssock = create_and_bind_udp_socket(&dhcps.dnsaddr, + intrfc_handle); + if (dhcps.dnssock < 0) + return -1; + } + + dhcps.ctrladdr.sin_family = AF_INET; + dhcps.ctrladdr.sin_addr.s_addr = inet_addr("127.0.0.1"); + dhcps.ctrladdr.sin_port = htons(CTRL_PORT); + dhcps.ctrlsock = create_and_bind_udp_socket(&dhcps.ctrladdr, + intrfc_handle); + if ( dhcps.ctrlsock < 0 ) + { + ret = -1; + goto out; + } + + dhcps.prv = intrfc_handle; + + dhcps.current_ip = ntohl(dhcps.my_ip & dhcps.netmask) | ((99) & ntohl(~dhcps.netmask)); + //LWIP_LOGI("[abc] %x, %x, %x\r\n", dhcps.current_ip, dhcps.my_ip, dhcps.router_ip); + + return 0; + +out: + os_mem_free(dhcps.msg); + dhcps.msg = NULL; + rtos_deinit_mutex(&dhcpd_mutex); + return ret; +} + +void dhcp_enable_nack_dns_server(void) +{ + dhcp_nack_dns_server_handler = process_dns_message; +} + +static int send_ctrl_msg(const char *msg) +{ + int ret; + + ret = lwip_sendto(dhcps.ctrlsock, msg, os_strlen(msg)+1, 0, + (struct sockaddr *)&dhcps.ctrladdr, sizeof(struct sockaddr_in)); + + return ret; +} + +int dhcp_send_halt(void) +{ + int ret; + + ret = send_ctrl_msg("HALT"); + if ( ret < 0 ) + { + dhcp_w("Failed to send HALT: %d.\r\n", ret); + return -1; + } + + ret = dhcp_free_allocations(); + + return ret; +} + +int dhcp_free_allocations(void) +{ + /* Wait for 10 seconds */ + rtos_lock_mutex(&dhcpd_mutex); + + dhcp_clean_sockets(); + + rtos_unlock_mutex(&dhcpd_mutex); + + if (dhcps.msg) { + os_mem_free(dhcps.msg); + dhcps.msg = NULL; + } + return rtos_deinit_mutex(&dhcpd_mutex); +} + +static int send_gratuitous_arp(uint32_t ip) +{ + int sock; + struct arp_packet pkt; + struct sockaddr_in to_addr; + to_addr.sin_family = AF_INET; + to_addr.sin_addr.s_addr = ip; + pkt.frame_type = htons(ARP_FRAME_TYPE); + pkt.hw_type = htons(ETHER_HW_TYPE); + pkt.prot_type = htons(IP_PROTO_TYPE); + pkt.hw_addr_size = ETH_HW_ADDR_LEN; + pkt.prot_addr_size = IP_ADDR_LEN; + pkt.op = htons(OP_ARP_REQUEST); + + write_u32(pkt.sndr_ip_addr, ip); + write_u32(pkt.rcpt_ip_addr, ip); + + memset(pkt.targ_hw_addr, 0xff, ETH_HW_ADDR_LEN); + memset(pkt.rcpt_hw_addr, 0xff, ETH_HW_ADDR_LEN); + get_mac_addr_from_interface((void*)pkt.sndr_hw_addr, dhcps.prv); + get_mac_addr_from_interface((void*)pkt.src_hw_addr, dhcps.prv); + + sock = lwip_socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) { + dhcp_e("Could not open socket to send Gratuitous ARP\r\n"); + return -1; + } + memset(pkt.padding, 0, sizeof(pkt.padding)); + + if (lwip_sendto(sock, (char *)&pkt, sizeof(pkt), 0, + (struct sockaddr *)&to_addr, sizeof(to_addr)) < 0) { + dhcp_e("Failed to send Gratuitous ARP\r\n"); + lwip_close(sock); + return -1; + } + dhcp_d("Gratuitous ARP sent\r\n"); + lwip_close(sock); + return 0; +} + +static void get_broadcast_addr(struct sockaddr_in *addr) +{ + addr->sin_family = AF_INET; + /* limited broadcast addr (255.255.255.255) */ + addr->sin_addr.s_addr = 0xffffffff; + addr->sin_len = sizeof(struct sockaddr_in); +} + +static int get_mac_addr_from_interface(void *mac, void *interface_handle) +{ + return net_get_if_macaddr(mac, interface_handle); +} + +static int get_ip_addr_from_interface(uint32_t *ip, void *interface_handle) +{ + return net_get_if_ip_addr(ip, interface_handle); +} + +static int get_netmask_from_interface(uint32_t *nm, void *interface_handle) +{ + return net_get_if_ip_mask(nm, interface_handle); +} + +static int get_gateway_from_interface(uint32_t *gw, void *interface_handle) +{ + return net_get_if_gw_addr(gw, interface_handle); +} + +uint8_t* dhcp_lookup_mac(uint8_t *chaddr) +{ + /* returns ip address, if mac address is present in cache */ + int i; + struct in_addr ip; + for (i = 0; i < dhcps.count_clients && i < MAC_IP_CACHE_SIZE; i++) { + if ((dhcps.ip_mac_mapping[i].client_mac[0] == chaddr[0]) && + (dhcps.ip_mac_mapping[i].client_mac[1] == chaddr[1]) && + (dhcps.ip_mac_mapping[i].client_mac[2] == chaddr[2]) && + (dhcps.ip_mac_mapping[i].client_mac[3] == chaddr[3]) && + (dhcps.ip_mac_mapping[i].client_mac[4] == chaddr[4]) && + (dhcps.ip_mac_mapping[i].client_mac[5] == chaddr[5])) { + + ip.s_addr = dhcps.ip_mac_mapping[i].client_ip; + + return (uint8_t*)inet_ntoa(ip); + } + } + return 0; +} diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dns.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dns.h new file mode 100755 index 0000000..68396ce --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/dhcpd/dns.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 __DNS_H__ +#define __DNS_H__ + +struct dns_header { + uint16_t id; + union { + struct { + uint16_t rcode:4, /* response code */ + cd:1, /* checking disabled RFC-2535 */ + ad:1, /* authentic data RFC-2535 */ + z:1, /* zero */ + ra:1, /* recursion available */ + rd:1, /* recursion desired */ + tc:1, /* truncated */ + aa:1, /* authoritative answer */ + opcode:4, /* (should be 0 for normal DNS messages) */ + qr:1; /* query/response */ + } fields ; + uint16_t num; + } flags ; + uint16_t num_questions; + uint16_t answer_rrs; + uint16_t authority_rrs; + uint16_t additional_rrs; +} __attribute__((packed)); + +struct dns_question { + /* query name (label) field */ + uint16_t type; + uint16_t class; +} __attribute__((packed)); + +struct dns_rr { + uint16_t name_ptr; /* pointer to name */ + uint16_t type; /* resource type */ + uint16_t class; /* resource class */ + uint32_t ttl; /* time to live */ + uint16_t rdlength; /* resource data length */ + uint32_t rd; /* resource data: we only provide a + 4-byte data response (an IP + address) but this is actually a + field of length rdlength */ +} __attribute__((packed)); + +#endif /* __DNS_H__ */ diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/arch/cc.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/arch/cc.h new file mode 100755 index 0000000..3683496 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/arch/cc.h @@ -0,0 +1,127 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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. + */ +/* + * cc.h - Architecture environment, some compiler specific, some + * environment specific (probably should move env stuff + * to sys_arch.h.) + * + * Typedefs for the types used by lwip - + * u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t + * + * Compiler hints for packing lwip's structures - + * PACK_STRUCT_FIELD(x) + * PACK_STRUCT_STRUCT + * PACK_STRUCT_BEGIN + * PACK_STRUCT_END + * + * Platform specific diagnostic output - + * LWIP_PLATFORM_DIAG(x) - non-fatal, print a message. + * LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution. + * Portability defines for printf formatters: + * U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F + * + * "lightweight" synchronization mechanisms - + * SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. + * SYS_ARCH_PROTECT(x) - enter protection mode. + * SYS_ARCH_UNPROTECT(x) - leave protection mode. + * + * If the compiler does not provide memset() this file must include a + * definition of it, or include a file which defines it. + * + * This file must either include a system-local which defines + * the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO + * to make lwip/arch.h define the codes which are used throughout. + */ + +#ifndef __CC_H__ +#define __CC_H__ + +#include +#include "bk_uart.h" + +#define LWIP_NO_STDINT_H 1 +/* + * Typedefs for the types used by lwip - + * u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t + */ +#ifndef LWIP_SIMPLE_TYPES +#define LWIP_SIMPLE_TYPES 1 +typedef uint8_t u8_t; +typedef int8_t s8_t; +typedef uint16_t u16_t; +typedef int16_t s16_t; +typedef uint32_t u32_t; +typedef int32_t s32_t; +#endif + +typedef int intptr_t; +typedef unsigned int uintptr_t; +typedef int sys_prot_t; +typedef uintptr_t mem_ptr_t; + +#if defined(__GNUC__) + #define PACK_STRUCT_BEGIN + #define PACK_STRUCT_STRUCT __attribute__((packed)) + #define PACK_STRUCT_FIELD(x) x +#elif defined(__ICCARM__) + #define PACK_STRUCT_BEGIN __packed + #define PACK_STRUCT_STRUCT + #define PACK_STRUCT_FIELD(x) x +#else + #define PACK_STRUCT_BEGIN + #define PACK_STRUCT_STRUCT + #define PACK_STRUCT_FIELD(x) x +#endif + + +/* + * Platform specific diagnostic output - + * LWIP_PLATFORM_DIAG(x) - non-fatal, print a message. + * LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution. + * Portability defines for printf formatters: + * U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F + */ +#ifndef LWIP_PLATFORM_ASSERT +#define LWIP_PLATFORM_ASSERT(x) \ + do \ + { fatal_prf("Assertion \"%s\" failed at line %d in %s\n", x, __LINE__, __FILE__); \ + } while(0) +#endif + +#ifndef LWIP_PLATFORM_DIAG +#define LWIP_PLATFORM_DIAG(x) do {fatal_prf x ;} while(0) +#endif + +#define U16_F "4d" +#define S16_F "4d" +#define X16_F "4x" +#define U32_F "8ld" +#define S32_F "8ld" +#define X32_F "8lx" + +/* + * unknow defination + */ +// cup byte order +#ifndef BYTE_ORDER +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +extern int bk_rand(); /* FIXME: move to right place */ +#define LWIP_TIMEVAL_PRIVATE 1 +#define LWIP_RAND() ((uint32_t)bk_rand()) +#endif +// eof + diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/arch/sys_arch.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/arch/sys_arch.h new file mode 100755 index 0000000..3e19f50 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/arch/sys_arch.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __SYS_RTXC_H__ +#define __SYS_RTXC_H__ + +#include "sys_rtos.h" + +#define SYS_MBOX_NULL (beken_queue_t)0 +#define SYS_SEM_NULL (beken_semaphore_t)0 +#define SYS_DEFAULT_THREAD_STACK_DEPTH 256 + +typedef beken_mutex_t sys_mutex_t; +typedef beken_semaphore_t sys_sem_t; +typedef beken_queue_t sys_mbox_t; +typedef beken_thread_t sys_thread_t; + +typedef struct _sys_arch_state_t +{ + // Task creation data. + char cTaskName[16]; + unsigned short nStackDepth; + unsigned short nTaskCount; +} sys_arch_state_t; + +/* Message queue constants. */ +#define archMESG_QUEUE_LENGTH ( 32 ) +#endif /* __SYS_RTXC_H__ */ + diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/ethernetif.c b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/ethernetif.c new file mode 100755 index 0000000..87d8d6e --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/ethernetif.c @@ -0,0 +1,363 @@ +/** + * @file + * Ethernet Interface Skeleton + * + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* + * This file is a skeleton for developing Ethernet network interface + * drivers for lwIP. Add code to the low_level functions and do a + * search-and-replace for the word "ethernetif" to replace it with + * something that better describes your network interface. + */ + +#include "common/bk_include.h" + +#include "lwip/opt.h" +#include "lwip/def.h" +#include "lwip/mem.h" +#include "lwip/pbuf.h" +#include "lwip/sys.h" +#include +#include +#ifdef CONFIG_IPV6 +#include +#endif + +#include "ethernetif.h" + +#include +#include + +#include "netif/etharp.h" + +#include "lwip_netif_address.h" + +#include "bk_drv_model.h" +#include + +#include + +/* Define those to better describe your network interface. */ +#define IFNAME0 'e' +#define IFNAME1 'n' + +#include "bk_uart.h" +#include "bk_wifi_netif.h" +#include "bk_private/bk_wifi.h" + +//TODO should use registered callback here!!! +extern int ke_l2_packet_tx(unsigned char *buf, int len, int flag); +extern int bmsg_tx_sender(struct pbuf *p, uint32_t vif_idx); +#if CONFIG_WIFI6_CODE_STACK +extern int bmsg_special_tx_sender(struct pbuf *p, uint32_t vif_idx); +#endif +/* Forward declarations. */ +void ethernetif_input(int iface, struct pbuf *p); + +/** + * In this function, the hardware should be initialized. + * Called from ethernetif_init(). + * + * @param netif the already initialized lwip network interface structure + * for this ethernetif + */ + +const char wlan_name[][6] = +{ + "wlan0\0", + "wlan1\0", + "wlan2\0", + "wlan3\0", +}; +static void low_level_init(struct netif *netif) +{ + void *vif = netif->state; + u8 *macptr = wifi_netif_vif_to_mac(vif); + int vif_index = wifi_netif_vif_to_vifid(vif); + +#if LWIP_NETIF_HOSTNAME + /* Initialize interface hostname */ + netif->hostname = (char*)&wlan_name[vif_index]; +#endif /* LWIP_NETIF_HOSTNAME */ + + /* set MAC hardware address length */ + LWIP_LOGI("enter low level!\r\n"); + LWIP_LOGI("mac %2x:%2x:%2x:%2x:%2x:%2x\r\n", macptr[0], macptr[1], macptr[2], + macptr[3], macptr[4], macptr[5]); + + netif->hwaddr_len = ETHARP_HWADDR_LEN; + os_memcpy(netif->hwaddr, macptr, ETHARP_HWADDR_LEN); + /* maximum transfer unit */ + netif->mtu = 1500; + /* device capabilities */ + /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ + netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; + #ifdef LWIP_IGMP + netif->flags |= NETIF_FLAG_IGMP; + #endif + #if defined (LWIP_IPV6_MLD) && (LWIP_IPV6_MLD == 1) + netif->flags |= NETIF_FLAG_MLD6; + #endif + LWIP_LOGI("leave low level!\r\n"); +} + +/** + * This function should do the actual transmission of the packet. The packet is + * contained in the pbuf that is passed to the function. This pbuf + * might be chained. + * + * @param netif the lwip network interface structure for this ethernetif + * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) + * @return ERR_OK if the packet could be sent + * an err_t value if the packet couldn't be sent + * + * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to + * strange results. You might consider waiting for space in the DMA queue + * to become availale since the stack doesn't retry to send a packet + * dropped because of memory failure (except for the TCP timers). + */ +static err_t low_level_output(struct netif *netif, struct pbuf *p) +{ + int ret; + err_t err = ERR_OK; + uint8_t vif_idx = wifi_netif_vif_to_vifid(netif->state); +#if !CONFIG_HARMONY_LWIP +#if CONFIG_WIFI6_CODE_STACK + //LWIP_LOGI("output:%x\r\n", p); + extern bool special_arp_flag; + if(special_arp_flag) + { + ret = bmsg_special_tx_sender(p, (uint32_t)vif_idx); + special_arp_flag = false; + } + else +#endif +#endif + { + ret = bmsg_tx_sender(p, (uint32_t)vif_idx); + } + if(0 != ret) + { + err = ERR_TIMEOUT; + } + + return err; +} + +/** + * This function should be called when a packet is ready to be read + * from the interface. It uses the function low_level_input() that + * should handle the actual reception of bytes from the network + * interface. Then the type of the received packet is determined and + * the appropriate input function is called. + * + * @param netif the lwip network interface structure for this ethernetif + */ +void +ethernetif_input(int iface, struct pbuf *p) +{ + struct eth_hdr *ethhdr; + struct netif *netif; + void *vif; + + if (p->len <= SIZEOF_ETH_HDR) { + pbuf_free(p); + return; + } + + vif = wifi_netif_vifid_to_vif(iface); + netif = (struct netif *)wifi_netif_get_vif_private_data(vif); + if(!netif) { + //LWIP_LOGI("ethernetif_input no netif found %d\r\n", iface); + pbuf_free(p); + p = NULL; + return; + } + + /* points to packet payload, which starts with an Ethernet header */ + ethhdr = p->payload; + + if( (memcmp(netif->hwaddr,ethhdr->src.addr,NETIF_MAX_HWADDR_LEN)==0) && (htons(ethhdr->type) !=ETHTYPE_ARP) ) + { + LWIP_DEBUGF(ETHARP_DEBUG ,("ethernet_input frame is my send,drop it\r\n")); + pbuf_free(p); + return; + } + + switch (htons(ethhdr->type)) + { + /* IP or ARP packet? */ + case ETHTYPE_IP: + case ETHTYPE_ARP: +#ifdef CONFIG_IPV6 + case ETHTYPE_IPV6: + wlan_set_multicast_flag(); +#endif +#if PPPOE_SUPPORT + /* PPPoE packet? */ + case ETHTYPE_PPPOEDISC: + case ETHTYPE_PPPOE: +#endif /* PPPOE_SUPPORT */ + /* full packet send to tcpip_thread to process */ + if (netif->input(p, netif) != ERR_OK) // ethernet_input + { + LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\r\n")); + pbuf_free(p); + p = NULL; + } + break; +#if CONFIG_HARMONY_LWIP + /* ETHTYPE_EAPOL */ + case 0x888EU: +#else + case ETHTYPE_EAPOL: +#endif + ke_l2_packet_tx(p->payload, p->len, iface); + pbuf_free(p); + p = NULL; + break; + + default: + pbuf_free(p); + p = NULL; + break; + } + +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t +ethernetif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000); + + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; + netif->linkoutput = low_level_output; +#ifdef CONFIG_IPV6 + netif->output_ip6 = ethip6_output; +#endif + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} + +/** + * Should be called at the beginning of the program to set up the + * network interface. It calls the function low_level_init() to do the + * actual setup of the hardware. + * + * This function should be passed as a parameter to netifapi_netif_add(). + * + * @param netif the lwip network interface structure for this ethernetif + * @return ERR_OK if the loopif is initialized + * ERR_MEM if private data couldn't be allocated + * any other err_t on error + */ +err_t lwip_netif_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + /* + * Initialize the snmp variables and counters inside the struct netif. + * The last argument should be replaced with your link speed, in units + * of bits per second. + */ + NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, 10000000); + + netif->name[0] = IFNAME0; + netif->name[1] = IFNAME1; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; + netif->linkoutput = low_level_output; +#ifdef CONFIG_IPV6 + netif->output_ip6 = ethip6_output; +#endif + + /* initialize the hardware */ + low_level_init(netif); + return ERR_OK; +} + +err_t lwip_netif_uap_init(struct netif *netif) +{ + LWIP_ASSERT("netif != NULL", (netif != NULL)); + + //netif->state = NULL; + netif->name[0] = 'u'; + netif->name[1] = 'a'; + /* We directly use etharp_output() here to save a function call. + * You can instead declare your own function an call etharp_output() + * from it if you have to do some checks before sending (e.g. if link + * is available...) */ + netif->output = etharp_output; + netif->linkoutput = low_level_output; + + /* initialize the hardware */ + low_level_init(netif); + + return ERR_OK; +} + +// eof diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/ethernetif.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/ethernetif.h new file mode 100755 index 0000000..637055d --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/ethernetif.h @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 __ETHERNETIF_H__ +#define __ETHERNETIF_H__ + + +#include "lwip/err.h" +#include "lwip/netif.h" + + +void ethernetif_recv(struct netif *netif, int total_len); +err_t ethernetif_init(struct netif *netif); + + +#endif diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_hooks.c b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_hooks.c new file mode 100755 index 0000000..e7f3b81 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_hooks.c @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include +#include "lwip/netif.h" +#include "lwip_hooks.h" + +extern struct netif *netif_list; + +bool ip4_netif_exist(const ip4_addr_t *dest, const ip4_addr_t *src) +{ + struct netif *netif = NULL; + + for (netif = netif_list; netif != NULL; netif = netif->next) { + /* is the netif up, does it have a link and a valid address? */ + if (netif_is_up(netif) && netif_is_link_up(netif) + && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { + /* source netif and dest netif match? */ + if (ip4_addr_netcmp(src, netif_ip4_addr(netif), netif_ip4_netmask(netif)) + || ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) { + /* return false when both netif don't match */ + return true; + } + } + } + + return false; +} + +/** + * Source based IPv4 routing hook function. + * + * IP route algorithm: + * + * 1. Source IP based routing has highest priority + * 2. Then the destination IP based routing + * 3. Least priority is default netif + * + * + * Default netif in different scenario: + * + * | STA | AP | Default Netif | + * ----------------------------- + * | ON | OFF | STA | + * | ON | ON | STA | + * | OFF | ON | AP | + * + * + * Routing examples: + * + * | sta-ip | ap-ip | src-ip/netif | dst-ip | out netif | notes | + * --------------------------------------------------------------------------------------- + * | 192.168.0.5 | 10.10.10.1 | 10.10.10.1/ap | 10.10.10.2 | ap | src-ip-route | + * | 192.168.0.5 | 10.10.10.1 | 10.10.10.1/ap | 192.168.0.x | ap | src-ip-route | + * | 192.168.0.5 | 10.10.10.1 | 10.10.10.2/ap | 192.168.0.x | sta | dst-ip-route | + * | 192.168.0.5 | 10.10.10.1 | 10.10.10.2/ap | 192.168.1.x | sta | default netif| + * | 192.168.0.5 | 10.10.10.1 | 192.168.0.5/sta | 192.168.0.x | sta | src-ip-route | + * | 192.168.0.5 | 10.10.10.1 | 192.168.0.5/sta | 192.168.1.x | sta | src-ip-route | + * | 192.168.0.5 | 10.10.10.1 | 192.168.0.5/sta | 10.10.10.x | sta | src-ip-route | + * | unknown | 10.10.10.1 | unknown/sta | 10.10.10.x | ap | dst-ip-route | + * | unknown | 10.10.10.1 | unknown/sta | 10.10.9.x | sta | default netif| + * | 192.168.0.5 | 10.10.10.1 | 192.168.0.5/sta | 255.255.255.255 | sta | src-ip-route | + * | 192.168.0.5 | 10.10.10.1 | 10.10.10.1/ap | 255.255.255.255 | ap | src-ip-route | + * | unknown | 10.10.10.1 | unknown/sta | 255.255.255.255 | sta | default netif| + * + * + * General rules for STA/AP coexisting routing: + * + * 1. The IP of AP is always known, so if the AP netif want to send multicast/broadcast + * traffic, bind the AP's IP to the socket + * 2. Anytime if you want to send traffic that is different than the STA/IP's subnet via + * specific netif, bind the IP of the out netif to the socket + * 3. Avoid configuring the IP of AP's address to the same sub-net as STA's, suggest using + * the special local sub-net address scope. + */ +struct netif* ip4_route_src_hook(const ip4_addr_t *dest, const ip4_addr_t *src) +{ + struct netif *netif = NULL; + + /* destination IP is broadcast IP? */ + if ((src != NULL) && !ip4_addr_isany(src)) { + /* iterate through netifs */ + for (netif = netif_list; netif != NULL; netif = netif->next) { + /* is the netif up, does it have a link and a valid address? */ + if (netif_is_up(netif) && netif_is_link_up(netif) + && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { + /* source IP matches? */ + if (ip4_addr_cmp(src, netif_ip4_addr(netif))) { + /* return netif on which to forward IP packet */ + return netif; + } + } + } + } + + return netif; +} diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_hooks.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_hooks.h new file mode 100755 index 0000000..6937549 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_hooks.h @@ -0,0 +1,22 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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. + */ + +#pragma once +#include "lwip/ip_addr.h" +#include "lwip/arch.h" +#include "lwip/err.h" + +bool ip4_netif_exist(const ip4_addr_t *src, const ip4_addr_t *dest); +struct netif* ip4_route_src_hook(const ip4_addr_t *src,const ip4_addr_t *dest); diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_intf.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_intf.h new file mode 100755 index 0000000..07285e1 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_intf.h @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 __LWIP_INTF_H__ +#define __LWIP_INTF_H__ + +#define LWIP_INTF_DEBUG +#ifdef LWIP_INTF_DEBUG +#define LWIP_INTF_PRT warning_prf +#define LWIP_INTF_WARN warning_prf +#define LWIP_INTF_FATAL fatal_prf +#else +#define LWIP_INTF_PRT null_prf +#define LWIP_INTF_WARN null_prf +#define LWIP_INTF_FATAL null_prf +#endif + +#endif +// eof + diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_netif_address.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_netif_address.h new file mode 100755 index 0000000..985a886 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwip_netif_address.h @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 _MXCHIP_NETIF_ADDR_H_ +#define _MXCHIP_NETIF_ADDR_H_ +#include + +/** MLAN BSS type */ +typedef enum _wifi_interface_type +{ + WIFI_INTERFACE_TYPE_STA = 0, + WIFI_INTERFACE_TYPE_UAP = 1, + + WIFI_INTERFACE_TYPE_ANY = 0xff, +} wifi_interface_type; + +#define ADDR_TYPE_STATIC 1 +#define ADDR_TYPE_DHCP 0 + +/** This data structure represents an IPv4 address */ +struct ipv4_config { + /** DHCP_Disable DHCP_Client DHCP_Server */ + unsigned addr_type; + /** The system's IP address in network order. */ + unsigned address; + /** The system's default gateway in network order. */ + unsigned gw; + /** The system's subnet mask in network order. */ + unsigned netmask; + /** The system's primary dns server in network order. */ + unsigned dns1; + /** The system's secondary dns server in network order. */ + unsigned dns2; +}; + + +#ifdef CONFIG_IPV6 +#define MAX_IPV6_ADDRESSES 3 +struct ipv6_config { + ip6_addr_t address; + u8 addr_state; +}; + +#endif + + +/** Network IP configuration. + * + * This data structure represents the network IP configuration + * for IPv4 as well as IPv6 addresses + */ +struct wlan_ip_config { +#ifdef CONFIG_IPV6 + /** The network IPv6 address configuration that should be + * associated with this interface. */ + struct ipv6_config ipv6[MAX_IPV6_ADDRESSES]; +#endif + /** The network IPv4 address configuration that should be + * associated with this interface. */ + struct ipv4_config ipv4; +}; + +#endif diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwipopts.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwipopts.h new file mode 100755 index 0000000..cc14072 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/lwipopts.h @@ -0,0 +1,526 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ +#ifndef __LWIPOPTS_H__ +#define __LWIPOPTS_H__ + +#include +#include + + + +/** + * Loopback demo related options. + */ +#define LWIP_NETIF_LOOPBACK 1 +#define LWIP_HAVE_LOOPIF 1 +#define LWIP_NETIF_LOOPBACK_MULTITHREADING 1 +#define LWIP_LOOPBACK_MAX_PBUFS 8 + +#define TCPIP_THREAD_NAME "tcp/ip" +#ifdef CONFIG_KEYVALUE +#define TCPIP_THREAD_STACKSIZE 1024 +#else +#define TCPIP_THREAD_STACKSIZE 512 +#endif + +#if CONFIG_LITEOS_M +#define TCPIP_THREAD_PRIO 7 +#else +#define TCPIP_THREAD_PRIO 2 +#endif + +#define DEFAULT_THREAD_STACKSIZE 200 +#if CONFIG_LITEOS_M +#define DEFAULT_THREAD_PRIO 1 +#else +#define DEFAULT_THREAD_PRIO 8 +#endif + +/* Disable lwIP asserts */ +#define LWIP_NOASSERT 1 + +#define LWIP_DEBUG 0 +#define LWIP_DEBUG_TRACE 0 +#define SOCKETS_DEBUG LWIP_DBG_OFF +#define IP_DEBUG LWIP_DBG_OFF +#define ETHARP_DEBUG LWIP_DBG_OFF +#define NETIF_DEBUG LWIP_DBG_OFF +#define PBUF_DEBUG LWIP_DBG_OFF +#define MEMP_DEBUG LWIP_DBG_OFF +#define API_LIB_DEBUG LWIP_DBG_OFF +#define API_MSG_DEBUG LWIP_DBG_OFF +#define ICMP_DEBUG LWIP_DBG_OFF +#define IGMP_DEBUG LWIP_DBG_OFF +#define INET_DEBUG LWIP_DBG_OFF +#define IP_REASS_DEBUG LWIP_DBG_OFF +#define RAW_DEBUG LWIP_DBG_OFF +#define MEM_DEBUG LWIP_DBG_OFF +#define SYS_DEBUG LWIP_DBG_OFF +#define TCP_DEBUG LWIP_DBG_OFF +#define TCP_INPUT_DEBUG LWIP_DBG_OFF +#define TCP_FR_DEBUG LWIP_DBG_OFF +#define TCP_RTO_DEBUG LWIP_DBG_OFF +#define TCP_CWND_DEBUG LWIP_DBG_OFF +#define TCP_WND_DEBUG LWIP_DBG_OFF +#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF +#define TCP_RST_DEBUG LWIP_DBG_OFF +#define TCP_QLEN_DEBUG LWIP_DBG_OFF +#define UDP_DEBUG LWIP_DBG_OFF +#define TCPIP_DEBUG LWIP_DBG_OFF +#define PPP_DEBUG LWIP_DBG_OFF +#define SLIP_DEBUG LWIP_DBG_OFF +#define DHCP_DEBUG LWIP_DBG_OFF +#define AUTOIP_DEBUG LWIP_DBG_OFF +#define SNMP_MSG_DEBUG LWIP_DBG_OFF +#define SNMP_MIB_DEBUG LWIP_DBG_OFF +#define DNS_DEBUG LWIP_DBG_OFF +#define IP6_DEBUG LWIP_DBG_OFF +#define MDNS_DEBUG LWIP_DBG_OFF + +//#define LWIP_COMPAT_MUTEX 1 +/** + * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain + * critical regions during buffer allocation, deallocation and memory + * allocation and deallocation. + */ +#define SYS_LIGHTWEIGHT_PROT 1 + +/* + ------------------------------------ + ---------- Memory options ---------- + ------------------------------------ +*/ + +#define MEM_TRX_DYNAMIC_EN 0 + +/** + * MEM_ALIGNMENT: should be set to the alignment of the CPU + * 4 byte alignment -> #define MEM_ALIGNMENT 4 + * 2 byte alignment -> #define MEM_ALIGNMENT 2 + */ +#define MEM_ALIGNMENT 4 + +#define MAX_SOCKETS_TCP 8 +#define MAX_LISTENING_SOCKETS_TCP 4 +#define MAX_SOCKETS_UDP 8 +#define TCP_SND_BUF_COUNT 5 + +/* Value of TCP_SND_BUF_COUNT denotes the number of buffers and is set by + * CONFIG option available in the SDK + */ +/* Buffer size needed for TCP: Max. number of TCP sockets * Size of pbuf * + * Max. number of TCP sender buffers per socket + * + * Listening sockets for TCP servers do not require the same amount buffer + * space. Hence do not consider these sockets for memory computation + */ +#define TCP_MEM_SIZE (MAX_SOCKETS_TCP * \ + PBUF_POOL_BUFSIZE * (TCP_SND_BUF/TCP_MSS)) + +/* Buffer size needed for UDP: Max. number of UDP sockets * Size of pbuf + */ +#define UDP_MEM_SIZE (MAX_SOCKETS_UDP * PBUF_POOL_BUFSIZE) + +/** + * MEM_SIZE: the size of the heap memory. If the application will send + * a lot of data that needs to be copied, this should be set high. + */ +#if (MEM_TRX_DYNAMIC_EN) +#define MEM_SIZE (60*1024) +#define MEM_MAX_TX_SIZE (MEM_SIZE*5)/6 +#define MEM_MAX_RX_SIZE (MEM_SIZE*3)/4 +#else +#if (CONFIG_LWIP_MEM_REDUCE) +#define MEM_SIZE (32*1024) +#else +#define MEM_SIZE (48*1024) +#endif //CONFIG_LWIP_MEM_REDUCE +#endif //MEM_TRX_DYNAMIC_EN + + +/* + ------------------------------------------------ + ---------- Internal Memory Pool Sizes ---------- + ------------------------------------------------ +*/ +/** + * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). + * If the application sends a lot of data out of ROM (or other static memory), + * this should be set high. + */ +#define MEMP_NUM_PBUF 10 + +/** + * MEMP_NUM_TCP_PCB: the number of simulatenously active TCP connections. + * (requires the LWIP_TCP option) + */ +#define MEMP_NUM_TCP_PCB MAX_SOCKETS_TCP + +#define MEMP_NUM_TCP_PCB_LISTEN MAX_LISTENING_SOCKETS_TCP + +/** + * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. + * (requires the LWIP_TCP option) + */ +//#define MEMP_NUM_TCP_SEG 12 + +/** + * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used + * for incoming packets. + * (only needed if you use tcpip.c) + */ + +#define MEMP_NUM_TCPIP_MSG_INPKT 16 + +/** + * MEMP_NUM_SYS_TIMEOUT: the number of simulateously active timeouts. + * (requires NO_SYS==0) + */ +#define MEMP_NUM_SYS_TIMEOUT 12 + +/** + * MEMP_NUM_NETBUF: the number of struct netbufs. + * (only needed if you use the sequential API, like api_lib.c) + */ +#if (MEM_TRX_DYNAMIC_EN) +#define MEMP_NUM_NETBUF 32 +#else +#define MEMP_NUM_NETBUF 16 +#endif +/** + * MEMP_NUM_NETCONN: the number of struct netconns. + * (only needed if you use the sequential API, like api_lib.c) + * + * This number corresponds to the maximum number of active sockets at any + * given point in time. This number must be sum of max. TCP sockets, max. TCP + * sockets used for listening, and max. number of UDP sockets + */ +#define MEMP_NUM_NETCONN (MAX_SOCKETS_TCP + \ + MAX_LISTENING_SOCKETS_TCP + MAX_SOCKETS_UDP) + + + +/** + * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. + */ +#if (MEM_TRX_DYNAMIC_EN) +#define PBUF_POOL_SIZE 3 +#else +#define PBUF_POOL_SIZE 20 +#endif + +/* + ---------------------------------- + ---------- Pbuf options ---------- + ---------------------------------- +*/ + +/** + * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is + * designed to accomodate single full size TCP frame in one pbuf, including + * TCP_MSS, IP header, and link header. + */ +#if CONFIG_WIFI6_CODE_STACK +#define PBUF_LINK_ENCAPSULATION_HLEN CONFIG_MSDU_RESV_HEAD_LENGTH +#define PBUF_POOL_BUFSIZE (1580 + PBUF_LINK_ENCAPSULATION_HLEN) +#else +#define PBUF_POOL_BUFSIZE 1580 +#endif + + +/* + --------------------------------- + ---------- RAW options ---------- + --------------------------------- +*/ +/** + * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. + */ +#define LWIP_RAW 1 +#ifdef CONFIG_IPV6 +#define LWIP_IPV6 1 +#endif + +/* Enable IPv4 Auto IP */ +#ifdef CONFIG_AUTOIP +#define LWIP_AUTOIP 1 +#define LWIP_DHCP_AUTOIP_COOP 1 +#define LWIP_DHCP_AUTOIP_COOP_TRIES 5 +#endif + + +/* Enable MDNS */ +#ifdef CONFIG_MDNS +#define LWIP_MDNS_RESPONDER 1 +#define LWIP_NUM_NETIF_CLIENT_DATA (LWIP_MDNS_RESPONDER) +#endif + + + + +/* + ------------------------------------ + ---------- Socket options ---------- + ------------------------------------ +*/ +/** + * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) + */ +#define LWIP_SOCKET 1 +#define LWIP_NETIF_API 1 + +/** + * LWIP_RECV_CB==1: Enable callback when a socket receives data. + */ +#define LWIP_RECV_CB 1 +/** + * SO_REUSE==1: Enable SO_REUSEADDR option. + */ +#define SO_REUSE 1 +#define SO_REUSE_RXTOALL 1 + +/** + * Enable TCP_KEEPALIVE + */ +#define LWIP_TCP_KEEPALIVE 1 + +/* + ---------------------------------------- + ---------- Statistics options ---------- + ---------------------------------------- +*/ +/** + * LWIP_STATS==1: Enable statistics collection in lwip_stats. + */ +#define LWIP_STATS 1 + +/** + * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. + */ +#define LWIP_STATS_DISPLAY 1 + +/* + ---------------------------------- + ---------- DHCP options ---------- + ---------------------------------- +*/ +/** + * LWIP_DHCP==1: Enable DHCP module. + */ +#define LWIP_DHCP 1 +#define LWIP_NETIF_STATUS_CALLBACK 1 + +/** + * DNS related options, revisit later to fine tune. + */ +#define LWIP_DNS 1 +#define DNS_TABLE_SIZE 2 // number of table entries, default 4 +//#define DNS_MAX_NAME_LENGTH 64 // max. name length, default 256 +#define DNS_MAX_SERVERS 2 // number of DNS servers, default 2 +#define DNS_DOES_NAME_CHECK 1 // compare received name with given,def 0 +#define DNS_MSG_SIZE 512 +#define MDNS_MSG_SIZE 512 +#define MDNS_TABLE_SIZE 1 // number of mDNS table entries +#define MDNS_MAX_SERVERS 1 // number of mDNS multicast addresses +/* TODO: Number of active UDP PCBs is equal to number of active UDP sockets plus + * two. Need to find the users of these 2 PCBs + */ +#define MEMP_NUM_UDP_PCB (MAX_SOCKETS_UDP + 2) +/* NOTE: some times the socket() call for SOCK_DGRAM might fail if you dont + * have enough MEMP_NUM_UDP_PCB */ + +/* + ---------------------------------- + ---------- IGMP options ---------- + ---------------------------------- +*/ +/** + * LWIP_IGMP==1: Turn on IGMP module. + */ +#define LWIP_IGMP 1 + +/** + * LWIP_SO_CONTIMEO==1: Enable send timeout for sockets/netconns and + * SO_CONTIMEO processing. + */ +#define LWIP_SO_CONTIMEO 1 + +/** + * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and + * SO_SNDTIMEO processing. + */ +#define LWIP_SO_SNDTIMEO 1 + +/** + * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and + * SO_RCVTIMEO processing. + */ +#define LWIP_SO_RCVTIMEO 1 +#define LWIP_SO_SNDTIMEO 1 +/** + * TCP_LISTEN_BACKLOG==1: Handle backlog connections. + */ +#define TCP_LISTEN_BACKLOG 1 +#define LWIP_PROVIDE_ERRNO 1 + +#include +#define ERRNO 1 + +//#define LWIP_SNMP 1 + + +/* + ------------------------------------------------ + ---------- Network Interfaces options ---------- + ------------------------------------------------ +*/ +/** + * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname + * field. + */ +#define LWIP_NETIF_HOSTNAME 1 + + +/* +The STM32F107 allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware: + - To use this feature let the following define uncommented. + - To disable it and process by CPU comment the the checksum. +*/ +//#define CHECKSUM_BY_HARDWARE + + +#ifdef CHECKSUM_BY_HARDWARE + /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/ + #define CHECKSUM_GEN_IP 0 + /* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/ + #define CHECKSUM_GEN_UDP 0 + /* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/ + #define CHECKSUM_GEN_TCP 0 + /* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/ + #define CHECKSUM_CHECK_IP 0 + /* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/ + #define CHECKSUM_CHECK_UDP 0 + /* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/ + #define CHECKSUM_CHECK_TCP 0 +#else + /* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/ + #define CHECKSUM_GEN_IP 1 + /* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/ + #define CHECKSUM_GEN_UDP 1 + /* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/ + #define CHECKSUM_GEN_TCP 1 + /* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/ + #define CHECKSUM_CHECK_IP 1 + /* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/ + #define CHECKSUM_CHECK_UDP 1 + /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/ + #define CHECKSUM_CHECK_TCP 1 +#endif + +/** + * TCP_RESOURCE_FAIL_RETRY_LIMIT: limit for retrying sending of tcp segment + * on resource failure error returned by driver. + */ +#define TCP_RESOURCE_FAIL_RETRY_LIMIT 50 + +//#ifdef CONFIG_ENABLE_MXCHIP +/* save memory */ +#if (CONFIG_LWIP_MEM_REDUCE) +#define TCP_MSS (1500 - 40) +/* TCP receive window. */ +#define TCP_WND (10 * TCP_MSS) +/* TCP sender buffer space (bytes). */ +#define TCP_SND_BUF (10*TCP_MSS) + +#define TCP_SND_QUEUELEN (20) +#else +#define TCP_MSS (1500 - 40) +/* TCP receive window. */ +#define TCP_WND (10*TCP_MSS) +/* TCP sender buffer space (bytes). */ +#define TCP_SND_BUF (10*TCP_MSS) + +#define TCP_SND_QUEUELEN (20) +#endif + +/* ARP before DHCP causes multi-second delay - turn it off */ +#define DHCP_DOES_ARP_CHECK (0) + +#define TCP_MAX_ACCEPT_CONN 5 +#define MEMP_NUM_TCP_SEG (TCP_SND_QUEUELEN*2) + +#define IP_REASS_MAX_PBUFS 0 +#define IP_REASSEMBLY 0 +#define IP_REASS_MAX_PBUFS 0 +#define IP_REASSEMBLY 0 +#define MEMP_NUM_REASSDATA 0 +#define IP_FRAG 0 + +#define MEM_LIBC_MALLOC (0) + +#if (CONFIG_LWIP_MEM_REDUCE) +#define DEFAULT_UDP_RECVMBOX_SIZE 16 //each udp socket max buffer 3 packets. +#else +#define DEFAULT_UDP_RECVMBOX_SIZE 16 //each udp socket max buffer 16 packets. +#endif + +#define MEMP_MEM_MALLOC (0) +#define TCP_MSL (TCP_TMR_INTERVAL) + +#define LWIP_COMPAT_MUTEX_ALLOWED (1) + +#define MEMP_STATS 1 +#define MEM_STATS 1 + +#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS + +#define ETHARP_SUPPORT_STATIC_ENTRIES 1 + +#define LWIP_RIPPLE20 1 + +/* Beken specific LWIP options */ +#define BK_DHCP 1 + +#define LWIP_TAG "lwip" +#define LWIP_LOGI(...) BK_LOGI(LWIP_TAG, ##__VA_ARGS__) +#define LWIP_LOGW(...) BK_LOGW(LWIP_TAG, ##__VA_ARGS__) +#define LWIP_LOGE(...) BK_LOGE(LWIP_TAG, ##__VA_ARGS__) +#define LWIP_LOGD(...) BK_LOGD(LWIP_TAG, ##__VA_ARGS__) +#if 0 +#define LWIP_HOOK_FILENAME "lwip_hooks.h" +#define LWIP_HOOK_IP4_ROUTE_SRC ip4_route_src_hook +#endif +#define BK_IP4_ROUTE 1 +#define BK_DHCPS_DNS 1 + +#endif /* __LWIPOPTS_H__ */ + diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/net.c b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/net.c new file mode 100755 index 0000000..cce7be3 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/net.c @@ -0,0 +1,841 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 +#include +#include + +#include +#include "netif/etharp.h" +#include "lwip/netif.h" +#include +#include +#include +#include +#include "lwip/prot/dhcp.h" +#include "lwip/apps/mdns.h" + +#include +#include "ethernetif.h" + +#include +#include "bk_drv_model.h" +#include +#include "bk_wifi_netif.h" //TODO use standard EVENT instead!!! +#include "lwip_netif_address.h" +#include +#include "net.h" + +#include "wlan_defs_pub.h" +#include "bk_wifi.h" +#include +#include +#include "wlan_ui_pub.h" + +/* forward declaration */ +FUNC_1PARAM_PTR bk_wlan_get_status_cb(void); + +struct ipv4_config sta_ip_settings = { + .addr_type = ADDR_TYPE_DHCP, + .address = 0, + .gw = 0, + .netmask = 0, + .dns1 = 0, + .dns2 = 0, +}; + +struct ipv4_config uap_ip_settings = { + .addr_type = ADDR_TYPE_STATIC, + .address = 0xc0a80001, //192.168.0.1 + .gw = 0xc0a80001, //192.168.0.1 + .netmask = 0xffffff00, //255.255.255.0 + .dns1 = 0xc0a80001, //192.168.0.1 + .dns2 = 0, +}; +static char up_iface; +uint8 sta_ip_start_flag = 0; +uint8 uap_ip_start_flag = 0; + +#ifdef CONFIG_IPV6 +#define IPV6_ADDR_STATE_TENTATIVE "Tentative" +#define IPV6_ADDR_STATE_PREFERRED "Preferred" +#define IPV6_ADDR_STATE_INVALID "Invalid" +#define IPV6_ADDR_STATE_VALID "Valid" +#define IPV6_ADDR_STATE_DEPRECATED "Deprecated" +#define IPV6_ADDR_TYPE_LINKLOCAL "Link-Local" +#define IPV6_ADDR_TYPE_GLOBAL "Global" +#define IPV6_ADDR_TYPE_UNIQUELOCAL "Unique-Local" +#define IPV6_ADDR_TYPE_SITELOCAL "Site-Local" +#define IPV6_ADDR_UNKNOWN "Unknown" +#endif + +typedef void (*net_sta_ipup_cb_fn)(void* data); + +struct interface { + struct netif netif; + ip_addr_t ipaddr; + ip_addr_t nmask; + ip_addr_t gw; +}; +FUNCPTR sta_connected_func; + +static struct interface g_mlan = {{0}}; +static struct interface g_uap = {{0}}; +net_sta_ipup_cb_fn sta_ipup_cb = NULL; + +extern void *net_get_sta_handle(void); +extern void *net_get_uap_handle(void); +extern err_t lwip_netif_init(struct netif *netif); +extern err_t lwip_netif_uap_init(struct netif *netif); +extern int net_get_if_ip_addr(uint32_t *ip, void *intrfc_handle); +extern int net_get_if_ip_mask(uint32_t *nm, void *intrfc_handle); +extern int net_configure_address(struct ipv4_config *addr, void *intrfc_handle); +extern int dhcp_server_start(void *intrfc_handle); +extern void dhcp_server_stop(void); +extern void net_configure_dns(struct wlan_ip_config *ip); +extern bk_err_t bk_wifi_get_ip_status(IPStatusTypedef *outNetpara, WiFi_Interface inInterface); + + +#ifdef CONFIG_IPV6 +char *ipv6_addr_state_to_desc(unsigned char addr_state) +{ + if (ip6_addr_istentative(addr_state)) + return IPV6_ADDR_STATE_TENTATIVE; + else if (ip6_addr_ispreferred(addr_state)) + return IPV6_ADDR_STATE_PREFERRED; + else if (ip6_addr_isinvalid(addr_state)) + return IPV6_ADDR_STATE_INVALID; + else if (ip6_addr_isvalid(addr_state)) + return IPV6_ADDR_STATE_VALID; + else if (ip6_addr_isdeprecated(addr_state)) + return IPV6_ADDR_STATE_DEPRECATED; + else + return IPV6_ADDR_UNKNOWN; +} + +char *ipv6_addr_type_to_desc(struct ipv6_config *ipv6_conf) +{ + if (ip6_addr_islinklocal((ip6_addr_t *)&ipv6_conf->address)) + return IPV6_ADDR_TYPE_LINKLOCAL; + else if (ip6_addr_isglobal((ip6_addr_t *)&ipv6_conf->address)) + return IPV6_ADDR_TYPE_GLOBAL; + else if (ip6_addr_isuniquelocal((ip6_addr_t *)&ipv6_conf->address)) + return IPV6_ADDR_TYPE_UNIQUELOCAL; + else if (ip6_addr_issitelocal((ip6_addr_t *)&ipv6_conf->address)) + return IPV6_ADDR_TYPE_SITELOCAL; + else + return IPV6_ADDR_UNKNOWN; +} +#endif /* CONFIG_IPV6 */ + +int net_dhcp_hostname_set(char *hostname) +{ + netif_set_hostname(&g_mlan.netif, hostname); + return 0; +} + +void net_ipv4stack_init(void) +{ + static bool tcpip_init_done = 0; + if (tcpip_init_done) + return; + + LWIP_LOGI("init TCP/IP\r\n"); + tcpip_init(NULL, NULL); + tcpip_init_done = true; +} + +#ifdef CONFIG_IPV6 +void net_ipv6stack_init(struct netif *netif) +{ + bk_get_mac(netif->hwaddr, MAC_TYPE_STA); + netif->hwaddr_len = 6; +} +#endif /* CONFIG_IPV6 */ + +void net_wlan_init(void) +{ + static int wlan_init_done = 0; + int ret; + + if (!wlan_init_done) { + net_ipv4stack_init(); + ip_addr_set_ip4_u32(&g_mlan.ipaddr,INADDR_ANY); + ret = netifapi_netif_add(&g_mlan.netif,ip_2_ip4(&g_mlan.ipaddr), + ip_2_ip4(&g_mlan.ipaddr), ip_2_ip4(&g_mlan.ipaddr), NULL, + lwip_netif_init, tcpip_input); + if (ret) { + /*FIXME: Handle the error case cleanly */ + LWIP_LOGE("sta netif add failed"); + } +#ifdef CONFIG_IPV6 + net_ipv6stack_init(&g_mlan.netif); +#endif /* CONFIG_IPV6 */ + + ret = netifapi_netif_add(&g_uap.netif, ip_2_ip4(&g_uap.ipaddr), + ip_2_ip4(&g_uap.ipaddr), ip_2_ip4(&g_uap.ipaddr), NULL, + lwip_netif_uap_init, tcpip_input); + if (ret) { + /*FIXME: Handle the error case cleanly */ + LWIP_LOGE("ap netif add failed"); + } + wlan_init_done = 1; + } + + return; +} + +void net_set_sta_ipup_callback(void *fn) +{ + sta_ipup_cb = (net_sta_ipup_cb_fn)fn; +} + +void user_connected_callback(FUNCPTR fn) +{ + sta_connected_func = fn; +} + +static void wm_netif_status_static_callback(struct netif *n) +{ + if (n->flags & NETIF_FLAG_UP) { + // static IP success; + LWIP_LOGI("using static ip...\n"); + wifi_netif_notify_sta_got_ip(); +#if CONFIG_LWIP_FAST_DHCP + /* read stored IP from flash as the static IP */ + struct wlan_fast_connect_info fci = {0}; + wlan_read_fast_connect_info(&fci); + os_memcpy((char *)&n->ip_addr, (char *)&fci.ip_addr, sizeof(fci.ip_addr)); + os_memcpy((char *)&n->netmask, (char *)&fci.netmask, sizeof(fci.netmask)); + os_memcpy((char *)&n->gw, (char *)&fci.gw, sizeof(fci.gw)); + os_memcpy((char *)&n->dns1, (char *)&fci.dns1, sizeof(fci.dns1)); + LWIP_LOGI("ip_addr: "BK_IP4_FORMAT" \r\n", BK_IP4_STR(ip_addr_get_ip4_u32(&n->ip_addr))); +#endif + +#if !CONFIG_DISABLE_DEPRECIATED_WIFI_API + if (sta_ipup_cb != NULL) + sta_ipup_cb(NULL); + + if (sta_connected_func != NULL) + (*sta_connected_func)(); +#endif + } else { + // static IP fail; + } +} + +extern wifi_connect_tick_t sta_tick; +static void wm_netif_status_callback(struct netif *n) +{ + struct dhcp *dhcp; + + if (n->flags & NETIF_FLAG_UP) { + dhcp = netif_dhcp_data(n); +#ifdef CONFIG_IPV6 + int i; + u8 *ipv6_addr; + + { + for (i = 0; i < MAX_IPV6_ADDRESSES; i++) { + if (ip6_addr_isvalid(netif_ip6_addr_state(n, i))) { + ipv6_addr = (u8*)(ip_2_ip6(&n->ip6_addr[i]))->addr; + bk_printf("ipv6_addr[%d] : %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x\r\n", i, + ipv6_addr[0], ipv6_addr[1], ipv6_addr[2], ipv6_addr[3], + ipv6_addr[4], ipv6_addr[5], ipv6_addr[6], ipv6_addr[7], + ipv6_addr[8], ipv6_addr[9], ipv6_addr[10], ipv6_addr[11], + ipv6_addr[12], ipv6_addr[13], ipv6_addr[14], ipv6_addr[15]); + bk_printf("ipv6_type[%d] :0x%x\r\n", i, n->ip6_addr[i].type); + bk_printf("ipv6_state[%d] :0x%x\r\n", i, n->ip6_addr_state[i]); + } + } + } +#endif + +#ifdef CONFIG_MDNS + if(!ip_addr_isany(&n->ip_addr)){ + mdns_resp_restart(n); + } +#endif + + if(dhcp != NULL) { + /* dhcp success*/ + if (dhcp->state == DHCP_STATE_BOUND) { + LWIP_LOGI("ip_addr: "BK_IP4_FORMAT" \r\n", BK_IP4_STR(ip_addr_get_ip4_u32(&n->ip_addr))); + sta_tick.sta_ip_tick = rtos_get_time(); + LWIP_LOGI("STA assoc delta:%d, eapol delta:%d, dhcp delta:%d, total:%d\n", + sta_tick.sta_assoc_tick - sta_tick.sta_start_tick, + sta_tick.sta_eapol_tick - sta_tick.sta_assoc_tick, + sta_tick.sta_ip_tick - sta_tick.sta_eapol_tick, + sta_tick.sta_ip_tick - sta_tick.sta_start_tick); +#if !CONFIG_DISABLE_DEPRECIATED_WIFI_API + wifi_netif_call_status_cb_when_sta_got_ip(); +#endif + wifi_netif_notify_sta_got_ip(); + +#if CONFIG_LWIP_FAST_DHCP + /* store current IP to flash */ + const ip_addr_t *dns_server; + dns_server = dns_getserver(0); + n->dns1 = ip_addr_get_ip4_u32(dns_server); + struct wlan_fast_connect_info fci = {0}; + wlan_read_fast_connect_info(&fci); + os_memset(&fci.ip_addr, 0, sizeof(ip_addr_t)*4); + os_memcpy((char *)&fci.ip_addr, (char *)&n->ip_addr, sizeof(n->ip_addr)); + os_memcpy((char *)&fci.netmask, (char *)&n->netmask, sizeof(n->netmask)); + os_memcpy((char *)&fci.gw, (char *)&n->gw, sizeof(n->gw)); + os_memcpy((char *)&fci.dns1, (char *)&n->dns1, sizeof(n->dns1)); + wlan_write_fast_connect_info(&fci); +#endif + +#if !CONFIG_DISABLE_DEPRECIATED_WIFI_API + if(sta_ipup_cb != NULL) + sta_ipup_cb(NULL); + + if(sta_connected_func != NULL) + (*sta_connected_func)(); +#endif + } else { + // dhcp fail +#if !CONFIG_DISABLE_DEPRECIATED_WIFI_API + wifi_netif_call_status_cb_when_sta_dhcp_timeout(); +#endif + } + } else { + // static IP success; + } + } else { + // dhcp fail; + } +} + +static int check_iface_mask(void *handle, uint32_t ipaddr) +{ + uint32_t interface_ip, interface_mask; + net_get_if_ip_addr(&interface_ip, handle); + net_get_if_ip_mask(&interface_mask, handle); + if (interface_ip > 0) + if ((interface_ip & interface_mask) == + (ipaddr & interface_mask)) + return 0; + return -1; +} + +void *net_ip_to_interface(uint32_t ipaddr) +{ + int ret; + void *handle; + /* Check mlan handle */ + handle = net_get_sta_handle(); + ret = check_iface_mask(handle, ipaddr); + if (ret == 0) + return handle; + + /* Check uap handle */ + handle = net_get_uap_handle(); + ret = check_iface_mask(handle, ipaddr); + if (ret == 0) + return handle; + + /* If more interfaces are added then above check needs to done for + * those newly added interfaces + */ + return NULL; +} + +void *net_sock_to_interface(int sock) +{ + struct sockaddr_in peer; + unsigned long peerlen = sizeof(struct sockaddr_in); + void *req_iface = NULL; + + getpeername(sock, (struct sockaddr *)&peer, &peerlen); + req_iface = net_ip_to_interface(peer.sin_addr.s_addr); + return req_iface; +} + +void *net_get_sta_handle(void) +{ + return &g_mlan.netif; +} + +void *net_get_uap_handle(void) +{ + return &g_uap.netif; +} + +void *net_get_netif_handle(uint8_t iface) +{ + + return NULL; +} + +void net_interface_up(void *intrfc_handle) +{ + struct interface *if_handle = (struct interface *)intrfc_handle; + netifapi_netif_set_up(&if_handle->netif); +} + +void net_interface_down(void *intrfc_handle) +{ + struct interface *if_handle = (struct interface *)intrfc_handle; + netifapi_netif_set_down(&if_handle->netif); +} + + +void net_interface_dhcp_stop(void *intrfc_handle) +{ + struct interface *if_handle = (struct interface *)intrfc_handle; + netifapi_dhcp_stop(&if_handle->netif); + netif_set_status_callback(&if_handle->netif, NULL); +} + +void sta_ip_down(void) +{ + if(sta_ip_start_flag) + { + LWIP_LOGI("sta ip down\r\n"); + + sta_ip_start_flag = 0; + + netifapi_netif_set_down(&g_mlan.netif); + netif_set_status_callback(&g_mlan.netif, NULL); + netifapi_dhcp_stop(&g_mlan.netif); +#if LWIP_IPV6 + for(u8_t addr_idx = 1; addr_idx < LWIP_IPV6_NUM_ADDRESSES; addr_idx++) { + netif_ip6_addr_set(&g_mlan.netif, addr_idx, (const ip6_addr_t *)IP6_ADDR_ANY); + g_mlan.netif.ip6_addr_state[addr_idx] = IP6_ADDR_INVALID; + } +#endif + } +} + +void sta_ip_start(void) +{ + struct wlan_ip_config address = {0}; + + if(!sta_ip_start_flag) { + LWIP_LOGI("sta ip start\r\n"); + sta_ip_start_flag = 1; + net_configure_address(&sta_ip_settings, net_get_sta_handle()); + return; + } + + LWIP_LOGI("sta ip start: "BK_IP4_FORMAT" \r\n", BK_IP4_STR(address.ipv4.address)); + net_get_if_addr(&address, net_get_sta_handle()); + if(wifi_netif_sta_is_connected() + && (0 != address.ipv4.address)) { + wifi_netif_notify_sta_got_ip(); + } +} + +void sta_set_default_netif(void) +{ + netifapi_netif_set_default(net_get_sta_handle()); +} + +void ap_set_default_netif(void) +{ + // as the default netif is sta's netif, so ap need to send + // boardcast or not sub net packets, need set ap netif before + // send those packets, after finish sending, reset default netif + // to sat's netif. + netifapi_netif_set_default(net_get_uap_handle()); +} + +void reset_default_netif(void) +{ + netifapi_netif_set_default(NULL); +} + +uint32_t sta_ip_is_start(void) +{ + return sta_ip_start_flag; +} + +void uap_ip_down(void) +{ + if (uap_ip_start_flag ) + { + LWIP_LOGI("uap ip down\r\n"); + uap_ip_start_flag = 0; + + netifapi_netif_set_down(&g_uap.netif); + netif_set_status_callback(&g_uap.netif, NULL); + dhcp_server_stop(); + } +} + +void uap_ip_start(void) +{ + if ( !uap_ip_start_flag ) + { + LWIP_LOGI("uap ip start\r\n"); + uap_ip_start_flag = 1; + net_configure_address(&uap_ip_settings, net_get_uap_handle()); + } +} + +uint32_t uap_ip_is_start(void) +{ + return uap_ip_start_flag; +} + +#define DEF_UAP_IP 0xc0a80a01UL /* 192.168.10.1 */ + +void ip_address_set(int iface, int dhcp, char *ip, char *mask, char*gw, char*dns) +{ + uint32_t tmp; + struct ipv4_config addr; + + memset(&addr, 0, sizeof(struct ipv4_config)); + if (dhcp == 1) { + addr.addr_type = ADDR_TYPE_DHCP; + } else { + addr.addr_type = ADDR_TYPE_STATIC; + tmp = inet_addr((char*)ip); + addr.address = (tmp); + tmp = inet_addr((char*)mask); + if (tmp == 0xFFFFFFFF) + tmp = 0x00FFFFFF;// if not set valid netmask, set as 255.255.255.0 + addr.netmask= (tmp); + tmp = inet_addr((char*)gw); + addr.gw = (tmp); + + tmp = inet_addr((char*)dns); + addr.dns1 = (tmp); + } + + if (iface == 1) // Station + memcpy(&sta_ip_settings, &addr, sizeof(addr)); + else + memcpy(&uap_ip_settings, &addr, sizeof(addr)); +} + +void sta_ip_mode_set(int dhcp) +{ + if (dhcp == 1) { + ip_address_set(1, DHCP_CLIENT, NULL, NULL, NULL, NULL); + } else { + IPStatusTypedef ipStatus; + bk_err_t ret = kNoErr; + os_memset(&ipStatus, 0x0, sizeof(IPStatusTypedef)); + ret = bk_wifi_get_ip_status(&ipStatus, BK_STATION); + if (ret == kNoErr) + ip_address_set(1, DHCP_DISABLE, ipStatus.ip, ipStatus.mask, ipStatus.gate, ipStatus.dns); + } +} + +#if CONFIG_LWIP_FAST_DHCP +void net_restart_dhcp(void) +{ + sta_ip_down(); + ip_address_set(BK_STATION, DHCP_CLIENT, NULL, NULL, NULL, NULL); + sta_ip_start(); +} +#endif + +int net_configure_address(struct ipv4_config *addr, void *intrfc_handle) +{ + if (!intrfc_handle) + return -1; + + struct interface *if_handle = (struct interface *)intrfc_handle; + + LWIP_LOGI("configuring interface %s (with %s)\n", + (if_handle == &g_mlan) ? "sta" :"ap", + (addr->addr_type == ADDR_TYPE_DHCP) + ? "DHCP client" : "Static IP"); + netifapi_netif_set_down(&if_handle->netif); + + /* De-register previously registered DHCP Callback for correct + * address configuration. + */ + netif_set_status_callback(&if_handle->netif, NULL); + + switch (addr->addr_type) { + case ADDR_TYPE_STATIC: + ip_addr_set_ip4_u32(&if_handle->ipaddr , addr->address); + ip_addr_set_ip4_u32(&if_handle->nmask,addr->netmask); + ip_addr_set_ip4_u32(&if_handle->gw ,addr->gw); + + netifapi_netif_set_addr(&if_handle->netif, ip_2_ip4(&if_handle->ipaddr), + ip_2_ip4(&if_handle->nmask), ip_2_ip4(&if_handle->gw)); + + //AP never configure DNS server address!!! + + if(if_handle == &g_mlan) + { + netif_set_status_callback(&if_handle->netif, + wm_netif_status_static_callback); + } + netifapi_netif_set_up(&if_handle->netif); + net_configure_dns((struct wlan_ip_config *)addr); + break; + + case ADDR_TYPE_DHCP: + /* Reset the address since we might be transitioning from static to DHCP */ + memset(&if_handle->ipaddr, 0, sizeof(ip_addr_t)); + memset(&if_handle->nmask, 0, sizeof(ip_addr_t)); + memset(&if_handle->gw, 0, sizeof(ip_addr_t)); + netifapi_netif_set_addr(&if_handle->netif, ip_2_ip4(&if_handle->ipaddr), + ip_2_ip4(&if_handle->nmask), ip_2_ip4(&if_handle->gw)); + + netif_set_status_callback(&if_handle->netif, + wm_netif_status_callback); + netifapi_netif_set_up(&if_handle->netif); + netifapi_dhcp_start(&if_handle->netif); + break; + + default: + break; + } + /* Finally this should send the following event. */ + if (if_handle == &g_mlan) { + // static IP up; + + /* XXX For DHCP, the above event will only indicate that the + * DHCP address obtaining process has started. Once the DHCP + * address has been obtained, another event, + * WD_EVENT_NET_DHCP_CONFIG, should be sent to the wlcmgr. + */ + up_iface = 1; + + // we always set sta netif as the default. + sta_set_default_netif(); + } else { + // softap IP up, start dhcp server; + dhcp_server_start(net_get_uap_handle()); + up_iface = 0; + } + + return 0; +} + +int net_get_if_addr(struct wlan_ip_config *addr, void *intrfc_handle) +{ + const ip_addr_t *tmp; + struct interface *if_handle = (struct interface *)intrfc_handle; + + if(netif_is_up(&if_handle->netif)) { + addr->ipv4.address = ip_addr_get_ip4_u32(&if_handle->netif.ip_addr); + addr->ipv4.netmask = ip_addr_get_ip4_u32(&if_handle->netif.netmask); + addr->ipv4.gw = ip_addr_get_ip4_u32(&if_handle->netif.gw); + + tmp = dns_getserver(0); + addr->ipv4.dns1 = ip_addr_get_ip4_u32(tmp); + tmp = dns_getserver(1); + addr->ipv4.dns2 = ip_addr_get_ip4_u32(tmp); + } + + return 0; +} + +int net_get_if_macaddr(void *macaddr, void *intrfc_handle) +{ + struct interface *if_handle = (struct interface *)intrfc_handle; + + os_memcpy(macaddr, &if_handle->netif.hwaddr[0], if_handle->netif.hwaddr_len); + + return 0; +} + +#ifdef CONFIG_IPV6 +int net_get_if_ipv6_addr(struct wlan_ip_config *addr, void *intrfc_handle) +{ + struct interface *if_handle = (struct interface *)intrfc_handle; + int i; + + for (i = 0; i < MAX_IPV6_ADDRESSES; i++) { + memcpy(&addr->ipv6[i].address, + ip_2_ip6(&(if_handle->netif.ip6_addr[i])), 16); + addr->ipv6[i].addr_state = if_handle->netif.ip6_addr_state[i]; + } + /* TODO carry out more processing based on IPv6 fields in netif */ + return 0; +} + +int net_get_if_ipv6_pref_addr(struct wlan_ip_config *addr, void *intrfc_handle) +{ + int i, ret = 0; + struct interface *if_handle = (struct interface *)intrfc_handle; + + for (i = 0; i < MAX_IPV6_ADDRESSES; i++) { + if (if_handle->netif.ip6_addr_state[i] == IP6_ADDR_PREFERRED) { + memcpy(&addr->ipv6[ret++].address, + &(if_handle->netif.ip6_addr[i]), 16); + } + } + return ret; +} +#endif /* CONFIG_IPV6 */ + +int net_get_if_ip_addr(uint32_t *ip, void *intrfc_handle) +{ + struct interface *if_handle = (struct interface *)intrfc_handle; + + *ip = ip_addr_get_ip4_u32(&if_handle->netif.ip_addr); + return 0; +} + +int net_get_if_gw_addr(uint32_t *ip, void *intrfc_handle) +{ + struct interface *if_handle = (struct interface *)intrfc_handle; + + *ip = ip_addr_get_ip4_u32(&if_handle->netif.gw); + + return 0; +} + +int net_get_if_ip_mask(uint32_t *nm, void *intrfc_handle) +{ + struct interface *if_handle = (struct interface *)intrfc_handle; + + *nm = ip_addr_get_ip4_u32(&if_handle->netif.netmask); + return 0; +} + +void net_configure_dns(struct wlan_ip_config *ip) +{ + ip_addr_t tmp; + + if (ip->ipv4.addr_type == ADDR_TYPE_STATIC) { + + if (ip->ipv4.dns1 == 0){ +#ifdef CONFIG_LWIP_FAST_DHCP + struct wlan_fast_connect_info fci = {0}; + wlan_read_fast_connect_info(&fci); + os_memcpy((char *)&ip->ipv4.dns1, (char *)&fci.dns1, sizeof(fci.dns1)); +#else + ip->ipv4.dns1 = ip->ipv4.gw; +#endif + } + if (ip->ipv4.dns2 == 0) + ip->ipv4.dns2 = ip->ipv4.dns1; + + ip_addr_set_ip4_u32(&tmp,ip->ipv4.dns1); + dns_setserver(0, &tmp); + ip_addr_set_ip4_u32(&tmp, ip->ipv4.dns2); + dns_setserver(1, &tmp); + } + + /* DNS MAX Retries should be configured in lwip/dns.c to 3/4 */ + /* DNS Cache size of about 4 is sufficient */ +} + +void net_wlan_initial(void) +{ + net_ipv4stack_init(); + +#ifdef CONFIG_IPV6 + net_ipv6stack_init(&g_mlan.netif); +#endif /* CONFIG_IPV6 */ +} + +int net_wlan_add_netif(uint8_t *mac) +{ + struct interface *wlan_if = NULL; + netif_if_t netif_if; + void *vif = NULL; + int vifid = 0; + err_t err; + + vifid = wifi_netif_mac_to_vifid(mac); + vif = wifi_netif_mac_to_vif(mac); + netif_if = wifi_netif_vif_to_netif_type(vif); + if (netif_if == NETIF_IF_AP) { + wlan_if = &g_uap; + } else if(netif_if == NETIF_IF_STA) { + wlan_if = &g_mlan; + } else { + LWIP_LOGE("unknown netif(%d)\n", netif_if); + return ERR_ARG; + } + + ip_addr_set_ip4_u32(&wlan_if->ipaddr, INADDR_ANY); + err = netifapi_netif_add(&wlan_if->netif, + ip_2_ip4(&wlan_if->ipaddr), + ip_2_ip4(&wlan_if->ipaddr), + ip_2_ip4(&wlan_if->ipaddr), + vif, + ethernetif_init, + tcpip_input); + if (err) { + LWIP_LOGE("net_wlan_add_netif failed(%d)\n", err); + return err; + } else { + wifi_netif_set_vif_private_data(vif, &wlan_if->netif); + #if CONFIG_IPV6 + if(netif_if == NETIF_IF_STA) { + netif_create_ip6_linklocal_address(&wlan_if->netif, 1); + netif_set_ip6_autoconfig_enabled(&wlan_if->netif, 1); + } + #endif + } + + LWIP_LOGI("add vif%d\n", vifid); + return ERR_OK; +} + +int net_wlan_remove_netif(uint8_t *mac) +{ + struct netif *netif = NULL; + void *vif; + err_t err; + int vifid; + + vifid = wifi_netif_mac_to_vifid(mac); + vif = wifi_netif_mac_to_vif(mac); + if(!vif) { + LWIP_LOGE("remove netif, vif%d not found\n", vifid); + return ERR_ARG; + } + + netif = (struct netif *)wifi_netif_get_vif_private_data(vif); + if(!netif) { + LWIP_LOGE("remove netif, netif is null\n"); + return ERR_ARG; + } + + err = netifapi_netif_remove(netif); + if(err != ERR_OK) { + LWIP_LOGE("remove netif, failed(%d)\n", err); + return err; + } else { + netif->state = NULL; + } + + LWIP_LOGI("remove vif%d\n", vifid); + return ERR_OK; +} +#if CONFIG_WIFI6_CODE_STACK +bool etharp_tmr_flag = false; +void net_begin_send_arp_reply(bool is_send_arp, bool is_allow_send_req) +{ +#if !CONFIG_HARMONY_LWIP + //send reply + if(is_send_arp && !is_allow_send_req) { + etharp_tmr_flag = true; + LWIP_LOGI("send reply %s\n", __func__); + } + //stop send reply + if(!is_send_arp && is_allow_send_req) { + etharp_tmr_flag = false; + LWIP_LOGI("stop send reply %s\n", __func__); + return; + } + etharp_reply(); +#endif +} +#endif diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/net.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/net.h new file mode 100755 index 0000000..b82903b --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/net.h @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 _NET_H_ +#define _NET_H_ +#ifdef __cplusplus +extern "C" { +#endif + +#include "lwip_netif_address.h" + +extern void uap_ip_down(void); +extern void uap_ip_start(void); +extern void sta_ip_down(void); +extern void sta_ip_start(void); +extern uint32_t uap_ip_is_start(void); +extern uint32_t sta_ip_is_start(void); +extern void *net_get_sta_handle(void); +extern void *net_get_uap_handle(void); +extern int net_wlan_remove_netif(uint8_t *mac); +extern int net_get_if_macaddr(void *macaddr, void *intrfc_handle); +extern int net_get_if_addr(struct wlan_ip_config *addr, void *intrfc_handle); +extern void ip_address_set(int iface, int dhcp, char *ip, char *mask, char*gw, char*dns); +extern void sta_ip_mode_set(int dhcp); +#if CONFIG_WIFI6_CODE_STACK +extern bool etharp_tmr_flag; +extern void net_begin_send_arp_reply(bool is_send_arp, bool is_allow_send_req); +#endif +#if CONFIG_LWIP_FAST_DHCP +extern void net_restart_dhcp(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif // _NET_H_ +// eof + diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/ping.h b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/ping.h new file mode 100755 index 0000000..488f82d --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/ping.h @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2022 Beken Corporation + * 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 LWIP_PING_H +#define LWIP_PING_H + +extern int ping(char* target_name, uint32_t times, size_t size); +void ping_stop(void); +void ping_start(char* target_name, uint32_t times, size_t size); + + +#endif /* LWIP_PING_H */ diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/sockets.c b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/sockets.c new file mode 100755 index 0000000..1bf4981 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/sockets.c @@ -0,0 +1,4232 @@ +/** + * @file + * Sockets BSD-Like API module + */ + +/* + * Copyright (c) 2001-2004 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + * Improved by Marc Boucher and David Haas + * + */ + +#include "lwip/opt.h" + +#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ +#if 1 +int errno=0; +#endif + +#include "lwip/sockets.h" +#include "lwip/priv/sockets_priv.h" +#include "lwip/api.h" +#include "lwip/igmp.h" +#include "lwip/inet.h" +#include "lwip/tcp.h" +#include "lwip/raw.h" +#include "lwip/udp.h" +#include "lwip/memp.h" +#include "lwip/pbuf.h" +#include "lwip/netif.h" +#include "lwip/priv/tcpip_priv.h" +#include "lwip/mld6.h" +#if LWIP_ENABLE_DISTRIBUTED_NET +#include "lwip/distributed_net/distributed_net.h" +#include "lwip/distributed_net/distributed_net_core.h" +#endif /* LWIP_ENABLE_DISTRIBUTED_NET */ +#if LWIP_CHECKSUM_ON_COPY +#include "lwip/inet_chksum.h" +#endif + +#if LWIP_COMPAT_SOCKETS == 2 && LWIP_POSIX_SOCKETS_IO_NAMES +#include +#endif + +#include + +#ifdef LWIP_HOOK_FILENAME +#include LWIP_HOOK_FILENAME +#endif + +/* If the netconn API is not required publicly, then we include the necessary + files here to get the implementation */ +#if !LWIP_NETCONN +#undef LWIP_NETCONN +#define LWIP_NETCONN 1 +#include "api_msg.c" +#include "api_lib.c" +#include "netbuf.c" +#undef LWIP_NETCONN +#define LWIP_NETCONN 0 +#endif + +#define API_SELECT_CB_VAR_REF(name) API_VAR_REF(name) +#define API_SELECT_CB_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_select_cb, name) +#define API_SELECT_CB_VAR_ALLOC(name, retblock) API_VAR_ALLOC_EXT(struct lwip_select_cb, MEMP_SELECT_CB, name, retblock) +#define API_SELECT_CB_VAR_FREE(name) API_VAR_FREE(MEMP_SELECT_CB, name) + +#if LWIP_IPV4 +#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \ + (sin)->sin_len = sizeof(struct sockaddr_in); \ + (sin)->sin_family = AF_INET; \ + (sin)->sin_port = lwip_htons((port)); \ + inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \ + memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0) +#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \ + inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \ + (port) = lwip_ntohs((sin)->sin_port); }while(0) +#endif /* LWIP_IPV4 */ + +#if LWIP_IPV6 +#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipaddr, port) do { \ + (sin6)->sin6_len = sizeof(struct sockaddr_in6); \ + (sin6)->sin6_family = AF_INET6; \ + (sin6)->sin6_port = lwip_htons((port)); \ + (sin6)->sin6_flowinfo = 0; \ + inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipaddr); \ + (sin6)->sin6_scope_id = ip6_addr_zone(ipaddr); }while(0) +#define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipaddr, port) do { \ + inet6_addr_to_ip6addr(ip_2_ip6(ipaddr), &((sin6)->sin6_addr)); \ + if (ip6_addr_has_scope(ip_2_ip6(ipaddr), IP6_UNKNOWN)) { \ + ip6_addr_set_zone(ip_2_ip6(ipaddr), (u8_t)((sin6)->sin6_scope_id)); \ + } \ + (port) = lwip_ntohs((sin6)->sin6_port); }while(0) +#endif /* LWIP_IPV6 */ + +#if LWIP_IPV4 && LWIP_IPV6 +static void sockaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *ipaddr, u16_t *port); + +#define IS_SOCK_ADDR_LEN_VALID(namelen) (((namelen) == sizeof(struct sockaddr_in)) || \ + ((namelen) == sizeof(struct sockaddr_in6))) +#define IS_SOCK_ADDR_TYPE_VALID(name) (((name)->sa_family == AF_INET) || \ + ((name)->sa_family == AF_INET6)) +#define SOCK_ADDR_TYPE_MATCH(name, sock) \ + ((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \ + (((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type)))) +#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) do { \ + if (IP_IS_ANY_TYPE_VAL(*ipaddr) || IP_IS_V6_VAL(*ipaddr)) { \ + IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port); \ + } else { \ + IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port); \ + } } while(0) +#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) sockaddr_to_ipaddr_port(sockaddr, ipaddr, &(port)) +#define DOMAIN_TO_NETCONN_TYPE(domain, type) (((domain) == AF_INET) ? \ + (type) : (enum netconn_type)((type) | NETCONN_TYPE_IPV6)) +#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ +#define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in6)) +#define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET6) +#define SOCK_ADDR_TYPE_MATCH(name, sock) 1 +#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ + IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port) +#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ + SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6*)(const void*)(sockaddr), ipaddr, port) +#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) +#else /*-> LWIP_IPV4: LWIP_IPV4 && LWIP_IPV6 */ +#define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in)) +#define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET) +#define SOCK_ADDR_TYPE_MATCH(name, sock) 1 +#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ + IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port) +#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ + SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in*)(const void*)(sockaddr), ipaddr, port) +#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) +#endif /* LWIP_IPV6 */ + +#define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) (((name)->sa_family == AF_UNSPEC) || \ + IS_SOCK_ADDR_TYPE_VALID(name)) +#define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) (((name)->sa_family == AF_UNSPEC) || \ + SOCK_ADDR_TYPE_MATCH(name, sock)) +#define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % 4) == 0) + + +#define LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype) do { if ((optlen) < sizeof(opttype)) { done_socket(sock); return EINVAL; }}while(0) +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, opttype) do { \ + LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype); \ + if ((sock)->conn == NULL) { done_socket(sock); return EINVAL; } }while(0) +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \ + LWIP_SOCKOPT_CHECK_OPTLEN(sock, optlen, opttype); \ + if (((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { done_socket(sock); return EINVAL; } }while(0) +#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \ + if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { done_socket(sock); return ENOPROTOOPT; } }while(0) + + +#define LWIP_SETGETSOCKOPT_DATA_VAR_REF(name) API_VAR_REF(name) +#define LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_setgetsockopt_data, name) +#define LWIP_SETGETSOCKOPT_DATA_VAR_FREE(name) API_VAR_FREE(MEMP_SOCKET_SETGETSOCKOPT_DATA, name) +#if LWIP_MPU_COMPATIBLE +#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) do { \ + name = (struct lwip_setgetsockopt_data *)memp_malloc(MEMP_SOCKET_SETGETSOCKOPT_DATA); \ + if (name == NULL) { \ + sock_set_errno(sock, ENOMEM); \ + done_socket(sock); \ + return -1; \ + } }while(0) +#else /* LWIP_MPU_COMPATIBLE */ +#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) +#endif /* LWIP_MPU_COMPATIBLE */ + +#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD +#define LWIP_SO_SNDRCVTIMEO_OPTTYPE int +#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) (*(int *)(optval) = (val)) +#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((long)*(const int*)(optval)) +#else +#define LWIP_SO_SNDRCVTIMEO_OPTTYPE struct timeval +#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) do { \ + u32_t loc = (val); \ + ((struct timeval *)(optval))->tv_sec = (long)((loc) / 1000U); \ + ((struct timeval *)(optval))->tv_usec = (long)(((loc) % 1000U) * 1000U); }while(0) +#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((((const struct timeval *)(optval))->tv_sec * 1000) + (((const struct timeval *)(optval))->tv_usec / 1000)) +#endif + + +/** A struct sockaddr replacement that has the same alignment as sockaddr_in/ + * sockaddr_in6 if instantiated. + */ +union sockaddr_aligned { + struct sockaddr sa; +#if LWIP_IPV6 + struct sockaddr_in6 sin6; +#endif /* LWIP_IPV6 */ +#if LWIP_IPV4 + struct sockaddr_in sin; +#endif /* LWIP_IPV4 */ +}; + +/* Define the number of IPv4 multicast memberships, default is one per socket */ +#ifndef LWIP_SOCKET_MAX_MEMBERSHIPS +#define LWIP_SOCKET_MAX_MEMBERSHIPS NUM_SOCKETS +#endif + +#if LWIP_IGMP +/* This is to keep track of IP_ADD_MEMBERSHIP calls to drop the membership when + a socket is closed */ +struct lwip_socket_multicast_pair { + /** the socket */ + struct lwip_sock *sock; + /** the interface address */ + ip4_addr_t if_addr; + /** the group address */ + ip4_addr_t multi_addr; +}; + +static struct lwip_socket_multicast_pair socket_ipv4_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS]; + +static int lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); +static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); +static void lwip_socket_drop_registered_memberships(int s); +#endif /* LWIP_IGMP */ + +#if LWIP_IPV6_MLD +/* This is to keep track of IP_JOIN_GROUP calls to drop the membership when + a socket is closed */ +struct lwip_socket_multicast_mld6_pair { + /** the socket */ + struct lwip_sock *sock; + /** the interface index */ + u8_t if_idx; + /** the group address */ + ip6_addr_t multi_addr; +}; + +static struct lwip_socket_multicast_mld6_pair socket_ipv6_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS]; + +static int lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr); +static void lwip_socket_unregister_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr); +static void lwip_socket_drop_registered_mld6_memberships(int s); +#endif /* LWIP_IPV6_MLD */ + +/** The global array of available sockets */ +static struct lwip_sock sockets[NUM_SOCKETS]; + +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL +#if LWIP_TCPIP_CORE_LOCKING +/* protect the select_cb_list using core lock */ +#define LWIP_SOCKET_SELECT_DECL_PROTECT(lev) +#define LWIP_SOCKET_SELECT_PROTECT(lev) LOCK_TCPIP_CORE() +#define LWIP_SOCKET_SELECT_UNPROTECT(lev) UNLOCK_TCPIP_CORE() +#else /* LWIP_TCPIP_CORE_LOCKING */ +/* protect the select_cb_list using SYS_LIGHTWEIGHT_PROT */ +#define LWIP_SOCKET_SELECT_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev) +#define LWIP_SOCKET_SELECT_PROTECT(lev) SYS_ARCH_PROTECT(lev) +#define LWIP_SOCKET_SELECT_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev) +/** This counter is increased from lwip_select when the list is changed + and checked in select_check_waiters to see if it has changed. */ +static volatile int select_cb_ctr; +#endif /* LWIP_TCPIP_CORE_LOCKING */ +/** The global list of tasks waiting for select */ +static struct lwip_select_cb *select_cb_list; +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ + +#define sock_set_errno(sk, e) do { \ + const int sockerr = (e); \ + set_errno(sockerr); \ +} while (0) + +/* Forward declaration of some functions */ +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL +static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); +#define DEFAULT_SOCKET_EVENTCB event_callback +static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent); +#else +#define DEFAULT_SOCKET_EVENTCB NULL +#endif +#if !LWIP_TCPIP_CORE_LOCKING +static void lwip_getsockopt_callback(void *arg); +static void lwip_setsockopt_callback(void *arg); +#endif +static int lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen); +static int lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen); +static int free_socket_locked(struct lwip_sock *sock, int is_tcp, struct netconn **conn, + union lwip_sock_lastdata *lastdata); +static void free_socket_free_elements(int is_tcp, struct netconn *conn, union lwip_sock_lastdata *lastdata); + +#if LWIP_IPV4 && LWIP_IPV6 +static void +sockaddr_to_ipaddr_port(const struct sockaddr *sockaddr, ip_addr_t *ipaddr, u16_t *port) +{ + if ((sockaddr->sa_family) == AF_INET6) { + SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6 *)(const void *)(sockaddr), ipaddr, *port); + ipaddr->type = IPADDR_TYPE_V6; + } else { + SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in *)(const void *)(sockaddr), ipaddr, *port); + ipaddr->type = IPADDR_TYPE_V4; + } +} +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + +/** LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */ +void +lwip_socket_thread_init(void) +{ + netconn_thread_init(); +} + +/** LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */ +void +lwip_socket_thread_cleanup(void) +{ + netconn_thread_cleanup(); +} + +#if LWIP_NETCONN_FULLDUPLEX +/* Thread-safe increment of sock->fd_used, with overflow check */ +static int +sock_inc_used(struct lwip_sock *sock) +{ + int ret; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_ASSERT("sock != NULL", sock != NULL); + + SYS_ARCH_PROTECT(lev); + if (sock->fd_free_pending) { + /* prevent new usage of this socket if free is pending */ + ret = 0; + } else { + ++sock->fd_used; + ret = 1; + LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); + } + SYS_ARCH_UNPROTECT(lev); + return ret; +} + +/* Like sock_inc_used(), but called under SYS_ARCH_PROTECT lock. */ +static int +sock_inc_used_locked(struct lwip_sock *sock) +{ + LWIP_ASSERT("sock != NULL", sock != NULL); + + if (sock->fd_free_pending) { + LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); + return 0; + } + + ++sock->fd_used; + LWIP_ASSERT("sock->fd_used != 0", sock->fd_used != 0); + return 1; +} + +/* In full-duplex mode,sock->fd_used != 0 prevents a socket descriptor from being + * released (and possibly reused) when used from more than one thread + * (e.g. read-while-write or close-while-write, etc) + * This function is called at the end of functions using (try)get_socket*(). + */ +static void +done_socket(struct lwip_sock *sock) +{ + int freed = 0; + int is_tcp = 0; + struct netconn *conn = NULL; + union lwip_sock_lastdata lastdata; + SYS_ARCH_DECL_PROTECT(lev); + LWIP_ASSERT("sock != NULL", sock != NULL); + + SYS_ARCH_PROTECT(lev); + LWIP_ASSERT("sock->fd_used > 0", sock->fd_used > 0); + if (--sock->fd_used == 0) { + if (sock->fd_free_pending) { + /* free the socket */ + sock->fd_used = 1; + is_tcp = sock->fd_free_pending & LWIP_SOCK_FD_FREE_TCP; + freed = free_socket_locked(sock, is_tcp, &conn, &lastdata); + } + } + SYS_ARCH_UNPROTECT(lev); + + if (freed) { + free_socket_free_elements(is_tcp, conn, &lastdata); + } +} + +#else /* LWIP_NETCONN_FULLDUPLEX */ +#define sock_inc_used(sock) 1 +#define sock_inc_used_locked(sock) 1 +#define done_socket(sock) +#endif /* LWIP_NETCONN_FULLDUPLEX */ + +/* Translate a socket 'int' into a pointer (only fails if the index is invalid) */ +static struct lwip_sock * +tryget_socket_unconn_nouse(int fd) +{ + int s = fd - LWIP_SOCKET_OFFSET; + if ((s < 0) || (s >= NUM_SOCKETS)) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("tryget_socket_unconn(%d): invalid\n", fd)); + return NULL; + } + return &sockets[s]; +} + +struct lwip_sock * +lwip_socket_dbg_get_socket(int fd) +{ + return tryget_socket_unconn_nouse(fd); +} + +/* Translate a socket 'int' into a pointer (only fails if the index is invalid) */ +static struct lwip_sock * +tryget_socket_unconn(int fd) +{ + struct lwip_sock *ret = tryget_socket_unconn_nouse(fd); + if (ret != NULL) { + if (!sock_inc_used(ret)) { + return NULL; + } + } + return ret; +} + +/* Like tryget_socket_unconn(), but called under SYS_ARCH_PROTECT lock. */ +static struct lwip_sock * +tryget_socket_unconn_locked(int fd) +{ + struct lwip_sock *ret = tryget_socket_unconn_nouse(fd); + if (ret != NULL) { + if (!sock_inc_used_locked(ret)) { + return NULL; + } + } + return ret; +} + +/** + * Same as get_socket but doesn't set errno + * + * @param fd externally used socket index + * @return struct lwip_sock for the socket or NULL if not found + */ +static struct lwip_sock * +tryget_socket(int fd) +{ + struct lwip_sock *sock = tryget_socket_unconn(fd); + if (sock != NULL) { + if (sock->conn) { + return sock; + } + done_socket(sock); + } + return NULL; +} + +/** + * Map a externally used socket index to the internal socket representation. + * + * @param fd externally used socket index + * @return struct lwip_sock for the socket or NULL if not found + */ +static struct lwip_sock * +get_socket(int fd) +{ + struct lwip_sock *sock = tryget_socket(fd); + if (!sock) { + if ((fd < LWIP_SOCKET_OFFSET) || (fd >= (LWIP_SOCKET_OFFSET + NUM_SOCKETS))) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", fd)); + } + set_errno(EBADF); + return NULL; + } + return sock; +} + +/** + * Allocate a new socket for a given netconn. + * + * @param newconn the netconn for which to allocate a socket + * @param accepted 1 if socket has been created by accept(), + * 0 if socket has been created by socket() + * @return the index of the new socket; -1 on error + */ +static int +alloc_socket(struct netconn *newconn, int accepted) +{ + int i; + SYS_ARCH_DECL_PROTECT(lev); + LWIP_UNUSED_ARG(accepted); + + /* allocate a new socket identifier */ + for (i = 0; i < NUM_SOCKETS; ++i) { + /* Protect socket array */ + SYS_ARCH_PROTECT(lev); + if (!sockets[i].conn) { +#if LWIP_NETCONN_FULLDUPLEX + if (sockets[i].fd_used) { + SYS_ARCH_UNPROTECT(lev); + continue; + } + sockets[i].fd_used = 1; + sockets[i].fd_free_pending = 0; +#endif + sockets[i].conn = newconn; + /* The socket is not yet known to anyone, so no need to protect + after having marked it as used. */ + SYS_ARCH_UNPROTECT(lev); + sockets[i].lastdata.pbuf = NULL; +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL + LWIP_ASSERT("sockets[i].select_waiting == 0", sockets[i].select_waiting == 0); + sockets[i].rcvevent = 0; + /* TCP sendbuf is empty, but the socket is not yet writable until connected + * (unless it has been created by accept()). */ + sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); + sockets[i].errevent = 0; + // init_waitqueue_head(&sockets[i].wq); +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ + return i + LWIP_SOCKET_OFFSET; + } + SYS_ARCH_UNPROTECT(lev); + } + return -1; +} + +/** Free a socket (under lock) + * + * @param sock the socket to free + * @param is_tcp != 0 for TCP sockets, used to free lastdata + * @param conn the socekt's netconn is stored here, must be freed externally + * @param lastdata lastdata is stored here, must be freed externally + */ +static int +free_socket_locked(struct lwip_sock *sock, int is_tcp, struct netconn **conn, + union lwip_sock_lastdata *lastdata) +{ +#if LWIP_NETCONN_FULLDUPLEX + LWIP_ASSERT("sock->fd_used > 0", sock->fd_used > 0); + sock->fd_used--; + if (sock->fd_used > 0) { + sock->fd_free_pending = LWIP_SOCK_FD_FREE_FREE | (is_tcp ? LWIP_SOCK_FD_FREE_TCP : 0); + return 0; + } +#else /* LWIP_NETCONN_FULLDUPLEX */ + LWIP_UNUSED_ARG(is_tcp); +#endif /* LWIP_NETCONN_FULLDUPLEX */ + + *lastdata = sock->lastdata; + sock->lastdata.pbuf = NULL; + *conn = sock->conn; + sock->conn = NULL; + return 1; +} + +/** Free a socket's leftover members. + */ +static void +free_socket_free_elements(int is_tcp, struct netconn *conn, union lwip_sock_lastdata *lastdata) +{ + if (lastdata->pbuf != NULL) { + if (is_tcp) { + pbuf_free(lastdata->pbuf); + } else { + netbuf_delete(lastdata->netbuf); + } + } + if (conn != NULL) { + /* netconn_prepare_delete() has already been called, here we only free the conn */ + netconn_delete(conn); + } +} + +/** Free a socket. The socket's netconn must have been + * delete before! + * + * @param sock the socket to free + * @param is_tcp != 0 for TCP sockets, used to free lastdata + */ +static void +free_socket(struct lwip_sock *sock, int is_tcp) +{ + int freed; + struct netconn *conn; + union lwip_sock_lastdata lastdata; + SYS_ARCH_DECL_PROTECT(lev); + + /* Protect socket array */ + SYS_ARCH_PROTECT(lev); + + freed = free_socket_locked(sock, is_tcp, &conn, &lastdata); + SYS_ARCH_UNPROTECT(lev); + /* don't use 'sock' after this line, as another task might have allocated it */ + + if (freed) { + free_socket_free_elements(is_tcp, conn, &lastdata); + } +} + +/* Below this, the well-known socket functions are implemented. + * Use google.com or opengroup.org to get a good description :-) + * + * Exceptions are documented! + */ + +int +lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) +{ + struct lwip_sock *sock, *nsock; + struct netconn *newconn; + ip_addr_t naddr; + u16_t port = 0; + int newsock; + err_t err; + int recvevent; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* wait for a new connection */ + err = netconn_accept(sock->conn, &newconn); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + } else if (err == ERR_CLSD) { + sock_set_errno(sock, EINVAL); + } else { + sock_set_errno(sock, err_to_errno(err)); + } + done_socket(sock); + return -1; + } + LWIP_ASSERT("newconn != NULL", newconn != NULL); + + newsock = alloc_socket(newconn, 1); + if (newsock == -1) { + netconn_delete(newconn); + sock_set_errno(sock, ENFILE); + done_socket(sock); + return -1; + } + LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET)); + nsock = &sockets[newsock - LWIP_SOCKET_OFFSET]; + + /* See event_callback: If data comes in right away after an accept, even + * though the server task might not have created a new socket yet. + * In that case, newconn->socket is counted down (newconn->socket--), + * so nsock->rcvevent is >= 1 here! + */ + SYS_ARCH_PROTECT(lev); + recvevent = (s16_t)(-1 - newconn->socket); + newconn->socket = newsock; + SYS_ARCH_UNPROTECT(lev); + + if (newconn->callback) { + LOCK_TCPIP_CORE(); + while (recvevent > 0) { + recvevent--; + newconn->callback(newconn, NETCONN_EVT_RCVPLUS, 0); + } + UNLOCK_TCPIP_CORE(); + } + + /* Note that POSIX only requires us to check addr is non-NULL. addrlen must + * not be NULL if addr is valid. + */ + if ((addr != NULL) && (addrlen != NULL)) { + union sockaddr_aligned tempaddr; + /* get the IP address and port of the remote host */ + err = netconn_peer(newconn, &naddr, &port); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); + netconn_delete(newconn); + free_socket(nsock, 1); + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return -1; + } + + IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port); + if (*addrlen > tempaddr.sa.sa_len) { + *addrlen = tempaddr.sa.sa_len; + } + MEMCPY(addr, &tempaddr, *addrlen); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); + ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); + } else { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d", s, newsock)); + } + + sock_set_errno(sock, 0); + done_socket(sock); + done_socket(nsock); + return newsock; +} + +int +lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) +{ + struct lwip_sock *sock; + ip_addr_t local_addr; + u16_t local_port; + err_t err; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (!SOCK_ADDR_TYPE_MATCH(name, sock)) { + /* sockaddr does not match socket type (IPv4/IPv6) */ + sock_set_errno(sock, err_to_errno(ERR_VAL)); + done_socket(sock); + return -1; + } + + /* check size, family and alignment of 'name' */ + LWIP_ERROR("lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) && + IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)), + sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + LWIP_UNUSED_ARG(namelen); + + SOCKADDR_TO_IPADDR_PORT(name, &local_addr, local_port); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); + ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port)); + +#if LWIP_IPV4 && LWIP_IPV6 + /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ + if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) { + unmap_ipv4_mapped_ipv6(ip_2_ip4(&local_addr), ip_2_ip6(&local_addr)); + IP_SET_TYPE_VAL(local_addr, IPADDR_TYPE_V4); + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + + err = netconn_bind(sock->conn, &local_addr, local_port); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); + sock_set_errno(sock, 0); + done_socket(sock); + return 0; +} + +int +lwip_close(int s) +{ +#if LWIP_ENABLE_DISTRIBUTED_NET + if (!is_distributed_net_enabled()) { + return lwip_close_internal(s); + } + return distributed_net_close(s); +} + +int +lwip_close_internal(int s) +{ +#endif + struct lwip_sock *sock; + int is_tcp = 0; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (sock->conn != NULL) { + is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP; + } else { + LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata.pbuf == NULL); + } + +#if LWIP_IGMP + /* drop all possibly joined IGMP memberships */ + lwip_socket_drop_registered_memberships(s); +#endif /* LWIP_IGMP */ +#if LWIP_IPV6_MLD + /* drop all possibly joined MLD6 memberships */ + lwip_socket_drop_registered_mld6_memberships(s); +#endif /* LWIP_IPV6_MLD */ + + err = netconn_prepare_delete(sock->conn); + if (err != ERR_OK) { + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return -1; + } + + free_socket(sock, is_tcp); + set_errno(0); + return 0; +} + +int +lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) +{ +#if LWIP_ENABLE_DISTRIBUTED_NET + if (!is_distributed_net_enabled()) { + return lwip_connect_internal(s, name, namelen); + } + return distributed_net_connect(s, name, namelen); +} + +int +lwip_connect_internal(int s, const struct sockaddr *name, socklen_t namelen) +{ +#endif + struct lwip_sock *sock; + err_t err; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) { + /* sockaddr does not match socket type (IPv4/IPv6) */ + sock_set_errno(sock, err_to_errno(ERR_VAL)); + done_socket(sock); + return -1; + } + + LWIP_UNUSED_ARG(namelen); + if (name->sa_family == AF_UNSPEC) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); + err = netconn_disconnect(sock->conn); + } else { + ip_addr_t remote_addr; + u16_t remote_port; + + /* check size, family and alignment of 'name' */ + LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) && + IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name), + sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + + SOCKADDR_TO_IPADDR_PORT(name, &remote_addr, remote_port); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); + ip_addr_debug_print_val(SOCKETS_DEBUG, remote_addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", remote_port)); + +#if LWIP_IPV4 && LWIP_IPV6 + /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ + if (IP_IS_V6_VAL(remote_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&remote_addr))) { + unmap_ipv4_mapped_ipv6(ip_2_ip4(&remote_addr), ip_2_ip6(&remote_addr)); + IP_SET_TYPE_VAL(remote_addr, IPADDR_TYPE_V4); + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + + err = netconn_connect(sock->conn, &remote_addr, remote_port); + } + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return -1; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); + sock_set_errno(sock, 0); + done_socket(sock); + return 0; +} + +/** + * Set a socket into listen mode. + * The socket may not have been used for another connection previously. + * + * @param s the socket to set to listening mode + * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1) + * @return 0 on success, non-zero on failure + */ +int +lwip_listen(int s, int backlog) +{ + struct lwip_sock *sock; + err_t err; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* limit the "backlog" parameter to fit in an u8_t */ + backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); + + err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); + + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + } else { + sock_set_errno(sock, err_to_errno(err)); + } + done_socket(sock); + return -1; + } + + sock_set_errno(sock, 0); + done_socket(sock); + return 0; +} + +#if LWIP_TCP +/* Helper function to loop over receiving pbufs from netconn + * until "len" bytes are received or we're otherwise done. + * Keeps sock->lastdata for peeking or partly copying. + */ +static ssize_t +lwip_recv_tcp(struct lwip_sock *sock, void *mem, size_t len, int flags) +{ + u8_t apiflags = NETCONN_NOAUTORCVD; + ssize_t recvd = 0; + ssize_t recv_left = (len <= SSIZE_MAX) ? (ssize_t)len : SSIZE_MAX; + + LWIP_ASSERT("no socket given", sock != NULL); + LWIP_ASSERT("this should be checked internally", NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP); + + if (flags & MSG_DONTWAIT) { + apiflags |= NETCONN_DONTBLOCK; + } + + do { + struct pbuf *p; + err_t err; + u16_t copylen; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: top while sock->lastdata=%p\n", (void *)sock->lastdata.pbuf)); + /* Check if there is data left from the last recv operation. */ + if (sock->lastdata.pbuf) { + p = sock->lastdata.pbuf; + } else { + /* No data was left from the previous operation, so we try to get + some from the network. */ + err = netconn_recv_tcp_pbuf_flags(sock->conn, &p, apiflags); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: netconn_recv err=%d, pbuf=%p\n", + err, (void *)p)); + + if (err != ERR_OK) { + if (recvd > 0) { + /* already received data, return that (this trusts in getting the same error from + netconn layer again next time netconn_recv is called) */ + goto lwip_recv_tcp_done; + } + /* We should really do some error checking here. */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: p == NULL, error is \"%s\"!\n", + lwip_strerr(err))); + sock_set_errno(sock, err_to_errno(err)); + if (err == ERR_CLSD) { + return 0; + } else { + return -1; + } + } + LWIP_ASSERT("p != NULL", p != NULL); + sock->lastdata.pbuf = p; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: buflen=%"U16_F" recv_left=%d off=%d\n", + p->tot_len, (int)recv_left, (int)recvd)); + + if (recv_left > p->tot_len) { + copylen = p->tot_len; + } else { + copylen = (u16_t)recv_left; + } + if (recvd + copylen < recvd) { + /* overflow */ + copylen = (u16_t)(SSIZE_MAX - recvd); + } + + /* copy the contents of the received buffer into + the supplied memory pointer mem */ + pbuf_copy_partial(p, (u8_t *)mem + recvd, copylen, 0); + + recvd += copylen; + + /* TCP combines multiple pbufs for one recv */ + LWIP_ASSERT("invalid copylen, len would underflow", recv_left >= copylen); + recv_left -= copylen; + + /* Unless we peek the incoming message... */ + if ((flags & MSG_PEEK) == 0) { + /* ... check if there is data left in the pbuf */ + LWIP_ASSERT("invalid copylen", p->tot_len >= copylen); + if (p->tot_len - copylen > 0) { + /* If so, it should be saved in the sock structure for the next recv call. + We store the pbuf but hide/free the consumed data: */ + sock->lastdata.pbuf = pbuf_free_header(p, copylen); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: lastdata now pbuf=%p\n", (void *)sock->lastdata.pbuf)); + } else { + sock->lastdata.pbuf = NULL; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recv_tcp: deleting pbuf=%p\n", (void *)p)); + pbuf_free(p); + } + } + /* once we have some data to return, only add more if we don't need to wait */ + apiflags |= NETCONN_DONTBLOCK | NETCONN_NOFIN; + /* @todo: do we need to support peeking more than one pbuf? */ + } while ((recv_left > 0) && !(flags & MSG_PEEK)); +lwip_recv_tcp_done: + if ((recvd > 0) && !(flags & MSG_PEEK)) { + /* ensure window update after copying all data */ + netconn_tcp_recvd(sock->conn, (size_t)recvd); + } + sock_set_errno(sock, 0); + return recvd; +} +#endif + +/* Convert a netbuf's address data to struct sockaddr */ +static int +lwip_sock_make_addr(struct netconn *conn, ip_addr_t *fromaddr, u16_t port, + struct sockaddr *from, socklen_t *fromlen) +{ + int truncated = 0; + union sockaddr_aligned saddr; + + LWIP_UNUSED_ARG(conn); + + LWIP_ASSERT("fromaddr != NULL", fromaddr != NULL); + LWIP_ASSERT("from != NULL", from != NULL); + LWIP_ASSERT("fromlen != NULL", fromlen != NULL); + +#if LWIP_IPV4 && LWIP_IPV6 + /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */ + if (NETCONNTYPE_ISIPV6(netconn_type(conn)) && IP_IS_V4(fromaddr)) { + ip4_2_ipv4_mapped_ipv6(ip_2_ip6(fromaddr), ip_2_ip4(fromaddr)); + IP_SET_TYPE(fromaddr, IPADDR_TYPE_V6); + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + + IPADDR_PORT_TO_SOCKADDR(&saddr, fromaddr, port); + //DF_NADDR(*fromaddr); + if (*fromlen < saddr.sa.sa_len) { + truncated = 1; + } else if (*fromlen > saddr.sa.sa_len) { + *fromlen = saddr.sa.sa_len; + } + MEMCPY(from, &saddr, *fromlen); + return truncated; +} + +#if LWIP_TCP +/* Helper function to get a tcp socket's remote address info */ +static int +lwip_recv_tcp_from(struct lwip_sock *sock, struct sockaddr *from, socklen_t *fromlen, const char *dbg_fn, int dbg_s, ssize_t dbg_ret) +{ + if (sock == NULL) { + return 0; + } + LWIP_UNUSED_ARG(dbg_fn); + LWIP_UNUSED_ARG(dbg_s); + LWIP_UNUSED_ARG(dbg_ret); + +#if !SOCKETS_DEBUG + if (from && fromlen) +#endif /* !SOCKETS_DEBUG */ + { + /* get remote addr/port from tcp_pcb */ + u16_t port; + ip_addr_t tmpaddr; + err_t err = netconn_getaddr(sock->conn, &tmpaddr, &port, 0); + LWIP_DEBUGF(SOCKETS_DEBUG, ("%s(%d): addr=", dbg_fn, dbg_s)); + ip_addr_debug_print_val(SOCKETS_DEBUG, tmpaddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, (int)dbg_ret)); + if (!err && from && fromlen) { + return lwip_sock_make_addr(sock->conn, &tmpaddr, port, from, fromlen); + } + } + return 0; +} +#endif + +/* Helper function to receive a netbuf from a udp or raw netconn. + * Keeps sock->lastdata for peeking. + */ +static err_t +lwip_recvfrom_udp_raw(struct lwip_sock *sock, int flags, struct msghdr *msg, u16_t *datagram_len, int dbg_s) +{ + struct netbuf *buf; + u8_t apiflags; + err_t err; + u16_t buflen, copylen, copied; + int i; + + LWIP_UNUSED_ARG(dbg_s); + LWIP_ERROR("lwip_recvfrom_udp_raw: invalid arguments", (msg->msg_iov != NULL) || (msg->msg_iovlen <= 0), return ERR_ARG;); + + if (flags & MSG_DONTWAIT) { + apiflags = NETCONN_DONTBLOCK; + } else { + apiflags = 0; + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: top sock->lastdata=%p\n", (void *)sock->lastdata.netbuf)); + /* Check if there is data left from the last recv operation. */ + buf = sock->lastdata.netbuf; + if (buf == NULL) { + /* No data was left from the previous operation, so we try to get + some from the network. */ + err = netconn_recv_udp_raw_netbuf_flags(sock->conn, &buf, apiflags); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw[UDP/RAW]: netconn_recv err=%d, netbuf=%p\n", + err, (void *)buf)); + + if (err != ERR_OK) { + return err; + } + LWIP_ASSERT("buf != NULL", buf != NULL); + sock->lastdata.netbuf = buf; + } + buflen = buf->p->tot_len; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw: buflen=%"U16_F"\n", buflen)); + + copied = 0; + /* copy the pbuf payload into the iovs */ + for (i = 0; (i < msg->msg_iovlen) && (copied < buflen); i++) { + u16_t len_left = (u16_t)(buflen - copied); + if (msg->msg_iov[i].iov_len > len_left) { + copylen = len_left; + } else { + copylen = (u16_t)msg->msg_iov[i].iov_len; + } + + /* copy the contents of the received buffer into + the supplied memory buffer */ + pbuf_copy_partial(buf->p, (u8_t *)msg->msg_iov[i].iov_base, copylen, copied); + copied = (u16_t)(copied + copylen); + } + + /* Check to see from where the data was.*/ +#if !SOCKETS_DEBUG + if (msg->msg_name && msg->msg_namelen) +#endif /* !SOCKETS_DEBUG */ + { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom_udp_raw(%d): addr=", dbg_s)); + ip_addr_debug_print_val(SOCKETS_DEBUG, *netbuf_fromaddr(buf)); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", netbuf_fromport(buf), copied)); + if (msg->msg_name && msg->msg_namelen) { + lwip_sock_make_addr(sock->conn, netbuf_fromaddr(buf), netbuf_fromport(buf), + (struct sockaddr *)msg->msg_name, &msg->msg_namelen); + } + } + + /* Initialize flag output */ + msg->msg_flags = 0; + + if (msg->msg_control) { + u8_t wrote_msg = 0; +#if LWIP_NETBUF_RECVINFO + /* Check if packet info was recorded */ + if (buf->flags & NETBUF_FLAG_DESTADDR) { + if (IP_IS_V4(&buf->toaddr)) { +#if LWIP_IPV4 + if (msg->msg_controllen >= CMSG_SPACE(sizeof(struct in_pktinfo))) { + struct cmsghdr *chdr = CMSG_FIRSTHDR(msg); /* This will always return a header!! */ + struct in_pktinfo *pkti = (struct in_pktinfo *)CMSG_DATA(chdr); + chdr->cmsg_level = IPPROTO_IP; + chdr->cmsg_type = IP_PKTINFO; + chdr->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo)); + pkti->ipi_ifindex = buf->p->if_idx; + inet_addr_from_ip4addr(&pkti->ipi_addr, ip_2_ip4(netbuf_destaddr(buf))); + msg->msg_controllen = CMSG_SPACE(sizeof(struct in_pktinfo)); + wrote_msg = 1; + } else { + msg->msg_flags |= MSG_CTRUNC; + } +#endif /* LWIP_IPV4 */ + } + } +#endif /* LWIP_NETBUF_RECVINFO */ + + if (!wrote_msg) { + msg->msg_controllen = 0; + } + } + + /* If we don't peek the incoming message: zero lastdata pointer and free the netbuf */ + if ((flags & MSG_PEEK) == 0) { + sock->lastdata.netbuf = NULL; + netbuf_delete(buf); + } + if (datagram_len) { + *datagram_len = buflen; + } + return ERR_OK; +} + +ssize_t +lwip_recvfrom(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen) +{ +#if LWIP_ENABLE_DISTRIBUTED_NET && LWIP_USE_GET_HOST_BY_NAME_EXTERNAL + if (!is_distributed_net_enabled()) { + return lwip_recvfrom_internal(s, mem, len, flags, from, fromlen); + } + return distributed_net_recvfrom(s, mem, len, flags, from, fromlen); +} + +ssize_t +lwip_recvfrom_internal(int s, void *mem, size_t len, int flags, + struct sockaddr *from, socklen_t *fromlen) +{ +#endif + struct lwip_sock *sock; + ssize_t ret; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); + sock = get_socket(s); + if (!sock) { + return -1; + } +#if LWIP_TCP + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { + ret = lwip_recv_tcp(sock, mem, len, flags); + lwip_recv_tcp_from(sock, from, fromlen, "lwip_recvfrom", s, ret); + done_socket(sock); + return ret; + } else +#endif + { + u16_t datagram_len = 0; + struct iovec vec; + struct msghdr msg; + err_t err; + vec.iov_base = mem; + vec.iov_len = len; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + msg.msg_iov = &vec; + msg.msg_iovlen = 1; + msg.msg_name = from; + msg.msg_namelen = (fromlen ? *fromlen : 0); + err = lwip_recvfrom_udp_raw(sock, flags, &msg, &datagram_len, s); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", + s, lwip_strerr(err))); + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return -1; + } + ret = (ssize_t)LWIP_MIN(LWIP_MIN(len, datagram_len), SSIZE_MAX); + if (fromlen) { + *fromlen = msg.msg_namelen; + } + } + + sock_set_errno(sock, 0); + done_socket(sock); + return ret; +} + +ssize_t +lwip_read(int s, void *mem, size_t len) +{ + return lwip_recvfrom(s, mem, len, 0, NULL, NULL); +} + +ssize_t +lwip_readv(int s, const struct iovec *iov, int iovcnt) +{ + struct msghdr msg; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + /* Hack: we have to cast via number to cast from 'const' pointer to non-const. + Blame the opengroup standard for this inconsistency. */ + msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov); + msg.msg_iovlen = iovcnt; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + return lwip_recvmsg(s, &msg, 0); +} + +ssize_t +lwip_recv(int s, void *mem, size_t len, int flags) +{ + return lwip_recvfrom(s, mem, len, flags, NULL, NULL); +} + +ssize_t +lwip_recvmsg(int s, struct msghdr *message, int flags) +{ + struct lwip_sock *sock; + int i; + ssize_t buflen; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg(%d, message=%p, flags=0x%x)\n", s, (void *)message, flags)); + LWIP_ERROR("lwip_recvmsg: invalid message pointer", message != NULL, return ERR_ARG;); + LWIP_ERROR("lwip_recvmsg: unsupported flags", (flags & ~(MSG_PEEK|MSG_DONTWAIT)) == 0, + set_errno(EOPNOTSUPP); return -1;); + + if ((message->msg_iovlen <= 0) || (message->msg_iovlen > IOV_MAX)) { + set_errno(EMSGSIZE); + return -1; + } + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* check for valid vectors */ + buflen = 0; + for (i = 0; i < message->msg_iovlen; i++) { + if ((message->msg_iov[i].iov_base == NULL) || ((ssize_t)message->msg_iov[i].iov_len <= 0) || + ((size_t)(ssize_t)message->msg_iov[i].iov_len != message->msg_iov[i].iov_len) || + ((ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len) <= 0)) { + sock_set_errno(sock, err_to_errno(ERR_VAL)); + done_socket(sock); + return -1; + } + buflen = (ssize_t)(buflen + (ssize_t)message->msg_iov[i].iov_len); + } + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { +#if LWIP_TCP + int recv_flags = flags; + message->msg_flags = 0; + /* recv the data */ + buflen = 0; + for (i = 0; i < message->msg_iovlen; i++) { + /* try to receive into this vector's buffer */ + ssize_t recvd_local = lwip_recv_tcp(sock, message->msg_iov[i].iov_base, message->msg_iov[i].iov_len, recv_flags); + if (recvd_local > 0) { + /* sum up received bytes */ + buflen += recvd_local; + } + if ((recvd_local < 0) || (recvd_local < (int)message->msg_iov[i].iov_len) || + (flags & MSG_PEEK)) { + /* returned prematurely (or peeking, which might actually be limitated to the first iov) */ + if (buflen <= 0) { + /* nothing received at all, propagate the error */ + buflen = recvd_local; + } + break; + } + /* pass MSG_DONTWAIT to lwip_recv_tcp() to prevent waiting for more data */ + recv_flags |= MSG_DONTWAIT; + } + if (buflen > 0) { + /* reset socket error since we have received something */ + sock_set_errno(sock, 0); + } + /* " If the socket is connected, the msg_name and msg_namelen members shall be ignored." */ + done_socket(sock); + return buflen; +#else /* LWIP_TCP */ + sock_set_errno(sock, err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; +#endif /* LWIP_TCP */ + } + /* else, UDP and RAW NETCONNs */ +#if LWIP_UDP || LWIP_RAW + { + u16_t datagram_len = 0; + err_t err; + err = lwip_recvfrom_udp_raw(sock, flags, message, &datagram_len, s); + if (err != ERR_OK) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvmsg[UDP/RAW](%d): buf == NULL, error is \"%s\"!\n", + s, lwip_strerr(err))); + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return -1; + } + if (datagram_len > buflen) { + message->msg_flags |= MSG_TRUNC; + } + + sock_set_errno(sock, 0); + done_socket(sock); + return (int)datagram_len; + } +#else /* LWIP_UDP || LWIP_RAW */ + sock_set_errno(sock, err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; +#endif /* LWIP_UDP || LWIP_RAW */ +} + +ssize_t +lwip_send(int s, const void *data, size_t size, int flags) +{ + struct lwip_sock *sock; + err_t err; + u8_t write_flags; + size_t written; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", + s, data, size, flags)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { +#if (LWIP_UDP || LWIP_RAW) + done_socket(sock); +#if LWIP_ENABLE_DISTRIBUTED_NET && LWIP_USE_GET_HOST_BY_NAME_EXTERNAL + return lwip_sendto_internal(s, data, size, flags, NULL, 0); +#else + return lwip_sendto(s, data, size, flags, NULL, 0); +#endif +#else /* (LWIP_UDP || LWIP_RAW) */ + sock_set_errno(sock, err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; +#endif /* (LWIP_UDP || LWIP_RAW) */ + } + + write_flags = (u8_t)(NETCONN_COPY | + ((flags & MSG_MORE) ? NETCONN_MORE : 0) | + ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0)); + written = 0; + err = netconn_write_partly(sock->conn, data, size, write_flags, &written); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written)); + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + /* casting 'written' to ssize_t is OK here since the netconn API limits it to SSIZE_MAX */ + return (err == ERR_OK ? (ssize_t)written : -1); +} + +ssize_t +lwip_sendmsg(int s, const struct msghdr *msg, int flags) +{ +#if LWIP_ENABLE_DISTRIBUTED_NET && LWIP_USE_GET_HOST_BY_NAME_EXTERNAL && LWIP_DISTRIBUTED_NET_ENABLE_SENDMSG + if (!is_distributed_net_enabled()) { + return lwip_sendmsg_internal(s, msg, flags); + } + return distributed_net_sendmsg(s, msg, flags); +} + +ssize_t +lwip_sendmsg_internal(int s, const struct msghdr *msg, int flags) +{ +#endif + struct lwip_sock *sock; +#if LWIP_TCP + u8_t write_flags; + size_t written; +#endif + err_t err = ERR_OK; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + LWIP_ERROR("lwip_sendmsg: invalid msghdr", msg != NULL, + sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + LWIP_ERROR("lwip_sendmsg: invalid msghdr iov", msg->msg_iov != NULL, + sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + LWIP_ERROR("lwip_sendmsg: maximum iovs exceeded", (msg->msg_iovlen > 0) && (msg->msg_iovlen <= IOV_MAX), + sock_set_errno(sock, EMSGSIZE); done_socket(sock); return -1;); + LWIP_ERROR("lwip_sendmsg: unsupported flags", (flags & ~(MSG_DONTWAIT | MSG_MORE)) == 0, + sock_set_errno(sock, EOPNOTSUPP); done_socket(sock); return -1;); + + LWIP_UNUSED_ARG(msg->msg_control); + LWIP_UNUSED_ARG(msg->msg_controllen); + LWIP_UNUSED_ARG(msg->msg_flags); + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { +#if LWIP_TCP + write_flags = (u8_t)(NETCONN_COPY | + ((flags & MSG_MORE) ? NETCONN_MORE : 0) | + ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0)); + + written = 0; + err = netconn_write_vectors_partly(sock->conn, (struct netvector *)msg->msg_iov, (u16_t)msg->msg_iovlen, write_flags, &written); + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + /* casting 'written' to ssize_t is OK here since the netconn API limits it to SSIZE_MAX */ + return (err == ERR_OK ? (ssize_t)written : -1); +#else /* LWIP_TCP */ + sock_set_errno(sock, err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; +#endif /* LWIP_TCP */ + } + /* else, UDP and RAW NETCONNs */ +#if LWIP_UDP || LWIP_RAW + { + struct netbuf chain_buf; + int i; + ssize_t size = 0; + + LWIP_UNUSED_ARG(flags); + LWIP_ERROR("lwip_sendmsg: invalid msghdr name", (((msg->msg_name == NULL) && (msg->msg_namelen == 0)) || + IS_SOCK_ADDR_LEN_VALID(msg->msg_namelen)), + sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + + /* initialize chain buffer with destination */ + memset(&chain_buf, 0, sizeof(struct netbuf)); + if (msg->msg_name) { + u16_t remote_port; + SOCKADDR_TO_IPADDR_PORT((const struct sockaddr *)msg->msg_name, &chain_buf.addr, remote_port); + netbuf_fromport(&chain_buf) = remote_port; + } +#if LWIP_NETIF_TX_SINGLE_PBUF + for (i = 0; i < msg->msg_iovlen; i++) { + size += msg->msg_iov[i].iov_len; + if ((msg->msg_iov[i].iov_len > INT_MAX) || (size < (int)msg->msg_iov[i].iov_len)) { + /* overflow */ + goto sendmsg_emsgsize; + } + } + if (size > 0xFFFF) { + /* overflow */ + goto sendmsg_emsgsize; + } + /* Allocate a new netbuf and copy the data into it. */ + if (netbuf_alloc(&chain_buf, (u16_t)size) == NULL) { + err = ERR_MEM; + } else { + /* flatten the IO vectors */ + size_t offset = 0; + for (i = 0; i < msg->msg_iovlen; i++) { + MEMCPY(&((u8_t *)chain_buf.p->payload)[offset], msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); + offset += msg->msg_iov[i].iov_len; + } +#if LWIP_CHECKSUM_ON_COPY + { + /* This can be improved by using LWIP_CHKSUM_COPY() and aggregating the checksum for each IO vector */ + u16_t chksum = ~inet_chksum_pbuf(chain_buf.p); + netbuf_set_chksum(&chain_buf, chksum); + } +#endif /* LWIP_CHECKSUM_ON_COPY */ + err = ERR_OK; + } +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + /* create a chained netbuf from the IO vectors. NOTE: we assemble a pbuf chain + manually to avoid having to allocate, chain, and delete a netbuf for each iov */ + for (i = 0; i < msg->msg_iovlen; i++) { + struct pbuf *p; + if (msg->msg_iov[i].iov_len > 0xFFFF) { + /* overflow */ + goto sendmsg_emsgsize; + } + p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); + if (p == NULL) { + err = ERR_MEM; /* let netbuf_delete() cleanup chain_buf */ + break; + } + p->payload = msg->msg_iov[i].iov_base; + p->len = p->tot_len = (u16_t)msg->msg_iov[i].iov_len; + /* netbuf empty, add new pbuf */ + if (chain_buf.p == NULL) { + chain_buf.p = chain_buf.ptr = p; + /* add pbuf to existing pbuf chain */ + } else { + if (chain_buf.p->tot_len + p->len > 0xffff) { + /* overflow */ + pbuf_free(p); + goto sendmsg_emsgsize; + } + pbuf_cat(chain_buf.p, p); + } + } + /* save size of total chain */ + if (err == ERR_OK) { + size = netbuf_len(&chain_buf); + } +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + + if (err == ERR_OK) { +#if LWIP_IPV4 && LWIP_IPV6 + /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ + if (IP_IS_V6_VAL(chain_buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&chain_buf.addr))) { + unmap_ipv4_mapped_ipv6(ip_2_ip4(&chain_buf.addr), ip_2_ip6(&chain_buf.addr)); + IP_SET_TYPE_VAL(chain_buf.addr, IPADDR_TYPE_V4); + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + + /* send the data */ + err = netconn_send(sock->conn, &chain_buf); + } + + /* deallocated the buffer */ + netbuf_free(&chain_buf); + + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return (err == ERR_OK ? size : -1); +sendmsg_emsgsize: + sock_set_errno(sock, EMSGSIZE); + netbuf_free(&chain_buf); + done_socket(sock); + return -1; + } +#else /* LWIP_UDP || LWIP_RAW */ + sock_set_errno(sock, err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; +#endif /* LWIP_UDP || LWIP_RAW */ +} + +ssize_t +lwip_sendto(int s, const void *data, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ +#if LWIP_ENABLE_DISTRIBUTED_NET && LWIP_USE_GET_HOST_BY_NAME_EXTERNAL + if (!is_distributed_net_enabled()) { + return lwip_sendto_internal(s, data, size, flags, to, tolen); + } + return distributed_net_sendto(s, data, size, flags, to, tolen); +} + +ssize_t +lwip_sendto_internal(int s, const void *data, size_t size, int flags, + const struct sockaddr *to, socklen_t tolen) +{ +#endif + struct lwip_sock *sock; + err_t err; + u16_t short_size; + u16_t remote_port; + struct netbuf buf; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { +#if LWIP_TCP + done_socket(sock); + return lwip_send(s, data, size, flags); +#else /* LWIP_TCP */ + LWIP_UNUSED_ARG(flags); + sock_set_errno(sock, err_to_errno(ERR_ARG)); + done_socket(sock); + return -1; +#endif /* LWIP_TCP */ + } + + if (size > LWIP_MIN(0xFFFF, SSIZE_MAX)) { + /* cannot fit into one datagram (at least for us) */ + sock_set_errno(sock, EMSGSIZE); + done_socket(sock); + return -1; + } + short_size = (u16_t)size; + LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || + (IS_SOCK_ADDR_LEN_VALID(tolen) && + ((to != NULL) && (IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))))), + sock_set_errno(sock, err_to_errno(ERR_ARG)); done_socket(sock); return -1;); + LWIP_UNUSED_ARG(tolen); + + /* initialize a buffer */ + buf.p = buf.ptr = NULL; +#if LWIP_CHECKSUM_ON_COPY + buf.flags = 0; +#endif /* LWIP_CHECKSUM_ON_COPY */ + if (to) { + SOCKADDR_TO_IPADDR_PORT(to, &buf.addr, remote_port); + } else { + remote_port = 0; + ip_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr); + } + netbuf_fromport(&buf) = remote_port; + + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", + s, data, short_size, flags)); + ip_addr_debug_print_val(SOCKETS_DEBUG, buf.addr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); + + /* make the buffer point to the data that should be sent */ +#if LWIP_NETIF_TX_SINGLE_PBUF + /* Allocate a new netbuf and copy the data into it. */ + if (netbuf_alloc(&buf, short_size) == NULL) { + err = ERR_MEM; + } else { +#if LWIP_CHECKSUM_ON_COPY + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) { + u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); + netbuf_set_chksum(&buf, chksum); + } else +#endif /* LWIP_CHECKSUM_ON_COPY */ + { + MEMCPY(buf.p->payload, data, short_size); + } + err = ERR_OK; + } +#else /* LWIP_NETIF_TX_SINGLE_PBUF */ + err = netbuf_ref(&buf, data, short_size); +#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ + if (err == ERR_OK) { +#if LWIP_IPV4 && LWIP_IPV6 + /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ + if (IP_IS_V6_VAL(buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&buf.addr))) { + unmap_ipv4_mapped_ipv6(ip_2_ip4(&buf.addr), ip_2_ip6(&buf.addr)); + IP_SET_TYPE_VAL(buf.addr, IPADDR_TYPE_V4); + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + + /* send the data */ + err = netconn_send(sock->conn, &buf); + } + + /* deallocated the buffer */ + netbuf_free(&buf); + + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return (err == ERR_OK ? short_size : -1); +} + +int +lwip_socket(int domain, int type, int protocol) +{ + struct netconn *conn; + int i; + + LWIP_UNUSED_ARG(domain); /* @todo: check this */ + + /* create a netconn */ + switch (type) { + case SOCK_RAW: + conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW), + (u8_t)protocol, DEFAULT_SOCKET_EVENTCB); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + case SOCK_DGRAM: + conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, + ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)), + DEFAULT_SOCKET_EVENTCB); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); +#if LWIP_NETBUF_RECVINFO + if (conn) { + /* netconn layer enables pktinfo by default, sockets default to off */ + conn->flags &= ~NETCONN_FLAG_PKTINFO; + } +#endif /* LWIP_NETBUF_RECVINFO */ + break; + case SOCK_STREAM: + conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), DEFAULT_SOCKET_EVENTCB); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", + domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", + domain, type, protocol)); + set_errno(EINVAL); + return -1; + } + + if (!conn) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); + set_errno(ENOBUFS); + return -1; + } + + i = alloc_socket(conn, 0); + + if (i == -1) { + netconn_delete(conn); + set_errno(ENFILE); + return -1; + } + conn->socket = i; + done_socket(&sockets[i - LWIP_SOCKET_OFFSET]); + LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); + set_errno(0); + return i; +} + +ssize_t +lwip_write(int s, const void *data, size_t size) +{ + return lwip_send(s, data, size, 0); +} + +ssize_t +lwip_writev(int s, const struct iovec *iov, int iovcnt) +{ + struct msghdr msg; + + msg.msg_name = NULL; + msg.msg_namelen = 0; + /* Hack: we have to cast via number to cast from 'const' pointer to non-const. + Blame the opengroup standard for this inconsistency. */ + msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov); + msg.msg_iovlen = iovcnt; + msg.msg_control = NULL; + msg.msg_controllen = 0; + msg.msg_flags = 0; + return lwip_sendmsg(s, &msg, 0); +} + +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL +/* Add select_cb to select_cb_list. */ +static void +lwip_link_select_cb(struct lwip_select_cb *select_cb) +{ + LWIP_SOCKET_SELECT_DECL_PROTECT(lev); + + /* Protect the select_cb_list */ + LWIP_SOCKET_SELECT_PROTECT(lev); + + /* Put this select_cb on top of list */ + select_cb->next = select_cb_list; + if (select_cb_list != NULL) { + select_cb_list->prev = select_cb; + } + select_cb_list = select_cb; +#if !LWIP_TCPIP_CORE_LOCKING + /* Increasing this counter tells select_check_waiters that the list has changed. */ + select_cb_ctr++; +#endif + + /* Now we can safely unprotect */ + LWIP_SOCKET_SELECT_UNPROTECT(lev); +} + +/* Remove select_cb from select_cb_list. */ +static void +lwip_unlink_select_cb(struct lwip_select_cb *select_cb) +{ + LWIP_SOCKET_SELECT_DECL_PROTECT(lev); + + /* Take us off the list */ + LWIP_SOCKET_SELECT_PROTECT(lev); + if (select_cb->next != NULL) { + select_cb->next->prev = select_cb->prev; + } + if (select_cb_list == select_cb) { + LWIP_ASSERT("select_cb->prev == NULL", select_cb->prev == NULL); + select_cb_list = select_cb->next; + } else { + LWIP_ASSERT("select_cb->prev != NULL", select_cb->prev != NULL); + select_cb->prev->next = select_cb->next; + } +#if !LWIP_TCPIP_CORE_LOCKING + /* Increasing this counter tells select_check_waiters that the list has changed. */ + select_cb_ctr++; +#endif + LWIP_SOCKET_SELECT_UNPROTECT(lev); +} +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ + +#if LWIP_SOCKET_SELECT +/** + * Go through the readset and writeset lists and see which socket of the sockets + * set in the sets has events. On return, readset, writeset and exceptset have + * the sockets enabled that had events. + * + * @param maxfdp1 the highest socket index in the sets + * @param readset_in set of sockets to check for read events + * @param writeset_in set of sockets to check for write events + * @param exceptset_in set of sockets to check for error events + * @param readset_out set of sockets that had read events + * @param writeset_out set of sockets that had write events + * @param exceptset_out set os sockets that had error events + * @return number of sockets that had events (read/write/exception) (>= 0) + */ +static int +lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in, + fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out) +{ + int i, nready = 0; + fd_set lreadset, lwriteset, lexceptset; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + FD_ZERO(&lreadset); + FD_ZERO(&lwriteset); + FD_ZERO(&lexceptset); + + /* Go through each socket in each list to count number of sockets which + currently match */ + for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) { + /* if this FD is not in the set, continue */ + if (!(readset_in && FD_ISSET(i, readset_in)) && + !(writeset_in && FD_ISSET(i, writeset_in)) && + !(exceptset_in && FD_ISSET(i, exceptset_in))) { + continue; + } + /* First get the socket's status (protected)... */ + SYS_ARCH_PROTECT(lev); + sock = tryget_socket_unconn_locked(i); + if (sock != NULL) { + void *lastdata = sock->lastdata.pbuf; + s16_t rcvevent = sock->rcvevent; + u16_t sendevent = sock->sendevent; + u16_t errevent = sock->errevent; + SYS_ARCH_UNPROTECT(lev); + + /* ... then examine it: */ + /* See if netconn of this socket is ready for read */ + if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) { + FD_SET(i, &lreadset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); + nready++; + } + /* See if netconn of this socket is ready for write */ + if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) { + FD_SET(i, &lwriteset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); + nready++; + } + /* See if netconn of this socket had an error */ + if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) { + FD_SET(i, &lexceptset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i)); + nready++; + } + done_socket(sock); + } else { + SYS_ARCH_UNPROTECT(lev); + /* no a valid open socket */ + return -1; + } + } + /* copy local sets to the ones provided as arguments */ + *readset_out = lreadset; + *writeset_out = lwriteset; + *exceptset_out = lexceptset; + + LWIP_ASSERT("nready >= 0", nready >= 0); + return nready; +} + +#if LWIP_NETCONN_FULLDUPLEX +/* Mark all of the set sockets in one of the three fdsets passed to select as used. + * All sockets are marked (and later unmarked), whether they are open or not. + * This is OK as lwip_selscan aborts select when non-open sockets are found. + */ +static void +lwip_select_inc_sockets_used_set(int maxfdp, fd_set *fdset, fd_set *used_sockets) +{ + SYS_ARCH_DECL_PROTECT(lev); + if (fdset) { + int i; + for (i = LWIP_SOCKET_OFFSET; i < maxfdp; i++) { + /* if this FD is in the set, lock it (unless already done) */ + if (FD_ISSET(i, fdset) && !FD_ISSET(i, used_sockets)) { + struct lwip_sock *sock; + SYS_ARCH_PROTECT(lev); + sock = tryget_socket_unconn_locked(i); + if (sock != NULL) { + /* leave the socket used until released by lwip_select_dec_sockets_used */ + FD_SET(i, used_sockets); + } + SYS_ARCH_UNPROTECT(lev); + } + } + } +} + +/* Mark all sockets passed to select as used to prevent them from being freed + * from other threads while select is running. + * Marked sockets are added to 'used_sockets' to mark them only once an be able + * to unmark them correctly. + */ +static void +lwip_select_inc_sockets_used(int maxfdp, fd_set *fdset1, fd_set *fdset2, fd_set *fdset3, fd_set *used_sockets) +{ + FD_ZERO(used_sockets); + lwip_select_inc_sockets_used_set(maxfdp, fdset1, used_sockets); + lwip_select_inc_sockets_used_set(maxfdp, fdset2, used_sockets); + lwip_select_inc_sockets_used_set(maxfdp, fdset3, used_sockets); +} + +/* Let go all sockets that were marked as used when starting select */ +static void +lwip_select_dec_sockets_used(int maxfdp, fd_set *used_sockets) +{ + int i; + for (i = LWIP_SOCKET_OFFSET; i < maxfdp; i++) { + /* if this FD is not in the set, continue */ + if (FD_ISSET(i, used_sockets)) { + struct lwip_sock *sock = tryget_socket_unconn_nouse(i); + LWIP_ASSERT("socket gone at the end of select", sock != NULL); + if (sock != NULL) { + done_socket(sock); + } + } + } +} +#else /* LWIP_NETCONN_FULLDUPLEX */ +#define lwip_select_inc_sockets_used(maxfdp1, readset, writeset, exceptset, used_sockets) +#define lwip_select_dec_sockets_used(maxfdp1, used_sockets) +#endif /* LWIP_NETCONN_FULLDUPLEX */ + +int +lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, + struct timeval *timeout) +{ + u32_t waitres = 0; + int nready; + fd_set lreadset, lwriteset, lexceptset; + u32_t msectimeout; + int i; + int maxfdp2; +#if LWIP_NETCONN_SEM_PER_THREAD + int waited = 0; +#endif +#if LWIP_NETCONN_FULLDUPLEX + fd_set used_sockets; +#endif + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n", + maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, + timeout ? (s32_t)timeout->tv_sec : (s32_t) - 1, + timeout ? (s32_t)timeout->tv_usec : (s32_t) - 1)); + + if ((maxfdp1 < 0) || (maxfdp1 > LWIP_SELECT_MAXNFDS)) { + set_errno(EINVAL); + return -1; + } + + lwip_select_inc_sockets_used(maxfdp1, readset, writeset, exceptset, &used_sockets); + + /* Go through each socket in each list to count number of sockets which + currently match */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + + if (nready < 0) { + /* one of the sockets in one of the fd_sets was invalid */ + set_errno(EBADF); + lwip_select_dec_sockets_used(maxfdp1, &used_sockets); + return -1; + } else if (nready > 0) { + /* one or more sockets are set, no need to wait */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); + } else { + /* If we don't have any current events, then suspend if we are supposed to */ + if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); + /* This is OK as the local fdsets are empty and nready is zero, + or we would have returned earlier. */ + } else { + /* None ready: add our semaphore to list: + We don't actually need any dynamic memory. Our entry on the + list is only valid while we are in this function, so it's ok + to use local variables (unless we're running in MPU compatible + mode). */ + API_SELECT_CB_VAR_DECLARE(select_cb); + API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(ENOMEM); lwip_select_dec_sockets_used(maxfdp1, &used_sockets); return -1); + memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); + + API_SELECT_CB_VAR_REF(select_cb).readset = readset; + API_SELECT_CB_VAR_REF(select_cb).writeset = writeset; + API_SELECT_CB_VAR_REF(select_cb).exceptset = exceptset; +#if LWIP_NETCONN_SEM_PER_THREAD + API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); +#else /* LWIP_NETCONN_SEM_PER_THREAD */ + if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) { + /* failed to create semaphore */ + set_errno(ENOMEM); + lwip_select_dec_sockets_used(maxfdp1, &used_sockets); + API_SELECT_CB_VAR_FREE(select_cb); + return -1; + } +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + + lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); + + /* Increase select_waiting for each socket we are interested in */ + maxfdp2 = maxfdp1; + for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) { + if ((readset && FD_ISSET(i, readset)) || + (writeset && FD_ISSET(i, writeset)) || + (exceptset && FD_ISSET(i, exceptset))) { + struct lwip_sock *sock; + SYS_ARCH_PROTECT(lev); + sock = tryget_socket_unconn_locked(i); + if (sock != NULL) { + sock->select_waiting++; + if (sock->select_waiting == 0) { + /* overflow - too many threads waiting */ + sock->select_waiting--; + nready = -1; + maxfdp2 = i; + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + set_errno(EBUSY); + break; + } + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + } else { + /* Not a valid socket */ + nready = -1; + maxfdp2 = i; + SYS_ARCH_UNPROTECT(lev); + set_errno(EBADF); + break; + } + } + } + + if (nready >= 0) { + /* Call lwip_selscan again: there could have been events between + the last scan (without us on the list) and putting us on the list! */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + if (!nready) { + /* Still none ready, just wait to be woken */ + if (timeout == 0) { + /* Wait forever */ + msectimeout = 0; + } else { + long msecs_long = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500) / 1000)); + if (msecs_long <= 0) { + /* Wait 1ms at least (0 means wait forever) */ + msectimeout = 1; + } else { + msectimeout = (u32_t)msecs_long; + } + } + + waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout); +#if LWIP_NETCONN_SEM_PER_THREAD + waited = 1; +#endif + } + } + + /* Decrease select_waiting for each socket we are interested in */ + for (i = LWIP_SOCKET_OFFSET; i < maxfdp2; i++) { + if ((readset && FD_ISSET(i, readset)) || + (writeset && FD_ISSET(i, writeset)) || + (exceptset && FD_ISSET(i, exceptset))) { + struct lwip_sock *sock; + SYS_ARCH_PROTECT(lev); + sock = tryget_socket_unconn_locked(i); + if (sock != NULL) { + /* for now, handle select_waiting==0... */ + LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); + if (sock->select_waiting > 0) { + sock->select_waiting--; + } + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + } else { + SYS_ARCH_UNPROTECT(lev); + /* Not a valid socket */ + nready = -1; + set_errno(EBADF); + } + } + } + + lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); + +#if LWIP_NETCONN_SEM_PER_THREAD + if (API_SELECT_CB_VAR_REF(select_cb).sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) { + /* don't leave the thread-local semaphore signalled */ + sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1); + } +#else /* LWIP_NETCONN_SEM_PER_THREAD */ + sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem); +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + API_SELECT_CB_VAR_FREE(select_cb); + + if (nready < 0) { + /* This happens when a socket got closed while waiting */ + lwip_select_dec_sockets_used(maxfdp1, &used_sockets); + return -1; + } + + if (waitres == SYS_ARCH_TIMEOUT) { + /* Timeout */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); + /* This is OK as the local fdsets are empty and nready is zero, + or we would have returned earlier. */ + } else { + /* See what's set now after waiting */ + nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); + } + } + } + + lwip_select_dec_sockets_used(maxfdp1, &used_sockets); + set_errno(0); + if (readset) { + *readset = lreadset; + } + if (writeset) { + *writeset = lwriteset; + } + if (exceptset) { + *exceptset = lexceptset; + } + return nready; +} +#endif /* LWIP_SOCKET_SELECT */ + +#if LWIP_SOCKET_POLL +/** Options for the lwip_pollscan function. */ +enum lwip_pollscan_opts +{ + /** Clear revents in each struct pollfd. */ + LWIP_POLLSCAN_CLEAR = 1, + + /** Increment select_waiting in each struct lwip_sock. */ + LWIP_POLLSCAN_INC_WAIT = 2, + + /** Decrement select_waiting in each struct lwip_sock. */ + LWIP_POLLSCAN_DEC_WAIT = 4 +}; + +/** + * Update revents in each struct pollfd. + * Optionally update select_waiting in struct lwip_sock. + * + * @param fds array of structures to update + * @param nfds number of structures in fds + * @param opts what to update and how + * @return number of structures that have revents != 0 + */ +static int +lwip_pollscan(struct pollfd *fds, nfds_t nfds, enum lwip_pollscan_opts opts) +{ + int nready = 0; + nfds_t fdi; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + /* Go through each struct pollfd in the array. */ + for (fdi = 0; fdi < nfds; fdi++) { + if ((opts & LWIP_POLLSCAN_CLEAR) != 0) { + fds[fdi].revents = 0; + } + + /* Negative fd means the caller wants us to ignore this struct. + POLLNVAL means we already detected that the fd is invalid; + if another thread has since opened a new socket with that fd, + we must not use that socket. */ + if (fds[fdi].fd >= 0 && (fds[fdi].revents & POLLNVAL) == 0) { + /* First get the socket's status (protected)... */ + SYS_ARCH_PROTECT(lev); + sock = tryget_socket_unconn_locked(fds[fdi].fd); + if (sock != NULL) { + void* lastdata = sock->lastdata.pbuf; + s16_t rcvevent = sock->rcvevent; + u16_t sendevent = sock->sendevent; + u16_t errevent = sock->errevent; + + if ((opts & LWIP_POLLSCAN_INC_WAIT) != 0) { + sock->select_waiting++; + if (sock->select_waiting == 0) { + /* overflow - too many threads waiting */ + sock->select_waiting--; + nready = -1; + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + break; + } + } else if ((opts & LWIP_POLLSCAN_DEC_WAIT) != 0) { + /* for now, handle select_waiting==0... */ + LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); + if (sock->select_waiting > 0) { + sock->select_waiting--; + } + } + SYS_ARCH_UNPROTECT(lev); + done_socket(sock); + + /* ... then examine it: */ + /* See if netconn of this socket is ready for read */ + if ((fds[fdi].events & POLLIN) != 0 && ((lastdata != NULL) || (rcvevent > 0))) { + fds[fdi].revents |= POLLIN; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for reading\n", fds[fdi].fd)); + } + /* See if netconn of this socket is ready for write */ + if ((fds[fdi].events & POLLOUT) != 0 && (sendevent != 0)) { + fds[fdi].revents |= POLLOUT; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for writing\n", fds[fdi].fd)); + } + /* See if netconn of this socket had an error */ + if (errevent != 0) { + /* POLLERR is output only. */ + fds[fdi].revents |= POLLERR; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_pollscan: fd=%d ready for exception\n", fds[fdi].fd)); + } + } else { + /* Not a valid socket */ + SYS_ARCH_UNPROTECT(lev); + /* POLLNVAL is output only. */ + fds[fdi].revents |= POLLNVAL; + return -1; + } + } + + /* Will return the number of structures that have events, + not the number of events. */ + if (fds[fdi].revents != 0) { + nready++; + } + } + + LWIP_ASSERT("nready >= 0", nready >= 0); + return nready; +} + +#if LWIP_NETCONN_FULLDUPLEX +/* Mark all sockets as used. + * + * All sockets are marked (and later unmarked), whether they are open or not. + * This is OK as lwip_pollscan aborts select when non-open sockets are found. + */ +static void +lwip_poll_inc_sockets_used(struct pollfd *fds, nfds_t nfds) +{ + nfds_t fdi; + + if(fds) { + /* Go through each struct pollfd in the array. */ + for (fdi = 0; fdi < nfds; fdi++) { + /* Increase the reference counter */ + tryget_socket_unconn(fds[fdi].fd); + } + } +} + +/* Let go all sockets that were marked as used when starting poll */ +static void +lwip_poll_dec_sockets_used(struct pollfd *fds, nfds_t nfds) +{ + nfds_t fdi; + + if(fds) { + /* Go through each struct pollfd in the array. */ + for (fdi = 0; fdi < nfds; fdi++) { + struct lwip_sock *sock = tryget_socket_unconn_nouse(fds[fdi].fd); + if (sock != NULL) { + done_socket(sock); + } + } + } +} +#else /* LWIP_NETCONN_FULLDUPLEX */ +#define lwip_poll_inc_sockets_used(fds, nfds) +#define lwip_poll_dec_sockets_used(fds, nfds) +#endif /* LWIP_NETCONN_FULLDUPLEX */ + +int +lwip_poll(struct pollfd *fds, nfds_t nfds, int timeout) +{ + u32_t waitres = 0; + int nready; + u32_t msectimeout; +#if LWIP_NETCONN_SEM_PER_THREAD + int waited = 0; +#endif + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll(%p, %d, %d)\n", + (void*)fds, (int)nfds, timeout)); + LWIP_ERROR("lwip_poll: invalid fds", ((fds != NULL && nfds > 0) || (fds == NULL && nfds == 0)), + set_errno(EINVAL); return -1;); + + lwip_poll_inc_sockets_used(fds, nfds); + + /* Go through each struct pollfd to count number of structures + which currently match */ + nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_CLEAR); + + if (nready < 0) { + lwip_poll_dec_sockets_used(fds, nfds); + return -1; + } + + /* If we don't have any current events, then suspend if we are supposed to */ + if (!nready) { + API_SELECT_CB_VAR_DECLARE(select_cb); + + if (timeout == 0) { + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: no timeout, returning 0\n")); + goto return_success; + } + API_SELECT_CB_VAR_ALLOC(select_cb, set_errno(EAGAIN); lwip_poll_dec_sockets_used(fds, nfds); return -1); + memset(&API_SELECT_CB_VAR_REF(select_cb), 0, sizeof(struct lwip_select_cb)); + + /* None ready: add our semaphore to list: + We don't actually need any dynamic memory. Our entry on the + list is only valid while we are in this function, so it's ok + to use local variables. */ + + API_SELECT_CB_VAR_REF(select_cb).poll_fds = fds; + API_SELECT_CB_VAR_REF(select_cb).poll_nfds = nfds; +#if LWIP_NETCONN_SEM_PER_THREAD + API_SELECT_CB_VAR_REF(select_cb).sem = LWIP_NETCONN_THREAD_SEM_GET(); +#else /* LWIP_NETCONN_SEM_PER_THREAD */ + if (sys_sem_new(&API_SELECT_CB_VAR_REF(select_cb).sem, 0) != ERR_OK) { + /* failed to create semaphore */ + set_errno(EAGAIN); + lwip_poll_dec_sockets_used(fds, nfds); + API_SELECT_CB_VAR_FREE(select_cb); + return -1; + } +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + + lwip_link_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); + + /* Increase select_waiting for each socket we are interested in. + Also, check for events again: there could have been events between + the last scan (without us on the list) and putting us on the list! */ + nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_INC_WAIT); + + if (!nready) { + /* Still none ready, just wait to be woken */ + if (timeout < 0) { + /* Wait forever */ + msectimeout = 0; + } else { + /* timeout == 0 would have been handled earlier. */ + LWIP_ASSERT("timeout > 0", timeout > 0); + msectimeout = timeout; + } + waitres = sys_arch_sem_wait(SELECT_SEM_PTR(API_SELECT_CB_VAR_REF(select_cb).sem), msectimeout); +#if LWIP_NETCONN_SEM_PER_THREAD + waited = 1; +#endif + } + + /* Decrease select_waiting for each socket we are interested in, + and check which events occurred while we waited. */ + nready = lwip_pollscan(fds, nfds, LWIP_POLLSCAN_DEC_WAIT); + + lwip_unlink_select_cb(&API_SELECT_CB_VAR_REF(select_cb)); + +#if LWIP_NETCONN_SEM_PER_THREAD + if (select_cb.sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) { + /* don't leave the thread-local semaphore signalled */ + sys_arch_sem_wait(API_SELECT_CB_VAR_REF(select_cb).sem, 1); + } +#else /* LWIP_NETCONN_SEM_PER_THREAD */ + sys_sem_free(&API_SELECT_CB_VAR_REF(select_cb).sem); +#endif /* LWIP_NETCONN_SEM_PER_THREAD */ + API_SELECT_CB_VAR_FREE(select_cb); + + if (nready < 0) { + /* This happens when a socket got closed while waiting */ + lwip_poll_dec_sockets_used(fds, nfds); + return -1; + } + + if (waitres == SYS_ARCH_TIMEOUT) { + /* Timeout */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: timeout expired\n")); + goto return_success; + } + } + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_poll: nready=%d\n", nready)); +return_success: + lwip_poll_dec_sockets_used(fds, nfds); + set_errno(0); + return nready; +} + +/** + * Check whether event_callback should wake up a thread waiting in + * lwip_poll. + */ +static int +lwip_poll_should_wake(const struct lwip_select_cb *scb, int fd, int has_recvevent, int has_sendevent, int has_errevent) +{ + nfds_t fdi; + for (fdi = 0; fdi < scb->poll_nfds; fdi++) { + const struct pollfd *pollfd = &scb->poll_fds[fdi]; + if (pollfd->fd == fd) { + /* Do not update pollfd->revents right here; + that would be a data race because lwip_pollscan + accesses revents without protecting. */ + if (has_recvevent && (pollfd->events & POLLIN) != 0) { + return 1; + } + if (has_sendevent && (pollfd->events & POLLOUT) != 0) { + return 1; + } + if (has_errevent) { + /* POLLERR is output only. */ + return 1; + } + } + } + return 0; +} +#endif /* LWIP_SOCKET_POLL */ + +#if LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL +/** + * Callback registered in the netconn layer for each socket-netconn. + * Processes recvevent (data available) and wakes up tasks waiting for select. + * + * @note for LWIP_TCPIP_CORE_LOCKING any caller of this function + * must have the core lock held when signaling the following events + * as they might cause select_list_cb to be checked: + * NETCONN_EVT_RCVPLUS + * NETCONN_EVT_SENDPLUS + * NETCONN_EVT_ERROR + * This requirement will be asserted in select_check_waiters() + */ +static void +event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) +{ + int s, check_waiters; + struct lwip_sock *sock; + SYS_ARCH_DECL_PROTECT(lev); + + LWIP_UNUSED_ARG(len); + + /* Get socket */ + if (conn) { + s = conn->socket; + if (s < 0) { + /* Data comes in right away after an accept, even though + * the server task might not have created a new socket yet. + * Just count down (or up) if that's the case and we + * will use the data later. Note that only receive events + * can happen before the new socket is set up. */ + SYS_ARCH_PROTECT(lev); + if (conn->socket < 0) { + if (evt == NETCONN_EVT_RCVPLUS) { + /* conn->socket is -1 on initialization + lwip_accept adjusts sock->recvevent if conn->socket < -1 */ + conn->socket--; + } + SYS_ARCH_UNPROTECT(lev); + return; + } + s = conn->socket; + SYS_ARCH_UNPROTECT(lev); + } + + sock = get_socket(s); + if (!sock) { + return; + } + } else { + return; + } + + check_waiters = 1; + SYS_ARCH_PROTECT(lev); + /* Set event as required */ + switch (evt) { + case NETCONN_EVT_RCVPLUS: + sock->rcvevent++; + if (sock->rcvevent > 1) { + check_waiters = 0; + } + break; + case NETCONN_EVT_RCVMINUS: + sock->rcvevent--; + check_waiters = 0; + break; + case NETCONN_EVT_SENDPLUS: + if (sock->sendevent) { + check_waiters = 0; + } + sock->sendevent = 1; + break; + case NETCONN_EVT_SENDMINUS: + sock->sendevent = 0; + check_waiters = 0; + break; + case NETCONN_EVT_ERROR: + sock->errevent = 1; + break; + default: + LWIP_ASSERT("unknown event", 0); + break; + } + + if (sock->select_waiting && check_waiters) { + /* Save which events are active */ + int has_recvevent, has_sendevent, has_errevent; + has_recvevent = sock->rcvevent > 0; + has_sendevent = sock->sendevent != 0; + has_errevent = sock->errevent != 0; + SYS_ARCH_UNPROTECT(lev); + /* Check any select calls waiting on this socket */ + select_check_waiters(s, has_recvevent, has_sendevent, has_errevent); + } else { + SYS_ARCH_UNPROTECT(lev); + } + // poll_check_waiters(s, check_waiters); + done_socket(sock); +} + +/** + * Check if any select waiters are waiting on this socket and its events + * + * @note on synchronization of select_cb_list: + * LWIP_TCPIP_CORE_LOCKING: the select_cb_list must only be accessed while holding + * the core lock. We do a single pass through the list and signal any waiters. + * Core lock should already be held when calling here!!!! + + * !LWIP_TCPIP_CORE_LOCKING: we use SYS_ARCH_PROTECT but unlock on each iteration + * of the loop, thus creating a possibility where a thread could modify the + * select_cb_list during our UNPROTECT/PROTECT. We use a generational counter to + * detect this change and restart the list walk. The list is expected to be small + */ +static void select_check_waiters(int s, int has_recvevent, int has_sendevent, int has_errevent) +{ + struct lwip_select_cb *scb; +#if !LWIP_TCPIP_CORE_LOCKING + int last_select_cb_ctr; + SYS_ARCH_DECL_PROTECT(lev); +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + + LWIP_ASSERT_CORE_LOCKED(); + +#if !LWIP_TCPIP_CORE_LOCKING + SYS_ARCH_PROTECT(lev); +again: + /* remember the state of select_cb_list to detect changes */ + last_select_cb_ctr = select_cb_ctr; +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + for (scb = select_cb_list; scb != NULL; scb = scb->next) { + if (scb->sem_signalled == 0) { + /* semaphore not signalled yet */ + int do_signal = 0; +#if LWIP_SOCKET_POLL + if (scb->poll_fds != NULL) { + do_signal = lwip_poll_should_wake(scb, s, has_recvevent, has_sendevent, has_errevent); + } +#endif /* LWIP_SOCKET_POLL */ +#if LWIP_SOCKET_SELECT && LWIP_SOCKET_POLL + else +#endif /* LWIP_SOCKET_SELECT && LWIP_SOCKET_POLL */ +#if LWIP_SOCKET_SELECT + { + /* Test this select call for our socket */ + if (has_recvevent) { + if (scb->readset && FD_ISSET(s, scb->readset)) { + do_signal = 1; + } + } + if (has_sendevent) { + if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) { + do_signal = 1; + } + } + if (has_errevent) { + if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) { + do_signal = 1; + } + } + } +#endif /* LWIP_SOCKET_SELECT */ + if (do_signal) { + scb->sem_signalled = 1; + /* For !LWIP_TCPIP_CORE_LOCKING, we don't call SYS_ARCH_UNPROTECT() before signaling + the semaphore, as this might lead to the select thread taking itself off the list, + invalidating the semaphore. */ + sys_sem_signal(SELECT_SEM_PTR(scb->sem)); + } + } +#if LWIP_TCPIP_CORE_LOCKING + } +#else + /* unlock interrupts with each step */ + SYS_ARCH_UNPROTECT(lev); + /* this makes sure interrupt protection time is short */ + SYS_ARCH_PROTECT(lev); + if (last_select_cb_ctr != select_cb_ctr) { + /* someone has changed select_cb_list, restart at the beginning */ + goto again; + } + /* remember the state of select_cb_list to detect changes */ + last_select_cb_ctr = select_cb_ctr; + } + SYS_ARCH_UNPROTECT(lev); +#endif +} +#endif /* LWIP_SOCKET_SELECT || LWIP_SOCKET_POLL */ + +/** + * Close one end of a full-duplex connection. + */ +int +lwip_shutdown(int s, int how) +{ + struct lwip_sock *sock; + err_t err; + u8_t shut_rx = 0, shut_tx = 0; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); + + sock = get_socket(s); + if (!sock) { + return -1; + } + + if (sock->conn != NULL) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + sock_set_errno(sock, EOPNOTSUPP); + done_socket(sock); + return -1; + } + } else { + sock_set_errno(sock, ENOTCONN); + done_socket(sock); + return -1; + } + + if (how == SHUT_RD) { + shut_rx = 1; + } else if (how == SHUT_WR) { + shut_tx = 1; + } else if (how == SHUT_RDWR) { + shut_rx = 1; + shut_tx = 1; + } else { + sock_set_errno(sock, EINVAL); + done_socket(sock); + return -1; + } + err = netconn_shutdown(sock->conn, shut_rx, shut_tx); + + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return (err == ERR_OK ? 0 : -1); +} + +static int +lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) +{ + struct lwip_sock *sock; + union sockaddr_aligned saddr; + ip_addr_t naddr; + u16_t port; + err_t err; + + sock = get_socket(s); + if (!sock) { + return -1; + } + + /* get the IP address and port */ + err = netconn_getaddr(sock->conn, &naddr, &port, local); + if (err != ERR_OK) { + sock_set_errno(sock, err_to_errno(err)); + done_socket(sock); + return -1; + } + +#if LWIP_IPV4 && LWIP_IPV6 + /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */ + if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn)) && + IP_IS_V4_VAL(naddr)) { + ip4_2_ipv4_mapped_ipv6(ip_2_ip6(&naddr), ip_2_ip4(&naddr)); + IP_SET_TYPE_VAL(naddr, IPADDR_TYPE_V6); + } +#endif /* LWIP_IPV4 && LWIP_IPV6 */ + + IPADDR_PORT_TO_SOCKADDR(&saddr, &naddr, port); + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); + ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); + LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port)); + + if (*namelen > saddr.sa.sa_len) { + *namelen = saddr.sa.sa_len; + } + MEMCPY(name, &saddr, *namelen); + + sock_set_errno(sock, 0); + done_socket(sock); + return 0; +} + +int +lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) +{ + return lwip_getaddrname(s, name, namelen, 0); +} + +int +lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) +{ + return lwip_getaddrname(s, name, namelen, 1); +} + +int +lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + int err; + struct lwip_sock *sock = get_socket(s); +#if !LWIP_TCPIP_CORE_LOCKING + err_t cberr; + LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + + if (!sock) { + return -1; + } + + if ((NULL == optval) || (NULL == optlen)) { + sock_set_errno(sock, EFAULT); + done_socket(sock); + return -1; + } + +#if LWIP_TCPIP_CORE_LOCKING + /* core-locking can just call the -impl function */ + LOCK_TCPIP_CORE(); + err = lwip_getsockopt_impl(s, level, optname, optval, optlen); + UNLOCK_TCPIP_CORE(); + +#else /* LWIP_TCPIP_CORE_LOCKING */ + +#if LWIP_MPU_COMPATIBLE + /* MPU_COMPATIBLE copies the optval data, so check for max size here */ + if (*optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) { + sock_set_errno(sock, ENOBUFS); + done_socket(sock); + return -1; + } +#endif /* LWIP_MPU_COMPATIBLE */ + + LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = *optlen; +#if !LWIP_MPU_COMPATIBLE + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.p = optval; +#endif /* !LWIP_MPU_COMPATIBLE */ + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; +#if LWIP_NETCONN_SEM_PER_THREAD + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); +#else + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; +#endif + cberr = tcpip_callback(lwip_getsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); + if (cberr != ERR_OK) { + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); + sock_set_errno(sock, err_to_errno(cberr)); + done_socket(sock); + return -1; + } + sys_arch_sem_wait((sys_sem_t *)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); + + /* write back optlen and optval */ + *optlen = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen; +#if LWIP_MPU_COMPATIBLE + MEMCPY(optval, LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen); +#endif /* LWIP_MPU_COMPATIBLE */ + + /* maybe lwip_getsockopt_internal has changed err */ + err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + sock_set_errno(sock, err); + done_socket(sock); + return err ? -1 : 0; +} + +#if !LWIP_TCPIP_CORE_LOCKING +/** lwip_getsockopt_callback: only used without CORE_LOCKING + * to get into the tcpip_thread + */ +static void +lwip_getsockopt_callback(void *arg) +{ + struct lwip_setgetsockopt_data *data; + LWIP_ASSERT("arg != NULL", arg != NULL); + data = (struct lwip_setgetsockopt_data *)arg; + + data->err = lwip_getsockopt_impl(data->s, data->level, data->optname, +#if LWIP_MPU_COMPATIBLE + data->optval, +#else /* LWIP_MPU_COMPATIBLE */ + data->optval.p, +#endif /* LWIP_MPU_COMPATIBLE */ + &data->optlen); + + sys_sem_signal((sys_sem_t *)(data->completed_sem)); +} +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +static int +lwip_sockopt_to_ipopt(int optname) +{ + /* Map SO_* values to our internal SOF_* values + * We should not rely on #defines in socket.h + * being in sync with ip.h. + */ + switch (optname) { + case SO_BROADCAST: + return SOF_BROADCAST; + case SO_KEEPALIVE: + return SOF_KEEPALIVE; + case SO_REUSEADDR: + return SOF_REUSEADDR; + default: + LWIP_ASSERT("Unknown socket option", 0); + return 0; + } +} + +/** lwip_getsockopt_impl: the actual implementation of getsockopt: + * same argument as lwip_getsockopt, either called directly or through callback + */ +static int +lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen) +{ + int err = 0; + struct lwip_sock *sock = tryget_socket(s); + if (!sock) { + return EBADF; + } + +#ifdef LWIP_HOOK_SOCKETS_GETSOCKOPT + if (LWIP_HOOK_SOCKETS_GETSOCKOPT(s, sock, level, optname, optval, optlen, &err)) { + return err; + } +#endif + + switch (level) { + + /* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + +#if LWIP_TCP + case SO_ACCEPTCONN: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) { + done_socket(sock); + return ENOPROTOOPT; + } + if ((sock->conn->pcb.tcp != NULL) && (sock->conn->pcb.tcp->state == LISTEN)) { + *(int *)optval = 1; + } else { + *(int *)optval = 0; + } + break; +#endif /* LWIP_TCP */ + + /* The option flags */ + case SO_BROADCAST: + case SO_KEEPALIVE: +#if SO_REUSE + case SO_REUSEADDR: +#endif /* SO_REUSE */ + if ((optname == SO_BROADCAST) && + (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) { + done_socket(sock); + return ENOPROTOOPT; + } + + optname = lwip_sockopt_to_ipopt(optname); + + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + *(int *)optval = ip_get_option(sock->conn->pcb.ip, optname); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", + s, optname, (*(int *)optval ? "on" : "off"))); + break; + + case SO_TYPE: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); + switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) { + case NETCONN_RAW: + *(int *)optval = SOCK_RAW; + break; + case NETCONN_TCP: + *(int *)optval = SOCK_STREAM; + break; + case NETCONN_UDP: + *(int *)optval = SOCK_DGRAM; + break; + default: /* unrecognized socket type */ + *(int *)optval = netconn_type(sock->conn); + LWIP_DEBUGF(SOCKETS_DEBUG, + ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", + s, *(int *)optval)); + } /* switch (netconn_type(sock->conn)) */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", + s, *(int *)optval)); + break; + + case SO_ERROR: + LWIP_SOCKOPT_CHECK_OPTLEN(sock, *optlen, int); + *(int *)optval = err_to_errno(netconn_err(sock->conn)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", + s, *(int *)optval)); + break; + +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_sendtimeout(sock->conn)); + break; +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_recvtimeout(sock->conn)); + break; +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); + *(int *)optval = netconn_get_recvbufsize(sock->conn); + break; +#endif /* LWIP_SO_RCVBUF */ +#if LWIP_SO_LINGER + case SO_LINGER: { + s16_t conn_linger; + struct linger *linger = (struct linger *)optval; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, struct linger); + conn_linger = sock->conn->linger; + if (conn_linger >= 0) { + linger->l_onoff = 1; + linger->l_linger = (int)conn_linger; + } else { + linger->l_onoff = 0; + linger->l_linger = 0; + } + } + break; +#endif /* LWIP_SO_LINGER */ +#if LWIP_UDP + case SO_NO_CHECK: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_UDP); +#if LWIP_UDPLITE + if (udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_UDPLITE)) { + /* this flag is only available for UDP, not for UDP lite */ + done_socket(sock); + return EAFNOSUPPORT; + } +#endif /* LWIP_UDPLITE */ + *(int *)optval = udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM) ? 1 : 0; + break; +#endif /* LWIP_UDP*/ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + + /* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + *(int *)optval = sock->conn->pcb.ip->ttl; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_TOS: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + *(int *)optval = sock->conn->pcb.ip->tos; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", + s, *(int *)optval)); + break; +#if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP + case IP_MULTICAST_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { + done_socket(sock); + return ENOPROTOOPT; + } + *(u8_t *)optval = udp_get_multicast_ttl(sock->conn->pcb.udp); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", + s, *(int *)optval)); + break; + case IP_MULTICAST_IF: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, struct in_addr); + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { + done_socket(sock); + return ENOPROTOOPT; + } + inet_addr_from_ip4addr((struct in_addr *)optval, udp_get_multicast_netif_addr(sock->conn->pcb.udp)); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", + s, *(u32_t *)optval)); + break; + case IP_MULTICAST_LOOP: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); + if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) { + *(u8_t *)optval = 1; + } else { + *(u8_t *)optval = 0; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", + s, *(int *)optval)); + break; +#endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + +#if LWIP_TCP + /* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + /* Special case: all IPPROTO_TCP option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_TCP); + if (sock->conn->pcb.tcp->state == LISTEN) { + done_socket(sock); + return EINVAL; + } + switch (optname) { + case TCP_NODELAY: + *(int *)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", + s, (*(int *)optval) ? "on" : "off") ); + break; + case TCP_KEEPALIVE: + *(int *)optval = (int)sock->conn->pcb.tcp->keep_idle; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) = %d\n", + s, *(int *)optval)); + break; + +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + *(int *)optval = (int)(sock->conn->pcb.tcp->keep_idle / 1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPINTVL: + *(int *)optval = (int)(sock->conn->pcb.tcp->keep_intvl / 1000); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) = %d\n", + s, *(int *)optval)); + break; + case TCP_KEEPCNT: + *(int *)optval = (int)sock->conn->pcb.tcp->keep_cnt; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) = %d\n", + s, *(int *)optval)); + break; +#endif /* LWIP_TCP_KEEPALIVE */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP */ + +#if LWIP_IPV6 + /* Level: IPPROTO_IPV6 */ + case IPPROTO_IPV6: + switch (optname) { + case IPV6_V6ONLY: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); + *(int *)optval = (netconn_get_ipv6only(sock->conn) ? 1 : 0); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY) = %d\n", + s, *(int *)optval)); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_IPV6 */ + +#if LWIP_UDP && LWIP_UDPLITE + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + /* Special case: all IPPROTO_UDPLITE option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); + /* If this is no UDP lite socket, ignore any options. */ + if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { + done_socket(sock); + return ENOPROTOOPT; + } + switch (optname) { + case UDPLITE_SEND_CSCOV: + *(int *)optval = sock->conn->pcb.udp->chksum_len_tx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", + s, (*(int *)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + *(int *)optval = sock->conn->pcb.udp->chksum_len_rx; + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", + s, (*(int *)optval)) ); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP */ + /* Level: IPPROTO_RAW */ + case IPPROTO_RAW: + switch (optname) { +#if LWIP_IPV6 && LWIP_RAW + case IPV6_CHECKSUM: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_RAW); + if (sock->conn->pcb.raw->chksum_reqd == 0) { + *(int *)optval = -1; + } else { + *(int *)optval = sock->conn->pcb.raw->chksum_offset; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM) = %d\n", + s, (*(int *)optval)) ); + break; +#endif /* LWIP_IPV6 && LWIP_RAW */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + break; + } /* switch (level) */ + + done_socket(sock); + return err; +} + +int +lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + int err = 0; + struct lwip_sock *sock = get_socket(s); +#if !LWIP_TCPIP_CORE_LOCKING + err_t cberr; + LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); +#endif /* !LWIP_TCPIP_CORE_LOCKING */ + + if (!sock) { + return -1; + } + + if (NULL == optval) { + sock_set_errno(sock, EFAULT); + done_socket(sock); + return -1; + } + +#if LWIP_TCPIP_CORE_LOCKING + /* core-locking can just call the -impl function */ + LOCK_TCPIP_CORE(); + err = lwip_setsockopt_impl(s, level, optname, optval, optlen); + UNLOCK_TCPIP_CORE(); + +#else /* LWIP_TCPIP_CORE_LOCKING */ + +#if LWIP_MPU_COMPATIBLE + /* MPU_COMPATIBLE copies the optval data, so check for max size here */ + if (optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) { + sock_set_errno(sock, ENOBUFS); + done_socket(sock); + return -1; + } +#endif /* LWIP_MPU_COMPATIBLE */ + + LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = optlen; +#if LWIP_MPU_COMPATIBLE + MEMCPY(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, optval, optlen); +#else /* LWIP_MPU_COMPATIBLE */ + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.pc = (const void *)optval; +#endif /* LWIP_MPU_COMPATIBLE */ + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; +#if LWIP_NETCONN_SEM_PER_THREAD + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); +#else + LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; +#endif + cberr = tcpip_callback(lwip_setsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); + if (cberr != ERR_OK) { + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); + sock_set_errno(sock, err_to_errno(cberr)); + done_socket(sock); + return -1; + } + sys_arch_sem_wait((sys_sem_t *)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); + + /* maybe lwip_getsockopt_internal has changed err */ + err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; + LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); +#endif /* LWIP_TCPIP_CORE_LOCKING */ + + sock_set_errno(sock, err); + done_socket(sock); + return err ? -1 : 0; +} + +#if !LWIP_TCPIP_CORE_LOCKING +/** lwip_setsockopt_callback: only used without CORE_LOCKING + * to get into the tcpip_thread + */ +static void +lwip_setsockopt_callback(void *arg) +{ + struct lwip_setgetsockopt_data *data; + LWIP_ASSERT("arg != NULL", arg != NULL); + data = (struct lwip_setgetsockopt_data *)arg; + + data->err = lwip_setsockopt_impl(data->s, data->level, data->optname, +#if LWIP_MPU_COMPATIBLE + data->optval, +#else /* LWIP_MPU_COMPATIBLE */ + data->optval.pc, +#endif /* LWIP_MPU_COMPATIBLE */ + data->optlen); + + sys_sem_signal((sys_sem_t *)(data->completed_sem)); +} +#endif /* LWIP_TCPIP_CORE_LOCKING */ + +/** lwip_setsockopt_impl: the actual implementation of setsockopt: + * same argument as lwip_setsockopt, either called directly or through callback + */ +static int +lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen) +{ + int err = 0; + struct lwip_sock *sock = tryget_socket(s); + if (!sock) { + return EBADF; + } + +#ifdef LWIP_HOOK_SOCKETS_SETSOCKOPT + if (LWIP_HOOK_SOCKETS_SETSOCKOPT(s, sock, level, optname, optval, optlen, &err)) { + return err; + } +#endif + + switch (level) { + + /* Level: SOL_SOCKET */ + case SOL_SOCKET: + switch (optname) { + + /* SO_ACCEPTCONN is get-only */ + + /* The option flags */ + case SO_BROADCAST: + case SO_KEEPALIVE: +#if SO_REUSE + case SO_REUSEADDR: +#endif /* SO_REUSE */ + if ((optname == SO_BROADCAST) && + (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_UDP)) { + done_socket(sock); + return ENOPROTOOPT; + } + + optname = lwip_sockopt_to_ipopt(optname); + + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + if (*(const int *)optval) { + ip_set_option(sock->conn->pcb.ip, optname); + } else { + ip_reset_option(sock->conn->pcb.ip, optname); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", + s, optname, (*(const int *)optval ? "on" : "off"))); + break; + + /* SO_TYPE is get-only */ + /* SO_ERROR is get-only */ + +#if LWIP_SO_SNDTIMEO + case SO_SNDTIMEO: { + long ms_long; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + ms_long = LWIP_SO_SNDRCVTIMEO_GET_MS(optval); + if (ms_long < 0) { + done_socket(sock); + return EINVAL; + } + netconn_set_sendtimeout(sock->conn, ms_long); + break; + } +#endif /* LWIP_SO_SNDTIMEO */ +#if LWIP_SO_RCVTIMEO + case SO_RCVTIMEO: { + long ms_long; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); + ms_long = LWIP_SO_SNDRCVTIMEO_GET_MS(optval); + if (ms_long < 0) { + done_socket(sock); + return EINVAL; + } + netconn_set_recvtimeout(sock->conn, (u32_t)ms_long); + break; + } +#endif /* LWIP_SO_RCVTIMEO */ +#if LWIP_SO_RCVBUF + case SO_RCVBUF: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, int); + netconn_set_recvbufsize(sock->conn, *(const int *)optval); + break; +#endif /* LWIP_SO_RCVBUF */ +#if LWIP_SO_LINGER + case SO_LINGER: { + const struct linger *linger = (const struct linger *)optval; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct linger); + if (linger->l_onoff) { + int lingersec = linger->l_linger; + if (lingersec < 0) { + done_socket(sock); + return EINVAL; + } + if (lingersec > 0xFFFF) { + lingersec = 0xFFFF; + } + sock->conn->linger = (s16_t)lingersec; + } else { + sock->conn->linger = -1; + } + } + break; +#endif /* LWIP_SO_LINGER */ +#if LWIP_UDP + case SO_NO_CHECK: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP); +#if LWIP_UDPLITE + if (udp_is_flag_set(sock->conn->pcb.udp, UDP_FLAGS_UDPLITE)) { + /* this flag is only available for UDP, not for UDP lite */ + done_socket(sock); + return EAFNOSUPPORT; + } +#endif /* LWIP_UDPLITE */ + if (*(const int *)optval) { + udp_set_flags(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + } else { + udp_clear_flags(sock->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); + } + break; +#endif /* LWIP_UDP */ + case SO_BINDTODEVICE: { + const struct ifreq *iface; + struct netif *n = NULL; + + LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct ifreq); + + iface = (const struct ifreq *)optval; + if (iface->ifr_name[0] != 0) { + n = netif_find(iface->ifr_name); + if (n == NULL) { + done_socket(sock); + return ENODEV; + } + } + + switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) { +#if LWIP_TCP + case NETCONN_TCP: + tcp_bind_netif(sock->conn->pcb.tcp, n); + break; +#endif +#if LWIP_UDP + case NETCONN_UDP: + udp_bind_netif(sock->conn->pcb.udp, n); + break; +#endif +#if LWIP_RAW + case NETCONN_RAW: + raw_bind_netif(sock->conn->pcb.raw, n); + break; +#endif + default: + LWIP_ASSERT("Unhandled netconn type in SO_BINDTODEVICE", 0); + break; + } + } + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + + /* Level: IPPROTO_IP */ + case IPPROTO_IP: + switch (optname) { + case IP_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + sock->conn->pcb.ip->ttl = (u8_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", + s, sock->conn->pcb.ip->ttl)); + break; + case IP_TOS: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + sock->conn->pcb.ip->tos = (u8_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", + s, sock->conn->pcb.ip->tos)); + break; +#if LWIP_NETBUF_RECVINFO + case IP_PKTINFO: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP); + if (*(const int *)optval) { + sock->conn->flags |= NETCONN_FLAG_PKTINFO; + } else { + sock->conn->flags &= ~NETCONN_FLAG_PKTINFO; + } + break; +#endif /* LWIP_NETBUF_RECVINFO */ +#if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP + case IP_MULTICAST_TTL: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); + udp_set_multicast_ttl(sock->conn->pcb.udp, (u8_t)(*(const u8_t *)optval)); + break; + case IP_MULTICAST_IF: { + ip4_addr_t if_addr; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct in_addr, NETCONN_UDP); + inet_addr_to_ip4addr(&if_addr, (const struct in_addr *)optval); + udp_set_multicast_netif_addr(sock->conn->pcb.udp, &if_addr); + } + break; + case IP_MULTICAST_LOOP: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); + if (*(const u8_t *)optval) { + udp_set_flags(sock->conn->pcb.udp, UDP_FLAGS_MULTICAST_LOOP); + } else { + udp_clear_flags(sock->conn->pcb.udp, UDP_FLAGS_MULTICAST_LOOP); + } + break; +#endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */ +#if LWIP_IGMP + case IP_ADD_MEMBERSHIP: + case IP_DROP_MEMBERSHIP: { + /* If this is a TCP or a RAW socket, ignore these options. */ + err_t igmp_err; + const struct ip_mreq *imr = (const struct ip_mreq *)optval; + ip4_addr_t if_addr; + ip4_addr_t multi_addr; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ip_mreq, NETCONN_UDP); + inet_addr_to_ip4addr(&if_addr, &imr->imr_interface); + inet_addr_to_ip4addr(&multi_addr, &imr->imr_multiaddr); + if (optname == IP_ADD_MEMBERSHIP) { + if (!lwip_socket_register_membership(s, &if_addr, &multi_addr)) { + /* cannot track membership (out of memory) */ + err = ENOMEM; + igmp_err = ERR_OK; + } else { + igmp_err = igmp_joingroup(&if_addr, &multi_addr); + } + } else { + igmp_err = igmp_leavegroup(&if_addr, &multi_addr); + lwip_socket_unregister_membership(s, &if_addr, &multi_addr); + } + if (igmp_err != ERR_OK) { + err = EADDRNOTAVAIL; + } + } + break; +#endif /* LWIP_IGMP */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + +#if LWIP_TCP + /* Level: IPPROTO_TCP */ + case IPPROTO_TCP: + /* Special case: all IPPROTO_TCP option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP); + if (sock->conn->pcb.tcp->state == LISTEN) { + done_socket(sock); + return EINVAL; + } + switch (optname) { + case TCP_NODELAY: + if (*(const int *)optval) { + tcp_nagle_disable(sock->conn->pcb.tcp); + } else { + tcp_nagle_enable(sock->conn->pcb.tcp); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", + s, (*(const int *)optval) ? "on" : "off") ); + break; + case TCP_KEEPALIVE: + sock->conn->pcb.tcp->keep_idle = (u32_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + +#if LWIP_TCP_KEEPALIVE + case TCP_KEEPIDLE: + sock->conn->pcb.tcp->keep_idle = 1000 * (u32_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_idle)); + break; + case TCP_KEEPINTVL: + sock->conn->pcb.tcp->keep_intvl = 1000 * (u32_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_intvl)); + break; + case TCP_KEEPCNT: + sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(const int *)optval); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", + s, sock->conn->pcb.tcp->keep_cnt)); + break; +#endif /* LWIP_TCP_KEEPALIVE */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_TCP*/ + +#if LWIP_IPV6 + /* Level: IPPROTO_IPV6 */ + case IPPROTO_IPV6: + switch (optname) { + case IPV6_V6ONLY: + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + if (*(const int *)optval) { + netconn_set_ipv6only(sock->conn, 1); + } else { + netconn_set_ipv6only(sock->conn, 0); + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n", + s, (netconn_get_ipv6only(sock->conn) ? 1 : 0))); + break; +#if LWIP_IPV6_MLD + case IPV6_JOIN_GROUP: + case IPV6_LEAVE_GROUP: { + /* If this is a TCP or a RAW socket, ignore these options. */ + err_t mld6_err; + struct netif *netif; + ip6_addr_t multi_addr; + const struct ipv6_mreq *imr = (const struct ipv6_mreq *)optval; + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ipv6_mreq, NETCONN_UDP); + inet6_addr_to_ip6addr(&multi_addr, &imr->ipv6mr_multiaddr); + LWIP_ASSERT("Invalid netif index", imr->ipv6mr_interface <= 0xFFu); + netif = netif_get_by_index((u8_t)imr->ipv6mr_interface); + if (netif == NULL) { + err = EADDRNOTAVAIL; + break; + } + + if (optname == IPV6_JOIN_GROUP) { + if (!lwip_socket_register_mld6_membership(s, imr->ipv6mr_interface, &multi_addr)) { + /* cannot track membership (out of memory) */ + err = ENOMEM; + mld6_err = ERR_OK; + } else { + mld6_err = mld6_joingroup_netif(netif, &multi_addr); + } + } else { + mld6_err = mld6_leavegroup_netif(netif, &multi_addr); + lwip_socket_unregister_mld6_membership(s, imr->ipv6mr_interface, &multi_addr); + } + if (mld6_err != ERR_OK) { + err = EADDRNOTAVAIL; + } + } + break; +#endif /* LWIP_IPV6_MLD */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_IPV6 */ + +#if LWIP_UDP && LWIP_UDPLITE + /* Level: IPPROTO_UDPLITE */ + case IPPROTO_UDPLITE: + /* Special case: all IPPROTO_UDPLITE option take an int */ + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); + /* If this is no UDP lite socket, ignore any options. */ + if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { + done_socket(sock); + return ENOPROTOOPT; + } + switch (optname) { + case UDPLITE_SEND_CSCOV: + if ((*(const int *)optval != 0) && ((*(const int *)optval < 8) || (*(const int *)optval > 0xffff))) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_tx = 8; + } else { + sock->conn->pcb.udp->chksum_len_tx = (u16_t) * (const int *)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", + s, (*(const int *)optval)) ); + break; + case UDPLITE_RECV_CSCOV: + if ((*(const int *)optval != 0) && ((*(const int *)optval < 8) || (*(const int *)optval > 0xffff))) { + /* don't allow illegal values! */ + sock->conn->pcb.udp->chksum_len_rx = 8; + } else { + sock->conn->pcb.udp->chksum_len_rx = (u16_t) * (const int *)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", + s, (*(const int *)optval)) ); + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; +#endif /* LWIP_UDP */ + /* Level: IPPROTO_RAW */ + case IPPROTO_RAW: + switch (optname) { +#if LWIP_IPV6 && LWIP_RAW + case IPV6_CHECKSUM: + /* It should not be possible to disable the checksum generation with ICMPv6 + * as per RFC 3542 chapter 3.1 */ + if (sock->conn->pcb.raw->protocol == IPPROTO_ICMPV6) { + done_socket(sock); + return EINVAL; + } + + LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_RAW); + if (*(const int *)optval < 0) { + sock->conn->pcb.raw->chksum_reqd = 0; + } else if (*(const int *)optval & 1) { + /* Per RFC3542, odd offsets are not allowed */ + done_socket(sock); + return EINVAL; + } else { + sock->conn->pcb.raw->chksum_reqd = 1; + sock->conn->pcb.raw->chksum_offset = (u16_t) * (const int *)optval; + } + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM, ..) -> %d\n", + s, sock->conn->pcb.raw->chksum_reqd)); + break; +#endif /* LWIP_IPV6 && LWIP_RAW */ + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", + s, optname)); + err = ENOPROTOOPT; + break; + } /* switch (optname) */ + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", + s, level, optname)); + err = ENOPROTOOPT; + break; + } /* switch (level) */ + + done_socket(sock); + return err; +} + +int +lwip_ioctl(int s, long cmd, void *argp) +{ + struct lwip_sock *sock = get_socket(s); + u8_t val; +#if LWIP_SO_RCVBUF + int recv_avail; +#endif /* LWIP_SO_RCVBUF */ + + if (!sock) { + return -1; + } + + switch (cmd) { +#if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE + case FIONREAD: + if (!argp) { + sock_set_errno(sock, EINVAL); + done_socket(sock); + return -1; + } +#if LWIP_FIONREAD_LINUXMODE + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { + struct netbuf *nb; + if (sock->lastdata.netbuf) { + nb = sock->lastdata.netbuf; + *((int *)argp) = nb->p->tot_len; + } else { + struct netbuf *rxbuf; + err_t err = netconn_recv_udp_raw_netbuf_flags(sock->conn, &rxbuf, NETCONN_DONTBLOCK); + if (err != ERR_OK) { + *((int *)argp) = 0; + } else { + sock->lastdata.netbuf = rxbuf; + *((int *)argp) = rxbuf->p->tot_len; + } + } + done_socket(sock); + return 0; + } +#endif /* LWIP_FIONREAD_LINUXMODE */ + +#if LWIP_SO_RCVBUF + /* we come here if either LWIP_FIONREAD_LINUXMODE==0 or this is a TCP socket */ + SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); + if (recv_avail < 0) { + recv_avail = 0; + } + + /* Check if there is data left from the last recv operation. /maq 041215 */ + if (sock->lastdata.netbuf) { + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { + recv_avail += sock->lastdata.pbuf->tot_len; + } else { + recv_avail += sock->lastdata.netbuf->p->tot_len; + } + } + *((int *)argp) = recv_avail; + + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t *)argp))); + sock_set_errno(sock, 0); + done_socket(sock); + return 0; +#else /* LWIP_SO_RCVBUF */ + break; +#endif /* LWIP_SO_RCVBUF */ +#endif /* LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE */ + + case (long)FIONBIO: + val = 0; + if (argp && *(int *)argp) { + val = 1; + } + netconn_set_nonblocking(sock->conn, val); + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val)); + sock_set_errno(sock, 0); + done_socket(sock); + return 0; + + default: + // IOCTL_CMD_CASE_HANDLER(); + break; + } /* switch (cmd) */ + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); + sock_set_errno(sock, ENOSYS); /* not yet implemented */ + done_socket(sock); + return -1; +} + +/** A minimal implementation of fcntl. + * Currently only the commands F_GETFL and F_SETFL are implemented. + * The flag O_NONBLOCK and access modes are supported for F_GETFL, only + * the flag O_NONBLOCK is implemented for F_SETFL. + */ +int +lwip_fcntl(int s, int cmd, int val) +{ + struct lwip_sock *sock = get_socket(s); + int ret = -1; + int op_mode = 0; + + if (!sock) { + return -1; + } + + switch (cmd) { + case F_GETFL: + ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0; + sock_set_errno(sock, 0); + + if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { +#if LWIP_TCPIP_CORE_LOCKING + LOCK_TCPIP_CORE(); +#else + SYS_ARCH_DECL_PROTECT(lev); + /* the proper thing to do here would be to get into the tcpip_thread, + but locking should be OK as well since we only *read* some flags */ + SYS_ARCH_PROTECT(lev); +#endif +#if LWIP_TCP + if (sock->conn->pcb.tcp) { + if (!(sock->conn->pcb.tcp->flags & TF_RXCLOSED)) { + op_mode |= O_RDONLY; + } + if (!(sock->conn->pcb.tcp->flags & TF_FIN)) { + op_mode |= O_WRONLY; + } + } +#endif +#if LWIP_TCPIP_CORE_LOCKING + UNLOCK_TCPIP_CORE(); +#else + SYS_ARCH_UNPROTECT(lev); +#endif + } else { + op_mode |= O_RDWR; + } + + /* ensure O_RDWR for (O_RDONLY|O_WRONLY) != O_RDWR cases */ + ret |= (op_mode == (O_RDONLY | O_WRONLY)) ? O_RDWR : op_mode; + + break; + case F_SETFL: + /* Bits corresponding to the file access mode and the file creation flags [..] that are set in arg shall be ignored */ + val &= ~(O_RDONLY | O_WRONLY | O_RDWR); + if ((val & ~O_NONBLOCK) == 0) { + /* only O_NONBLOCK, all other bits are zero */ + netconn_set_nonblocking(sock->conn, val & O_NONBLOCK); + ret = 0; + sock_set_errno(sock, 0); + } else { + sock_set_errno(sock, ENOSYS); /* not yet implemented */ + } + break; + default: + LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); + sock_set_errno(sock, ENOSYS); /* not yet implemented */ + break; + } + done_socket(sock); + return ret; +} + +#if LWIP_COMPAT_SOCKETS == 2 && LWIP_POSIX_SOCKETS_IO_NAMES +int +fcntl(int s, int cmd, ...) +{ + va_list ap; + int val; + + va_start(ap, cmd); + val = va_arg(ap, int); + va_end(ap); + return lwip_fcntl(s, cmd, val); +} +#endif + +const char * +lwip_inet_ntop(int af, const void *src, char *dst, socklen_t size) +{ + const char *ret = NULL; + int size_int = (int)size; + if (size_int < 0) { + set_errno(ENOSPC); + return NULL; + } + switch (af) { +#if LWIP_IPV4 + case AF_INET: + ret = ip4addr_ntoa_r((const ip4_addr_t *)src, dst, size_int); + if (ret == NULL) { + set_errno(ENOSPC); + } + break; +#endif +#if LWIP_IPV6 + case AF_INET6: + ret = ip6addr_ntoa_r((const ip6_addr_t *)src, dst, size_int); + if (ret == NULL) { + set_errno(ENOSPC); + } + break; +#endif + default: + set_errno(EAFNOSUPPORT); + break; + } + return ret; +} + +int +lwip_inet_pton(int af, const char *src, void *dst) +{ + int err; + switch (af) { +#if LWIP_IPV4 + case AF_INET: + err = ip4addr_aton(src, (ip4_addr_t *)dst); + break; +#endif +#if LWIP_IPV6 + case AF_INET6: { + /* convert into temporary variable since ip6_addr_t might be larger + than in6_addr when scopes are enabled */ + ip6_addr_t addr; + err = ip6addr_aton(src, &addr); + if (err) { + memcpy(dst, &addr.addr, sizeof(addr.addr)); + } + break; + } +#endif + default: + err = -1; + set_errno(EAFNOSUPPORT); + break; + } + return err; +} + +#if LWIP_IGMP +/** Register a new IGMP membership. On socket close, the membership is dropped automatically. + * + * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). + * + * @return 1 on success, 0 on failure + */ +static int +lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) +{ + struct lwip_sock *sock = get_socket(s); + int i; + + if (!sock) { + return 0; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if (socket_ipv4_multicast_memberships[i].sock == NULL) { + socket_ipv4_multicast_memberships[i].sock = sock; + ip4_addr_copy(socket_ipv4_multicast_memberships[i].if_addr, *if_addr); + ip4_addr_copy(socket_ipv4_multicast_memberships[i].multi_addr, *multi_addr); + done_socket(sock); + return 1; + } + } + done_socket(sock); + return 0; +} + +/** Unregister a previously registered membership. This prevents dropping the membership + * on socket close. + * + * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). + */ +static void +lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) +{ + struct lwip_sock *sock = get_socket(s); + int i; + + if (!sock) { + return; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if ((socket_ipv4_multicast_memberships[i].sock == sock) && + ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].if_addr, if_addr) && + ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].multi_addr, multi_addr)) { + socket_ipv4_multicast_memberships[i].sock = NULL; + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); + break; + } + } + done_socket(sock); +} + +/** Drop all memberships of a socket that were not dropped explicitly via setsockopt. + * + * ATTENTION: this function is NOT called from tcpip_thread (or under CORE_LOCK). + */ +static void +lwip_socket_drop_registered_memberships(int s) +{ + struct lwip_sock *sock = get_socket(s); + int i; + + if (!sock) { + return; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if (socket_ipv4_multicast_memberships[i].sock == sock) { + ip_addr_t multi_addr, if_addr; + ip_addr_copy_from_ip4(multi_addr, socket_ipv4_multicast_memberships[i].multi_addr); + ip_addr_copy_from_ip4(if_addr, socket_ipv4_multicast_memberships[i].if_addr); + socket_ipv4_multicast_memberships[i].sock = NULL; + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); + ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); + + netconn_join_leave_group(sock->conn, &multi_addr, &if_addr, NETCONN_LEAVE); + } + } + done_socket(sock); +} +#endif /* LWIP_IGMP */ + +#if LWIP_IPV6_MLD +/** Register a new MLD6 membership. On socket close, the membership is dropped automatically. + * + * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). + * + * @return 1 on success, 0 on failure + */ +static int +lwip_socket_register_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr) +{ + struct lwip_sock *sock = get_socket(s); + int i; + + if (!sock) { + return 0; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if (socket_ipv6_multicast_memberships[i].sock == NULL) { + socket_ipv6_multicast_memberships[i].sock = sock; + socket_ipv6_multicast_memberships[i].if_idx = (u8_t)if_idx; + ip6_addr_copy(socket_ipv6_multicast_memberships[i].multi_addr, *multi_addr); + done_socket(sock); + return 1; + } + } + done_socket(sock); + return 0; +} + +/** Unregister a previously registered MLD6 membership. This prevents dropping the membership + * on socket close. + * + * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). + */ +static void +lwip_socket_unregister_mld6_membership(int s, unsigned int if_idx, const ip6_addr_t *multi_addr) +{ + struct lwip_sock *sock = get_socket(s); + int i; + + if (!sock) { + return; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if ((socket_ipv6_multicast_memberships[i].sock == sock) && + (socket_ipv6_multicast_memberships[i].if_idx == if_idx) && + ip6_addr_cmp(&socket_ipv6_multicast_memberships[i].multi_addr, multi_addr)) { + socket_ipv6_multicast_memberships[i].sock = NULL; + socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX; + ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr); + break; + } + } + done_socket(sock); +} + +/** Drop all MLD6 memberships of a socket that were not dropped explicitly via setsockopt. + * + * ATTENTION: this function is NOT called from tcpip_thread (or under CORE_LOCK). + */ +static void +lwip_socket_drop_registered_mld6_memberships(int s) +{ + struct lwip_sock *sock = get_socket(s); + int i; + + if (!sock) { + return; + } + + for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { + if (socket_ipv6_multicast_memberships[i].sock == sock) { + ip_addr_t multi_addr; + u8_t if_idx; + + ip_addr_copy_from_ip6(multi_addr, socket_ipv6_multicast_memberships[i].multi_addr); + if_idx = socket_ipv6_multicast_memberships[i].if_idx; + + socket_ipv6_multicast_memberships[i].sock = NULL; + socket_ipv6_multicast_memberships[i].if_idx = NETIF_NO_INDEX; + ip6_addr_set_zero(&socket_ipv6_multicast_memberships[i].multi_addr); + + netconn_join_leave_group_netif(sock->conn, &multi_addr, if_idx, NETCONN_LEAVE); + } + } + done_socket(sock); +} +#endif /* LWIP_IPV6_MLD */ + +#endif /* LWIP_SOCKET */ diff --git a/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/sys_arch.c b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/sys_arch.c new file mode 100755 index 0000000..95006e2 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/lwip_intf_v2_1/lwip-2.1.2/port/sys_arch.c @@ -0,0 +1,502 @@ +/* + * Copyright (c) 2001-2003 Swedish Institute of Computer Science. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT + * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + * + * This file is part of the lwIP TCP/IP stack. + * + * Author: Adam Dunkels + * + */ + +/* lwIP includes. */ +#include "lwip/debug.h" +#include "lwip/def.h" +#include "lwip/sys.h" +#include "lwip/mem.h" +#include "lwip/stats.h" +#include "sys_rtos.h" +#include "lwip/timeouts.h" +#include +#include + +#define CFG_ENABLE_LWIP_MUTEX 1 + +#if CFG_ENABLE_LWIP_MUTEX +static sys_mutex_t sys_arch_mutex; +#endif + +/*-----------------------------------------------------------------------------------*/ +err_t sys_mbox_new(sys_mbox_t *mbox, int size) +{ + bk_err_t ret; + + if (size > 0) + ret = rtos_init_queue(mbox, NULL, sizeof( void * ), size); + else + ret = rtos_init_queue(mbox, NULL, sizeof( void * ), archMESG_QUEUE_LENGTH); + +#if SYS_STATS + ++lwip_stats.sys.mbox.used; + if (lwip_stats.sys.mbox.max < lwip_stats.sys.mbox.used) { + lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used; + } +#endif /* SYS_STATS */ + + if (kNoErr != ret) + return ERR_MEM; + + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Deallocates a mailbox. If there are messages still present in the + mailbox when the mailbox is deallocated, it is an indication of a + programming error in lwIP and the developer should be notified. +*/ +void sys_mbox_free(sys_mbox_t *mbox) +{ + rtos_deinit_queue(mbox); + +#if SYS_STATS + --lwip_stats.sys.mbox.used; +#endif /* SYS_STATS */ +} + +/*-----------------------------------------------------------------------------------*/ +// Posts the "msg" to the mailbox. +void sys_mbox_post(sys_mbox_t *mbox, void *data) +{ + bk_err_t ret; + + ret = rtos_push_to_queue(mbox, &data, BEKEN_WAIT_FOREVER); + if (ret != kNoErr) { + LWIP_DEBUGF(SYS_DEBUG, ("%s: sys_mbox_post error %u\n", __FUNCTION__, ret)); + } +} + + +/*-----------------------------------------------------------------------------------*/ +// Try to post the "msg" to the mailbox. +err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) +{ + err_t result; + bk_err_t ret; + + ret = rtos_push_to_queue(mbox, &msg, 0); + if (kNoErr == ret) + { + result = ERR_OK; + } + else + { + // could not post, queue must be full + result = ERR_MEM; + +#if SYS_STATS + lwip_stats.sys.mbox.err++; +#endif /* SYS_STATS */ + + } + + return result; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread until a message arrives in the mailbox, but does + not block the thread longer than "timeout" milliseconds (similar to + the sys_arch_sem_wait() function). The "msg" argument is a result + parameter that is set by the function (i.e., by doing "*msg = + ptr"). The "msg" parameter maybe NULL to indicate that the message + should be dropped. + + The return values are the same as for the sys_arch_sem_wait() function: + Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a + timeout. + + Note that a function with a similar name, sys_mbox_fetch(), is + implemented by lwIP. +*/ +u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) +{ + void *dummyptr; + beken_time_t StartTime, EndTime, Elapsed; + + beken_time_get_time(&StartTime); + + if ( NULL == msg ) + { + msg = &dummyptr; + } + + if ( timeout != 0 ) + { + if ( kNoErr == rtos_pop_from_queue(mbox, &(*msg), timeout) ) + { + beken_time_get_time(&EndTime); + Elapsed = (EndTime - StartTime) * 1; + + return ( Elapsed ); + } + else // timed out blocking for message + { + *msg = NULL; + + return SYS_ARCH_TIMEOUT; + } + } + else // block forever for a message. + { + rtos_pop_from_queue(mbox, &(*msg), BEKEN_WAIT_FOREVER); + beken_time_get_time(&EndTime); + Elapsed = (EndTime - StartTime) * 1; + + return ( Elapsed ); // return time blocked TODO test + } +} + +/*-----------------------------------------------------------------------------------*/ +/* + Similar to sys_arch_mbox_fetch, but if message is not ready immediately, we'll + return with SYS_MBOX_EMPTY. On success, 0 is returned. +*/ +u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) +{ +void *dummyptr; + + if ( msg == NULL ) + { + msg = &dummyptr; + } + + if ( kNoErr == rtos_pop_from_queue(mbox, &(*msg), 0) ) + { + return ERR_OK; + } + else + { + return SYS_MBOX_EMPTY; + } +} +/*----------------------------------------------------------------------------------*/ +int sys_mbox_valid(sys_mbox_t *mbox) +{ + if (*mbox == SYS_MBOX_NULL) + return 0; + else + return 1; +} +/*-----------------------------------------------------------------------------------*/ +void sys_mbox_set_invalid(sys_mbox_t *mbox) +{ + *mbox = SYS_MBOX_NULL; +} + +/*-----------------------------------------------------------------------------------*/ +// Creates a new semaphore. The "count" argument specifies +// the initial state of the semaphore. +err_t sys_sem_new(sys_sem_t *sem, u8_t count) +{ + bk_err_t ret; + + ret = rtos_init_semaphore_adv(sem, 0xff, count); + if(kNoErr != ret) + return ERR_ARG; + +#if SYS_STATS + ++lwip_stats.sys.sem.used; + if (lwip_stats.sys.sem.max < lwip_stats.sys.sem.used) { + lwip_stats.sys.sem.max = lwip_stats.sys.sem.used; + } +#endif /* SYS_STATS */ + + return ERR_OK; +} + +/*-----------------------------------------------------------------------------------*/ +/* + Blocks the thread while waiting for the semaphore to be + signaled. If the "timeout" argument is non-zero, the thread should + only be blocked for the specified time (measured in + milliseconds). + + If the timeout argument is non-zero, the return value is the number of + milliseconds spent waiting for the semaphore to be signaled. If the + semaphore wasn't signaled within the specified time, the return value is + SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore + (i.e., it was already signaled), the function may return zero. + + Notice that lwIP implements a function with a similar name, + sys_sem_wait(), that uses the sys_arch_sem_wait() function. +*/ +u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) +{ + bk_err_t ret; + beken_time_t StartTime, EndTime, Elapsed; + + beken_time_get_time(&StartTime); + + if( timeout != 0) + { + ret = rtos_get_semaphore(sem, timeout); + if( kNoErr == ret ) + { + beken_time_get_time(&EndTime); + Elapsed = (EndTime - StartTime) * 1; + + return (Elapsed); // return time blocked TODO test + } + else + { + return SYS_ARCH_TIMEOUT; + } + } + else // must block without a timeout + { + ret = rtos_get_semaphore(sem, BEKEN_WAIT_FOREVER); + if( kNoErr != ret ) + return SYS_ARCH_TIMEOUT; + + beken_time_get_time(&EndTime); + Elapsed = (EndTime - StartTime) * 1; + + return ( Elapsed ); // return time blocked + } +} + +/*-----------------------------------------------------------------------------------*/ +// Signals a semaphore +void sys_sem_signal(sys_sem_t *sem) +{ + rtos_set_semaphore(sem); +} + +/*-----------------------------------------------------------------------------------*/ +// Deallocates a semaphore +void sys_sem_free(sys_sem_t *sem) +{ +#if SYS_STATS + --lwip_stats.sys.sem.used; +#endif /* SYS_STATS */ + + rtos_deinit_semaphore(sem); +} +/*-----------------------------------------------------------------------------------*/ +int sys_sem_valid(sys_sem_t *sem) +{ + if (*sem == SYS_SEM_NULL) + return 0; + else + return 1; +} + +/*-----------------------------------------------------------------------------------*/ +void sys_sem_set_invalid(sys_sem_t *sem) +{ + *sem = SYS_SEM_NULL; +} + +/*-----------------------------------------------------------------------------------*/ +err_t sys_mutex_trylock(sys_mutex_t *pxMutex) +{ + bk_err_t ret; + + ret = rtos_trylock_mutex(pxMutex); + if (kNoErr == ret) + return 0; + else + return -1; +} + +/*-----------------------------------------------------------------------------------*/ +// Initialize sys arch +void sys_init(void) +{ +#if CFG_ENABLE_LWIP_MUTEX + sys_mutex_new(&sys_arch_mutex); +#endif +} + +/*-----------------------------------------------------------------------------------*/ + /* Mutexes*/ +/*-----------------------------------------------------------------------------------*/ +err_t sys_mutex_new(sys_mutex_t *mutex) +{ + bk_err_t ret; + + ret = rtos_init_mutex(mutex); + if(kNoErr != ret) + return ERR_VAL; + +#if SYS_STATS + ++lwip_stats.sys.mutex.used; + if (lwip_stats.sys.mutex.max < lwip_stats.sys.mutex.used) { + lwip_stats.sys.mutex.max = lwip_stats.sys.mutex.used; + } +#endif /* SYS_STATS */ + + return ERR_OK; +} +/*-----------------------------------------------------------------------------------*/ +/* Deallocate a mutex*/ +void sys_mutex_free(sys_mutex_t *mutex) +{ +#if SYS_STATS + --lwip_stats.sys.mutex.used; +#endif /* SYS_STATS */ + + rtos_deinit_mutex(mutex); +} + +void sys_mutex_lock(sys_mutex_t *mutex) +{ + rtos_lock_mutex(mutex); +} + +void sys_mutex_unlock(sys_mutex_t *mutex) +{ + rtos_unlock_mutex(mutex); +} + +/*-----------------------------------------------------------------------------------*/ +// TODO +/*-----------------------------------------------------------------------------------*/ +/* + Starts a new thread with priority "prio" that will begin its execution in the + function "thread()". The "arg" argument will be passed as an argument to the + thread() function. The id of the new thread is returned. Both the id and + the priority are system dependent. +*/ +sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread , void *arg, int stacksize, int prio) +{ + sys_thread_t CreatedTask; + bk_err_t result; + + result = rtos_create_thread(&CreatedTask, prio, name, thread, stacksize * sizeof(uint32_t), arg); + if(result == kNoErr) + { + return CreatedTask; + } + else + { + return NULL; + } +} + +int sys_thread_delete(sys_thread_t pid) +{ + bk_err_t ret; + + ret = rtos_delete_thread(&pid); + if(kNoErr == ret) + { + return ERR_OK; + } + else + { + return ERR_ARG; + } +} + +/* + This optional function does a "fast" critical region protection and returns + the previous protection level. This function is only called during very short + critical regions. An embedded system which supports ISR-based drivers might + want to implement this function by disabling interrupts. Task-based systems + might want to implement this by using a mutex or disabling tasking. This + function should support recursive calls from the same task or interrupt. In + other words, sys_arch_protect() could be called while already protected. In + that case the return value indicates that it is already protected. + + sys_arch_protect() is only required if your port is supporting an operating + system. +*/ +sys_prot_t sys_arch_protect(void) +{ +#if CFG_ENABLE_LWIP_MUTEX + sys_mutex_lock(&sys_arch_mutex); + + return 0; +#else + return port_disable_interrupts_flag(); +#endif +} + +/* + This optional function does a "fast" set of critical region protection to the + value specified by pval. See the documentation for sys_arch_protect() for + more information. This function is only required if your port is supporting + an operating system. +*/ +void sys_arch_unprotect(sys_prot_t pval) +{ +#if CFG_ENABLE_LWIP_MUTEX + (void)pval; + sys_mutex_unlock(&sys_arch_mutex); +#else + port_enable_interrupts_flag(pval); +#endif +} + +/* + * Prints an assertion messages and aborts execution. + */ +void sys_assert( const char *msg ) +{ + (void) msg; + + /*FSL:only needed for debugging*/ + os_printf(msg); + os_printf("\n\r"); + + rtos_enter_critical(); + + for(;;) + ; +} + +u32_t sys_now(void) +{ + beken_time_t now_tick = 0; + + beken_time_get_time(&now_tick); + return now_tick * beken_ms_per_tick(); +} + +u32_t sys_jiffies(void) +{ + beken_time_t now_tick = 0; + + beken_time_get_time(&now_tick); + return now_tick; +} + +void sys_arch_msleep(int ms) +{ + rtos_delay_milliseconds(ms); +} + +// eof diff --git a/bk7235/liteos_m/components/mbedtls/BUILD.gn b/bk7235/liteos_m/third_party_adapter/mbedtls/BUILD.gn similarity index 99% rename from bk7235/liteos_m/components/mbedtls/BUILD.gn rename to bk7235/liteos_m/third_party_adapter/mbedtls/BUILD.gn index fbe5797..f74deef 100755 --- a/bk7235/liteos_m/components/mbedtls/BUILD.gn +++ b/bk7235/liteos_m/third_party_adapter/mbedtls/BUILD.gn @@ -47,4 +47,3 @@ ndk_lib("mbedtls_ndk") { deps = [ ":mbedtls" ] head_files = [ "include" ] } - diff --git a/bk7235/liteos_m/components/mbedtls/config/config_liteos_m.h b/bk7235/liteos_m/third_party_adapter/mbedtls/config/config_liteos_m.h similarity index 100% rename from bk7235/liteos_m/components/mbedtls/config/config_liteos_m.h rename to bk7235/liteos_m/third_party_adapter/mbedtls/config/config_liteos_m.h diff --git a/bk7235/liteos_m/third_party_adapter/mbedtls/library/tls_hardware.c b/bk7235/liteos_m/third_party_adapter/mbedtls/library/tls_hardware.c new file mode 100755 index 0000000..dd936b5 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/mbedtls/library/tls_hardware.c @@ -0,0 +1,58 @@ +/* +// Copyright (C) 2022 Beken Corporation + * 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. + */ +#if !defined(MBEDTLS_CONFIG_FILE) +#include "mbedtls/config.h" +#else +#include MBEDTLS_CONFIG_FILE +#endif + +#include +#include +#include + +#if defined(MBEDTLS_ENTROPY_HARDWARE_ALT) + +static int os_get_random(unsigned char *buf, size_t len) +{ + int i, j; + unsigned long tmp; + + for (i = 0; i < (((int)len + 3) & ~3) / 4; i++) { + tmp = rand(); + + for (j = 0; j < 4; j++) { + if ((i * 4 + j) < (int)len) { + buf[i * 4 + j] = (unsigned char)(tmp >> (j * 8)); + } else { + break; + } + } + } + + return 0; +} + +int mbedtls_hardware_poll( void *data, + unsigned char *output, size_t len, size_t *olen ) +{ + (void)data; + os_get_random(output, len); + *olen = len; + + return 0; +} +#endif + + diff --git a/bk7235/liteos_m/third_party_adapter/musl/BUILD.gn b/bk7235/liteos_m/third_party_adapter/musl/BUILD.gn new file mode 100755 index 0000000..89766af --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/musl/BUILD.gn @@ -0,0 +1,30 @@ +# Copyright (C) 2022 Beken Corporation +# 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. + +import("//kernel/liteos_m/liteos.gni") +import("//third_party/musl/porting/liteos_m/kernel/musl.gni") + +module_switch = defined(LOSCFG_LIBC_MUSL) +module_name = "musl_atapter" +kernel_module(module_name) { + sources = [ + "fs.c", + "qsort.c", + ] + include_dirs = [ "//commonlibrary/utils_lite/include" ] + deps = [ "//third_party/musl/porting/liteos_m/kernel" ] +} + +config("public") { + include_dirs = MUSL_INCLUDE_DIRS +} diff --git a/bk7235/liteos_m/third_party_adapter/musl/fs.c b/bk7235/liteos_m/third_party_adapter/musl/fs.c new file mode 100755 index 0000000..4b9ef75 --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/musl/fs.c @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. + * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, + * are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * 3. Neither the name of the copyright holder nor the names of its contributors may be used + * to endorse or promote products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#define _GNU_SOURCE + +#include "los_config.h" +#include +#include +#include +#include +#include +#include +#include + +#ifdef LOSCFG_LIBC_MUSL_FS +#include "los_fs.h" + +int mount(const char *source, const char *target, + const char *filesystemtype, unsigned long mountflags, + const void *data) +{ + return LOS_FsMount(source, target, filesystemtype, mountflags, data); +} + +int umount(const char *target) +{ + return LOS_FsUmount(target); +} + +int umount2(const char *target, int flag) +{ + return LOS_FsUmount2(target, flag); +} + +int open(const char *path, int oflag, ...) +{ + va_list vaList; + va_start(vaList, oflag); + int ret; + ret = LOS_Open(path, oflag, vaList); + va_end(vaList); + return ret; +} + +int close(int fd) +{ + return LOS_Close(fd); +} + +ssize_t read(int fd, void *buf, size_t nbyte) +{ + return LOS_Read(fd, buf, nbyte); +} + +ssize_t write(int fd, const void *buf, size_t nbyte) +{ + return LOS_Write(fd, buf, nbyte); +} + +off_t lseek(int fd, off_t offset, int whence) +{ + return LOS_Lseek(fd, offset, whence); +} + +int unlink(const char *path) +{ + return LOS_Unlink(path); +} + +int fstat(int fd, struct stat *buf) +{ + return LOS_Fstat(fd, buf); +} + +int stat(const char *path, struct stat *buf) +{ + return LOS_Stat(path, buf); +} + +int fsync(int fd) +{ + return LOS_Fsync(fd); +} + +int mkdir(const char *path, mode_t mode) +{ + return LOS_Mkdir(path, mode); +} + +DIR *opendir(const char *dirName) +{ + return LOS_Opendir(dirName); +} + +struct dirent *readdir(DIR *dir) +{ + return LOS_Readdir(dir); +} + +int closedir(DIR *dir) +{ + return LOS_Closedir(dir); +} + +int rmdir(const char *path) +{ + return LOS_Unlink(path); +} + +int rename(const char *oldName, const char *newName) +{ + return LOS_Rename(oldName, newName); +} + +int statfs(const char *path, struct statfs *buf) +{ + return LOS_Statfs(path, buf); +} + +int ftruncate(int fd, off_t length) +{ + return LOS_Ftruncate(fd, length); +} + +ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset) +{ + return LOS_Pread(fd, buf, nbyte, offset); +} + +ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset) +{ + return LOS_Pwrite(fd, buf, nbyte, offset); +} + +int access(const char *path, int mode) +{ + struct stat st; + + if (stat(path, &st) < 0) { + return -1; + } + if ((st.st_mode & S_IFDIR) || (st.st_mode & S_IFREG)) { + return 0; + } + if ((mode & W_OK) && !(st.st_mode & S_IWRITE)) { + return -1; + } + + return 0; +} + +int fcntl(int fd, int cmd, ...) +{ + int ret; + va_list vaList; + + va_start(vaList, cmd); + ret = OsFcntl(fd, cmd, vaList); + va_end(vaList); + return ret; +} + +int ioctl(int fd, int req, ...) +{ + int ret; + va_list vaList; + + va_start(vaList, req); + ret = OsIoctl(fd, req, vaList); + va_end(vaList); + return ret; +} + +#else /* #ifdef LOSCFG_FS_VFS */ + +int mount(const char *source, const char *target, + const char *filesystemtype, unsigned long mountflags, + const void *data) +{ + return -1; +} + +int umount(const char *target) +{ + return -1; +} + +int umount2(const char *target, int flag) +{ + return -1; +} + +int open(const char *path, int oflag, ...) +{ + return -1; +} + +int close(int fd) +{ + return -1; +} + +ssize_t read(int fd, void *buf, size_t nbyte) +{ + return -1; +} + +ssize_t write(int fd, const void *buf, size_t nbyte) +{ + return -1; +} + +off_t lseek(int fd, off_t offset, int whence) +{ + return -1; +} + +int unlink(const char *path) +{ + return -1; +} + +int fstat(int fd, struct stat *buf) +{ + return -1; +} + +int stat(const char *path, struct stat *buf) +{ + return -1; +} + +int fsync(int fd) +{ + return -1; +} + +int mkdir(const char *path, mode_t mode) +{ + return -1; +} + +DIR *opendir(const char *dirName) +{ + return NULL; +} + +struct dirent *readdir(DIR *dir) +{ + return NULL; +} + +int closedir(DIR *dir) +{ + return -1; +} + +int rmdir(const char *path) +{ + return -1; +} + +int rename(const char *oldName, const char *newName) +{ + return -1; +} + +int statfs(const char *path, struct statfs *buf) +{ + return -1; +} + +int ftruncate(int fd, off_t length) +{ + return -1; +} + +ssize_t pread(int fd, void *buf, size_t nbyte, off_t offset) +{ + return -1; +} + +ssize_t pwrite(int fd, const void *buf, size_t nbyte, off_t offset) +{ + return -1; +} + +int access(const char *path, int mode) +{ + return -1; +} + +int fcntl(int fd, int cmd, ...) +{ + return -1; +} + +int ioctl(int fd, int req, ...) +{ + return -1; +} +#endif diff --git a/bk7235/liteos_m/third_party_adapter/musl/qsort.c b/bk7235/liteos_m/third_party_adapter/musl/qsort.c new file mode 100755 index 0000000..1ae77bb --- /dev/null +++ b/bk7235/liteos_m/third_party_adapter/musl/qsort.c @@ -0,0 +1,261 @@ +/* Copyright (C) 2011 by Valentin Ochs + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* Minor changes by Rich Felker for integration in musl, 2011-04-27. */ + +/* Smoothsort, an adaptive variant of Heapsort. Memory usage: O(1). + Run time: Worst case O(n log n), close to O(n) in the mostly-sorted case. */ + +#include +#include +#include + +//#include "atomic.h" +#ifndef a_ctz_32 +#define a_ctz_32 a_ctz_32 +static inline int a_ctz_32(uint32_t x) +{ +#ifdef a_clz_32 + return 31-a_clz_32(x&-x); +#else + static const char debruijn32[32] = { + 0, 1, 23, 2, 29, 24, 19, 3, 30, 27, 25, 11, 20, 8, 4, 13, + 31, 22, 28, 18, 26, 10, 7, 12, 21, 17, 9, 6, 16, 5, 15, 14 + }; + return debruijn32[(x&-x)*0x076be629 >> 27]; +#endif +} +#endif + +#ifndef a_ctz_64 +#define a_ctz_64 a_ctz_64 +static inline int a_ctz_64(uint64_t x) +{ + static const char debruijn64[64] = { + 0, 1, 2, 53, 3, 7, 54, 27, 4, 38, 41, 8, 34, 55, 48, 28, + 62, 5, 39, 46, 44, 42, 22, 9, 24, 35, 59, 56, 49, 18, 29, 11, + 63, 52, 6, 26, 37, 40, 33, 47, 61, 45, 43, 21, 23, 58, 17, 10, + 51, 25, 36, 32, 60, 20, 57, 16, 50, 31, 19, 15, 30, 14, 13, 12 + }; + if (sizeof(long) < 8) { + uint32_t y = x; + if (!y) { + y = x>>32; + return 32 + a_ctz_32(y); + } + return a_ctz_32(y); + } + return debruijn64[(x&-x)*0x022fdd63cc95386dull >> 58]; +} +#endif + +static inline int a_ctz_l(unsigned long x) +{ + return (sizeof(long) < 8) ? a_ctz_32(x) : a_ctz_64(x); +} + +#define ntz(x) a_ctz_l((x)) + +typedef int (*cmpfun)(const void *, const void *); + +static inline int pntz(size_t p[2]) { + int r = ntz(p[0] - 1); + if(r != 0 || (r = 8*sizeof(size_t) + ntz(p[1])) != 8*sizeof(size_t)) { + return r; + } + return 0; +} + +static void cycle(size_t width, unsigned char* ar[], int n) +{ + unsigned char tmp[256]; + size_t l; + int i; + + if(n < 2) { + return; + } + + ar[n] = tmp; + while(width) { + l = sizeof(tmp) < width ? sizeof(tmp) : width; + memcpy(ar[n], ar[0], l); + for(i = 0; i < n; i++) { + memcpy(ar[i], ar[i + 1], l); + ar[i] += l; + } + width -= l; + } +} + +/* shl() and shr() need n > 0 */ +static inline void shl(size_t p[2], int n) +{ + if(n >= 8 * sizeof(size_t)) { + n -= 8 * sizeof(size_t); + p[1] = p[0]; + p[0] = 0; + } + p[1] <<= n; + p[1] |= p[0] >> (sizeof(size_t) * 8 - n); + p[0] <<= n; +} + +static inline void shr(size_t p[2], int n) +{ + if(n >= 8 * sizeof(size_t)) { + n -= 8 * sizeof(size_t); + p[0] = p[1]; + p[1] = 0; + } + p[0] >>= n; + p[0] |= p[1] << (sizeof(size_t) * 8 - n); + p[1] >>= n; +} + +static void sift(unsigned char *head, size_t width, cmpfun cmp, int pshift, size_t lp[]) +{ + unsigned char *rt, *lf; + unsigned char *ar[14 * sizeof(size_t) + 1]; + int i = 1; + + ar[0] = head; + while(pshift > 1) { + rt = head - width; + lf = head - width - lp[pshift - 2]; + + if((*cmp)(ar[0], lf) >= 0 && (*cmp)(ar[0], rt) >= 0) { + break; + } + if((*cmp)(lf, rt) >= 0) { + ar[i++] = lf; + head = lf; + pshift -= 1; + } else { + ar[i++] = rt; + head = rt; + pshift -= 2; + } + } + cycle(width, ar, i); +} + +static void trinkle(unsigned char *head, size_t width, cmpfun cmp, size_t pp[2], int pshift, int trusty, size_t lp[]) +{ + unsigned char *stepson, + *rt, *lf; + size_t p[2]; + unsigned char *ar[14 * sizeof(size_t) + 1]; + int i = 1; + int trail; + + p[0] = pp[0]; + p[1] = pp[1]; + + ar[0] = head; + while(p[0] != 1 || p[1] != 0) { + stepson = head - lp[pshift]; + if((*cmp)(stepson, ar[0]) <= 0) { + break; + } + if(!trusty && pshift > 1) { + rt = head - width; + lf = head - width - lp[pshift - 2]; + if((*cmp)(rt, stepson) >= 0 || (*cmp)(lf, stepson) >= 0) { + break; + } + } + + ar[i++] = stepson; + head = stepson; + trail = pntz(p); + shr(p, trail); + pshift += trail; + trusty = 0; + } + if(!trusty) { + cycle(width, ar, i); + sift(head, width, cmp, pshift, lp); + } +} + +void qsort(void *base, size_t nel, size_t width, cmpfun cmp) +{ + size_t lp[12*sizeof(size_t)]; + size_t i, size = width * nel; + unsigned char *head, *high; + size_t p[2] = {1, 0}; + int pshift = 1; + int trail; + + if (!size) return; + + head = base; + high = head + size - width; + + /* Precompute Leonardo numbers, scaled by element width */ + for(lp[0]=lp[1]=width, i=2; (lp[i]=lp[i-2]+lp[i-1]+width) < size; i++); + + while(head < high) { + if((p[0] & 3) == 3) { + sift(head, width, cmp, pshift, lp); + shr(p, 2); + pshift += 2; + } else { + if(lp[pshift - 1] >= high - head) { + trinkle(head, width, cmp, p, pshift, 0, lp); + } else { + sift(head, width, cmp, pshift, lp); + } + + if(pshift == 1) { + shl(p, 1); + pshift = 0; + } else { + shl(p, pshift - 1); + pshift = 1; + } + } + + p[0] |= 1; + head += width; + } + + trinkle(head, width, cmp, p, pshift, 0, lp); + + while(pshift != 1 || p[0] != 1 || p[1] != 0) { + if(pshift <= 1) { + trail = pntz(p); + shr(p, trail); + pshift += trail; + } else { + shl(p, 2); + pshift -= 2; + p[0] ^= 7; + shr(p, 1); + trinkle(head - lp[pshift] - width, width, cmp, p, pshift + 1, 1, lp); + shl(p, 1); + p[0] |= 1; + trinkle(head - width, width, cmp, p, pshift, 1, lp); + } + head -= width; + } +}