diff --git a/APP_Framework/Framework/connection/4g/ec200t/ec200t.c b/APP_Framework/Framework/connection/4g/ec200t/ec200t.c index aa8873a73..67076fe44 100644 --- a/APP_Framework/Framework/connection/4g/ec200t/ec200t.c +++ b/APP_Framework/Framework/connection/4g/ec200t/ec200t.c @@ -163,6 +163,8 @@ static int Ec200tIoctl(struct Adapter *adapter, int cmd, void *args) serial_cfg.serial_parity_mode = PARITY_NONE; serial_cfg.serial_bit_order = STOP_BITS_1; serial_cfg.serial_invert_mode = NRZ_NORMAL; + //serial receive timeout 10s + serial_cfg.serial_timeout = 10000; serial_cfg.is_ext_uart = 0; #ifdef ADAPTER_EC200T_DRIVER_EXT_PORT serial_cfg.is_ext_uart = 1; diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board.h index 405566e68..3693cb79c 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board.h @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/include/board.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you 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. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file board.h + * @brief sabre-lite board.h file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ #ifndef __BOARDS_ARM_IMX6_SABRE_LITE_INCLUDE_BOARD_H #define __BOARDS_ARM_IMX6_SABRE_LITE_INCLUDE_BOARD_H diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board_memorymap.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board_memorymap.h index d49e77662..14fa834cf 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board_memorymap.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/include/board_memorymap.h @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/include/board_memorymap.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you 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. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file board_memorymap.h + * @brief sabre-lite board memorymap + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ #ifndef __BOARDS_ARM_IMX6_SABRE_LITE_INCLUDE_BOARD_MEMORYMAP_H #define __BOARDS_ARM_IMX6_SABRE_LITE_INCLUDE_BOARD_MEMORYMAP_H diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_appinit.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_appinit.c index a90b2913a..26c471a34 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_appinit.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_appinit.c @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/imx_appinit.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you 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. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imx_appinit.c + * @brief sabre-lite imx_appinit.c file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ /**************************************************************************** * Included Files diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_autoleds.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_autoleds.c index ab081c440..cfd34ca69 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_autoleds.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_autoleds.c @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/imx_autoleds.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you 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. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imx_autoleds.c + * @brief sabre-lite imx_autoleds.c file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ /* LEDs * diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_boardinit.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_boardinit.c index df29c3b07..3f49cef5c 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_boardinit.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_boardinit.c @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/imx_boardinit.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you 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. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imx_boardinit.c + * @brief sabre-lite imx_boardinit.c file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ /**************************************************************************** * Included Files diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_bringup.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_bringup.c index b26bf4582..71e55b8b2 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_bringup.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_bringup.c @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/imx_bringup.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you 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. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imx_bringup.c + * @brief sabre-lite imx_bringup.c file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ /**************************************************************************** * Included Files diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_userleds.c b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_userleds.c index f86268f1c..2261bf165 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_userleds.c +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/imx_userleds.c @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/imx_userleds.c - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you 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. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file imx_userleds.c + * @brief sabre-lite imx_userleds.c file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ /**************************************************************************** * Included Files diff --git a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/sabre-lite.h b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/sabre-lite.h index 76568b434..f4b310767 100644 --- a/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/sabre-lite.h +++ b/Ubiquitous/Nuttx_Fusion_XiUOS/aiit_board/sabre-lite/src/sabre-lite.h @@ -1,22 +1,22 @@ -/**************************************************************************** - * boards/arm/imx6/sabre-lite/src/sabre-lite.h - * - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. The - * ASF licenses this file to you 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. - * - ****************************************************************************/ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** + * @file sabre-lite.h + * @brief sabre-lite sabre-lite.h file + * @version 1.0 + * @author AIIT XUOS Lab + * @date 2023.05.15 + */ #ifndef __BOARDS_ARM_IMX6_SABRE_LITE_SRC_SABRE_LITE_H #define __BOARDS_ARM_IMX6_SABRE_LITE_SRC_SABRE_LITE_H diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile index 4ca20e597..93ec6f896 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := task.c schedule.c ipc.c +SRC_FILES := schedule.c ipc.c include $(KERNEL_ROOT)/compiler.mk diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/ipc.c b/Ubiquitous/XiZi_AIoT/softkernel/task/ipc.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c b/Ubiquitous/XiZi_AIoT/softkernel/task/schedule.c deleted file mode 100644 index e69de29bb..000000000 diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c index e69de29bb..808804462 100644 --- a/Ubiquitous/XiZi_AIoT/softkernel/task/task.c +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.c @@ -0,0 +1,537 @@ + +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: task.c +* @brief: file task.c +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/05/18 +* +*/ + +#include + + +// 全局运行队列和本地运行队列 +tcb_t *global_run_queue_head = NULL; +tcb_t *global_run_queue_tail = NULL; +tcb_t *local_run_queue_head[8] = {NULL}; +tcb_t *local_run_queue_tail[8] = {NULL}; + +// 当前任务的指针 +volatile tcb_t *current_task = NULL; + + +/******************************************************************************* +* 函 数 名: tcb_init +* 功能描述: 初始化任务控制块 +* 形 参: tcb:任务控制块指针,priority:任务优先级,stack_size:栈大小 +* 返 回 值: 无 +*******************************************************************************/ +void tcb_init(tcb_t *tcb, int priority, int stack_size) { + tcb->priority = priority; + tcb->state = TASK_CREATED; + tcb->message_queue = NULL; + tcb->stack = (uint8_t*)malloc(stack_size); + tcb->stack_size = stack_size; + tcb->stack_ptr = tcb->stack + stack_size - sizeof(context_t); + // 将任务的上下文保存在栈中 + context_t *context = (context_t*)tcb->stack_ptr; + context_init(context, (void*)task_entry, tcb->stack_ptr); +} + +/******************************************************************************* +* 函 数 名: tcb_destroy +* 功能描述: 销毁任务控制块 +* 形 参: tcb:任务控制块指针 +* 返 回 值: 无 +*******************************************************************************/ +void tcb_destroy(tcb_t *tcb) { + free(tcb->stack_bottom); + tcb->stack_ptr = NULL; + tcb->stack_bottom = NULL; + tcb->stack_size = 0; + tcb->state = TASK_BLOCKED; + tcb->priority = 0; + tcb->next = NULL; + if (tcb->message_queue != NULL) { + message_queue_destroy(tcb->message_queue); + tcb->message_queue = NULL; + } +} + +/******************************************************************************* +* 函 数 名: get_current_task +* 功能描述: 获取当前任务的指针 +* 形 参: 无 +* 返 回 值: 任务控制块指针 +*******************************************************************************/ +tcb_t *get_current_task() { + return (tcb_t*)current_task; +} + + +/******************************************************************************* +* 函 数 名: get_local_run_queue_head +* 功能描述: 获取本地运行队列的头指针 +* 形 参: cpu_id:当前cpu的id +* 返 回 值: 任务控制块指针 +*******************************************************************************/ +tcb_t *get_local_run_queue_head(int cpu_id) { + return local_run_queue_head[cpu_id]; +} + + +/******************************************************************************* +* 函 数 名: add_to_global_run_queue +* 功能描述: 将任务添加到全局运行队列中 +* 形 参: tcb:任务控制块指针 +* 返 回 值: 无 +*******************************************************************************/ +void add_to_global_run_queue(tcb_t *tcb) { + // 将任务添加到全局运行队列的尾部 + if (global_run_queue_head == NULL) { + global_run_queue_head = tcb; + global_run_queue_tail = tcb; + } else { + global_run_queue_tail->next = tcb; + global_run_queue_tail = tcb; + } +} + + +/******************************************************************************* +* 函 数 名: take_from_global_run_queue +* 功能描述: 从全局运行队列中取出一个任务 +* 形 参: 无 +* 返 回 值: tcb:任务控制块指针 +*******************************************************************************/ +tcb_t *take_from_global_run_queue() { + // 从全局运行队列的头部取出一个任务 + if (global_run_queue_head == NULL) { + return NULL; + } else { + tcb_t *tcb = global_run_queue_head; + global_run_queue_head = tcb->next; + if (global_run_queue_head == NULL) { + global_run_queue_tail = NULL; + } + return tcb; + } +} + + +/******************************************************************************* +* 函 数 名: add_to_local_run_queue +* 功能描述: 将任务添加到本地运行队列中 +* 形 参: tcb:任务控制块指针,cpu_id:任务绑定的CPU id +* 返 回 值: 无 +*******************************************************************************/ +void add_to_local_run_queue(tcb_t *tcb, int cpu_id) { + // 将任务添加到本地运行队列的尾部 + if (local_run_queue_head[cpu_id] == NULL) { + local_run_queue_head[cpu_id] = tcb; + local_run_queue_tail[cpu_id] = tcb; + } else { + local_run_queue_tail[cpu_id]->next = tcb; + local_run_queue_tail[cpu_id] = tcb; + } +} + + +/******************************************************************************* +* 函 数 名: take_from_local_run_queue +* 功能描述: 从本地运行队列中取出一个任务 +* 形 参: cpu_id:CPU id +* 返 回 值: 无 +*******************************************************************************/ +tcb_t *take_from_local_run_queue(int cpu_id) { + // 从本地运行队列的头部取出一个任务 + if (local_run_queue_head[cpu_id] == NULL) { + return NULL; + } else { + tcb_t *tcb = local_run_queue_head[cpu_id]; + local_run_queue_head[cpu_id] = tcb->next; + if (local_run_queue_head[cpu_id] == NULL) { + local_run_queue_tail[cpu_id] = NULL; + } + return tcb; + } +} + + +/******************************************************************************* +* 函 数 名: move_current_task_to_global_run_queue +* 功能描述: 将当前任务从本地运行队列中取出,并添加到全局运行队列中 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void move_current_task_to_global_run_queue() { + int cpu_id = get_cpu_id(); + tcb_t *tcb = (tcb_t*)current_task; + tcb->state = TASK_READY; + add_to_global_run_queue(tcb); + local_run_queue_head[cpu_id] = NULL; + local_run_queue_tail[cpu_id] = NULL; + current_task = NULL; +} + + +/******************************************************************************* +* 函 数 名: switch_to_next_task +* 功能描述: 切换到下一个任务 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void switch_to_next_task() { + int cpu_id = get_cpu_id(); + tcb_t *current_tcb = (tcb_t*)current_task; + tcb_t *next_tcb = take_from_local_run_queue(cpu_id); + if (next_tcb == NULL) { + next_tcb = take_from_global_run_queue(); + } + if (next_tcb == NULL) { + // 如果没有可运行的任务,则将当前任务继续运行 + return; + } + // 保存当前任务的上下文 + if (current_tcb != NULL) { + current_tcb->stack_ptr = get_stack_pointer(); + } + // 切换到下一个任务的上下文 + current_task = next_tcb; + set_stack_pointer(next_tcb->stack_ptr); + // 如果切换到的任务是新的任务,需要执行任务初始化函数 + if (current_tcb != next_tcb) { + next_tcb->state = TASK_RUNNING; + task_init(next_tcb); + } +} + + +/******************************************************************************* +* 函 数 名: task_init +* 功能描述: 任务初始化函数 +* 形 参: tcb:任务控制块指针 +* 返 回 值: 无 +*******************************************************************************/ +void task_init(tcb_t *tcb) { + // 创建消息队列 + message_queue_t mq = (message_queue_t)malloc(sizeof(message_queue_t)); + mq->buffer = (message_t)malloc(sizeof(message_t) * 16); + mq->capacity = 16; + mq->head = 0; + mq->tail = 0; + mq->count = 0; + tcb->message_queue = mq; +} + + +/******************************************************************************* +* 函 数 名: create_task +* 功能描述: 创建任务 +* 形 参: priority:任务优先级,stack_size:栈大小 +* 返 回 值: 无 +*******************************************************************************/ +tcb_t *create_task(int priority, int stack_size) { + tcb_t *tcb = (tcb_t*)malloc(sizeof(tcb_t)); + tcb_init(tcb, priority, stack_size); + add_to_global_run_queue(tcb); + return tcb; +} + + +/******************************************************************************* +* 函 数 名: destroy_task +* 功能描述: 销毁任务 +* 形 参: tcb:任务控制块指针 +* 返 回 值: 无 +*******************************************************************************/ +void destroy_task(tcb_t *tcb) { + tcb_destroy(tcb); + free(tcb); +} + + +/******************************************************************************* +* 函 数 名: send_message +* 功能描述: 发送消息 +* 形 参: dest_tcb:目标任务的控制块指针,type:消息类型,data:消息的具体内容 +* 返 回 值: 无 +*******************************************************************************/ +void send_message(tcb_t *dest_tcb, int type, void *data) { + message_t message; + message.type = type; + message.data = data; + if (dest_tcb->message_queue == NULL) { + // 如果目标任务没有消息队列,则创建一个消息队列 + dest_tcb->message_queue = message_queue_create(16); + } + // 将消息添加到目标任务的消息队列中 + message_queue_push(dest_tcb->message_queue, &message); +} + + +/******************************************************************************* +* 函 数 名: receive_message +* 功能描述: 接收消息 +* 形 参: type:接收的消息类型,data:存储接收到的消息 +* 返 回 值: 无 +*******************************************************************************/ +void receive_message(int type, void *data) { + tcb_t *current_tcb = (tcb_t*)current_task; + message_t message; + // 从当前任务的消息队列中取出消息 + while (message_queue_pop(current_tcb->message_queue, &message) != 0) { + if (message.type == type) { + // 如果消息的类型匹配,则返回消息数据 + memcpy(data, message.data, sizeof(void*)); + return; + } + } + // 如果没有匹配的消息,则当前任务被阻塞,直到有匹配的消息为止 + current_tcb->state = TASK_BLOCKED; + while (message_queue_pop(current_tcb->message_queue, &message) != 0) { + if (message.type == type) { + // 如果有匹配的消息,则返回消息数据,并将当前任务状态设置为就绪 + memcpy(data, message.data, sizeof(void*)); + current_tcb->state = TASK_READY; + return; + } + } + // 如果还是没有匹配的消息,则当前任务一直被阻塞 + while (1) { + wait_for_interrupt(); + } +} + + +/******************************************************************************* +* 函 数 名: message_queue_create +* 功能描述: 创建消息队列 +* 形 参: capacity:消息队列的容量 +* 返 回 值: 生成的消息队列的指针 +*******************************************************************************/ +message_queue_t *message_queue_create(int capacity) { + message_queue_t *mq = (message_queue_t*)malloc(sizeof(message_queue_t)); + mq->buffer = (message_t*)malloc(sizeof(message_t) * capacity); + mq->capacity = capacity; + mq->head = 0; + mq->tail = 0; + mq->count = 0; + return mq; +} + + +/******************************************************************************* +* 函 数 名: message_queue_destroy +* 功能描述: 销毁消息队列 +* 形 参: mq:消息队列的指针 +* 返 回 值: 无 +*******************************************************************************/ +void message_queue_destroy(message_queue_t *mq) { + free(mq->buffer); + free(mq); +} + + +/******************************************************************************* +* 函 数 名: message_queue_push +* 功能描述: 将消息添加到消息队列中 +* 形 参: message_queue_t:消息队列的指针,message_t:存储的消息 +* 返 回 值: 0:成功,-1:失败 +*******************************************************************************/ +int message_queue_push(message_queue_t *mq, message_t *message) { + if (mq->count >= mq->capacity) { + return -1; // 队列已满 + } + mq->buffer[mq->tail] = *message; + mq->tail = (mq->tail + 1) % mq->capacity; + mq->count++; + return 0; +} + + +/******************************************************************************* +* 函 数 名: message_queue_pop +* 功能描述: 从消息队列中取出消息 +* 形 参: message_queue_t:消息队列的指针,message_t:存储的消息 +* 返 回 值: 0:成功,-1:失败 +*******************************************************************************/ +int message_queue_pop(message_queue_t *mq, message_t *message) { + if (mq->count <= 0) { + return -1; // 队列已空 + } + *message = mq->buffer[mq->head]; + mq->head = (mq->head + 1) % mq->capacity; + mq->count--; + return 0; +} + + +/******************************************************************************* +* 函 数 名: context_init +* 功能描述: 初始化上下文 +* 形 参: message_queue_t:消息队列的指针,message_t:存储的消息 +* 返 回 值: 0:成功,-1:失败 +*******************************************************************************/ +void context_init(context_t *context, void (*entry)(void), void *stack_ptr) { + context->cpsr = 0x10; // 设置 CPSR 的初始值 + context->pc = (uint32_t)entry; // 设置 PC 的初始值为任务入口地址 + context->r0 = (uint32_t)stack_ptr; // 设置 R0 的初始值为栈指针 + context->r1 = 0; // 设置 R1 的初始值为 0 + context->r2 = 0; // 设置 R2 的初始值为 0 + context->r3 = 0; // 设置 R3 的初始值为 0 + context->r4 = 0; // 设置 R4 的初始值为 0 + context->r5 = 0; // 设置 R5 的初始值为 0 + context->r6 = 0; // 设置 R6 的初始值为 0 + context->r7 = 0; // 设置 R7 的初始值为 0 + context->r8 = 0; // 设置 R8 的初始值为 0 + context->r9 = 0; // 设置 R9 的初始值为 0 + context->r10 = 0; // 设置 R10 的初始值为 0 + context->r11 = 0; // 设置 R11 的初始值为 0 + context->r12 = 0; // 设置 R12 的初始值为 0 + context->sp = (uint32_t)stack_ptr; // 设置 SP 的初始值为栈指针 + context->lr = (uint32_t)task_exit; // 设置 LR 的初始值为线程退出函数的地址 +} + +/******************************************************************************* +* 函 数 名: wait_for_interrupt +* 功能描述: 等待中断 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void wait_for_interrupt() { + // 在实现中,可以使用 WFI 指令等待中断 + __asm__ volatile("wfi"); +} + +/******************************************************************************* +* 函 数 名: get_cpu_id +* 功能描述: 获取CPU id +* 形 参: 无 +* 返 回 值: 获取的cpu id +*******************************************************************************/ +int get_cpu_id() { + uint32_t mpidr; + __asm__ volatile("mrc p15, 0, %0, c0, c0, 5" : "=r"(mpidr)); + return mpidr & 0xff; +} + + +/******************************************************************************* +* 函 数 名: get_stack_pointer +* 功能描述: 获取栈指针 +* 形 参: 无 +* 返 回 值: 获取到的栈指针 +*******************************************************************************/ +void *get_stack_pointer() { + // 在实现中,可以使用 ARM 的 SP 寄存器获取栈指针 + void *sp; + __asm__ volatile("mov %0, sp" : "=r"(sp)); + return sp; +} + + +/******************************************************************************* +* 函 数 名: set_stack_pointer +* 功能描述: 设置栈指针 +* 形 参: 设置的栈指针 +* 返 回 值: 无 +*******************************************************************************/ +void set_stack_pointer(void *sp) { + // 在实现中,可以使用 ARM 的 SP 寄存器设置栈指针 + __asm__ volatile("mov sp, %0" : : "r"(sp)); +} + +/******************************************************************************* +* 函 数 名: add_interrupt_handler +* 功能描述: 添加中断处理函数 +* 形 参: irq:中断号,handler:中断句柄,priority:中断优先级 +* 返 回 值: 无 +*******************************************************************************/ +void add_interrupt_handler(int irq, void (*handler)(void), int priority) { + uint32_t *vector_table = (uint32_t*)0x0; + + // 将中断处理函数写入中断向量表中 + vector_table[irq + 16] = (uint32_t)handler; + + // 设置中断优先级 + uint8_t priority_shift = 8 - __NVIC_PRIO_BITS; + uint32_t priority_mask = 0xff << priority_shift; + uint32_t priority_value = (priority << priority_shift) & priority_mask; + uint32_t *priority_reg = (uint32_t*)0xE000E400; + int index = irq / 4; + int offset = irq % 4; + priority_reg[index] &= ~(0xff << (offset * 8)); + priority_reg[index] |= (priority_value << (offset * 8)); + + // 使能中断 + uint32_t *enable_reg = (uint32_t*)0xE000E100; + enable_reg[irq / 32] |= 1 << (irq % 32); +} + + +/******************************************************************************* +* 函 数 名: enter_critical +* 功能描述: 进入临界区 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void enter_critical() { + // 在实现中,可以使用 ARM 的 CPSR 寄存器进入临界区 + __asm__ volatile("cpsid i"); +} + +/******************************************************************************* +* 函 数 名: leave_critical +* 功能描述: 离开临界区 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void leave_critical() { + // 在实现中,可以使用 ARM 的 CPSR 寄存器离开临界区 + __asm__ volatile("cpsie i"); +} + + + +/******************************************************************************* +* 函 数 名: task_exit +* 功能描述: 任务退出函数 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void task_exit() { + // 切换到下一个任务 + switch_to_next_task(); + // 在实现中,可以使用 ARM 的 WFE 指令等待下一个中断 + __asm__ volatile("wfe"); +} + + +/******************************************************************************* +* 函 数 名: task_entry +* 功能描述: 任务入口函数 +* 形 参: 无 +* 返 回 值: 无 +*******************************************************************************/ +void task_entry() { + tcb_t *current_tcb = (tcb_t*)current_task; + current_tcb->state = TASK_RUNNING; + task_init(current_tcb); + while (1) { + switch_to_next_task(); + } +} diff --git a/Ubiquitous/XiZi_AIoT/softkernel/task/task.h b/Ubiquitous/XiZi_AIoT/softkernel/task/task.h new file mode 100644 index 000000000..fdcc38fa0 --- /dev/null +++ b/Ubiquitous/XiZi_AIoT/softkernel/task/task.h @@ -0,0 +1,135 @@ +/* +* Copyright (c) 2020 AIIT XUOS Lab +* XiUOS is licensed under Mulan PSL v2. +* You can use this software according to the terms and conditions of the Mulan PSL v2. +* You may obtain a copy of Mulan PSL v2 at: +* http://license.coscl.org.cn/MulanPSL2 +* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, +* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, +* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. +* See the Mulan PSL v2 for more details. +*/ + +/** +* @file: task.h +* @brief: file task.h +* @version: 1.0 +* @author: AIIT XUOS Lab +* @date: 2023/05/18 +* +*/ + +#ifndef __TASK_H__ +#define __TASK_H__ + +#include +#include +#include +#include +#include + +// 任务状态枚举类型 +typedef enum { + TASK_CREATED, // 初始状态 + TASK_READY, // 就绪状态 + TASK_RUNNING, // 运行状态 + TASK_BLOCKED, // 阻塞状态 +} task_state_t; + + +// 任务控制块结构体 +typedef struct tcb { + uint32_t *stack_ptr; // 任务堆栈指针 + uint32_t *stack_bottom; // 任务堆栈底部指针 + uint32_t stack_size; // 任务堆栈大小 + task_state_t state; // 任务状态 + int priority; // 任务优先级 + struct tcb *next; // 指向下一个任务控制块的指针 + struct message_queue *message_queue; // 消息队列 +} tcb_t; + + +// 消息结构体 +typedef struct message { + int type; // 消息类型 + void *data; // 消息数据指针 +} message_t; + + +// 消息队列结构体 +typedef struct message_queue { + message_t *buffer; // 消息缓冲区 + int capacity; // 缓冲区容量 + int count; // 当前缓冲区中的消息数量 + int head; // 队头指针 + int tail; // 队尾指针 + semaphore_t *semaphore; // 信号量,用于实现消息队列的同步机制 +} message_queue_t; + + +// 信号量结构体 +typedef struct semaphore { + int count; // 计数器 + tcb_t *wait_list_head; // 指向等待信号量的任务控制块的指针 + mutex_t mutex; // 互斥锁,用于保护信号量和等待队列的访问 +} semaphore_t; + + +// 互斥锁结构体 +typedef struct mutex { + int lock; // 锁标志 +} mutex_t; + + +// 上下文结构体 +typedef struct { + uint32_t cpsr; // 控制寄存器 + uint32_t pc; // 程序计数器 + uint32_t r0; // 寄存器 R0 + uint32_t r1; // 寄存器 R1 + uint32_t r2; // 寄存器 R2 + uint32_t r3; // 寄存器 R3 + uint32_t r4; // 寄存器 R4 + uint32_t r5; // 寄存器 R5 + uint32_t r6; // 寄存器 R6 + uint32_t r7; // 寄存器 R7 + uint32_t r8; // 寄存器 R8 + uint32_t r9; // 寄存器 R9 + uint32_t r10; // 寄存器 R10 + uint32_t r11; // 寄存器 R11 + uint32_t r12; // 寄存器 R12 + uint32_t sp; // 栈指针 + uint32_t lr; // 链接寄存器 +} context_t; + +void tcb_init(tcb_t *tcb, int priority, int stack_size); +void tcb_destroy(tcb_t *tcb); +tcb_t *get_current_task(void); +tcb_t *get_local_run_queue_head(int cpu_id); +void add_to_global_run_queue(tcb_t *tcb); +tcb_t *take_from_global_run_queue(void); +void add_to_local_run_queue(tcb_t *tcb, int cpu_id); +tcb_t *take_from_local_run_queue(int cpu_id); +void move_current_task_to_global_run_queue(void); +void switch_to_next_task(void); +void task_init(tcb_t *tcb); +tcb_t *create_task(int priority, int stack_size); +void destroy_task(tcb_t *tcb); +void send_message(tcb_t *dest_tcb, int type, void *data); +void receive_message(int type, void *data); +message_queue_t *message_queue_create(int capacity); +void message_queue_destroy(message_queue_t *mq); +int message_queue_push(message_queue_t *mq, message_t *message); +int message_queue_pop(message_queue_t *mq, message_t *message); +int message_queue_push(message_queue_t *mq, message_t *message); +void context_init(context_t *context, void (*entry)(void), void *stack_ptr); +void wait_for_interrupt(void); +int get_cpu_id(void); +void *get_stack_pointer(void); +void set_stack_pointer(void *sp); +void add_interrupt_handler(int irq, void (*handler)(void), int priority); +void enter_critical(void); +void leave_critical(void); +void task_exit(void); +void task_entry(void); +#endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig index 7f43c0a50..67bf8db13 100755 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/Kconfig @@ -11,7 +11,7 @@ menuconfig BSP_USING_SPI bool "Using SPI device" default n select RESOURCES_SPI - select BSP_USING_DMA + select BSP_USING_DMA if BSP_USING_SPI source "$BSP_DIR/third_party_driver/spi/Kconfig" endif @@ -117,6 +117,7 @@ menuconfig BSP_USING_WIZCHIP bool "Using w5500 as network device" default n select RESOURCES_WIZCHIP + select BSP_USING_SPI if BSP_USING_WIZCHIP source "$BSP_DIR/third_party_driver/ethernet/Kconfig" endif diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig index baf59367c..b374d8fb0 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Kconfig @@ -1,15 +1,17 @@ # Kconfig file config BSP_USING_W5500 -bool "Using w5500 " -default y + bool "Using w5500" + default y -# if BSP_USING_W5500 - config BSP_WIZ_RST_PIN - int - default 13 +config BSP_WIZ_RST_PIN + int + default 13 - config BSP_WIZ_INT_PIN - int - default 14 -# endif \ No newline at end of file +config BSP_WIZ_INT_PIN + int + default 14 + +config BSP_WIZ_USE_IPERF + bool "Using iperf" + default y diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile index 1ea20caac..b5bc3166b 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/Makefile @@ -1,3 +1,3 @@ -SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c +SRC_FILES := socket.c connect_w5500.c w5500.c wizchip_conf.c spi_interface.c wiz_ping.c connect_w5500_test.c wiz_iperf.c include $(KERNEL_ROOT)/compiler.mk \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c index d06dfaa2d..0b245b11d 100644 --- a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500.c @@ -23,47 +23,53 @@ extern void spi_select_cs(void); extern void spi_deselete_cs(void); // global configurations for w5500 tcp connection -const uint32_t g_wiznet_buf_size = 2048; +uint32_t get_gbuf_size() { + static const uint32_t g_wiznet_buf_size = 2048; + return g_wiznet_buf_size; +} -static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}, - .ip = {192, 168, 131, 42}, - .sn = {255, 255, 254, 0}, - .gw = {192, 168, 130, 1}, - .dns = {0, 0, 0, 0}, - .dhcp = NETINFO_STATIC}; +wiz_NetInfo *get_gnetinfo() { + static wiz_NetInfo g_wiz_netinfo = {.mac = {0x00, 0x08, 0xdc, 0x11, 0x11, 0x11}, + .ip = {192, 168, 130, 77}, + .sn = {255, 255, 254, 0}, + .gw = {192, 168, 130, 1}, + .dns = {0, 0, 0, 0}, + .dhcp = NETINFO_STATIC}; + return &g_wiz_netinfo; +} int network_init() { wiz_NetInfo check_wiz_netinfo; check_wiz_netinfo.dhcp = NETINFO_STATIC; - ctlnetwork(CN_SET_NETINFO, (void *)&g_wiz_netinfo); + ctlnetwork(CN_SET_NETINFO, (void *)get_gnetinfo()); ctlnetwork(CN_GET_NETINFO, (void *)&check_wiz_netinfo); - if (memcmp(&g_wiz_netinfo, &check_wiz_netinfo, sizeof(wiz_NetInfo)) != 0) { + if (memcmp(get_gnetinfo(), &check_wiz_netinfo, sizeof(wiz_NetInfo)) != 0) { KPrintf( "mac: %d; ip: %d; gw: %d; sn: %d; dns: %d; dhcp: %d;\n", - memcmp(&g_wiz_netinfo.mac, &check_wiz_netinfo.mac, sizeof(uint8_t) * 6), - memcmp(&g_wiz_netinfo.ip, &check_wiz_netinfo.ip, sizeof(uint8_t) * 4), - memcmp(&g_wiz_netinfo.sn, &check_wiz_netinfo.sn, sizeof(uint8_t) * 4), - memcmp(&g_wiz_netinfo.gw, &check_wiz_netinfo.gw, sizeof(uint8_t) * 4), - memcmp(&g_wiz_netinfo.dns, &check_wiz_netinfo.dns, sizeof(uint8_t) * 4), - memcmp(&g_wiz_netinfo.dhcp, &check_wiz_netinfo.dhcp, sizeof(uint8_t))); + memcmp(&get_gnetinfo()->mac, &check_wiz_netinfo.mac, sizeof(uint8_t) * 6), + memcmp(&get_gnetinfo()->ip, &check_wiz_netinfo.ip, sizeof(uint8_t) * 4), + memcmp(&get_gnetinfo()->sn, &check_wiz_netinfo.sn, sizeof(uint8_t) * 4), + memcmp(&get_gnetinfo()->gw, &check_wiz_netinfo.gw, sizeof(uint8_t) * 4), + memcmp(&get_gnetinfo()->dns, &check_wiz_netinfo.dns, sizeof(uint8_t) * 4), + memcmp(&get_gnetinfo()->dhcp, &check_wiz_netinfo.dhcp, sizeof(uint8_t))); KPrintf("WIZCHIP set network information fail.\n"); return ERROR; } uint8_t tmpstr[6]; ctlwizchip(CW_GET_ID, (void *)tmpstr); KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); - KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", g_wiz_netinfo.mac[0], - g_wiz_netinfo.mac[1], g_wiz_netinfo.mac[2], g_wiz_netinfo.mac[3], - g_wiz_netinfo.mac[4], g_wiz_netinfo.mac[5]); - KPrintf("SIP: %d.%d.%d.%d\r\n", g_wiz_netinfo.ip[0], g_wiz_netinfo.ip[1], - g_wiz_netinfo.ip[2], g_wiz_netinfo.ip[3]); - KPrintf("GAR: %d.%d.%d.%d\r\n", g_wiz_netinfo.gw[0], g_wiz_netinfo.gw[1], - g_wiz_netinfo.gw[2], g_wiz_netinfo.gw[3]); - KPrintf("SUB: %d.%d.%d.%d\r\n", g_wiz_netinfo.sn[0], g_wiz_netinfo.sn[1], - g_wiz_netinfo.sn[2], g_wiz_netinfo.sn[3]); - KPrintf("DNS: %d.%d.%d.%d\r\n", g_wiz_netinfo.dns[0], g_wiz_netinfo.dns[1], - g_wiz_netinfo.dns[2], g_wiz_netinfo.dns[3]); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", get_gnetinfo()->mac[0], + get_gnetinfo()->mac[1], get_gnetinfo()->mac[2], get_gnetinfo()->mac[3], + get_gnetinfo()->mac[4], get_gnetinfo()->mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", get_gnetinfo()->ip[0], get_gnetinfo()->ip[1], + get_gnetinfo()->ip[2], get_gnetinfo()->ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", get_gnetinfo()->gw[0], get_gnetinfo()->gw[1], + get_gnetinfo()->gw[2], get_gnetinfo()->gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", get_gnetinfo()->sn[0], get_gnetinfo()->sn[1], + get_gnetinfo()->sn[2], get_gnetinfo()->sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", get_gnetinfo()->dns[0], get_gnetinfo()->dns[1], + get_gnetinfo()->dns[2], get_gnetinfo()->dns[3]); KPrintf("======================\r\n"); return EOK; @@ -255,312 +261,4 @@ int HwWiznetInit(void) { network_init(); return EOK; -} - -/****************** basic functions ********************/ - -enum TCP_OPTION { - SEND_DATA = 0, - RECV_DATA, -}; - -uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, - uint8_t dst_ip[4], uint16_t dst_port, - enum TCP_OPTION opt) { - // assert(buf_size <= g_wiznet_buf_size); - int32_t ret; - switch (getSn_SR(sn)) { - case SOCK_CLOSE_WAIT: - wiz_sock_disconnect(sn); - break; - case SOCK_CLOSED: - wiz_socket(sn, Sn_MR_TCP, 5000, 0x00); - break; - case SOCK_INIT: - KPrintf("[SOCKET CLIENT] sock init.\n"); - wiz_sock_connect(sn, dst_ip, dst_port); - break; - case SOCK_ESTABLISHED: - if (getSn_IR(sn) & Sn_IR_CON) { - printf("[SOCKET CLIENT] %d:Connected\r\n", sn); - setSn_IR(sn, Sn_IR_CON); - } - if (opt == SEND_DATA) { - uint32_t sent_size = 0; - ret = wiz_sock_send(sn, buf, buf_size); - if (ret < 0) { - wiz_sock_close(sn); - return ret; - } - } else if (opt == RECV_DATA) { - uint32_t size = 0; - if ((size = getSn_RX_RSR(sn)) > 0) { - if (size > buf_size) size = buf_size; - ret = wiz_sock_recv(sn, buf, size); - if (ret <= 0) return ret; - } - } - break; - default: - break; - } -} - -void wiz_client_op_test(int argc, char *argv[]) { - /* argv[1]: ip ip addr - * argv[2]: port port number - * argv[3]: msg send msg - * argv[4]: count test times,if no this parameter,default 10 times - */ - if (argc < 4) - { - KPrintf("wiz_client_op_test error\n"); - return; - } - uint8_t client_sock = 2; - uint32_t tmp_ip[4]; - uint8_t ip[4]; - uint64_t pCount = 10; - uint8_t buf[g_wiznet_buf_size]; - uint16_t port; - - sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); - ip[0] = (uint8_t)tmp_ip[0]; - ip[1] = (uint8_t)tmp_ip[1]; - ip[2] = (uint8_t)tmp_ip[2]; - ip[3] = (uint8_t)tmp_ip[3]; - - port = atoi(argv[2]); - KPrintf("wiz client to wiz_server, send to %d.%d.%d.%d %d\n", // tip info - ip[0], ip[1], ip[2], ip[3], port); - - if (argc >= 5){ - pCount = atoi(argv[4]); - } - for(uint64_t i = 0; i < pCount; i++) - { - wiz_client_op(client_sock, argv[3], strlen(argv[3]), ip, port, SEND_DATA); - MdelayKTask(10); - // waiting for a responding. - wiz_client_op(client_sock, buf, g_wiznet_buf_size, ip, port, RECV_DATA); - KPrintf("received msg: %s\n", buf); - memset(buf, 0, g_wiznet_buf_size); - } -} - -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), - wiz_client_op, wiz_client_op_test, - wiz_sock_recv or wiz_sock_send data as tcp client); - -int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, - uint16_t port, enum TCP_OPTION opt) { - int32_t ret = 0; - uint16_t size = 0, sentsize = 0; - switch (getSn_SR(sn)) { - case SOCK_ESTABLISHED: - if (getSn_IR(sn) & Sn_IR_CON) { - printf("%d:Connected\r\n", sn); - setSn_IR(sn, Sn_IR_CON); - } - if (opt == SEND_DATA) { - uint32_t sent_size = 0; - ret = wiz_sock_send(sn, buf, buf_size); - if (ret < 0) { - wiz_sock_close(sn); - return ret; - } - } else if (opt == RECV_DATA) { - uint32_t size = 0; - if ((size = getSn_RX_RSR(sn)) > 0) { - if (size > buf_size) size = buf_size; - ret = wiz_sock_recv(sn, buf, size); - return ret; - } - } - break; - case SOCK_CLOSE_WAIT: - printf("%d:CloseWait\r\n", sn); - if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret; - printf("%d:Closed\r\n", sn); - break; - case SOCK_INIT: - printf("%d:Listen, port [%d]\r\n", sn, port); - if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret; - break; - case SOCK_CLOSED: - printf("%d:LBTStart\r\n", sn); - if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; - printf("%d:Opened\r\n", sn); - break; - default: - break; - } - return 0; -} - -void wiz_server(void *param) { - uint16_t port = *(uint16_t *)param; - KPrintf("wiz server, listen port: %d\n", port); - uint8_t buf[g_wiznet_buf_size]; - memset(buf, 0, g_wiznet_buf_size); - int ret = 0; - uint32_t size = 0; - - while (1) { - ret = wiz_server_op(0, buf, g_wiznet_buf_size, port, RECV_DATA); - while(buf[size] != 0){ - size ++; - } - if (ret > 0) { - KPrintf("received %d bytes: %s\n", size, buf); - - wiz_server_op(0, buf, g_wiznet_buf_size, port, SEND_DATA); - memset(buf, 0, g_wiznet_buf_size); - } - size = 0; - } -} - -void wiz_server_test(uint16_t port) { - /* argv[1]: port - */ - int32 wiz_server_id = - KTaskCreate("wiz_server", wiz_server, (void *)&port, 4096, 25); - x_err_t flag = StartupKTask(wiz_server_id); - if (flag != EOK) { - KPrintf("StartupKTask wiz_server_id failed .\n"); - } -} - -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | - SHELL_CMD_PARAM_NUM(1), - wiz_server_op, wiz_server_test, - wiz_sock_recv or wiz_sock_send data as tcp server); - -void loopback_udps(int argc, char *argv[]) -{ - /* argv[1]: remote_ip ip address of remote udp - * argv[2]: remote_port the port number of the remote udp - * argv[2]: local_port the port number of the local udp - */ - uint32_t tmp_ip[4]; - uint8_t remote_ip[4]; - uint16_t remote_port, local_port; - uint8_t buffer[g_wiznet_buf_size]; - uint16_t len = 0; - - if (argc < 4) - { - KPrintf("loopback_udps test error\n"); - return; - } - - sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); - for(int i = 0;i < 4; i++) - { - remote_ip[i] = (uint8_t)tmp_ip[i]; - } - - remote_port = atoi(argv[2]); - local_port = atoi(argv[3]); - while(1) - { - switch (getSn_SR(0)) - { - case SOCK_UDP: - if(getSn_IR(0) & Sn_IR_RECV) - { - setSn_IR(0, Sn_IR_RECV); - } - if((len = getSn_RX_RSR(0))>0) - { - memset(buffer,0,len+1); - wiz_sock_recvfrom(0, buffer, len, remote_ip, (uint16_t *)&remote_port); - printf("received msg: %s\n", buffer); - wiz_sock_sendto(0, buffer, len, remote_ip, remote_port); - } - break; - - case SOCK_CLOSED: - printf("LBUStart\r\n"); - wiz_socket(0, Sn_MR_UDP, local_port, 0); - break; - } - } -} - -/* wiz_udp remote_ip remote_port local_port */ -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), - wiz_udp, loopback_udps, w5500 upd test); - -void ifconfig() { - wiz_NetInfo wiz_netinfo; - ctlnetwork(CN_GET_NETINFO, (void *)&wiz_netinfo); - uint8_t tmpstr[6]; - ctlwizchip(CW_GET_ID, (void *)tmpstr); - KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); - KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", wiz_netinfo.mac[0], - wiz_netinfo.mac[1], wiz_netinfo.mac[2], wiz_netinfo.mac[3], - wiz_netinfo.mac[4], wiz_netinfo.mac[5]); - KPrintf("SIP: %d.%d.%d.%d\r\n", wiz_netinfo.ip[0], wiz_netinfo.ip[1], - wiz_netinfo.ip[2], wiz_netinfo.ip[3]); - KPrintf("GAR: %d.%d.%d.%d\r\n", wiz_netinfo.gw[0], wiz_netinfo.gw[1], - wiz_netinfo.gw[2], wiz_netinfo.gw[3]); - KPrintf("SUB: %d.%d.%d.%d\r\n", wiz_netinfo.sn[0], wiz_netinfo.sn[1], - wiz_netinfo.sn[2], wiz_netinfo.sn[3]); - KPrintf("DNS: %d.%d.%d.%d\r\n", wiz_netinfo.dns[0], wiz_netinfo.dns[1], - wiz_netinfo.dns[2], wiz_netinfo.dns[3]); - KPrintf("======================\r\n"); -} -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), - ifconfig, ifconfig, printf w5500 configurations); - -void char_arr_assign(uint8_t *dst, uint32_t *src, int len) { - for (int i = 0; i < len; ++i) { - dst[i] = (uint8_t)(src[i]); - } -} - -char *network_param_name[] = {"ip", "sn", "gw"}; - -void config_w5500_network(int argc, char *argv[]) { - if (argc < 2) { - KPrintf("[W5500] Network config require params.\n"); - return; - } - - wiz_NetInfo wiz_netinfo; - memcpy(&wiz_netinfo, &g_wiz_netinfo, sizeof(wiz_NetInfo)); - - int cur_arg_idx = 1; - - while (argv[cur_arg_idx] != NULL) { - if (argv[cur_arg_idx + 1] == NULL) { - KPrintf("[W5500] Network config %s requires value.\n", argv[cur_arg_idx]); - return; - } - uint32_t tmp_arr[4]; - sscanf(argv[cur_arg_idx + 1], "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], - &tmp_arr[2], &tmp_arr[3]); - if (memcmp(argv[cur_arg_idx], network_param_name[0], 2 * sizeof(char)) == - 0) { - char_arr_assign(wiz_netinfo.ip, tmp_arr, 4); - } else if (memcmp(argv[cur_arg_idx], network_param_name[1], - 2 * sizeof(char)) == 0) { - char_arr_assign(wiz_netinfo.sn, tmp_arr, 4); - } else if (memcmp(argv[cur_arg_idx], network_param_name[2], - 2 * sizeof(char)) == 0) { - char_arr_assign(wiz_netinfo.gw, tmp_arr, 4); - } else { - KPrintf("[W5500] Invalid network param.\n"); - } - cur_arg_idx += 2; - } - - ctlnetwork(CN_SET_NETINFO, (void *)&wiz_netinfo); - KPrintf("[W5500] Network config success.\n", argv[cur_arg_idx]); - ifconfig(); -} -SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), - config_w5500_network, config_w5500_network, - set w5500 configurations); \ No newline at end of file +} \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500_test.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500_test.c new file mode 100644 index 000000000..c85c33090 --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/connect_w5500_test.c @@ -0,0 +1,314 @@ +#include +#include +#include + +#include "socket.h" + +extern uint32_t get_gbuf_size(); +extern wiz_NetInfo *get_gnetinfo(); + +enum TCP_OPTION { + SEND_DATA = 0, + RECV_DATA, +}; + +uint32_t wiz_client_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint8_t dst_ip[4], uint16_t dst_port, + enum TCP_OPTION opt) { + // assert(buf_size <= get_gbuf_size()); + int32_t ret; + switch (getSn_SR(sn)) { + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(sn); + break; + case SOCK_CLOSED: + wiz_socket(sn, Sn_MR_TCP, 5000, 0x00); + break; + case SOCK_INIT: + KPrintf("[SOCKET CLIENT] sock init.\n"); + wiz_sock_connect(sn, dst_ip, dst_port); + break; + case SOCK_ESTABLISHED: + if (getSn_IR(sn) & Sn_IR_CON) { + printf("[SOCKET CLIENT] %d:Connected\r\n", sn); + setSn_IR(sn, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(sn, buf, buf_size); + if (ret < 0) { + wiz_sock_close(sn); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + if (ret <= 0) return ret; + } + } + break; + default: + break; + } +} + +void wiz_client_op_test(int argc, char *argv[]) { + /* argv[1]: ip ip addr + * argv[2]: port port number + * argv[3]: msg send msg + * argv[4]: count test times,if no this parameter,default 10 times + */ + if (argc < 4) + { + KPrintf("wiz_client_op_test error\n"); + return; + } + uint8_t client_sock = 2; + uint32_t tmp_ip[4]; + uint8_t ip[4]; + uint64_t pCount = 10; + uint8_t buf[get_gbuf_size()]; + uint16_t port; + + sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); + ip[0] = (uint8_t)tmp_ip[0]; + ip[1] = (uint8_t)tmp_ip[1]; + ip[2] = (uint8_t)tmp_ip[2]; + ip[3] = (uint8_t)tmp_ip[3]; + + port = atoi(argv[2]); + KPrintf("wiz client to wiz_server, send to %d.%d.%d.%d %d\n", // tip info + ip[0], ip[1], ip[2], ip[3], port); + + if (argc >= 5){ + pCount = atoi(argv[4]); + } + for(uint64_t i = 0; i < pCount; i++) + { + wiz_client_op(client_sock, argv[3], strlen(argv[3]), ip, port, SEND_DATA); + MdelayKTask(10); + // waiting for a responding. + wiz_client_op(client_sock, buf, get_gbuf_size(), ip, port, RECV_DATA); + KPrintf("received msg: %s\n", buf); + memset(buf, 0, get_gbuf_size()); + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + wiz_client_op, wiz_client_op_test, + wiz_sock_recv or wiz_sock_send data as tcp client); + +int32_t wiz_server_op(uint8_t sn, uint8_t *buf, uint32_t buf_size, + uint16_t port, enum TCP_OPTION opt) { + int32_t ret = 0; + uint16_t size = 0, sentsize = 0; + switch (getSn_SR(sn)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sn) & Sn_IR_CON) { + printf("%d:Connected\r\n", sn); + setSn_IR(sn, Sn_IR_CON); + } + if (opt == SEND_DATA) { + uint32_t sent_size = 0; + ret = wiz_sock_send(sn, buf, buf_size); + if (ret < 0) { + wiz_sock_close(sn); + return ret; + } + } else if (opt == RECV_DATA) { + uint32_t size = 0; + if ((size = getSn_RX_RSR(sn)) > 0) { + if (size > buf_size) size = buf_size; + ret = wiz_sock_recv(sn, buf, size); + return ret; + } + } + break; + case SOCK_CLOSE_WAIT: + printf("%d:CloseWait\r\n", sn); + if ((ret = wiz_sock_disconnect(sn)) != SOCK_OK) return ret; + printf("%d:Closed\r\n", sn); + break; + case SOCK_INIT: + printf("%d:Listen, port [%d]\r\n", sn, port); + if ((ret = wiz_sock_listen(sn)) != SOCK_OK) return ret; + break; + case SOCK_CLOSED: + printf("%d:LBTStart\r\n", sn); + if ((ret = wiz_socket(sn, Sn_MR_TCP, port, 0x00)) != sn) return ret; + printf("%d:Opened\r\n", sn); + break; + default: + break; + } + return 0; +} + +void wiz_server(void *param) { + uint16_t port = *(uint16_t *)param; + KPrintf("wiz server, listen port: %d\n", port); + uint8_t buf[get_gbuf_size()]; + memset(buf, 0, get_gbuf_size()); + int ret = 0; + uint32_t size = 0; + + while (1) { + ret = wiz_server_op(0, buf, get_gbuf_size(), port, RECV_DATA); + while(buf[size] != 0){ + size ++; + } + if (ret > 0) { + KPrintf("received %d bytes: %s\n", size, buf); + + wiz_server_op(0, buf, get_gbuf_size(), port, SEND_DATA); + memset(buf, 0, get_gbuf_size()); + } + size = 0; + } +} + +void wiz_server_test(uint16_t port) { + /* argv[1]: port + */ + int32 wiz_server_id = + KTaskCreate("wiz_server", wiz_server, (void *)&port, 4096, 25); + x_err_t flag = StartupKTask(wiz_server_id); + if (flag != EOK) { + KPrintf("StartupKTask wiz_server_id failed .\n"); + } +} + +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC) | + SHELL_CMD_PARAM_NUM(1), + wiz_server_op, wiz_server_test, + wiz_sock_recv or wiz_sock_send data as tcp server); + +void loopback_udps(int argc, char *argv[]) +{ + /* argv[1]: remote_ip ip address of remote udp + * argv[2]: remote_port the port number of the remote udp + * argv[2]: local_port the port number of the local udp + */ + uint32_t tmp_ip[4]; + uint8_t remote_ip[4]; + uint16_t remote_port, local_port; + uint8_t buffer[get_gbuf_size()]; + uint16_t len = 0; + + if (argc < 4) + { + KPrintf("loopback_udps test error\n"); + return; + } + + sscanf(argv[1], "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], &tmp_ip[2], &tmp_ip[3]); + for(int i = 0;i < 4; i++) + { + remote_ip[i] = (uint8_t)tmp_ip[i]; + } + + remote_port = atoi(argv[2]); + local_port = atoi(argv[3]); + while(1) + { + switch (getSn_SR(0)) + { + case SOCK_UDP: + if(getSn_IR(0) & Sn_IR_RECV) + { + setSn_IR(0, Sn_IR_RECV); + } + if((len = getSn_RX_RSR(0))>0) + { + memset(buffer, 0, len + 1); + wiz_sock_recvfrom(0, buffer, len, remote_ip, (uint16_t *)&remote_port); + printf("received msg: %s\n", buffer); + wiz_sock_sendto(0, buffer, len, remote_ip, remote_port); + } + break; + + case SOCK_CLOSED: + printf("LBUStart\r\n"); + wiz_socket(0, Sn_MR_UDP, local_port, 0); + break; + } + } +} + +/* wiz_udp remote_ip remote_port local_port */ +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + wiz_udp, loopback_udps, w5500 upd test); + +void ifconfig() { + wiz_NetInfo wiz_netinfo; + ctlnetwork(CN_GET_NETINFO, (void *)&wiz_netinfo); + uint8_t tmpstr[6]; + ctlwizchip(CW_GET_ID, (void *)tmpstr); + KPrintf("=== %s NET CONF ===\r\n", (char *)tmpstr); + KPrintf("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", wiz_netinfo.mac[0], + wiz_netinfo.mac[1], wiz_netinfo.mac[2], wiz_netinfo.mac[3], + wiz_netinfo.mac[4], wiz_netinfo.mac[5]); + KPrintf("SIP: %d.%d.%d.%d\r\n", wiz_netinfo.ip[0], wiz_netinfo.ip[1], + wiz_netinfo.ip[2], wiz_netinfo.ip[3]); + KPrintf("GAR: %d.%d.%d.%d\r\n", wiz_netinfo.gw[0], wiz_netinfo.gw[1], + wiz_netinfo.gw[2], wiz_netinfo.gw[3]); + KPrintf("SUB: %d.%d.%d.%d\r\n", wiz_netinfo.sn[0], wiz_netinfo.sn[1], + wiz_netinfo.sn[2], wiz_netinfo.sn[3]); + KPrintf("DNS: %d.%d.%d.%d\r\n", wiz_netinfo.dns[0], wiz_netinfo.dns[1], + wiz_netinfo.dns[2], wiz_netinfo.dns[3]); + KPrintf("======================\r\n"); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_FUNC), + ifconfig, ifconfig, printf w5500 configurations); + +void char_arr_assign(uint8_t *dst, uint32_t *src, int len) { + for (int i = 0; i < len; ++i) { + dst[i] = (uint8_t)(src[i]); + } +} + +char *network_param_name[] = {"ip", "sn", "gw"}; + +void config_w5500_network(int argc, char *argv[]) { + if (argc < 2) { + KPrintf("[W5500] Network config require params.\n"); + return; + } + + wiz_NetInfo wiz_netinfo; + memcpy(&wiz_netinfo, get_gnetinfo(), sizeof(wiz_NetInfo)); + + int cur_arg_idx = 1; + + while (argv[cur_arg_idx] != NULL) { + if (argv[cur_arg_idx + 1] == NULL) { + KPrintf("[W5500] Network config %s requires value.\n", argv[cur_arg_idx]); + return; + } + uint32_t tmp_arr[4]; + sscanf(argv[cur_arg_idx + 1], "%d.%d.%d.%d", &tmp_arr[0], &tmp_arr[1], + &tmp_arr[2], &tmp_arr[3]); + if (memcmp(argv[cur_arg_idx], network_param_name[0], 2 * sizeof(char)) == + 0) { + char_arr_assign(wiz_netinfo.ip, tmp_arr, 4); + } else if (memcmp(argv[cur_arg_idx], network_param_name[1], + 2 * sizeof(char)) == 0) { + char_arr_assign(wiz_netinfo.sn, tmp_arr, 4); + } else if (memcmp(argv[cur_arg_idx], network_param_name[2], + 2 * sizeof(char)) == 0) { + char_arr_assign(wiz_netinfo.gw, tmp_arr, 4); + } else { + KPrintf("[W5500] Invalid network param.\n"); + } + cur_arg_idx += 2; + } + + ctlnetwork(CN_SET_NETINFO, (void *)&wiz_netinfo); + KPrintf("[W5500] Network config success.\n", argv[cur_arg_idx]); + ifconfig(); +} +SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN), + config_w5500_network, config_w5500_network, + set w5500 configurations); \ No newline at end of file diff --git a/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c new file mode 100644 index 000000000..3b1647c0f --- /dev/null +++ b/Ubiquitous/XiZi_IIoT/board/edu-riscv64/third_party_driver/ethernet/wiz_iperf.c @@ -0,0 +1,465 @@ +#include "socket.h" +#include "w5500.h" +#include "connect_w5500.h" + +#ifdef BSP_WIZ_USE_IPERF + +#define IPERF_PORT 5001 +#define IPERF_BUFSZ (4 * 1024) + +#define IPERF_MODE_STOP 0 +#define IPERF_MODE_SERVER 1 +#define IPERF_MODE_CLIENT 2 + +typedef struct{ + int mode; + uint8 host[4]; + uint16 port; +} IPERF_PARAM; +static IPERF_PARAM param = {IPERF_MODE_STOP, {0, 0, 0, 0}, IPERF_PORT}; + +static void iperf_udp_client(void *thread_param) +{ + int sock; + uint8 *buffer; + uint16 local_port = 4840; + uint32 packet_count = 0; + uint32 tick; + int send_size; + + send_size = IPERF_BUFSZ > 1470 ? 1470 : IPERF_BUFSZ; + + sock = 0; // w5500支持8个socket独立工作,todo socket端口管理 + // setSn_TXBUF_SIZE(sock, 16); + // setSn_RXBUF_SIZE(sock, 16); + + + buffer = malloc(IPERF_BUFSZ); + if (buffer == NULL){ + printf("[%s:%d] malloc failed\n", __FILE__, __LINE__); + return; + } + for(int i = 0; i < IPERF_BUFSZ; i++) + buffer[i] = i % 10; + + KPrintf("iperf udp mode run...\n"); + while (param.mode != IPERF_MODE_STOP){ + switch(getSn_SR(sock)){ + case SOCK_CLOSED: + wiz_socket(sock, Sn_MR_UDP, local_port, 0x00); + break; + case SOCK_UDP: + packet_count++; + tick = CurrentTicksGain(); + buffer[0] = (uint8)(packet_count >> 24); + buffer[1] = (uint8)(packet_count >> 16); + buffer[2] = (uint8)(packet_count >> 8); + buffer[3] = (uint8)(packet_count); + + buffer[4] = (uint8)((tick / TICK_PER_SECOND) >> 24); + buffer[5] = (uint8)((tick / TICK_PER_SECOND) >> 16); + buffer[6] = (uint8)((tick / TICK_PER_SECOND) >> 8); + buffer[7] = (uint8)((tick / TICK_PER_SECOND)); + + buffer[8] = (uint8)(((tick % TICK_PER_SECOND) * 1000) >> 24); + buffer[9] = (uint8)(((tick % TICK_PER_SECOND) * 1000) >> 16); + buffer[10] = (uint8)(((tick % TICK_PER_SECOND) * 1000) >> 8); + buffer[11] = (uint8)(((tick % TICK_PER_SECOND) * 1000)); + wiz_sock_sendto(sock, buffer, send_size, param.host, param.port); + break; + } + } + if(getSn_SR(sock) != SOCK_CLOSED) wiz_sock_close(sock); + free(buffer); + KPrintf("iperf udp mode exit...\n"); +} + +static void iperf_udp_server(void *thread_param) +{ + int sock, sender_len, r_size; + uint8 *buffer, client_addr[4]; + uint16 client_port; + uint32 pcount = 0, last_pcount = 0; + uint32 lost, total; + uint64 recvlen; + x_ticks_t tick1, tick2; + struct timeval timeout; + + buffer = malloc(IPERF_BUFSZ); + if (buffer == NULL){ + return; + } + + sock = 0; //todo + // setSn_RXBUF_SIZE(sock, 16); + // setSn_TXBUF_SIZE(sock, 16); + + KPrintf("iperf udp server run...\n"); + while (param.mode != IPERF_MODE_STOP){ + tick1 = CurrentTicksGain(); + tick2 = tick1; + lost = 0; + total = 0; + recvlen = 0; + while ((tick2 - tick1) < (TICK_PER_SECOND * 5)){ + switch(getSn_SR(sock)){ + case SOCK_UDP: + if ((r_size = getSn_RX_RSR(sock)) > 0){ + if (r_size > IPERF_BUFSZ) r_size = IPERF_BUFSZ; + memset(buffer, 0, IPERF_BUFSZ); + wiz_sock_recvfrom(sock, buffer, r_size, client_addr, &client_port); + recvlen += r_size; + last_pcount = buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]; + if(last_pcount > pcount){ + total += last_pcount - pcount; + lost += last_pcount - pcount - 1; + pcount = last_pcount; + } + else if(last_pcount < 10){ + pcount = last_pcount; + total = 1; + lost = 0; + } + } + tick2 = CurrentTicksGain(); + break; + case SOCK_CLOSED: + wiz_socket(sock, Sn_MR_UDP, param.port, 0x00); + break; + } + } + if (recvlen > 0){ + long data; + int integer, decimal; + KTaskDescriptorType tid; + + tid = GetKTaskDescriptor(); + data = recvlen * TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = data/1000; + decimal = data%1000; + KPrintf("%s: %d.%03d0 Mbps! recv:%d lost:%d total:%d\n", tid->task_base_info.name, integer, decimal, total - lost, lost, total); + } + } + free(buffer); + if(getSn_SR(sock) != SOCK_CLOSED) wiz_sock_close(sock); +} + +static void iperf_client(void *thread_param) +{ + int i; + int sock = 0; + int ret; + uint8_t *send_buf, connected = 0; + uint64 sentlen; + x_ticks_t tick1, tick2; + + // setSn_RXBUF_SIZE(sock, 16); + // setSn_TXBUF_SIZE(sock, 16); + + send_buf = (uint8_t *) malloc(IPERF_BUFSZ); + if (!send_buf) return ; + + for (i = 0; i < IPERF_BUFSZ; i ++) + send_buf[i] = i & 0xff; + + while (param.mode != IPERF_MODE_STOP) + { + while((getSn_SR(sock) != SOCK_ESTABLISHED || !connected) && param.mode != IPERF_MODE_STOP){ + switch (getSn_SR(sock)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sock) & Sn_IR_CON) { + KPrintf("Connected\n", sock); + setSn_IR(sock, Sn_IR_CON); + } + connected = 1; + break; + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(sock); + break; + case SOCK_INIT: + KPrintf("Socket %d:try to connect to [%d.%d.%d.%d:%d]...", + sock, param.host[0], param.host[1], param.host[2], param.host[3], param.port); + ret = wiz_sock_connect(sock, param.host, param.port); + if (ret != SOCK_OK){ + printf("failed, wait 1s to try again\n"); + MdelayKTask(1000); + } + break; + case SOCK_CLOSED: + if(connected) KPrintf("Socket %d:closed\n", sock); + wiz_socket(sock, Sn_MR_TCP, param.port, 0x00); + connected = 0; + break; + default: + break; + } + } + + sentlen = 0; + + tick1 = CurrentTicksGain(); + while (param.mode != IPERF_MODE_STOP){ + tick2 = CurrentTicksGain(); + if (tick2 - tick1 >= TICK_PER_SECOND * 5){ + long data; + int integer, decimal; + KTaskDescriptorType tid; + + tid = GetKTaskDescriptor(); + data = sentlen * TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = data/1000; + decimal = data%1000; + KPrintf("%s: %d.%03d0 Mbps!\n", tid->task_base_info.name, integer, decimal); + tick1 = tick2; + sentlen = 0; + } + + ret = wiz_sock_send(sock, send_buf, IPERF_BUFSZ); + if (ret > 0){ + sentlen += ret; + } + + if (ret < 0) break; + } + + if(getSn_SR(sock) != SOCK_CLOSED)wiz_sock_close(sock); + + KPrintf("Disconnected, iperf client exit!"); + } + free(send_buf); +} + +static void iperf_server(void *thread_param) +{ + uint8_t *recv_data; + x_ticks_t tick1, tick2; + int sock = -1, connected = 0, bytes_received; + uint64 recvlen; + + sock = 0; //todo + // setSn_RXBUF_SIZE(sock, 16); + // setSn_TXBUF_SIZE(sock, 16); + + recv_data = (uint8_t *)malloc(IPERF_BUFSZ); + if (recv_data == NULL){ + KPrintf("No memory!\n"); + goto __exit; + } + + while (param.mode != IPERF_MODE_STOP){ + while((getSn_SR(sock) != SOCK_ESTABLISHED || !connected)){ + switch (getSn_SR(sock)) { + case SOCK_ESTABLISHED: + if (getSn_IR(sock) & Sn_IR_CON) { + KPrintf("Socket %d:Connected\n", sock); + setSn_IR(sock, Sn_IR_CON); + } + recvlen = 0; + tick1 = CurrentTicksGain(); + connected = 1; + break; + case SOCK_CLOSE_WAIT: + wiz_sock_disconnect(sock); + break; + case SOCK_INIT: + KPrintf("Socket %d:Listen, port [%d]\n", sock, param.port); + wiz_sock_listen(sock); + break; + case SOCK_CLOSED: + if(connected) KPrintf("Socket %d:closed\n", sock); + wiz_socket(sock, Sn_MR_TCP, param.port, 0x00); + connected = 0; + break; + default: + break; + } + if(param.mode == IPERF_MODE_STOP) goto __exit; + } + + if ((bytes_received = getSn_RX_RSR(sock)) > 0) { + if (bytes_received > IPERF_BUFSZ) bytes_received = IPERF_BUFSZ; + memset(recv_data, 0, IPERF_BUFSZ); + wiz_sock_recv(sock, recv_data, bytes_received); + recvlen += bytes_received; + } + + tick2 = CurrentTicksGain(); + if (tick2 - tick1 >= TICK_PER_SECOND * 5){ + long data; + int integer, decimal; + KTaskDescriptorType tid; + + tid = GetKTaskDescriptor(); + data = recvlen * TICK_PER_SECOND / 125 / (tick2 - tick1); + integer = data/1000; + decimal = data%1000; + KPrintf("%s: %d.%03d0 Mbps!\n", tid->task_base_info.name, integer, decimal); + tick1 = tick2; + recvlen = 0; + } + } + +__exit: + if(getSn_SR(sock) != SOCK_CLOSED)wiz_sock_close(sock); + if (recv_data) free(recv_data); +} + +void iperf_usage(void) +{ + KPrintf("Usage: iperf [-s|-c host] [options] [multi-threaded]\n"); + KPrintf(" iperf [-h|--stop]\n"); + KPrintf("\n"); + KPrintf("Client/Server:\n"); + KPrintf(" -p # server port to listen on/connect to\n"); + KPrintf("\n"); + KPrintf("Server specific:\n"); + KPrintf(" -s run in server mode\n"); + KPrintf("\n"); + KPrintf("Client specific:\n"); + KPrintf(" -c run in client mode, connecting to \n"); + KPrintf("\n"); + KPrintf("Miscellaneous:\n"); + KPrintf(" -h print this message and quit\n"); + KPrintf(" --stop stop iperf program\n"); + KPrintf(" -u testing UDP protocol\n"); + KPrintf(" -m