forked from xuos/xiuos
				
			Merge branch 'prepare_for_master' of https://gitlink.org.cn/xuos/xiuos into lorawan_develop
This commit is contained in:
		
						commit
						02b676e910
					
				| 
						 | 
				
			
			@ -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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
SRC_FILES := task.c schedule.c ipc.c
 | 
			
		||||
SRC_FILES := schedule.c ipc.c
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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 <task.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// 全局运行队列和本地运行队列
 | 
			
		||||
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();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -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 <stdio.h>
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
// 任务状态枚举类型
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
config BSP_WIZ_RST_PIN
 | 
			
		||||
    int 
 | 
			
		||||
    default 13
 | 
			
		||||
 | 
			
		||||
    config BSP_WIZ_INT_PIN
 | 
			
		||||
config BSP_WIZ_INT_PIN
 | 
			
		||||
    int 
 | 
			
		||||
    default 14
 | 
			
		||||
# endif
 | 
			
		||||
 | 
			
		||||
config BSP_WIZ_USE_IPERF
 | 
			
		||||
    bool "Using iperf"
 | 
			
		||||
    default y
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
| 
						 | 
				
			
			@ -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},
 | 
			
		||||
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;
 | 
			
		||||
| 
						 | 
				
			
			@ -256,311 +262,3 @@ int HwWiznetInit(void) {
 | 
			
		|||
 | 
			
		||||
  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);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,314 @@
 | 
			
		|||
#include <dev_pin.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#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);
 | 
			
		||||
| 
						 | 
				
			
			@ -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 <host>    run in client mode, connecting to <host>\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 <time>    the number of multi-threaded \ns");
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int iperf(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    int mode = 0; /* server mode */
 | 
			
		||||
    char *host = NULL;
 | 
			
		||||
    int port = IPERF_PORT;
 | 
			
		||||
    int numtid = 1;
 | 
			
		||||
    int use_udp = 0;
 | 
			
		||||
    int index = 1;
 | 
			
		||||
 | 
			
		||||
    if (argc == 1)
 | 
			
		||||
    {
 | 
			
		||||
        goto __usage;
 | 
			
		||||
    }
 | 
			
		||||
    if (strcmp(argv[1], "-u") == 0)
 | 
			
		||||
    {
 | 
			
		||||
        index = 2;
 | 
			
		||||
        use_udp = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (strcmp(argv[index], "-h") == 0) goto __usage;
 | 
			
		||||
    else if (strcmp(argv[index], "--stop") == 0)
 | 
			
		||||
    {
 | 
			
		||||
        /* stop iperf */
 | 
			
		||||
        param.mode = IPERF_MODE_STOP;
 | 
			
		||||
        MdelayKTask(10);
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else if (strcmp(argv[index], "-s") == 0)
 | 
			
		||||
    {
 | 
			
		||||
        mode = IPERF_MODE_SERVER; /* server mode */
 | 
			
		||||
 | 
			
		||||
        /* iperf -s -p 5000 */
 | 
			
		||||
        if (argc >= 4)
 | 
			
		||||
        {
 | 
			
		||||
            if (strcmp(argv[index + 1], "-p") == 0)
 | 
			
		||||
            {
 | 
			
		||||
                port = atoi(argv[index + 2]);
 | 
			
		||||
            }
 | 
			
		||||
            else goto __usage;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if (strcmp(argv[index], "-c") == 0)
 | 
			
		||||
    {
 | 
			
		||||
        mode = IPERF_MODE_CLIENT; /* client mode */
 | 
			
		||||
        if (argc < 3) goto __usage;
 | 
			
		||||
 | 
			
		||||
        host = argv[index + 1];
 | 
			
		||||
        if (argc >= 5)
 | 
			
		||||
        {
 | 
			
		||||
            /* iperf -c host -p port */
 | 
			
		||||
            if (strcmp(argv[index + 2], "-p") == 0)
 | 
			
		||||
            {
 | 
			
		||||
                port = atoi(argv[index + 3]);
 | 
			
		||||
            }
 | 
			
		||||
            else goto __usage;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else goto __usage;
 | 
			
		||||
 | 
			
		||||
    if (argc >= 7)
 | 
			
		||||
    {
 | 
			
		||||
        if(strcmp(argv[argc - 2], "-m") == 0)
 | 
			
		||||
        {
 | 
			
		||||
            numtid = atoi(argv[argc - 1]);
 | 
			
		||||
        }
 | 
			
		||||
        else  goto __usage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* start iperf */
 | 
			
		||||
    if (param.mode == IPERF_MODE_STOP)
 | 
			
		||||
    {
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        char tid_name[NAME_NUM_MAX + 1] = {0};
 | 
			
		||||
 | 
			
		||||
        param.mode = mode;
 | 
			
		||||
        param.port = port;
 | 
			
		||||
        if (host) {
 | 
			
		||||
            uint32 t1,t2,t3,t4;
 | 
			
		||||
            sscanf(host, "%d.%d.%d.%d", &t1, &t2, &t3, &t4);
 | 
			
		||||
            param.host[0] = (uint8)t1;
 | 
			
		||||
            param.host[1] = (uint8)t2;
 | 
			
		||||
            param.host[2] = (uint8)t3;
 | 
			
		||||
            param.host[3] = (uint8)t4;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (i = 0; i < numtid; i++)
 | 
			
		||||
        {
 | 
			
		||||
            int32 tid = 0;
 | 
			
		||||
            void (*function)(void *parameter);
 | 
			
		||||
 | 
			
		||||
            if (use_udp)
 | 
			
		||||
            {
 | 
			
		||||
                if (mode == IPERF_MODE_CLIENT)
 | 
			
		||||
                {
 | 
			
		||||
                    snprintf(tid_name, sizeof(tid_name), "iperfc%02d", i + 1);
 | 
			
		||||
                    function = iperf_udp_client;
 | 
			
		||||
                }
 | 
			
		||||
                else if (mode == IPERF_MODE_SERVER)
 | 
			
		||||
                {
 | 
			
		||||
                    snprintf(tid_name, sizeof(tid_name), "iperfd%02d", i + 1);
 | 
			
		||||
                    function = iperf_udp_server;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (mode == IPERF_MODE_CLIENT)
 | 
			
		||||
                {
 | 
			
		||||
                    snprintf(tid_name, sizeof(tid_name), "iperfc%02d", i + 1);
 | 
			
		||||
                    function = iperf_client;
 | 
			
		||||
                }
 | 
			
		||||
                else if (mode == IPERF_MODE_SERVER)
 | 
			
		||||
                {
 | 
			
		||||
                    snprintf(tid_name, sizeof(tid_name), "iperfd%02d", i + 1);
 | 
			
		||||
                    function = iperf_server;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            tid = KTaskCreate(tid_name, function, NULL, 4096, 25);
 | 
			
		||||
            if (tid) StartupKTask(tid);
 | 
			
		||||
            MdelayKTask(10);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        KPrintf("Please stop iperf firstly, by:\n");
 | 
			
		||||
        KPrintf("iperf --stop\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
__usage:
 | 
			
		||||
    iperf_usage();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN),
 | 
			
		||||
                 iperf, iperf,
 | 
			
		||||
                 iperf throughput test);
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			@ -78,6 +78,10 @@ Modification:
 | 
			
		|||
#include <connect_can.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef BSP_USING_LWIP
 | 
			
		||||
#include <connect_ethernet.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
extern void entry(void);
 | 
			
		||||
extern int HwUsartInit();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -209,6 +213,8 @@ struct InitSequenceDesc _board_init[] =
 | 
			
		|||
#endif
 | 
			
		||||
#ifdef BSP_USING_CAN
 | 
			
		||||
	{ "can", HwCanInit },
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef BSP_USING_LWIP
 | 
			
		||||
#endif
 | 
			
		||||
    { " NONE ", NONE },
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1 +1,3 @@
 | 
			
		|||
 | 
			
		||||
config BSP_USING_ETH
 | 
			
		||||
    bool 
 | 
			
		||||
    default y
 | 
			
		||||
| 
						 | 
				
			
			@ -1,3 +1,3 @@
 | 
			
		|||
SRC_FILES := ethernetif.c 
 | 
			
		||||
SRC_FILES := ethernetif.c eth_driver.c
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,287 @@
 | 
			
		|||
/**
 | 
			
		||||
* @file ethernetif.c
 | 
			
		||||
* @brief support hc32f4a0-board ethernetif function and register to Lwip
 | 
			
		||||
* @version 3.0 
 | 
			
		||||
* @author AIIT XUOS Lab
 | 
			
		||||
* @date 2022-12-05
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <connect_ethernet.h>
 | 
			
		||||
#include <hc32_ll_gpio.h>
 | 
			
		||||
#include <hc32_ll_utility.h>
 | 
			
		||||
#include <hc32_ll_fcg.h>
 | 
			
		||||
#include <lwip/timeouts.h>
 | 
			
		||||
#include <netif/etharp.h>
 | 
			
		||||
 | 
			
		||||
#include <sys_arch.h>
 | 
			
		||||
 | 
			
		||||
void eth_irq_handler(void) {
 | 
			
		||||
    static x_base eth_irq_lock;
 | 
			
		||||
    eth_irq_lock = DISABLE_INTERRUPT();
 | 
			
		||||
 | 
			
		||||
    // handle irq
 | 
			
		||||
    if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_RIS)) {
 | 
			
		||||
        sys_sem_signal(get_eth_recv_sem());
 | 
			
		||||
        ETH_DMA_ClearStatus(ETH_DMA_FLAG_RIS | ETH_DMA_FLAG_NIS);
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    ENABLE_INTERRUPT(eth_irq_lock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief  In this function, the hardware should be initialized.
 | 
			
		||||
 * @param  netif                         The already initialized network interface structure for this ethernetif.
 | 
			
		||||
 * @retval int32_t:
 | 
			
		||||
 *           - LL_OK: Initialize success
 | 
			
		||||
 *           - LL_ERR: Initialize failed
 | 
			
		||||
 */
 | 
			
		||||
int32_t low_level_init(struct netif *netif)
 | 
			
		||||
{
 | 
			
		||||
    int32_t i32Ret = LL_ERR;
 | 
			
		||||
    stc_eth_init_t stcEthInit;
 | 
			
		||||
    uint16_t u16RegVal;
 | 
			
		||||
 | 
			
		||||
    /* Enable ETH clock */
 | 
			
		||||
    FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_ETHMAC, ENABLE);
 | 
			
		||||
    /* Init Ethernet GPIO */
 | 
			
		||||
    Ethernet_GpioInit();
 | 
			
		||||
    /* Reset ETHERNET */
 | 
			
		||||
    (void)ETH_DeInit();
 | 
			
		||||
    /* Configure structure initialization */
 | 
			
		||||
    (void)ETH_CommStructInit(&EthHandle.stcCommInit);
 | 
			
		||||
    (void)ETH_StructInit(&stcEthInit);
 | 
			
		||||
 | 
			
		||||
#ifdef ETH_INTERFACE_RMII
 | 
			
		||||
    EthHandle.stcCommInit.u32Interface  = ETH_MAC_IF_RMII;
 | 
			
		||||
#else
 | 
			
		||||
    EthHandle.stcCommInit.u32Interface  = ETH_MAC_IF_MII;
 | 
			
		||||
#endif
 | 
			
		||||
    // stcEthInit.stcMacInit.u32ReceiveAll = ETH_MAC_RX_ALL_ENABLE;
 | 
			
		||||
    EthHandle.stcCommInit.u32ReceiveMode = ETH_RX_MD_INT;
 | 
			
		||||
    // EthHandle.stcCommInit.u32ChecksumMode = ETH_MAC_CHECKSUM_MD_SW;
 | 
			
		||||
 | 
			
		||||
    // install irq
 | 
			
		||||
    sys_sem_new(get_eth_recv_sem(), 0);
 | 
			
		||||
    hc32_install_irq_handler(ð_irq_config, eth_irq_handler, ENABLE);
 | 
			
		||||
 | 
			
		||||
    /* Configure ethernet peripheral */
 | 
			
		||||
    if (LL_OK == ETH_Init(&EthHandle, &stcEthInit)) {
 | 
			
		||||
        u8EthInitStatus = 1U;
 | 
			
		||||
        i32Ret = LL_OK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef ETHERNET_LOOPBACK_TEST
 | 
			
		||||
    /* Enable PHY loopback */
 | 
			
		||||
    (void)ETH_PHY_LoopBackCmd(&EthHandle, ENABLE);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* Initialize Tx Descriptors list: Chain Mode */
 | 
			
		||||
    (void)ETH_DMA_TxDescListInit(&EthHandle, EthDmaTxDscrTab, &EthTxBuff[0][0], ETH_TX_BUF_NUM);
 | 
			
		||||
    /* Initialize Rx Descriptors list: Chain Mode  */
 | 
			
		||||
    (void)ETH_DMA_RxDescListInit(&EthHandle, EthDmaRxDscrTab, &EthRxBuff[0][0], ETH_RX_BUF_NUM);
 | 
			
		||||
 | 
			
		||||
    /* set MAC hardware address length */
 | 
			
		||||
    netif->hwaddr_len = 6U;
 | 
			
		||||
    /* set MAC hardware address */
 | 
			
		||||
    EthHandle.stcCommInit.u16AutoNego = ETH_AUTO_NEGO_DISABLE;
 | 
			
		||||
 | 
			
		||||
    netif->hwaddr[0] = (EthHandle.stcCommInit).au8MacAddr[0];
 | 
			
		||||
    netif->hwaddr[1] = (EthHandle.stcCommInit).au8MacAddr[1];
 | 
			
		||||
    netif->hwaddr[2] = (EthHandle.stcCommInit).au8MacAddr[2];
 | 
			
		||||
    netif->hwaddr[3] = (EthHandle.stcCommInit).au8MacAddr[3];
 | 
			
		||||
    netif->hwaddr[4] = (EthHandle.stcCommInit).au8MacAddr[4];
 | 
			
		||||
    netif->hwaddr[5] = (EthHandle.stcCommInit).au8MacAddr[5];
 | 
			
		||||
    /* maximum transfer unit */
 | 
			
		||||
    netif->mtu = 1500U;
 | 
			
		||||
 | 
			
		||||
    /* device capabilities */
 | 
			
		||||
    netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
 | 
			
		||||
 | 
			
		||||
    /* Enable MAC and DMA transmission and reception */
 | 
			
		||||
    (void)ETH_Start();
 | 
			
		||||
 | 
			
		||||
    /* Configure PHY LED mode */
 | 
			
		||||
    u16RegVal = PHY_PAGE_ADDR_7;
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal);
 | 
			
		||||
    (void)ETH_PHY_ReadReg(&EthHandle, PHY_P7_IWLFR, &u16RegVal);
 | 
			
		||||
    MODIFY_REG16(u16RegVal, PHY_LED_SELECT, PHY_LED_SELECT_10);
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_P7_IWLFR, u16RegVal);
 | 
			
		||||
    u16RegVal = PHY_PAGE_ADDR_0;
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal);
 | 
			
		||||
 | 
			
		||||
#ifdef ETH_INTERFACE_RMII
 | 
			
		||||
    /* Disable Power Saving Mode */
 | 
			
		||||
    (void)ETH_PHY_ReadReg(&EthHandle, PHY_PSMR, &u16RegVal);
 | 
			
		||||
    CLR_REG16_BIT(u16RegVal, PHY_EN_PWR_SAVE);
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSMR, u16RegVal);
 | 
			
		||||
 | 
			
		||||
    /* Configure PHY to generate an interrupt when Eth Link state changes */
 | 
			
		||||
    u16RegVal = PHY_PAGE_ADDR_7;
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal);
 | 
			
		||||
    /* Enable Interrupt on change of link status */
 | 
			
		||||
    (void)ETH_PHY_ReadReg(&EthHandle, PHY_P7_IWLFR, &u16RegVal);
 | 
			
		||||
    SET_REG16_BIT(u16RegVal, PHY_INT_LINK_CHANGE);
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_P7_IWLFR, u16RegVal);
 | 
			
		||||
    u16RegVal = PHY_PAGE_ADDR_0;
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal);
 | 
			
		||||
#endif
 | 
			
		||||
    
 | 
			
		||||
    return i32Ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief  This function should do the actual transmission of the packet.
 | 
			
		||||
 * @param  netif                        The network interface structure for this ethernetif.
 | 
			
		||||
 * @param  p                            The MAC packet to send.
 | 
			
		||||
 * @retval int32_t:
 | 
			
		||||
 *           - LL_OK: The packet could be sent
 | 
			
		||||
 *           - LL_ERR: The packet couldn't be sent
 | 
			
		||||
 */
 | 
			
		||||
err_t low_level_output(struct netif *netif, struct pbuf *p)
 | 
			
		||||
{
 | 
			
		||||
    err_t i32Ret;
 | 
			
		||||
    struct pbuf *q;
 | 
			
		||||
    uint8_t *txBuffer;
 | 
			
		||||
    __IO stc_eth_dma_desc_t *DmaTxDesc;
 | 
			
		||||
    uint32_t byteCnt;
 | 
			
		||||
    uint32_t frameLength = 0UL;
 | 
			
		||||
    uint32_t bufferOffset;
 | 
			
		||||
    uint32_t payloadOffset;
 | 
			
		||||
 | 
			
		||||
    DmaTxDesc = EthHandle.stcTxDesc;
 | 
			
		||||
    txBuffer = (uint8_t *)((EthHandle.stcTxDesc)->u32Buf1Addr);
 | 
			
		||||
    bufferOffset = 0UL;
 | 
			
		||||
    /* Copy frame from pbufs to driver buffers */
 | 
			
		||||
    for (q = p; q != NULL; q = q->next) {
 | 
			
		||||
        /* If this buffer isn't available, goto error */
 | 
			
		||||
        if (0UL != (DmaTxDesc->u32ControlStatus & ETH_DMA_TXDESC_OWN)) {
 | 
			
		||||
            i32Ret = (err_t)ERR_USE;
 | 
			
		||||
            goto error;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Get bytes in current buffer */
 | 
			
		||||
        byteCnt = q->len;
 | 
			
		||||
        payloadOffset = 0UL;
 | 
			
		||||
        /* Check if the length of data to copy is bigger than Tx buffer size */
 | 
			
		||||
        while ((byteCnt + bufferOffset) > ETH_TX_BUF_SIZE) {
 | 
			
		||||
            /* Copy data to Tx buffer*/
 | 
			
		||||
            (void)memcpy((uint8_t *) & (txBuffer[bufferOffset]), (uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (ETH_TX_BUF_SIZE - bufferOffset));
 | 
			
		||||
            /* Point to next descriptor */
 | 
			
		||||
            DmaTxDesc = (stc_eth_dma_desc_t *)(DmaTxDesc->u32Buf2NextDescAddr);
 | 
			
		||||
            /* Check if the buffer is available */
 | 
			
		||||
            if (0UL != (DmaTxDesc->u32ControlStatus & ETH_DMA_TXDESC_OWN)) {
 | 
			
		||||
                i32Ret = (err_t)ERR_USE;
 | 
			
		||||
                goto error;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            txBuffer = (uint8_t *)(DmaTxDesc->u32Buf1Addr);
 | 
			
		||||
            byteCnt = byteCnt - (ETH_TX_BUF_SIZE - bufferOffset);
 | 
			
		||||
            payloadOffset = payloadOffset + (ETH_TX_BUF_SIZE - bufferOffset);
 | 
			
		||||
            frameLength = frameLength + (ETH_TX_BUF_SIZE - bufferOffset);
 | 
			
		||||
            bufferOffset = 0UL;
 | 
			
		||||
        }
 | 
			
		||||
        /* Copy the remaining bytes */
 | 
			
		||||
        (void)memcpy((uint8_t *) & (txBuffer[bufferOffset]), (uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), byteCnt);
 | 
			
		||||
        bufferOffset = bufferOffset + byteCnt;
 | 
			
		||||
        frameLength = frameLength + byteCnt;
 | 
			
		||||
    }
 | 
			
		||||
    /* Prepare transmit descriptors to give to DMA */
 | 
			
		||||
    if(LL_OK != ETH_DMA_SetTransFrame(&EthHandle, frameLength)) {
 | 
			
		||||
        KPrintf("[%s] Error sending eth DMA frame\n", __func__);
 | 
			
		||||
    }
 | 
			
		||||
    i32Ret = (err_t)ERR_OK;
 | 
			
		||||
 | 
			
		||||
error:
 | 
			
		||||
    /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
 | 
			
		||||
    if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_UNS)) {
 | 
			
		||||
        /* Clear DMA UNS flag */
 | 
			
		||||
        ETH_DMA_ClearStatus(ETH_DMA_FLAG_UNS);
 | 
			
		||||
        /* Resume DMA transmission */
 | 
			
		||||
        WRITE_REG32(CM_ETH->DMA_TXPOLLR, 0UL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return i32Ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief  Should allocate a pbuf and transfer the bytes of the incoming packet from the interface into the pbuf.
 | 
			
		||||
 * @param  netif                        The network interface structure for this ethernetif.
 | 
			
		||||
 * @retval A pbuf filled with the received packet (including MAC header) or NULL on memory error.
 | 
			
		||||
 */
 | 
			
		||||
struct pbuf *low_level_input(struct netif *netif)
 | 
			
		||||
{
 | 
			
		||||
    struct pbuf *p = NULL;
 | 
			
		||||
    struct pbuf *q;
 | 
			
		||||
    uint32_t len;
 | 
			
		||||
    uint8_t *rxBuffer;
 | 
			
		||||
    __IO stc_eth_dma_desc_t *DmaRxDesc;
 | 
			
		||||
    uint32_t byteCnt;
 | 
			
		||||
    uint32_t bufferOffset;
 | 
			
		||||
    uint32_t payloadOffset;
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
 | 
			
		||||
    /* Get received frame */
 | 
			
		||||
    if (LL_OK != ETH_DMA_GetReceiveFrame(&EthHandle)) {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Obtain the size of the packet */
 | 
			
		||||
    len = (EthHandle.stcRxFrame).u32Len;
 | 
			
		||||
    rxBuffer = (uint8_t *)(EthHandle.stcRxFrame).u32Buf;
 | 
			
		||||
    if (len > 0UL) {
 | 
			
		||||
        /* Allocate a pbuf chain of pbufs from the buffer */
 | 
			
		||||
        p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
 | 
			
		||||
        // p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
 | 
			
		||||
    }
 | 
			
		||||
    if (p != NULL) {
 | 
			
		||||
        DmaRxDesc = (EthHandle.stcRxFrame).pstcFSDesc;
 | 
			
		||||
        bufferOffset = 0UL;
 | 
			
		||||
        for (q = p; q != NULL; q = q->next) {
 | 
			
		||||
            byteCnt = q->len;
 | 
			
		||||
            payloadOffset = 0UL;
 | 
			
		||||
 | 
			
		||||
            /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size */
 | 
			
		||||
            while ((byteCnt + bufferOffset) > ETH_RX_BUF_SIZE) {
 | 
			
		||||
                /* Copy data to pbuf */
 | 
			
		||||
                (void)memcpy((uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (uint8_t *) & (rxBuffer[bufferOffset]), (ETH_RX_BUF_SIZE - bufferOffset));
 | 
			
		||||
                /* Point to next descriptor */
 | 
			
		||||
                DmaRxDesc = (stc_eth_dma_desc_t *)(DmaRxDesc->u32Buf2NextDescAddr);
 | 
			
		||||
                rxBuffer = (uint8_t *)(DmaRxDesc->u32Buf1Addr);
 | 
			
		||||
                byteCnt = byteCnt - (ETH_RX_BUF_SIZE - bufferOffset);
 | 
			
		||||
                payloadOffset = payloadOffset + (ETH_RX_BUF_SIZE - bufferOffset);
 | 
			
		||||
                bufferOffset = 0UL;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Copy remaining data in pbuf */
 | 
			
		||||
            (void)memcpy((uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (uint8_t *) & (rxBuffer[bufferOffset]), byteCnt);
 | 
			
		||||
            bufferOffset = bufferOffset + byteCnt;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /* Release descriptors to DMA */
 | 
			
		||||
    DmaRxDesc = (EthHandle.stcRxFrame).pstcFSDesc;
 | 
			
		||||
    for (i = 0UL; i < (EthHandle.stcRxFrame).u32SegCount; i++) {
 | 
			
		||||
        DmaRxDesc->u32ControlStatus |= ETH_DMA_RXDESC_OWN;
 | 
			
		||||
        DmaRxDesc = (stc_eth_dma_desc_t *)(DmaRxDesc->u32Buf2NextDescAddr);
 | 
			
		||||
    }
 | 
			
		||||
    /* Clear Segment_Count */
 | 
			
		||||
    (EthHandle.stcRxFrame).u32SegCount = 0UL;
 | 
			
		||||
 | 
			
		||||
    /* When Rx Buffer unavailable flag is set, clear it and resume reception */
 | 
			
		||||
    if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_RUS)) {
 | 
			
		||||
        /* Clear DMA RUS flag */
 | 
			
		||||
        ETH_DMA_ClearStatus(ETH_DMA_FLAG_RUS);
 | 
			
		||||
        /* Resume DMA reception */
 | 
			
		||||
        WRITE_REG32(CM_ETH->DMA_RXPOLLR, 0UL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return p;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
extern void LwipSetIPTest(int argc, char *argv[]);
 | 
			
		||||
int HwEthInit(void) {
 | 
			
		||||
//   lwip_config_tcp(0, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
 | 
			
		||||
  LwipSetIPTest(1, NULL);
 | 
			
		||||
  return EOK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -46,14 +46,15 @@ Modification:
 | 
			
		|||
/*******************************************************************************
 | 
			
		||||
 * Include files
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
#include <hardware_ethernetif.h>
 | 
			
		||||
#include <hc32_ll_eth.h>
 | 
			
		||||
#include <connect_ethernet.h>
 | 
			
		||||
#include <hc32_ll_gpio.h>
 | 
			
		||||
#include <hc32_ll_utility.h>
 | 
			
		||||
#include <hc32_ll_fcg.h>
 | 
			
		||||
#include <lwip/timeouts.h>
 | 
			
		||||
#include <netif/etharp.h>
 | 
			
		||||
 | 
			
		||||
#include <xs_isr.h>
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @addtogroup HC32F4A0_DDL_Examples
 | 
			
		||||
 * @{
 | 
			
		||||
| 
						 | 
				
			
			@ -71,33 +72,7 @@ Modification:
 | 
			
		|||
/*******************************************************************************
 | 
			
		||||
 * Local pre-processor symbols/macros ('#define')
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
/* Define those to better describe your network interface. */
 | 
			
		||||
#define IFNAME0                         'h'
 | 
			
		||||
#define IFNAME1                         'd'
 | 
			
		||||
 | 
			
		||||
/* PHY hardware reset time */
 | 
			
		||||
#define PHY_HW_RST_DELAY                (0x40U)
 | 
			
		||||
 | 
			
		||||
/* ETH_RST = PH11 */
 | 
			
		||||
#define ETH_RST_PORT                    (GPIO_PORT_H)
 | 
			
		||||
#define ETH_RST_PIN                     (GPIO_PIN_11)
 | 
			
		||||
 | 
			
		||||
/* ETH_LINK_LED = PD00 LED2 */
 | 
			
		||||
#define ETH_LINK_LED_PORT               (GPIO_PORT_D)
 | 
			
		||||
#define ETH_LINK_LED_PIN                (GPIO_PIN_00)
 | 
			
		||||
 | 
			
		||||
//#define ETHERNET_LOOPBACK_TEST
 | 
			
		||||
#ifdef ETHERNET_LOOPBACK_TEST
 | 
			
		||||
 | 
			
		||||
#define USER_KEY_PORT                  (GPIO_PORT_I)
 | 
			
		||||
#define USER_KEY_PIN                   (GPIO_PIN_07)
 | 
			
		||||
 | 
			
		||||
/* ethe global netif */
 | 
			
		||||
static struct netif testnetif;
 | 
			
		||||
/* eth tx buffer */
 | 
			
		||||
static struct pbuf txPbuf;
 | 
			
		||||
static char txBuf[] = "Ethernet Loop-Back Test";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Global variable definitions (declared in header file with 'extern')
 | 
			
		||||
| 
						 | 
				
			
			@ -110,19 +85,7 @@ static char txBuf[] = "Ethernet Loop-Back Test";
 | 
			
		|||
/*******************************************************************************
 | 
			
		||||
 * Local variable definitions ('static')
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
/* Global Ethernet handle*/
 | 
			
		||||
static stc_eth_handle_t EthHandle;
 | 
			
		||||
/* Ethernet Tx DMA Descriptor */
 | 
			
		||||
__ALIGN_BEGIN static stc_eth_dma_desc_t EthDmaTxDscrTab[ETH_TX_BUF_NUM];
 | 
			
		||||
/* Ethernet Rx DMA Descriptor */
 | 
			
		||||
__ALIGN_BEGIN static stc_eth_dma_desc_t EthDmaRxDscrTab[ETH_RX_BUF_NUM];
 | 
			
		||||
/* Ethernet Transmit Buffer */
 | 
			
		||||
__ALIGN_BEGIN static uint8_t EthTxBuff[ETH_TX_BUF_NUM][ETH_TX_BUF_SIZE];
 | 
			
		||||
/* Ethernet Receive Buffer */
 | 
			
		||||
__ALIGN_BEGIN static uint8_t EthRxBuff[ETH_RX_BUF_NUM][ETH_RX_BUF_SIZE];
 | 
			
		||||
 | 
			
		||||
/* Ethernet link status */
 | 
			
		||||
static uint8_t u8PhyLinkStatus = 0U, u8EthInitStatus = 0U;
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Function implementation - global ('extern') and local ('static')
 | 
			
		||||
| 
						 | 
				
			
			@ -132,22 +95,12 @@ static uint8_t u8PhyLinkStatus = 0U, u8EthInitStatus = 0U;
 | 
			
		|||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
void *ethernetif_config_enet_set(uint8_t enet_port)
 | 
			
		||||
{
 | 
			
		||||
    return NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Time_Update_LwIP(void)
 | 
			
		||||
{
 | 
			
		||||
    //no need to do
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief  Initializes the Ethernet GPIO.
 | 
			
		||||
 * @param  None
 | 
			
		||||
 * @retval None
 | 
			
		||||
 */
 | 
			
		||||
static void Ethernet_GpioInit(void)
 | 
			
		||||
void Ethernet_GpioInit(void)
 | 
			
		||||
{
 | 
			
		||||
    /* ETH_RST */
 | 
			
		||||
    stc_gpio_init_t stcGpioInit;
 | 
			
		||||
| 
						 | 
				
			
			@ -227,241 +180,12 @@ static void Ethernet_GpioInit(void)
 | 
			
		|||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief  In this function, the hardware should be initialized.
 | 
			
		||||
 * @param  netif                         The already initialized network interface structure for this ethernetif.
 | 
			
		||||
 * @retval int32_t:
 | 
			
		||||
 *           - LL_OK: Initialize success
 | 
			
		||||
 *           - LL_ERR: Initialize failed
 | 
			
		||||
 */
 | 
			
		||||
static int32_t low_level_init(struct netif *netif)
 | 
			
		||||
{
 | 
			
		||||
    int32_t i32Ret = LL_ERR;
 | 
			
		||||
    stc_eth_init_t stcEthInit;
 | 
			
		||||
    uint16_t u16RegVal;
 | 
			
		||||
 | 
			
		||||
    /* Enable ETH clock */
 | 
			
		||||
    FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_ETHMAC, ENABLE);
 | 
			
		||||
    /* Init Ethernet GPIO */
 | 
			
		||||
    Ethernet_GpioInit();
 | 
			
		||||
    /* Reset ETHERNET */
 | 
			
		||||
    (void)ETH_DeInit();
 | 
			
		||||
    /* Configure structure initialization */
 | 
			
		||||
    (void)ETH_CommStructInit(&EthHandle.stcCommInit);
 | 
			
		||||
    (void)ETH_StructInit(&stcEthInit);
 | 
			
		||||
#ifdef ETH_INTERFACE_RMII
 | 
			
		||||
    EthHandle.stcCommInit.u32Interface  = ETH_MAC_IF_RMII;
 | 
			
		||||
#else
 | 
			
		||||
    EthHandle.stcCommInit.u32Interface  = ETH_MAC_IF_MII;
 | 
			
		||||
#endif
 | 
			
		||||
    stcEthInit.stcMacInit.u32ReceiveAll = ETH_MAC_RX_ALL_ENABLE;
 | 
			
		||||
 | 
			
		||||
    /* Configure ethernet peripheral */
 | 
			
		||||
    if (LL_OK == ETH_Init(&EthHandle, &stcEthInit)) {
 | 
			
		||||
        u8EthInitStatus = 1U;
 | 
			
		||||
        i32Ret = LL_OK;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef ETHERNET_LOOPBACK_TEST
 | 
			
		||||
    /* Enable PHY loopback */
 | 
			
		||||
    (void)ETH_PHY_LoopBackCmd(&EthHandle, ENABLE);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* Initialize Tx Descriptors list: Chain Mode */
 | 
			
		||||
    (void)ETH_DMA_TxDescListInit(&EthHandle, EthDmaTxDscrTab, &EthTxBuff[0][0], ETH_TX_BUF_NUM);
 | 
			
		||||
    /* Initialize Rx Descriptors list: Chain Mode  */
 | 
			
		||||
    (void)ETH_DMA_RxDescListInit(&EthHandle, EthDmaRxDscrTab, &EthRxBuff[0][0], ETH_RX_BUF_NUM);
 | 
			
		||||
 | 
			
		||||
    /* set MAC hardware address length */
 | 
			
		||||
    netif->hwaddr_len = 6U;
 | 
			
		||||
    /* set MAC hardware address */
 | 
			
		||||
    netif->hwaddr[0] = (EthHandle.stcCommInit).au8MacAddr[0];
 | 
			
		||||
    netif->hwaddr[1] = (EthHandle.stcCommInit).au8MacAddr[1];
 | 
			
		||||
    netif->hwaddr[2] = (EthHandle.stcCommInit).au8MacAddr[2];
 | 
			
		||||
    netif->hwaddr[3] = (EthHandle.stcCommInit).au8MacAddr[3];
 | 
			
		||||
    netif->hwaddr[4] = (EthHandle.stcCommInit).au8MacAddr[4];
 | 
			
		||||
    netif->hwaddr[5] = (EthHandle.stcCommInit).au8MacAddr[5];
 | 
			
		||||
    /* maximum transfer unit */
 | 
			
		||||
    netif->mtu = 1500U;
 | 
			
		||||
 | 
			
		||||
    /* device capabilities */
 | 
			
		||||
    netif->flags |= NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
 | 
			
		||||
 | 
			
		||||
    /* Enable MAC and DMA transmission and reception */
 | 
			
		||||
    (void)ETH_Start();
 | 
			
		||||
 | 
			
		||||
    /* Configure PHY LED mode */
 | 
			
		||||
    u16RegVal = PHY_PAGE_ADDR_7;
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal);
 | 
			
		||||
    (void)ETH_PHY_ReadReg(&EthHandle, PHY_P7_IWLFR, &u16RegVal);
 | 
			
		||||
    MODIFY_REG16(u16RegVal, PHY_LED_SELECT, PHY_LED_SELECT_10);
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_P7_IWLFR, u16RegVal);
 | 
			
		||||
    u16RegVal = PHY_PAGE_ADDR_0;
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal);
 | 
			
		||||
 | 
			
		||||
#ifdef ETH_INTERFACE_RMII
 | 
			
		||||
    /* Disable Power Saving Mode */
 | 
			
		||||
    (void)ETH_PHY_ReadReg(&EthHandle, PHY_PSMR, &u16RegVal);
 | 
			
		||||
    CLR_REG16_BIT(u16RegVal, PHY_EN_PWR_SAVE);
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSMR, u16RegVal);
 | 
			
		||||
 | 
			
		||||
    /* Configure PHY to generate an interrupt when Eth Link state changes */
 | 
			
		||||
    u16RegVal = PHY_PAGE_ADDR_7;
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal);
 | 
			
		||||
    /* Enable Interrupt on change of link status */
 | 
			
		||||
    (void)ETH_PHY_ReadReg(&EthHandle, PHY_P7_IWLFR, &u16RegVal);
 | 
			
		||||
    SET_REG16_BIT(u16RegVal, PHY_INT_LINK_CHANGE);
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_P7_IWLFR, u16RegVal);
 | 
			
		||||
    u16RegVal = PHY_PAGE_ADDR_0;
 | 
			
		||||
    (void)ETH_PHY_WriteReg(&EthHandle, PHY_PSR, u16RegVal);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return i32Ret;
 | 
			
		||||
void *ethernetif_config_enet_set(uint8_t enet_port) {
 | 
			
		||||
    return NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief  This function should do the actual transmission of the packet.
 | 
			
		||||
 * @param  netif                        The network interface structure for this ethernetif.
 | 
			
		||||
 * @param  p                            The MAC packet to send.
 | 
			
		||||
 * @retval int32_t:
 | 
			
		||||
 *           - LL_OK: The packet could be sent
 | 
			
		||||
 *           - LL_ERR: The packet couldn't be sent
 | 
			
		||||
 */
 | 
			
		||||
err_t low_level_output(struct netif *netif, struct pbuf *p)
 | 
			
		||||
{
 | 
			
		||||
    err_t i32Ret;
 | 
			
		||||
    struct pbuf *q;
 | 
			
		||||
    uint8_t *txBuffer;
 | 
			
		||||
    __IO stc_eth_dma_desc_t *DmaTxDesc;
 | 
			
		||||
    uint32_t byteCnt;
 | 
			
		||||
    uint32_t frameLength = 0UL;
 | 
			
		||||
    uint32_t bufferOffset;
 | 
			
		||||
    uint32_t payloadOffset;
 | 
			
		||||
 | 
			
		||||
    DmaTxDesc = EthHandle.stcTxDesc;
 | 
			
		||||
    txBuffer = (uint8_t *)((EthHandle.stcTxDesc)->u32Buf1Addr);
 | 
			
		||||
    bufferOffset = 0UL;
 | 
			
		||||
    /* Copy frame from pbufs to driver buffers */
 | 
			
		||||
    for (q = p; q != NULL; q = q->next) {
 | 
			
		||||
        /* If this buffer isn't available, goto error */
 | 
			
		||||
        if (0UL != (DmaTxDesc->u32ControlStatus & ETH_DMA_TXDESC_OWN)) {
 | 
			
		||||
            i32Ret = LL_ERR;
 | 
			
		||||
            goto error;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* Get bytes in current buffer */
 | 
			
		||||
        byteCnt = q->len;
 | 
			
		||||
        payloadOffset = 0UL;
 | 
			
		||||
        /* Check if the length of data to copy is bigger than Tx buffer size */
 | 
			
		||||
        while ((byteCnt + bufferOffset) > ETH_TX_BUF_SIZE) {
 | 
			
		||||
            /* Copy data to Tx buffer*/
 | 
			
		||||
            (void)memcpy((uint8_t *) & (txBuffer[bufferOffset]), (uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (ETH_TX_BUF_SIZE - bufferOffset));
 | 
			
		||||
            /* Point to next descriptor */
 | 
			
		||||
            DmaTxDesc = (stc_eth_dma_desc_t *)(DmaTxDesc->u32Buf2NextDescAddr);
 | 
			
		||||
            /* Check if the buffer is available */
 | 
			
		||||
            if (0UL != (DmaTxDesc->u32ControlStatus & ETH_DMA_TXDESC_OWN)) {
 | 
			
		||||
                i32Ret = LL_ERR;
 | 
			
		||||
                goto error;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            txBuffer = (uint8_t *)(DmaTxDesc->u32Buf1Addr);
 | 
			
		||||
            byteCnt = byteCnt - (ETH_TX_BUF_SIZE - bufferOffset);
 | 
			
		||||
            payloadOffset = payloadOffset + (ETH_TX_BUF_SIZE - bufferOffset);
 | 
			
		||||
            frameLength = frameLength + (ETH_TX_BUF_SIZE - bufferOffset);
 | 
			
		||||
            bufferOffset = 0UL;
 | 
			
		||||
        }
 | 
			
		||||
        /* Copy the remaining bytes */
 | 
			
		||||
        (void)memcpy((uint8_t *) & (txBuffer[bufferOffset]), (uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), byteCnt);
 | 
			
		||||
        bufferOffset = bufferOffset + byteCnt;
 | 
			
		||||
        frameLength = frameLength + byteCnt;
 | 
			
		||||
    }
 | 
			
		||||
    /* Prepare transmit descriptors to give to DMA */
 | 
			
		||||
    (void)ETH_DMA_SetTransFrame(&EthHandle, frameLength);
 | 
			
		||||
    i32Ret = LL_OK;
 | 
			
		||||
 | 
			
		||||
error:
 | 
			
		||||
    /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */
 | 
			
		||||
    if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_UNS)) {
 | 
			
		||||
        /* Clear DMA UNS flag */
 | 
			
		||||
        ETH_DMA_ClearStatus(ETH_DMA_FLAG_UNS);
 | 
			
		||||
        /* Resume DMA transmission */
 | 
			
		||||
        WRITE_REG32(CM_ETH->DMA_TXPOLLR, 0UL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return i32Ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @brief  Should allocate a pbuf and transfer the bytes of the incoming packet from the interface into the pbuf.
 | 
			
		||||
 * @param  netif                        The network interface structure for this ethernetif.
 | 
			
		||||
 * @retval A pbuf filled with the received packet (including MAC header) or NULL on memory error.
 | 
			
		||||
 */
 | 
			
		||||
static struct pbuf *low_level_input(struct netif *netif)
 | 
			
		||||
{
 | 
			
		||||
    struct pbuf *p = NULL;
 | 
			
		||||
    struct pbuf *q;
 | 
			
		||||
    uint32_t len;
 | 
			
		||||
    uint8_t *rxBuffer;
 | 
			
		||||
    __IO stc_eth_dma_desc_t *DmaRxDesc;
 | 
			
		||||
    uint32_t byteCnt;
 | 
			
		||||
    uint32_t bufferOffset;
 | 
			
		||||
    uint32_t payloadOffset;
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
 | 
			
		||||
    /* Get received frame */
 | 
			
		||||
    if (LL_OK != ETH_DMA_GetReceiveFrame(&EthHandle)) {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Obtain the size of the packet */
 | 
			
		||||
    len = (EthHandle.stcRxFrame).u32Len;
 | 
			
		||||
    rxBuffer = (uint8_t *)(EthHandle.stcRxFrame).u32Buf;
 | 
			
		||||
    if (len > 0UL) {
 | 
			
		||||
        /* Allocate a pbuf chain of pbufs from the buffer */
 | 
			
		||||
        p = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM);
 | 
			
		||||
    }
 | 
			
		||||
    if (p != NULL) {
 | 
			
		||||
        DmaRxDesc = (EthHandle.stcRxFrame).pstcFSDesc;
 | 
			
		||||
        bufferOffset = 0UL;
 | 
			
		||||
        for (q = p; q != NULL; q = q->next) {
 | 
			
		||||
            byteCnt = q->len;
 | 
			
		||||
            payloadOffset = 0UL;
 | 
			
		||||
 | 
			
		||||
            /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size */
 | 
			
		||||
            while ((byteCnt + bufferOffset) > ETH_RX_BUF_SIZE) {
 | 
			
		||||
                /* Copy data to pbuf */
 | 
			
		||||
                (void)memcpy((uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (uint8_t *) & (rxBuffer[bufferOffset]), (ETH_RX_BUF_SIZE - bufferOffset));
 | 
			
		||||
                /* Point to next descriptor */
 | 
			
		||||
                DmaRxDesc = (stc_eth_dma_desc_t *)(DmaRxDesc->u32Buf2NextDescAddr);
 | 
			
		||||
                rxBuffer = (uint8_t *)(DmaRxDesc->u32Buf1Addr);
 | 
			
		||||
                byteCnt = byteCnt - (ETH_RX_BUF_SIZE - bufferOffset);
 | 
			
		||||
                payloadOffset = payloadOffset + (ETH_RX_BUF_SIZE - bufferOffset);
 | 
			
		||||
                bufferOffset = 0UL;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            /* Copy remaining data in pbuf */
 | 
			
		||||
            (void)memcpy((uint8_t *) & (((uint8_t *)q->payload)[payloadOffset]), (uint8_t *) & (rxBuffer[bufferOffset]), byteCnt);
 | 
			
		||||
            bufferOffset = bufferOffset + byteCnt;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    /* Release descriptors to DMA */
 | 
			
		||||
    DmaRxDesc = (EthHandle.stcRxFrame).pstcFSDesc;
 | 
			
		||||
    for (i = 0UL; i < (EthHandle.stcRxFrame).u32SegCount; i++) {
 | 
			
		||||
        DmaRxDesc->u32ControlStatus |= ETH_DMA_RXDESC_OWN;
 | 
			
		||||
        DmaRxDesc = (stc_eth_dma_desc_t *)(DmaRxDesc->u32Buf2NextDescAddr);
 | 
			
		||||
    }
 | 
			
		||||
    /* Clear Segment_Count */
 | 
			
		||||
    (EthHandle.stcRxFrame).u32SegCount = 0UL;
 | 
			
		||||
 | 
			
		||||
    /* When Rx Buffer unavailable flag is set, clear it and resume reception */
 | 
			
		||||
    if (RESET != ETH_DMA_GetStatus(ETH_DMA_FLAG_RUS)) {
 | 
			
		||||
        /* Clear DMA RUS flag */
 | 
			
		||||
        ETH_DMA_ClearStatus(ETH_DMA_FLAG_RUS);
 | 
			
		||||
        /* Resume DMA reception */
 | 
			
		||||
        WRITE_REG32(CM_ETH->DMA_RXPOLLR, 0UL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return p;
 | 
			
		||||
void Time_Update_LwIP(void) {
 | 
			
		||||
    //no need to do
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -485,8 +209,8 @@ err_t ethernetif_init(struct netif *netif)
 | 
			
		|||
    * 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 = ðarp_output;
 | 
			
		||||
    netif->linkoutput = &low_level_output;
 | 
			
		||||
    netif->output = etharp_output;
 | 
			
		||||
    netif->linkoutput = low_level_output;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    /* initialize the hardware */
 | 
			
		||||
| 
						 | 
				
			
			@ -498,34 +222,38 @@ err_t ethernetif_init(struct netif *netif)
 | 
			
		|||
 * @param  netif                        The network interface structure for this ethernetif.
 | 
			
		||||
 * @retval None
 | 
			
		||||
 */
 | 
			
		||||
void ethernetif_input(struct netif *netif)
 | 
			
		||||
void ethernetif_input(void *netif_arg)
 | 
			
		||||
{
 | 
			
		||||
    err_t err;
 | 
			
		||||
    struct pbuf *p;
 | 
			
		||||
    struct netif *netif = (struct netif *)netif_arg;
 | 
			
		||||
    x_base critical_lock;
 | 
			
		||||
 | 
			
		||||
    /* Move received packet into a new pbuf */
 | 
			
		||||
    while (1) {
 | 
			
		||||
        sys_arch_sem_wait(get_eth_recv_sem(), WAITING_FOREVER);
 | 
			
		||||
        while(1) {
 | 
			
		||||
            p = low_level_input(netif);
 | 
			
		||||
 | 
			
		||||
#ifndef ETHERNET_LOOPBACK_TEST
 | 
			
		||||
    /* No packet could be read, silently ignore this */
 | 
			
		||||
    if (NULL == p) {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
            /* Entry point to the LwIP stack */
 | 
			
		||||
    err = netif->input(p, netif);
 | 
			
		||||
    if (err != (err_t)ERR_OK) {
 | 
			
		||||
            if (p != NULL) {
 | 
			
		||||
                if (netif->input(p, netif) != ERR_OK) {
 | 
			
		||||
                    LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
 | 
			
		||||
        (void)pbuf_free(p);
 | 
			
		||||
                    KPrintf("ethernetif_input: IP input error\n");
 | 
			
		||||
                    pbuf_free(p);
 | 
			
		||||
                    p = NULL;
 | 
			
		||||
                }
 | 
			
		||||
#endif
 | 
			
		||||
#ifdef ETHERNET_LOOPBACK_TEST
 | 
			
		||||
            } else {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
#else
 | 
			
		||||
            /* No packet could be read, silently ignore this */
 | 
			
		||||
            if (p != NULL) {
 | 
			
		||||
                EthernetIF_InputCallback(netif, p);
 | 
			
		||||
                free(p);
 | 
			
		||||
            }
 | 
			
		||||
#endif
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
| 
						 | 
				
			
			@ -725,8 +453,7 @@ __WEAKDEF void EthernetIF_NotifyLinkChange(struct netif *netif)
 | 
			
		|||
 * @param  p                            The MAC packet to receive
 | 
			
		||||
 * @retval None
 | 
			
		||||
 */
 | 
			
		||||
__WEAKDEF void EthernetIF_InputCallback(struct netif *netif, struct pbuf *p)
 | 
			
		||||
{
 | 
			
		||||
__WEAKDEF void EthernetIF_InputCallback(struct netif *netif, struct pbuf *p) {
 | 
			
		||||
    /* This is function could be implemented in user file when the callback is needed */
 | 
			
		||||
#ifdef ETHERNET_LOOPBACK_TEST
 | 
			
		||||
    if ((0 == (memcmp(p->payload, txPbuf.payload, p->len))) && (p->len == txPbuf.len)) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,11 +22,49 @@
 | 
			
		|||
#define CONNECT_ETHERNET_H
 | 
			
		||||
 | 
			
		||||
#include "hardware_ethernetif.h"
 | 
			
		||||
#include <sys_arch.h>
 | 
			
		||||
#include <hc32_ll_eth.h>
 | 
			
		||||
#include <hardware_irq.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
 extern "C" {
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
struct hc32_irq_config
 | 
			
		||||
{
 | 
			
		||||
    IRQn_Type       irq_num;
 | 
			
		||||
    uint32_t        irq_prio;
 | 
			
		||||
    en_int_src_t    int_src;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* Global Ethernet handle*/
 | 
			
		||||
static stc_eth_handle_t EthHandle;
 | 
			
		||||
/* Ethernet Tx DMA Descriptor */
 | 
			
		||||
__ALIGN_BEGIN static stc_eth_dma_desc_t EthDmaTxDscrTab[ETH_TX_BUF_NUM];
 | 
			
		||||
/* Ethernet Rx DMA Descriptor */
 | 
			
		||||
__ALIGN_BEGIN static stc_eth_dma_desc_t EthDmaRxDscrTab[ETH_RX_BUF_NUM];
 | 
			
		||||
/* Ethernet Transmit Buffer */
 | 
			
		||||
__ALIGN_BEGIN static uint8_t EthTxBuff[ETH_TX_BUF_NUM][ETH_TX_BUF_SIZE];
 | 
			
		||||
/* Ethernet Receive Buffer */
 | 
			
		||||
__ALIGN_BEGIN static uint8_t EthRxBuff[ETH_RX_BUF_NUM][ETH_RX_BUF_SIZE];
 | 
			
		||||
 | 
			
		||||
/* Ethernet link status */
 | 
			
		||||
static uint8_t u8PhyLinkStatus = 0U, u8EthInitStatus = 0U;
 | 
			
		||||
 | 
			
		||||
static struct Hc32IrqConfig eth_irq_config = {
 | 
			
		||||
    .irq_num    = BSP_ETH_IRQ_NUM,
 | 
			
		||||
    .irq_prio   = BSP_ETH_IRQ_PRIO,                     
 | 
			
		||||
    .int_src    = INT_SRC_ETH_GLB_INT, 
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void Ethernet_GpioInit(void);
 | 
			
		||||
int32_t low_level_init(struct netif *netif);
 | 
			
		||||
err_t low_level_output(struct netif *netif, struct pbuf *p);
 | 
			
		||||
struct pbuf *low_level_input(struct netif *netif);
 | 
			
		||||
 | 
			
		||||
int HwEthInit(void);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifdef __cplusplus
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -133,9 +133,37 @@ extern "C"
 | 
			
		|||
 * @addtogroup ETH_IF_Global_Functions
 | 
			
		||||
 * @{
 | 
			
		||||
 */
 | 
			
		||||
/* Define those to better describe your network interface. */
 | 
			
		||||
#define IFNAME0                         'h'
 | 
			
		||||
#define IFNAME1                         'd'
 | 
			
		||||
 | 
			
		||||
/* PHY hardware reset time */
 | 
			
		||||
#define PHY_HW_RST_DELAY                (0x40U)
 | 
			
		||||
 | 
			
		||||
/* ETH_RST = PH11 */
 | 
			
		||||
#define ETH_RST_PORT                    (GPIO_PORT_H)
 | 
			
		||||
#define ETH_RST_PIN                     (GPIO_PIN_11)
 | 
			
		||||
 | 
			
		||||
/* ETH_LINK_LED = PD00 LED2 */
 | 
			
		||||
#define ETH_LINK_LED_PORT               (GPIO_PORT_D)
 | 
			
		||||
#define ETH_LINK_LED_PIN                (GPIO_PIN_00)
 | 
			
		||||
 | 
			
		||||
//#define ETHERNET_LOOPBACK_TEST
 | 
			
		||||
#ifdef ETHERNET_LOOPBACK_TEST
 | 
			
		||||
 | 
			
		||||
#define USER_KEY_PORT                  (GPIO_PORT_I)
 | 
			
		||||
#define USER_KEY_PIN                   (GPIO_PIN_07)
 | 
			
		||||
 | 
			
		||||
/* ethe global netif */
 | 
			
		||||
static struct netif testnetif;
 | 
			
		||||
/* eth tx buffer */
 | 
			
		||||
static struct pbuf txPbuf;
 | 
			
		||||
static char txBuf[] = "Ethernet Loop-Back Test";
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
err_t   ethernetif_init(struct netif *netif);
 | 
			
		||||
void    ethernetif_input(struct netif *netif);
 | 
			
		||||
err_t low_level_output(struct netif *netif, struct pbuf *p);
 | 
			
		||||
void    ethernetif_input(void *netif);
 | 
			
		||||
// err_t low_level_output(struct netif *netif, struct pbuf *p);
 | 
			
		||||
 | 
			
		||||
void    EthernetIF_CheckLink(struct netif *netif);
 | 
			
		||||
void    EthernetIF_UpdateLink(struct netif *netif);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -163,7 +163,7 @@ static int BoardHwtimerDevBend(void)
 | 
			
		|||
    return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/*K210 BOARD HWTIMER INIT*/
 | 
			
		||||
/*HC32F4A0 BOARD HWTIMER INIT*/
 | 
			
		||||
int HwTimerInit(void)
 | 
			
		||||
{
 | 
			
		||||
    x_err_t ret = EOK;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
				
			
			@ -2,10 +2,12 @@ SRC_DIR += api
 | 
			
		|||
SRC_DIR += arch
 | 
			
		||||
SRC_DIR += core
 | 
			
		||||
SRC_DIR += netif
 | 
			
		||||
SRC_DIR += apps
 | 
			
		||||
 | 
			
		||||
LWIP_DIR += api
 | 
			
		||||
LWIP_DIR += arch
 | 
			
		||||
LWIP_DIR += core
 | 
			
		||||
LWIP_DIR += netif
 | 
			
		||||
LWIP_DIR += apps
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,3 @@
 | 
			
		|||
SRC_FILES += lwiperf/lwiperf.c http/http_client.c
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +64,8 @@
 | 
			
		|||
 * HTTPC_DEBUG: Enable debugging for HTTP client.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef HTTPC_DEBUG
 | 
			
		||||
#define HTTPC_DEBUG                 LWIP_DBG_OFF
 | 
			
		||||
#define HTTPC_DEBUG                 LWIP_DBG_ON
 | 
			
		||||
// #define HTTPC_DEBUG                 LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/** Set this to 1 to keep server name and uri in request state */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,6 +30,193 @@
 | 
			
		|||
#ifndef __LWIPOPTS_H__
 | 
			
		||||
#define __LWIPOPTS_H__
 | 
			
		||||
 | 
			
		||||
/* ---------- Debug options ---------- */
 | 
			
		||||
#ifndef LWIP_DEBUG
 | 
			
		||||
#define LWIP_DEBUG  1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_DEBUG
 | 
			
		||||
#ifdef LWIP_SYS_DEBUG
 | 
			
		||||
#define SYS_DEBUG                   LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define SYS_DEBUG                   LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_ETHARP_DEBUG
 | 
			
		||||
#define ETHARP_DEBUG                LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define ETHARP_DEBUG                LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_PPP_DEBUG
 | 
			
		||||
#define PPP_DEBUG                   LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define PPP_DEBUG                   LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_MEM_DEBUG
 | 
			
		||||
#define MEM_DEBUG                   LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define MEM_DEBUG                   LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_MEMP_DEBUG
 | 
			
		||||
#define MEMP_DEBUG                  LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define MEMP_DEBUG                  LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_PBUF_DEBUG
 | 
			
		||||
#define PBUF_DEBUG                  LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define PBUF_DEBUG                  LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_API_LIB_DEBUG
 | 
			
		||||
#define API_LIB_DEBUG               LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define API_LIB_DEBUG               LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_API_MSG_DEBUG
 | 
			
		||||
#define API_MSG_DEBUG               LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define API_MSG_DEBUG               LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_TCPIP_DEBUG
 | 
			
		||||
#define TCPIP_DEBUG                 LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define TCPIP_DEBUG                 LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_NETIF_DEBUG
 | 
			
		||||
#define NETIF_DEBUG                 LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define NETIF_DEBUG                 LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_SOCKETS_DEBUG
 | 
			
		||||
#define SOCKETS_DEBUG               LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define SOCKETS_DEBUG               LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_DNS_DEBUG
 | 
			
		||||
#define DNS_DEBUG                   LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define DNS_DEBUG                   LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_AUTOIP_DEBUG
 | 
			
		||||
#define AUTOIP_DEBUG                LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define AUTOIP_DEBUG                LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_DHCP_DEBUG
 | 
			
		||||
#define DHCP_DEBUG                  LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define DHCP_DEBUG                  LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_IP_DEBUG
 | 
			
		||||
#define IP_DEBUG                    LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define IP_DEBUG                    LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_IP_REASS_DEBUG
 | 
			
		||||
#define IP_REASS_DEBUG              LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define IP_REASS_DEBUG              LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_ICMP_DEBUG
 | 
			
		||||
#define ICMP_DEBUG                  LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define ICMP_DEBUG                  LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_IGMP_DEBUG
 | 
			
		||||
#define IGMP_DEBUG                  LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define IGMP_DEBUG                  LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_UDP_DEBUG
 | 
			
		||||
#define UDP_DEBUG                   LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define UDP_DEBUG                   LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_TCP_DEBUG
 | 
			
		||||
#define TCP_DEBUG                   LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define TCP_DEBUG                   LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_TCP_INPUT_DEBUG
 | 
			
		||||
#define TCP_INPUT_DEBUG             LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define TCP_INPUT_DEBUG             LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_TCP_OUTPUT_DEBUG
 | 
			
		||||
#define TCP_OUTPUT_DEBUG            LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define TCP_OUTPUT_DEBUG            LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_TCP_RTO_DEBUG
 | 
			
		||||
#define TCP_RTO_DEBUG               LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define TCP_RTO_DEBUG               LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_TCP_CWND_DEBUG
 | 
			
		||||
#define TCP_CWND_DEBUG              LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define TCP_CWND_DEBUG              LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_TCP_WND_DEBUG
 | 
			
		||||
#define TCP_WND_DEBUG               LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define TCP_WND_DEBUG               LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_TCP_FR_DEBUG
 | 
			
		||||
#define TCP_FR_DEBUG                LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define TCP_FR_DEBUG                LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_TCP_QLEN_DEBUG
 | 
			
		||||
#define TCP_QLEN_DEBUG              LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define TCP_QLEN_DEBUG              LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_TCP_RST_DEBUG
 | 
			
		||||
#define TCP_RST_DEBUG               LWIP_DBG_ON
 | 
			
		||||
#else
 | 
			
		||||
#define TCP_RST_DEBUG               LWIP_DBG_OFF
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#endif /* LWIP_DEBUG */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define LWIP_TIMEVAL_PRIVATE    0
 | 
			
		||||
#define LWIP_NO_UNISTD_H        0
 | 
			
		||||
#define LWIP_NO_STDDEF_H        0
 | 
			
		||||
#define LWIP_NO_STDINT_H        0
 | 
			
		||||
#define LWIP_NO_INTTYPES_H      0
 | 
			
		||||
#define LWIP_NO_LIMITS_H        0
 | 
			
		||||
#define LWIP_NO_CTYPE_H         0
 | 
			
		||||
#define LWIP_SOCKET_SELECT      1
 | 
			
		||||
#define LWIP_SOCKET_POLL        1
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
 | 
			
		||||
 * critical regions during buffer allocation, deallocation and memory
 | 
			
		||||
| 
						 | 
				
			
			@ -57,35 +244,40 @@
 | 
			
		|||
 | 
			
		||||
/* 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. */
 | 
			
		||||
#define MEM_SIZE                (25*1024)
 | 
			
		||||
#define MEM_SIZE                (64*1024)
 | 
			
		||||
 | 
			
		||||
/* MEMP_NUM_PBUF: the number of memp struct pbufs. If the application
 | 
			
		||||
   sends a lot of data out of ROM (or other static memory), this
 | 
			
		||||
   should be set high. */
 | 
			
		||||
#define MEMP_NUM_PBUF           15
 | 
			
		||||
#define MEMP_NUM_PBUF           32
 | 
			
		||||
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
 | 
			
		||||
   per active UDP "connection". */
 | 
			
		||||
#define MEMP_NUM_UDP_PCB        4
 | 
			
		||||
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
 | 
			
		||||
   connections. */
 | 
			
		||||
#define MEMP_NUM_TCP_PCB        4
 | 
			
		||||
#define MEMP_NUM_TCP_PCB        64
 | 
			
		||||
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
 | 
			
		||||
   connections. */
 | 
			
		||||
#define MEMP_NUM_TCP_PCB_LISTEN 2
 | 
			
		||||
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
 | 
			
		||||
   segments. */
 | 
			
		||||
#define MEMP_NUM_TCP_SEG        20
 | 
			
		||||
#define MEMP_NUM_TCP_SEG        256
 | 
			
		||||
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
 | 
			
		||||
   timeouts. */
 | 
			
		||||
#define MEMP_NUM_SYS_TIMEOUT    6
 | 
			
		||||
 | 
			
		||||
// #define MEMP_NUM_SYS_TIMEOUT    6
 | 
			
		||||
#define MEMP_NUM_SYS_TIMEOUT       (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + (2*LWIP_IPV6)) : 0))
 | 
			
		||||
 | 
			
		||||
/* ---------- Pbuf options ---------- */
 | 
			
		||||
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
 | 
			
		||||
#define PBUF_POOL_SIZE          20
 | 
			
		||||
#define PBUF_POOL_SIZE          255
 | 
			
		||||
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
 | 
			
		||||
// #define PBUF_POOL_BUFSIZE       1024
 | 
			
		||||
#define PBUF_POOL_BUFSIZE       LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)
 | 
			
		||||
 | 
			
		||||
/* ---------- ARP options ---------- */
 | 
			
		||||
#define LWIP_ARP                    1
 | 
			
		||||
#define ARP_TABLE_SIZE              10
 | 
			
		||||
#define ARP_QUEUEING                1
 | 
			
		||||
 | 
			
		||||
/* ---------- TCP options ---------- */
 | 
			
		||||
#define LWIP_TCP                1
 | 
			
		||||
| 
						 | 
				
			
			@ -93,7 +285,7 @@ a lot of data that needs to be copied, this should be set high. */
 | 
			
		|||
 | 
			
		||||
/* Controls if TCP should queue segments that arrive out of
 | 
			
		||||
   order. Define to 0 if your device is low on memory. */
 | 
			
		||||
#define TCP_QUEUE_OOSEQ         0
 | 
			
		||||
#define TCP_QUEUE_OOSEQ         1
 | 
			
		||||
 | 
			
		||||
/* TCP Maximum segment size. */
 | 
			
		||||
#define TCP_MSS                 (1500 - 40)	  /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
 | 
			
		||||
| 
						 | 
				
			
			@ -107,9 +299,69 @@ a lot of data that needs to be copied, this should be set high. */
 | 
			
		|||
#define TCP_SND_QUEUELEN        (8* TCP_SND_BUF/TCP_MSS)
 | 
			
		||||
 | 
			
		||||
/* TCP receive window. */
 | 
			
		||||
#define TCP_WND                 (12*TCP_MSS)
 | 
			
		||||
#define TCP_WND                 8192
 | 
			
		||||
// #define TCP_WND                 (12 * TCP_MSS)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* Maximum number of retransmissions of data segments. */
 | 
			
		||||
#define TCP_MAXRTX                  12
 | 
			
		||||
 | 
			
		||||
/* Maximum number of retransmissions of SYN segments. */
 | 
			
		||||
#define TCP_SYNMAXRTX               4
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT
 | 
			
		||||
 * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set
 | 
			
		||||
 * in seconds. (does not require sockets.c, and will affect tcp.c)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LWIP_TCP_KEEPALIVE
 | 
			
		||||
#define LWIP_TCP_KEEPALIVE              1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * LWIP_NETIF_HOSTNAME==1: Support netif hostname
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LWIP_NETIF_HOSTNAME
 | 
			
		||||
#define LWIP_NETIF_HOSTNAME             1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * LWIP_NETIF_API==1: Support netif api (in netifapi.c)
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LWIP_NETIF_API
 | 
			
		||||
#define LWIP_NETIF_API                  1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and
 | 
			
		||||
 * SO_SNDTIMEO processing.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LWIP_SO_SNDTIMEO
 | 
			
		||||
#define LWIP_SO_SNDTIMEO                1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and
 | 
			
		||||
 * SO_RCVTIMEO processing.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LWIP_SO_RCVTIMEO
 | 
			
		||||
#define LWIP_SO_RCVTIMEO                1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef LWIP_SO_RCVBUF
 | 
			
		||||
#define LWIP_SO_RCVBUF                  1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize.
 | 
			
		||||
 */
 | 
			
		||||
#ifndef RECV_BUFSIZE_DEFAULT
 | 
			
		||||
#define RECV_BUFSIZE_DEFAULT            8192
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ---------- ICMP options ---------- */
 | 
			
		||||
#define LWIP_ICMP               1
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +379,6 @@ a lot of data that needs to be copied, this should be set high. */
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
/* ---------- Statistics options ---------- */
 | 
			
		||||
#define LWIP_STATS              0
 | 
			
		||||
#define LWIP_PROVIDE_ERRNO      1
 | 
			
		||||
 | 
			
		||||
/* ---------- link callback options ---------- */
 | 
			
		||||
| 
						 | 
				
			
			@ -146,7 +397,7 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums
 | 
			
		|||
 - To use this feature let the following define uncommented.
 | 
			
		||||
 - To disable it and process by CPU comment the  the checksum.
 | 
			
		||||
*/
 | 
			
		||||
//#define CHECKSUM_BY_HARDWARE
 | 
			
		||||
#define CHECKSUM_BY_HARDWARE
 | 
			
		||||
 | 
			
		||||
#ifdef CHECKSUM_BY_HARDWARE
 | 
			
		||||
  /* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +427,7 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums
 | 
			
		|||
  #define CHECKSUM_CHECK_UDP              1
 | 
			
		||||
  /* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
 | 
			
		||||
  #define CHECKSUM_CHECK_TCP              1
 | 
			
		||||
  /* CHECKSUM_CHECK_ICMP==1: Check checksums by hardware for incoming ICMP packets.*/
 | 
			
		||||
  /* CHECKSUM_CHECK_ICMP==1: Check checksums by software for incoming ICMP packets.*/
 | 
			
		||||
  #define CHECKSUM_GEN_ICMP               1
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -225,7 +476,50 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums
 | 
			
		|||
     /**
 | 
			
		||||
      * LWIP_SO_LINGER==1: Enable SO_LINGER processing.
 | 
			
		||||
      */
 | 
			
		||||
#define LWIP_SO_LINGER                  1
 | 
			
		||||
// #define LWIP_SO_LINGER                  1
 | 
			
		||||
 | 
			
		||||
/* ---------- IP options ---------- */
 | 
			
		||||
/* Define IP_FORWARD to 1 if you wish to have the ability to forward
 | 
			
		||||
   IP packets across network interfaces. If you are going to run lwIP
 | 
			
		||||
   on a device with only one network interface, define this to 0. */
 | 
			
		||||
#define IP_FORWARD                  0
 | 
			
		||||
 | 
			
		||||
/* IP reassembly and segmentation.These are orthogonal even
 | 
			
		||||
 * if they both deal with IP fragments */
 | 
			
		||||
#ifdef LWIP_REASSEMBLY_FRAG
 | 
			
		||||
#define IP_REASSEMBLY               1
 | 
			
		||||
#define IP_FRAG                     1
 | 
			
		||||
#define IP_REASS_MAX_PBUFS          10
 | 
			
		||||
#define MEMP_NUM_REASSDATA          10
 | 
			
		||||
#else
 | 
			
		||||
#define IP_REASSEMBLY               0
 | 
			
		||||
#define IP_FRAG                     0
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
/* ---------- ICMP options ---------- */
 | 
			
		||||
#define ICMP_TTL                    255
 | 
			
		||||
 | 
			
		||||
/* ---------- DHCP options ---------- */
 | 
			
		||||
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
 | 
			
		||||
   interfaces. */
 | 
			
		||||
#define LWIP_DHCP                   1
 | 
			
		||||
 | 
			
		||||
/* 1 if you want to do an ARP check on the offered address
 | 
			
		||||
   (recommended). */
 | 
			
		||||
#define DHCP_DOES_ARP_CHECK         (LWIP_DHCP)
 | 
			
		||||
 | 
			
		||||
/* ---------- AUTOIP options ------- */
 | 
			
		||||
#define LWIP_AUTOIP                 0
 | 
			
		||||
#define LWIP_DHCP_AUTOIP_COOP       (LWIP_DHCP && LWIP_AUTOIP)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define LWIP_UDPLITE                0
 | 
			
		||||
#define UDP_TTL                     255
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* ---------- Statistics options ---------- */
 | 
			
		||||
#define LWIP_STATS                  1
 | 
			
		||||
#define LWIP_STATS_DISPLAY          1
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
   ---------------------------------
 | 
			
		||||
| 
						 | 
				
			
			@ -236,23 +530,21 @@ The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums
 | 
			
		|||
#define DEFAULT_RAW_RECVMBOX_SIZE       8
 | 
			
		||||
#define DEFAULT_UDP_RECVMBOX_SIZE       8
 | 
			
		||||
#define DEFAULT_TCP_RECVMBOX_SIZE       8
 | 
			
		||||
#define DEFAULT_ACCEPTMBOX_SIZE         8
 | 
			
		||||
#define DEFAULT_ACCEPTMBOX_SIZE         10
 | 
			
		||||
 | 
			
		||||
#define DEFAULT_THREAD_PRIO             20
 | 
			
		||||
#define DEFAULT_THREAD_STACKSIZE        1024
 | 
			
		||||
 | 
			
		||||
#define TCPIP_THREAD_NAME               "tcp"
 | 
			
		||||
#define TCPIP_THREAD_STACKSIZE          8192
 | 
			
		||||
#define TCPIP_MBOX_SIZE                 8
 | 
			
		||||
#define TCPIP_THREAD_PRIO               15
 | 
			
		||||
#define TCPIP_THREAD_STACKSIZE          1024
 | 
			
		||||
#define TCPIP_MBOX_SIZE                 16
 | 
			
		||||
#define TCPIP_THREAD_PRIO               20
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
   ----------------------------------------
 | 
			
		||||
   ---------- Lwip Debug options ----------
 | 
			
		||||
   ----------------------------------------
 | 
			
		||||
*/
 | 
			
		||||
#define LWIP_DEBUG                      1
 | 
			
		||||
 | 
			
		||||
#define LWIP_IPV4                       1
 | 
			
		||||
#define LWIP_RAW                        1
 | 
			
		||||
#define LWIP_DNS                        1
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -69,96 +69,58 @@
 | 
			
		|||
#include "ethernet.h"
 | 
			
		||||
#include "connect_ethernet.h"
 | 
			
		||||
 | 
			
		||||
char lwip_ipaddr[20] = {192, 168, 131, 77};
 | 
			
		||||
char lwip_ipaddr[20] = {192, 168, 130, 77};
 | 
			
		||||
char lwip_netmask[20] = {255, 255, 254, 0};
 | 
			
		||||
char lwip_gwaddr[20] = {192, 168, 131, 23};
 | 
			
		||||
char lwip_gwaddr[20] = {192, 168, 130, 1};
 | 
			
		||||
 | 
			
		||||
char lwip_eth0_ipaddr[20] = {192, 168, 131, 77};
 | 
			
		||||
char lwip_eth0_ipaddr[20] = {192, 168, 130, 77};
 | 
			
		||||
char lwip_eth0_netmask[20] = {255, 255, 254, 0};
 | 
			
		||||
char lwip_eth0_gwaddr[20] = {192, 168, 131, 23};
 | 
			
		||||
char lwip_eth0_gwaddr[20] = {192, 168, 130, 1};
 | 
			
		||||
 | 
			
		||||
char lwip_eth1_ipaddr[20] = {192, 168, 131, 99};
 | 
			
		||||
char lwip_eth1_ipaddr[20] = {192, 168, 130, 99};
 | 
			
		||||
char lwip_eth1_netmask[20] = {255, 255, 254, 0};
 | 
			
		||||
char lwip_eth1_gwaddr[20] = {192, 168, 131, 23};
 | 
			
		||||
char lwip_eth1_gwaddr[20] = {192, 168, 130, 23};
 | 
			
		||||
 | 
			
		||||
char lwip_flag = 0;
 | 
			
		||||
 | 
			
		||||
x_ticks_t lwip_sys_now;
 | 
			
		||||
 | 
			
		||||
struct sys_timeouts {
 | 
			
		||||
  struct sys_timeo *next;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct timeoutlist
 | 
			
		||||
{
 | 
			
		||||
  struct sys_timeouts timeouts;
 | 
			
		||||
  int32 pid;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
#define SYS_THREAD_MAX 4
 | 
			
		||||
 | 
			
		||||
static struct timeoutlist s_timeoutlist[SYS_THREAD_MAX];
 | 
			
		||||
struct netif gnetif;
 | 
			
		||||
sys_sem_t* get_eth_recv_sem() {
 | 
			
		||||
    static sys_sem_t g_recv_sem = 0;
 | 
			
		||||
    return &g_recv_sem;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static u16_t s_nextthread = 0;
 | 
			
		||||
void sys_init(void) {
 | 
			
		||||
  // do nothing
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32_t
 | 
			
		||||
sys_jiffies(void)
 | 
			
		||||
{
 | 
			
		||||
sys_jiffies(void) {
 | 
			
		||||
  lwip_sys_now = CurrentTicksGain();
 | 
			
		||||
  return lwip_sys_now;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32_t
 | 
			
		||||
sys_now(void)
 | 
			
		||||
{
 | 
			
		||||
sys_now(void) {
 | 
			
		||||
  lwip_sys_now = CurrentTicksGain();
 | 
			
		||||
  return lwip_sys_now;
 | 
			
		||||
  return CalculateTimeMsFromTick(lwip_sys_now);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
sys_init(void)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  for(i = 0; i < SYS_THREAD_MAX; i++)
 | 
			
		||||
  {
 | 
			
		||||
    s_timeoutlist[i].pid = 0;
 | 
			
		||||
    s_timeoutlist[i].timeouts.next = NULL;
 | 
			
		||||
  }
 | 
			
		||||
  s_nextthread = 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
struct sys_timeouts *sys_arch_timeouts(void)
 | 
			
		||||
{
 | 
			
		||||
  int i;
 | 
			
		||||
  int32 pid;
 | 
			
		||||
  struct timeoutlist *tl;
 | 
			
		||||
  pid = (int32)GetKTaskDescriptor()->id.id;
 | 
			
		||||
  for(i = 0; i < s_nextthread; i++)
 | 
			
		||||
  {
 | 
			
		||||
    tl = &(s_timeoutlist[i]);
 | 
			
		||||
    if(tl->pid == pid)
 | 
			
		||||
    {
 | 
			
		||||
      return &(tl->timeouts);
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
sys_prot_t sys_arch_protect(void)
 | 
			
		||||
{
 | 
			
		||||
sys_prot_t sys_arch_protect(void) {
 | 
			
		||||
  return CriticalAreaLock();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sys_arch_unprotect(sys_prot_t pval)
 | 
			
		||||
{
 | 
			
		||||
void sys_arch_unprotect(sys_prot_t pval) {
 | 
			
		||||
  CriticalAreaUnLock(pval);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if !NO_SYS
 | 
			
		||||
 | 
			
		||||
err_t
 | 
			
		||||
sys_sem_new(sys_sem_t *sem, u8_t count)
 | 
			
		||||
{
 | 
			
		||||
sys_sem_new(sys_sem_t *sem, u8_t count) {
 | 
			
		||||
  *sem = KSemaphoreCreate((uint16)count);
 | 
			
		||||
 | 
			
		||||
#if SYS_STATS
 | 
			
		||||
| 
						 | 
				
			
			@ -170,8 +132,7 @@ sys_sem_new(sys_sem_t *sem, u8_t count)
 | 
			
		|||
 | 
			
		||||
  if(*sem >= 0)
 | 
			
		||||
    return ERR_OK;
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
  else {
 | 
			
		||||
#if SYS_STATS
 | 
			
		||||
    ++lwip_stats.sys.sem.err;
 | 
			
		||||
#endif /* SYS_STATS */
 | 
			
		||||
| 
						 | 
				
			
			@ -181,8 +142,7 @@ sys_sem_new(sys_sem_t *sem, u8_t count)
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
sys_sem_free(sys_sem_t *sem)
 | 
			
		||||
{
 | 
			
		||||
sys_sem_free(sys_sem_t *sem) {
 | 
			
		||||
#if SYS_STATS
 | 
			
		||||
   --lwip_stats.sys.sem.used;
 | 
			
		||||
#endif /* SYS_STATS */
 | 
			
		||||
| 
						 | 
				
			
			@ -190,19 +150,16 @@ sys_sem_free(sys_sem_t *sem)
 | 
			
		|||
  *sem = SYS_SEM_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sys_sem_valid(sys_sem_t *sem)
 | 
			
		||||
{
 | 
			
		||||
int sys_sem_valid(sys_sem_t *sem) {
 | 
			
		||||
  return (*sem > SYS_SEM_NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void
 | 
			
		||||
sys_sem_set_invalid(sys_sem_t *sem)
 | 
			
		||||
{
 | 
			
		||||
sys_sem_set_invalid(sys_sem_t *sem) {
 | 
			
		||||
  *sem = SYS_SEM_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
 | 
			
		||||
{
 | 
			
		||||
u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) {
 | 
			
		||||
  x_ticks_t start_tick = 0 ;
 | 
			
		||||
  int32 wait_time = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -220,61 +177,51 @@ u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout)
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
  if(KSemaphoreObtain(*sem, wait_time) == EOK)
 | 
			
		||||
    return ((CurrentTicksGain()-start_tick)*MS_PER_SYSTICK);
 | 
			
		||||
    return CalculateTimeMsFromTick(CurrentTicksGain()-start_tick);
 | 
			
		||||
  else
 | 
			
		||||
    return SYS_ARCH_TIMEOUT;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sys_sem_signal(sys_sem_t *sem)
 | 
			
		||||
{
 | 
			
		||||
  if(KSemaphoreAbandon( *sem ) != EOK)
 | 
			
		||||
void sys_sem_signal(sys_sem_t *sem) {
 | 
			
		||||
  if(KSemaphoreAbandon(*sem) != EOK)
 | 
			
		||||
    KPrintf("[sys_arch]:sem signal fail!\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
err_t sys_mutex_new(sys_mutex_t *mutex)
 | 
			
		||||
{
 | 
			
		||||
err_t sys_mutex_new(sys_mutex_t *mutex) {
 | 
			
		||||
  *mutex = KMutexCreate();
 | 
			
		||||
  if(*mutex > SYS_MRTEX_NULL)
 | 
			
		||||
  if (*mutex > SYS_MRTEX_NULL)
 | 
			
		||||
    return ERR_OK;
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
  else {
 | 
			
		||||
    KPrintf("[sys_arch]:new mutex fail!\n");
 | 
			
		||||
    return ERR_MEM;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sys_mutex_free(sys_mutex_t *mutex)
 | 
			
		||||
{
 | 
			
		||||
void sys_mutex_free(sys_mutex_t *mutex) {
 | 
			
		||||
  KMutexDelete(*mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sys_mutex_set_invalid(sys_mutex_t *mutex)
 | 
			
		||||
{
 | 
			
		||||
void sys_mutex_set_invalid(sys_mutex_t *mutex) {
 | 
			
		||||
  *mutex = SYS_MRTEX_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sys_mutex_lock(sys_mutex_t *mutex)
 | 
			
		||||
{
 | 
			
		||||
  KMutexObtain(*mutex,
 | 
			
		||||
                 WAITING_FOREVER);
 | 
			
		||||
void sys_mutex_lock(sys_mutex_t *mutex) {
 | 
			
		||||
  KMutexObtain(*mutex, WAITING_FOREVER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sys_mutex_unlock(sys_mutex_t *mutex)
 | 
			
		||||
{
 | 
			
		||||
  KMutexAbandon( *mutex );
 | 
			
		||||
void sys_mutex_unlock(sys_mutex_t *mutex) {
 | 
			
		||||
  KMutexAbandon(*mutex);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio)
 | 
			
		||||
{
 | 
			
		||||
sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg, int stacksize, int prio) {
 | 
			
		||||
  sys_thread_t handle = -1;
 | 
			
		||||
  handle =  KTaskCreate(name,
 | 
			
		||||
                         function,
 | 
			
		||||
                         arg,
 | 
			
		||||
                         (uint32)stacksize,
 | 
			
		||||
                         (uint8)prio);
 | 
			
		||||
  if (handle >= 0)
 | 
			
		||||
  {
 | 
			
		||||
  if (handle >= 0) {
 | 
			
		||||
    StartupKTask(handle);
 | 
			
		||||
    lw_print("lw: [%s] create %s handle %x\n", __func__, name, handle);
 | 
			
		||||
    return handle;
 | 
			
		||||
| 
						 | 
				
			
			@ -283,8 +230,7 @@ sys_thread_t sys_thread_new(const char *name, lwip_thread_fn function, void *arg
 | 
			
		|||
  return -ERROR;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
err_t sys_mbox_new(sys_mbox_t *mbox, int size)
 | 
			
		||||
{
 | 
			
		||||
err_t sys_mbox_new(sys_mbox_t *mbox, int size) {
 | 
			
		||||
  *mbox = KCreateMsgQueue(sizeof(void *), size);
 | 
			
		||||
 | 
			
		||||
#if SYS_STATS
 | 
			
		||||
| 
						 | 
				
			
			@ -293,8 +239,7 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int size)
 | 
			
		|||
         lwip_stats.sys.mbox.max = lwip_stats.sys.mbox.used;
 | 
			
		||||
    }
 | 
			
		||||
#endif /* SYS_STATS */
 | 
			
		||||
  if(*mbox < 0)
 | 
			
		||||
  {
 | 
			
		||||
  if(*mbox < 0) {
 | 
			
		||||
    lw_print("lw: [%s] alloc %d mbox %p failed\n", __func__, size, mbox);
 | 
			
		||||
    return ERR_MEM;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			@ -303,44 +248,38 @@ err_t sys_mbox_new(sys_mbox_t *mbox, int size)
 | 
			
		|||
  return ERR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sys_mbox_free(sys_mbox_t *mbox)
 | 
			
		||||
{
 | 
			
		||||
void sys_mbox_free(sys_mbox_t *mbox) {
 | 
			
		||||
  KDeleteMsgQueue(*mbox);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int sys_mbox_valid(sys_mbox_t *mbox)
 | 
			
		||||
{
 | 
			
		||||
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)
 | 
			
		||||
{
 | 
			
		||||
void sys_mbox_set_invalid(sys_mbox_t *mbox) {
 | 
			
		||||
  *mbox = SYS_MBOX_NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void sys_mbox_post(sys_mbox_t *q, void *msg)
 | 
			
		||||
{
 | 
			
		||||
  while(KMsgQueueSendwait( *q, &msg, sizeof(void *), WAITING_FOREVER) != EOK);
 | 
			
		||||
void sys_mbox_post(sys_mbox_t *q, void *msg) {
 | 
			
		||||
  KMsgQueueSendwait(*q, &msg, sizeof(void *), WAITING_FOREVER);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
err_t sys_mbox_trypost(sys_mbox_t *q, void *msg)
 | 
			
		||||
{
 | 
			
		||||
err_t sys_mbox_trypost(sys_mbox_t *q, void *msg) {
 | 
			
		||||
  // if(KMsgQueueSend(*q, &msg, sizeof(void *)) == EOK)
 | 
			
		||||
  if(KMsgQueueSend(*q, &msg, sizeof(void *)) == EOK)
 | 
			
		||||
    return ERR_OK;
 | 
			
		||||
  else
 | 
			
		||||
    return ERR_MEM;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
err_t sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg)
 | 
			
		||||
{
 | 
			
		||||
err_t sys_mbox_trypost_fromisr(sys_mbox_t *q, void *msg) {
 | 
			
		||||
  return sys_mbox_trypost(q, msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32_t sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout)
 | 
			
		||||
{
 | 
			
		||||
u32_t sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout) {
 | 
			
		||||
  x_ticks_t start_tick = 0 ;
 | 
			
		||||
  int32 wait_time = 0;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -351,17 +290,15 @@ u32_t sys_arch_mbox_fetch(sys_mbox_t *q, void **msg, u32_t timeout)
 | 
			
		|||
  else
 | 
			
		||||
    wait_time = timeout;
 | 
			
		||||
 | 
			
		||||
  if(KMsgQueueRecv(*q, &(*msg), sizeof(void *), wait_time) == EOK)
 | 
			
		||||
    return ((CurrentTicksGain()-start_tick)*MS_PER_SYSTICK);
 | 
			
		||||
  else{
 | 
			
		||||
    *msg = NULL;
 | 
			
		||||
  if(KMsgQueueRecv(*q, &(*msg), sizeof(void *), wait_time) == EOK) {
 | 
			
		||||
    return CalculateTimeMsFromTick(CurrentTicksGain() - start_tick);
 | 
			
		||||
  } else {
 | 
			
		||||
    return SYS_ARCH_TIMEOUT;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg)
 | 
			
		||||
{
 | 
			
		||||
  if(KMsgQueueRecv(*q, &(*msg), sizeof(void *), 0) == EOK)
 | 
			
		||||
u32_t sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg) {
 | 
			
		||||
  if (KMsgQueueRecv(*q, &(*msg), sizeof(void *), 0) == EOK)
 | 
			
		||||
    return ERR_OK;
 | 
			
		||||
  else
 | 
			
		||||
    return SYS_MBOX_EMPTY;
 | 
			
		||||
| 
						 | 
				
			
			@ -374,97 +311,15 @@ u32_t sys_arch_mbox_tryfetch(sys_mbox_t *q, void **msg)
 | 
			
		|||
#endif /* !NO_SYS */
 | 
			
		||||
 | 
			
		||||
/* Variables Initialization */
 | 
			
		||||
struct netif gnetif;
 | 
			
		||||
ip4_addr_t ipaddr;
 | 
			
		||||
ip4_addr_t netmask;
 | 
			
		||||
ip4_addr_t gw;
 | 
			
		||||
 | 
			
		||||
void lwip_tcp_init(void)
 | 
			
		||||
{
 | 
			
		||||
  tcpip_init(NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  /* IP addresses initialization */
 | 
			
		||||
  /* USER CODE BEGIN 0 */
 | 
			
		||||
#if LWIP_DHCP
 | 
			
		||||
  ip_addr_set_zero_ip4(&ipaddr);
 | 
			
		||||
  ip_addr_set_zero_ip4(&netmask);
 | 
			
		||||
  ip_addr_set_zero_ip4(&gw);
 | 
			
		||||
#else
 | 
			
		||||
  IP4_ADDR(&ipaddr, lwip_ipaddr[0], lwip_ipaddr[1], lwip_ipaddr[2], lwip_ipaddr[3]);
 | 
			
		||||
  IP4_ADDR(&netmask, lwip_netmask[0], lwip_netmask[1], lwip_netmask[2], lwip_netmask[3]);
 | 
			
		||||
  IP4_ADDR(&gw, lwip_gwaddr[0], lwip_gwaddr[1], lwip_gwaddr[2], lwip_gwaddr[3]);
 | 
			
		||||
#endif /* USE_DHCP */
 | 
			
		||||
  /* USER CODE END 0 */
 | 
			
		||||
  /* Initilialize the LwIP stack without RTOS */
 | 
			
		||||
  /* add the network interface (IPv4/IPv6) without RTOS */
 | 
			
		||||
#ifdef NETIF_ENET0_INIT_FUNC
 | 
			
		||||
  netif_add(&gnetif, &ipaddr, &netmask, &gw, NULL, NETIF_ENET0_INIT_FUNC, &tcpip_input);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
  /* Registers the default network interface */
 | 
			
		||||
  netif_set_default(&gnetif);
 | 
			
		||||
 | 
			
		||||
  if (netif_is_link_up(&gnetif))
 | 
			
		||||
  {
 | 
			
		||||
    /* When the netif is fully configured this function must be called */
 | 
			
		||||
    KPrintf("%s : netif_set_up\n", __func__);
 | 
			
		||||
    netif_set_up(&gnetif);
 | 
			
		||||
  }
 | 
			
		||||
  else
 | 
			
		||||
  {
 | 
			
		||||
    /* When the netif link is down this function must be called */
 | 
			
		||||
    KPrintf("%s : netif_set_down\n", __func__);
 | 
			
		||||
    netif_set_down(&gnetif);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#if LWIP_DHCP
 | 
			
		||||
  int err;
 | 
			
		||||
  /*  Creates a new DHCP client for this interface on the first call.
 | 
			
		||||
  Note: you must call dhcp_fine_tmr() and dhcp_coarse_tmr() at
 | 
			
		||||
  the predefined regular intervals after starting the client.
 | 
			
		||||
  You can peek in the netif->dhcp struct for the actual DHCP status.*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  err = dhcp_start(&gnetif);
 | 
			
		||||
  if(err == ERR_OK)
 | 
			
		||||
    KPrintf("lwip dhcp init success...\n\n");
 | 
			
		||||
  else
 | 
			
		||||
    KPrintf("lwip dhcp init fail...\n\n");
 | 
			
		||||
  while(ip_addr_cmp(&(gnetif.ip_addr),&ipaddr))
 | 
			
		||||
  {
 | 
			
		||||
    DelayKTask(1);
 | 
			
		||||
  }
 | 
			
		||||
#endif
 | 
			
		||||
  KPrintf("\n\nIP:%d.%d.%d.%d\n\n",  \
 | 
			
		||||
        ((gnetif.ip_addr.addr)&0x000000ff),       \
 | 
			
		||||
        (((gnetif.ip_addr.addr)&0x0000ff00)>>8),  \
 | 
			
		||||
        (((gnetif.ip_addr.addr)&0x00ff0000)>>16), \
 | 
			
		||||
        ((gnetif.ip_addr.addr)&0xff000000)>>24);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// lwip input thread to get network packet
 | 
			
		||||
void lwip_input_thread(void *param)
 | 
			
		||||
{
 | 
			
		||||
  struct netif *net = param;
 | 
			
		||||
 | 
			
		||||
  while (1)
 | 
			
		||||
  {
 | 
			
		||||
#ifdef FSL_RTOS_XIUOS
 | 
			
		||||
    if (lwip_obtain_semaphore(net) == EOK)
 | 
			
		||||
#endif
 | 
			
		||||
    {
 | 
			
		||||
        /* Poll the driver, get any outstanding frames */
 | 
			
		||||
        ethernetif_input(net);
 | 
			
		||||
        sys_check_timeouts(); /* Handle all system timeouts for all core protocols */
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lwip_config_input(struct netif *net)
 | 
			
		||||
{
 | 
			
		||||
void lwip_config_input(struct netif *net) {
 | 
			
		||||
  sys_thread_t th_id = 0;
 | 
			
		||||
 | 
			
		||||
  th_id = sys_thread_new("eth_input", lwip_input_thread, net, LWIP_TASK_STACK_SIZE, 15);
 | 
			
		||||
  extern void ethernetif_input(void *netif_arg);
 | 
			
		||||
  th_id = sys_thread_new("eth_input", ethernetif_input, net, LWIP_TASK_STACK_SIZE, 20);
 | 
			
		||||
 | 
			
		||||
  if (th_id >= 0) {
 | 
			
		||||
    lw_print("%s %d successfully!\n", __func__, th_id);
 | 
			
		||||
| 
						 | 
				
			
			@ -473,15 +328,65 @@ void lwip_config_input(struct netif *net)
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw)
 | 
			
		||||
{
 | 
			
		||||
void lwip_config_tcp(uint8_t enet_port, char *ip, char *mask, char *gw) {
 | 
			
		||||
  ip4_addr_t net_ipaddr, net_netmask, net_gw;
 | 
			
		||||
  char* eth_cfg;
 | 
			
		||||
 | 
			
		||||
  eth_cfg = ethernetif_config_enet_set(enet_port);
 | 
			
		||||
 | 
			
		||||
  if(chk_lwip_bit(LWIP_INIT_FLAG))
 | 
			
		||||
  {
 | 
			
		||||
  if(chk_lwip_bit(LWIP_INIT_FLAG)) {
 | 
			
		||||
    lw_print("lw: [%s] already ...\n", __func__);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  set_lwip_bit(LWIP_INIT_FLAG);
 | 
			
		||||
 | 
			
		||||
  tcpip_init(NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  lw_print("lw: [%s] start ...\n", __func__);
 | 
			
		||||
 | 
			
		||||
  IP4_ADDR(&net_ipaddr, ip[0], ip[1], ip[2], ip[3]);
 | 
			
		||||
  IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]);
 | 
			
		||||
  IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]);
 | 
			
		||||
 | 
			
		||||
  if (0 == enet_port) {
 | 
			
		||||
#ifdef NETIF_ENET0_INIT_FUNC
 | 
			
		||||
    printf("[%s:%d] call netif_add\n", __func__, __LINE__);
 | 
			
		||||
    netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC,
 | 
			
		||||
        tcpip_input);
 | 
			
		||||
#endif
 | 
			
		||||
  } else if (1 == enet_port) {
 | 
			
		||||
#ifdef NETIF_ENET1_INIT_FUNC
 | 
			
		||||
    netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC,
 | 
			
		||||
        tcpip_input);
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  netif_set_default(&gnetif);
 | 
			
		||||
  netif_set_up(&gnetif);
 | 
			
		||||
 | 
			
		||||
  lw_print("\r\n************************************************\r\n");
 | 
			
		||||
  lw_print(" Network Configuration\r\n");
 | 
			
		||||
  lw_print("************************************************\r\n");
 | 
			
		||||
  lw_print(" IPv4 Address   : %u.%u.%u.%u\r\n", ((u8_t *)&net_ipaddr)[0], ((u8_t *)&net_ipaddr)[1],
 | 
			
		||||
       ((u8_t *)&net_ipaddr)[2], ((u8_t *)&net_ipaddr)[3]);
 | 
			
		||||
  lw_print(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&net_netmask)[0], ((u8_t *)&net_netmask)[1],
 | 
			
		||||
       ((u8_t *)&net_netmask)[2], ((u8_t *)&net_netmask)[3]);
 | 
			
		||||
  lw_print(" IPv4 Gateway   : %u.%u.%u.%u\r\n", ((u8_t *)&net_gw)[0], ((u8_t *)&net_gw)[1],
 | 
			
		||||
       ((u8_t *)&net_gw)[2], ((u8_t *)&net_gw)[3]);
 | 
			
		||||
  lw_print("************************************************\r\n");
 | 
			
		||||
 | 
			
		||||
  lwip_config_input(&gnetif);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw) {
 | 
			
		||||
  ip4_addr_t net_ipaddr, net_netmask, net_gw;
 | 
			
		||||
  char* eth_cfg;
 | 
			
		||||
 | 
			
		||||
  eth_cfg = ethernetif_config_enet_set(enet_port);
 | 
			
		||||
 | 
			
		||||
  if(chk_lwip_bit(LWIP_INIT_FLAG)) {
 | 
			
		||||
    lw_print("lw: [%s] already ...\n", __func__);
 | 
			
		||||
 | 
			
		||||
    IP4_ADDR(&net_ipaddr, ip[0], ip[1], ip[2], ip[3]);
 | 
			
		||||
| 
						 | 
				
			
			@ -521,8 +426,7 @@ void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw)
 | 
			
		|||
  netif_set_default(&gnetif);
 | 
			
		||||
  netif_set_up(&gnetif);
 | 
			
		||||
 | 
			
		||||
  if(chk_lwip_bit(LWIP_PRINT_FLAG))
 | 
			
		||||
  {
 | 
			
		||||
  if(chk_lwip_bit(LWIP_PRINT_FLAG)) {
 | 
			
		||||
    lw_notice("\r\n************************************************\r\n");
 | 
			
		||||
    lw_notice(" Network Configuration\r\n");
 | 
			
		||||
    lw_notice("************************************************\r\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -537,55 +441,3 @@ void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw)
 | 
			
		|||
  lwip_config_input(&gnetif);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void lwip_config_tcp(uint8_t enet_port, char *ip, char *mask, char *gw)
 | 
			
		||||
{
 | 
			
		||||
  ip4_addr_t net_ipaddr, net_netmask, net_gw;
 | 
			
		||||
  char* eth_cfg;
 | 
			
		||||
 | 
			
		||||
  eth_cfg = ethernetif_config_enet_set(enet_port);
 | 
			
		||||
 | 
			
		||||
  if(chk_lwip_bit(LWIP_INIT_FLAG))
 | 
			
		||||
  {
 | 
			
		||||
    lw_print("lw: [%s] already ...\n", __func__);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  set_lwip_bit(LWIP_INIT_FLAG);
 | 
			
		||||
 | 
			
		||||
  tcpip_init(NULL, NULL);
 | 
			
		||||
 | 
			
		||||
  lw_print("lw: [%s] start ...\n", __func__);
 | 
			
		||||
 | 
			
		||||
  IP4_ADDR(&net_ipaddr, ip[0], ip[1], ip[2], ip[3]);
 | 
			
		||||
  IP4_ADDR(&net_netmask, mask[0], mask[1], mask[2], mask[3]);
 | 
			
		||||
  IP4_ADDR(&net_gw, gw[0], gw[1], gw[2], gw[3]);
 | 
			
		||||
 | 
			
		||||
  if(0 == enet_port) {
 | 
			
		||||
#ifdef NETIF_ENET0_INIT_FUNC
 | 
			
		||||
    netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET0_INIT_FUNC,
 | 
			
		||||
        ethernet_input);
 | 
			
		||||
#endif
 | 
			
		||||
  } else if (1 == enet_port) {
 | 
			
		||||
#ifdef NETIF_ENET1_INIT_FUNC
 | 
			
		||||
    netif_add(&gnetif, &net_ipaddr, &net_netmask, &net_gw, eth_cfg, NETIF_ENET1_INIT_FUNC,
 | 
			
		||||
        ethernet_input);
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  netif_set_default(&gnetif);
 | 
			
		||||
  netif_set_up(&gnetif);
 | 
			
		||||
 | 
			
		||||
  lw_print("\r\n************************************************\r\n");
 | 
			
		||||
  lw_print(" Network Configuration\r\n");
 | 
			
		||||
  lw_print("************************************************\r\n");
 | 
			
		||||
  lw_print(" IPv4 Address   : %u.%u.%u.%u\r\n", ((u8_t *)&net_ipaddr)[0], ((u8_t *)&net_ipaddr)[1],
 | 
			
		||||
       ((u8_t *)&net_ipaddr)[2], ((u8_t *)&net_ipaddr)[3]);
 | 
			
		||||
  lw_print(" IPv4 Subnet mask : %u.%u.%u.%u\r\n", ((u8_t *)&net_netmask)[0], ((u8_t *)&net_netmask)[1],
 | 
			
		||||
       ((u8_t *)&net_netmask)[2], ((u8_t *)&net_netmask)[3]);
 | 
			
		||||
  lw_print(" IPv4 Gateway   : %u.%u.%u.%u\r\n", ((u8_t *)&net_gw)[0], ((u8_t *)&net_gw)[1],
 | 
			
		||||
       ((u8_t *)&net_gw)[2], ((u8_t *)&net_gw)[3]);
 | 
			
		||||
  lw_print("************************************************\r\n");
 | 
			
		||||
 | 
			
		||||
  lwip_config_input(&gnetif);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -54,7 +54,7 @@
 | 
			
		|||
#define LWIP_TARGET_PORT            LWIP_LOCAL_PORT
 | 
			
		||||
 | 
			
		||||
#define LWIP_DEMO_TIMES             10
 | 
			
		||||
#define LWIP_TASK_STACK_SIZE        4096
 | 
			
		||||
#define LWIP_TASK_STACK_SIZE        1536
 | 
			
		||||
#define LWIP_DEMO_TASK_PRIO         20
 | 
			
		||||
 | 
			
		||||
// /* MAC address configuration. */
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +72,8 @@ typedef int32 sys_mbox_t;
 | 
			
		|||
typedef int32 sys_thread_t;
 | 
			
		||||
typedef x_base sys_prot_t;
 | 
			
		||||
 | 
			
		||||
#define MS_PER_SYSTICK (1000 / TICK_PER_SECOND)
 | 
			
		||||
#define MS_PER_SYSTICK (float)(1000 / TICK_PER_SECOND)
 | 
			
		||||
#define TICKS_PER_MS (TICK_PER_SECOND / 1000)
 | 
			
		||||
 | 
			
		||||
//debug rtos with IRQ
 | 
			
		||||
//#define FSL_RTOS_XIUOS
 | 
			
		||||
| 
						 | 
				
			
			@ -99,6 +100,7 @@ extern char lwip_eth1_netmask[];
 | 
			
		|||
extern char lwip_eth1_gwaddr[];
 | 
			
		||||
 | 
			
		||||
extern struct netif gnetif;
 | 
			
		||||
extern sys_sem_t* get_eth_recv_sem();
 | 
			
		||||
 | 
			
		||||
void lwip_tcp_init(void);
 | 
			
		||||
void lwip_config_net(uint8_t enet_port, char *ip, char *mask, char *gw);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -142,18 +142,22 @@
 | 
			
		|||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef LWIP_DEBUG
 | 
			
		||||
#define LWIP_DEBUGF(debug, message) do { \
 | 
			
		||||
#define LWIP_DEBUGF(debug_flag, message) do { \
 | 
			
		||||
                               if ( \
 | 
			
		||||
                                   ((debug) & LWIP_DBG_ON) && \
 | 
			
		||||
                                   ((debug) & LWIP_DBG_TYPES_ON) && \
 | 
			
		||||
                                   ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \
 | 
			
		||||
                                   ((debug_flag) & LWIP_DBG_ON) && \
 | 
			
		||||
                                   ((debug_flag) & LWIP_DBG_TYPES_ON) && \
 | 
			
		||||
                                   (debug_flag)) { \
 | 
			
		||||
                                 LWIP_PLATFORM_DIAG(message); \
 | 
			
		||||
                                 if ((debug) & LWIP_DBG_HALT) { \
 | 
			
		||||
                                 if ((debug_flag) & LWIP_DBG_HALT) { \
 | 
			
		||||
                                   while(1); \
 | 
			
		||||
                                 } \
 | 
			
		||||
                               } \
 | 
			
		||||
                             } while(0)
 | 
			
		||||
 | 
			
		||||
                                  //  ((s16_t)((debug_flag) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \
 | 
			
		||||
// #define LWIP_DEBUGF(debug, message) do { \
 | 
			
		||||
//                                  LWIP_PLATFORM_DIAG(message); \
 | 
			
		||||
//                              } while(0)
 | 
			
		||||
#else  /* LWIP_DEBUG */
 | 
			
		||||
#define LWIP_DEBUGF(debug, message)
 | 
			
		||||
#endif /* LWIP_DEBUG */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,3 +1,4 @@
 | 
			
		|||
SRC_FILES := ping.c lwip_ping_demo.c lwip_tcp_demo.c lwip_udp_demo.c tcpecho_raw.c lwip_config_demo.c lwip_dhcp_demo.c
 | 
			
		||||
SRC_FILES := ping.c lwip_ping_demo.c lwip_tcp_demo.c tcpecho_raw.c lwip_config_demo.c lwip_dhcp_demo.c iperf.c http_test.c
 | 
			
		||||
# SRC_FILES := ping.c lwip_ping_demo.c lwip_tcp_demo.c lwip_udp_demo.c tcpecho_raw.c lwip_config_demo.c lwip_dhcp_demo.c iperf.c
 | 
			
		||||
 | 
			
		||||
include $(KERNEL_ROOT)/compiler.mk
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,68 @@
 | 
			
		|||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <shell.h>
 | 
			
		||||
#include <debug.h>
 | 
			
		||||
 | 
			
		||||
#include "lwip/apps/http_client.h"
 | 
			
		||||
 | 
			
		||||
void httpc_app_recv_end(void *arg, httpc_result_t httpc_result, u32_t rx_content_len, u32_t srv_res, err_t err) {
 | 
			
		||||
    httpc_state_t **req = (httpc_state_t**)arg;
 | 
			
		||||
 | 
			
		||||
    LWIP_DEBUGF(LWIP_DEBUG, ("[HTTPC] Transfer finished. rx_content_len is %lu\r\n", rx_content_len));
 | 
			
		||||
    printf("[HTTPC] Transfer finished. rx_content_len is %lu\r\n", rx_content_len);
 | 
			
		||||
    *req = NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
err_t httpc_app_headers_done(httpc_state_t *connection, void *arg, struct pbuf *hdr, u16_t hdr_len, u32_t content_len) {
 | 
			
		||||
    LWIP_DEBUGF(LWIP_DEBUG, ("[%s] headers done call back.\n", __func__));
 | 
			
		||||
    printf("[%s] headers done call back, content len: %d.\n", __func__, content_len);
 | 
			
		||||
    return ERR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
err_t httpc_app_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) {
 | 
			
		||||
    printf("[%s] Get %d Data\n", __func__, p->len);
 | 
			
		||||
   
 | 
			
		||||
    pbuf_free(p);
 | 
			
		||||
    return ERR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ip_addr_t *get_server_ip() {
 | 
			
		||||
    static ip_addr_t server_ip;
 | 
			
		||||
    return &server_ip;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
httpc_state_t **get_conn_state() {
 | 
			
		||||
    static httpc_state_t *conn_state;
 | 
			
		||||
    return &conn_state;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
httpc_connection_t *get_conn_setting() {
 | 
			
		||||
    static httpc_connection_t conn_setting;
 | 
			
		||||
    return &conn_setting;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void httpc_get_file_app(int argc, char *argv[]) {
 | 
			
		||||
    // deal input ip
 | 
			
		||||
 | 
			
		||||
    // get file from server
 | 
			
		||||
    const uint8_t server_ip_by_arr[4] = {39, 156, 66, 10};
 | 
			
		||||
    // const uint8_t server_ip_by_arr[4] = {114, 215, 151, 106};
 | 
			
		||||
    IP4_ADDR(get_server_ip(), 
 | 
			
		||||
        server_ip_by_arr[0], server_ip_by_arr[1], server_ip_by_arr[2], server_ip_by_arr[3]);
 | 
			
		||||
 | 
			
		||||
    get_conn_setting()->use_proxy = 0;
 | 
			
		||||
    get_conn_setting()->result_fn = httpc_app_recv_end;
 | 
			
		||||
    get_conn_setting()->headers_done_fn = httpc_app_headers_done;
 | 
			
		||||
 | 
			
		||||
    LWIP_DEBUGF(HTTPC_DEBUG, ("[%s] Calling httpc_get_file\n", __func__));
 | 
			
		||||
    printf("[%s] Calling httpc_get_file\n", __func__);
 | 
			
		||||
    err_t errnum = httpc_get_file(get_server_ip(), 80, "/index.html", get_conn_setting(), httpc_app_recv, NULL, get_conn_state());
 | 
			
		||||
    // err_t errnum = httpc_get_file_dns("https://www.baidu.com", 80, "/index.html", get_conn_setting(), httpc_app_recv, NULL, get_conn_state());
 | 
			
		||||
 | 
			
		||||
    if (errnum != ERR_OK) {
 | 
			
		||||
        printf("httpc_get_file failed (%d)\n", errnum);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(0),
 | 
			
		||||
     lwip_http_test, httpc_get_file_app, get file from net server);
 | 
			
		||||
| 
						 | 
				
			
			@ -0,0 +1,686 @@
 | 
			
		|||
/**
 | 
			
		||||
* iperf-liked network performance tool
 | 
			
		||||
*
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
#include <xizi.h>
 | 
			
		||||
#include <shell.h>
 | 
			
		||||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <fcntl.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <sys/select.h>
 | 
			
		||||
#include <sys_arch.h>
 | 
			
		||||
#include "lwip/sockets.h"
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <lwiperf.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
    char *host;
 | 
			
		||||
    int port;
 | 
			
		||||
} IPERF_PARAM;
 | 
			
		||||
static IPERF_PARAM param = {IPERF_MODE_STOP, NULL, IPERF_PORT};
 | 
			
		||||
 | 
			
		||||
char tcp_iperf_ip[] = {192, 168, 130, 77};
 | 
			
		||||
char tcp_iperf_mask[] = {255, 255, 254, 0};
 | 
			
		||||
char tcp_iperf_gw[] = {192, 168, 130, 1};
 | 
			
		||||
 | 
			
		||||
static void iperf_udp_client(void *thread_param)
 | 
			
		||||
{
 | 
			
		||||
    int sock;
 | 
			
		||||
    uint32 *buffer;
 | 
			
		||||
    struct sockaddr_in server;
 | 
			
		||||
    uint32 packet_count = 0;
 | 
			
		||||
    uint32 tick;
 | 
			
		||||
    int send_size;
 | 
			
		||||
 | 
			
		||||
    send_size = IPERF_BUFSZ > 1470 ? 1470 : IPERF_BUFSZ;
 | 
			
		||||
 | 
			
		||||
    sock = socket(PF_INET, SOCK_DGRAM, 0);
 | 
			
		||||
    if(sock < 0){
 | 
			
		||||
        KPrintf("[%s:%d] can't create socket! exit!\n", __FILE__, __LINE__);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    server.sin_family = PF_INET;
 | 
			
		||||
    server.sin_port = htons(param.port);
 | 
			
		||||
    server.sin_addr.s_addr = inet_addr(param.host);
 | 
			
		||||
    memset(&(server.sin_zero), 0, sizeof(server.sin_zero));
 | 
			
		||||
 | 
			
		||||
    if (connect(sock, (struct sockaddr *)&server, sizeof(struct sockaddr))){
 | 
			
		||||
        lw_error("Unable to connect\n");
 | 
			
		||||
        closesocket(sock);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    buffer = malloc(IPERF_BUFSZ);
 | 
			
		||||
    if (buffer == NULL){
 | 
			
		||||
        printf("[%s:%d] malloc failed\n", __FILE__, __LINE__);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    memset(buffer, 0x00, IPERF_BUFSZ);
 | 
			
		||||
 | 
			
		||||
    KPrintf("iperf udp mode run...\n");
 | 
			
		||||
    while (param.mode != IPERF_MODE_STOP){
 | 
			
		||||
        packet_count++;
 | 
			
		||||
        tick = CurrentTicksGain();
 | 
			
		||||
        buffer[0] = htonl(packet_count);
 | 
			
		||||
        buffer[1] = htonl(tick / TICK_PER_SECOND);
 | 
			
		||||
        buffer[2] = htonl((tick % TICK_PER_SECOND) * 1000);
 | 
			
		||||
        sendto(sock, buffer, send_size, 0, (struct sockaddr *)&server, sizeof(struct sockaddr_in));
 | 
			
		||||
    }
 | 
			
		||||
    closesocket(sock);
 | 
			
		||||
    free(buffer);
 | 
			
		||||
    KPrintf("iperf udp mode exit...\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void iperf_udp_server(void *thread_param)
 | 
			
		||||
{
 | 
			
		||||
    int sock;
 | 
			
		||||
    uint32 *buffer;
 | 
			
		||||
    struct sockaddr_in server;
 | 
			
		||||
    struct sockaddr_in sender;
 | 
			
		||||
    int sender_len, r_size;
 | 
			
		||||
    uint64 sentlen;
 | 
			
		||||
    uint32 pcount = 0, last_pcount = 0;
 | 
			
		||||
    uint32 lost, total;
 | 
			
		||||
    x_ticks_t tick1, tick2;
 | 
			
		||||
    struct timeval timeout;
 | 
			
		||||
 | 
			
		||||
    buffer = malloc(IPERF_BUFSZ);
 | 
			
		||||
    if (buffer == NULL){
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    sock = socket(PF_INET, SOCK_DGRAM, 0);
 | 
			
		||||
    if(sock < 0){
 | 
			
		||||
        KPrintf("can't create socket! exit!");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    server.sin_family = PF_INET;
 | 
			
		||||
    server.sin_port = htons(param.port);
 | 
			
		||||
    server.sin_addr.s_addr = inet_addr("0.0.0.0");
 | 
			
		||||
 | 
			
		||||
    timeout.tv_sec = 2;
 | 
			
		||||
    timeout.tv_usec = 0;
 | 
			
		||||
    if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout)) == -1){
 | 
			
		||||
        KPrintf("setsockopt failed!");
 | 
			
		||||
        closesocket(sock);
 | 
			
		||||
        free(buffer);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (bind(sock, (struct sockaddr *)&server, sizeof(struct sockaddr_in)) < 0){
 | 
			
		||||
        KPrintf("iperf server bind failed! exit!");
 | 
			
		||||
        closesocket(sock);
 | 
			
		||||
        free(buffer);
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    while (param.mode != IPERF_MODE_STOP){
 | 
			
		||||
        tick1 = CurrentTicksGain();
 | 
			
		||||
        tick2 = tick1;
 | 
			
		||||
        lost = 0;
 | 
			
		||||
        total = 0;
 | 
			
		||||
        sentlen = 0;
 | 
			
		||||
        while ((tick2 - tick1) < (TICK_PER_SECOND * 5)){
 | 
			
		||||
            r_size = recvfrom(sock, buffer, IPERF_BUFSZ, 0, (struct sockaddr *)&sender, (socklen_t*)&sender_len);
 | 
			
		||||
            if (r_size > 12){
 | 
			
		||||
                pcount = ntohl(buffer[0]);
 | 
			
		||||
                if (last_pcount < pcount){
 | 
			
		||||
                    lost += pcount - last_pcount - 1;
 | 
			
		||||
                    total += pcount - last_pcount;
 | 
			
		||||
                }
 | 
			
		||||
                else{
 | 
			
		||||
                    last_pcount = pcount;
 | 
			
		||||
                }
 | 
			
		||||
                last_pcount = pcount;
 | 
			
		||||
                sentlen += r_size;
 | 
			
		||||
            }
 | 
			
		||||
            tick2 = CurrentTicksGain();
 | 
			
		||||
        }
 | 
			
		||||
        if (sentlen > 0){
 | 
			
		||||
            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! lost:%d total:%d\n", tid->task_base_info.name, integer, decimal, lost, total);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    free(buffer);
 | 
			
		||||
    closesocket(sock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void iperf_client(void *thread_param)
 | 
			
		||||
{
 | 
			
		||||
    int i;
 | 
			
		||||
    int sock;
 | 
			
		||||
    int ret;
 | 
			
		||||
    int tips = 1;
 | 
			
		||||
    uint8_t *send_buf;
 | 
			
		||||
    uint64 sentlen;
 | 
			
		||||
    x_ticks_t tick1, tick2;
 | 
			
		||||
    struct sockaddr_in addr;
 | 
			
		||||
 | 
			
		||||
    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)
 | 
			
		||||
    {
 | 
			
		||||
        sock = socket(AF_INET, SOCK_STREAM, 0);
 | 
			
		||||
        if (sock < 0){
 | 
			
		||||
            KPrintf("create socket failed!");
 | 
			
		||||
            DelayKTask(TICK_PER_SECOND);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        addr.sin_family = PF_INET;
 | 
			
		||||
        addr.sin_port = htons(param.port);
 | 
			
		||||
        addr.sin_addr.s_addr = inet_addr((char *)param.host);
 | 
			
		||||
 | 
			
		||||
        ret = connect(sock, (const struct sockaddr *)&addr, sizeof(addr));
 | 
			
		||||
        if (ret == -1){
 | 
			
		||||
            if (tips){
 | 
			
		||||
                KPrintf("Connect to iperf server faile, Waiting for the server to open!");
 | 
			
		||||
                tips = 0;
 | 
			
		||||
            }
 | 
			
		||||
            closesocket(sock);
 | 
			
		||||
            DelayKTask(TICK_PER_SECOND);
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
        KPrintf("Connect to iperf server successful!\n");
 | 
			
		||||
 | 
			
		||||
        {
 | 
			
		||||
            int flag = 1;
 | 
			
		||||
 | 
			
		||||
            setsockopt(sock,
 | 
			
		||||
                       IPPROTO_TCP,     /* set option at TCP level */
 | 
			
		||||
                       TCP_NODELAY,     /* name of option */
 | 
			
		||||
                       (void *) &flag,  /* the cast is historical cruft */
 | 
			
		||||
                       sizeof(int));    /* length of option value */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sentlen = 0;
 | 
			
		||||
 | 
			
		||||
        tick1 = CurrentTicksGain();
 | 
			
		||||
        while (param.mode != IPERF_MODE_STOP){
 | 
			
		||||
            tick2 = CurrentTicksGain();
 | 
			
		||||
            if (tick2 - tick1 >= TICK_PER_SECOND * 5){
 | 
			
		||||
                double speed;
 | 
			
		||||
                // int integer, decimal;
 | 
			
		||||
                KTaskDescriptorType tid;
 | 
			
		||||
 | 
			
		||||
                tid = GetKTaskDescriptor();
 | 
			
		||||
                speed = (double)(sentlen * TICK_PER_SECOND / 125 / (tick2 - tick1));
 | 
			
		||||
                speed = speed / 1000.0f;
 | 
			
		||||
                printf("%s: %2.4f Mbps!\n", tid->task_base_info.name, speed);
 | 
			
		||||
                tick1 = tick2;
 | 
			
		||||
                sentlen = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            ret = send(sock, send_buf, IPERF_BUFSZ, 0);
 | 
			
		||||
            if (ret > 0){
 | 
			
		||||
                sentlen += ret;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (ret < 0) break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        closesocket(sock);
 | 
			
		||||
 | 
			
		||||
        DelayKTask(TICK_PER_SECOND * 2);
 | 
			
		||||
        KPrintf("Disconnected, iperf server shut down!");
 | 
			
		||||
        tips = 1;
 | 
			
		||||
    }
 | 
			
		||||
    free(send_buf);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// iperf tcp server running thread
 | 
			
		||||
struct sock_conn_cb {
 | 
			
		||||
    struct sockaddr_in server_addr;
 | 
			
		||||
    struct sockaddr_in client_addr;
 | 
			
		||||
    int connected;
 | 
			
		||||
    int parent_id;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void iperf_sever_worker(void* arg) {
 | 
			
		||||
    struct sock_conn_cb *sccb = (struct sock_conn_cb *)arg;
 | 
			
		||||
    x_ticks_t tick1, tick2;
 | 
			
		||||
 | 
			
		||||
    uint8_t *recv_data = (uint8_t *)malloc(IPERF_BUFSZ);
 | 
			
		||||
    if(recv_data == NULL) {
 | 
			
		||||
        KPrintf("[%s] No Memory.\n", __func__);
 | 
			
		||||
        goto exit__;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint64 recvlen = 0;
 | 
			
		||||
    int32_t bytes_received = 0;
 | 
			
		||||
    
 | 
			
		||||
    int flag = 1;
 | 
			
		||||
    setsockopt(sccb->connected,
 | 
			
		||||
                IPPROTO_TCP,     /* set option at TCP level */
 | 
			
		||||
                TCP_NODELAY,     /* name of option */
 | 
			
		||||
                (void *) &flag,  /* the cast is historical cruft */
 | 
			
		||||
                sizeof(int));    /* length of option value */
 | 
			
		||||
 | 
			
		||||
    int cur_tid = GetKTaskDescriptor()->id.id;
 | 
			
		||||
 | 
			
		||||
    tick1 = CurrentTicksGain();
 | 
			
		||||
    while (param.mode != IPERF_MODE_STOP){
 | 
			
		||||
        bytes_received = recv(sccb->connected, recv_data, IPERF_BUFSZ, 0);
 | 
			
		||||
        if (bytes_received == 0) {
 | 
			
		||||
            KPrintf("client disconnected (%s, %d)\n",
 | 
			
		||||
                inet_ntoa(sccb->client_addr.sin_addr), ntohs(sccb->client_addr.sin_port));
 | 
			
		||||
            break;
 | 
			
		||||
        } else if (bytes_received < 0) {
 | 
			
		||||
            KPrintf("recv error, client: (%s, %d)\n",
 | 
			
		||||
                inet_ntoa(sccb->client_addr.sin_addr), ntohs(sccb->client_addr.sin_port));
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        recvlen += bytes_received;
 | 
			
		||||
 | 
			
		||||
        tick2 = CurrentTicksGain();
 | 
			
		||||
        if (tick2 - tick1 >= TICK_PER_SECOND * 5) {
 | 
			
		||||
            double speed;
 | 
			
		||||
            // int integer, decimal;
 | 
			
		||||
            KTaskDescriptorType tid;
 | 
			
		||||
 | 
			
		||||
            tid = GetKTaskDescriptor();
 | 
			
		||||
            speed = (double)(recvlen * TICK_PER_SECOND / (125 * (tick2 - tick1)));
 | 
			
		||||
            speed = speed / 1000.0f;
 | 
			
		||||
            printf("%s%d: %2.4f Mbps!\n",
 | 
			
		||||
                tid->task_base_info.name, cur_tid - sccb->parent_id, speed);
 | 
			
		||||
            tick1 = tick2;
 | 
			
		||||
            recvlen = 0;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    free(recv_data);
 | 
			
		||||
 | 
			
		||||
exit__:
 | 
			
		||||
    if (sccb->connected >= 0) closesocket(sccb->connected);
 | 
			
		||||
    sccb->connected = -1;
 | 
			
		||||
    free(sccb);
 | 
			
		||||
    KPrintf("iperf server %d quiting.\n", cur_tid - sccb->parent_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void iperf_server_multithread(void *thread_param)
 | 
			
		||||
{
 | 
			
		||||
    socklen_t sin_size;
 | 
			
		||||
    x_ticks_t tick1, tick2;
 | 
			
		||||
    int sock;
 | 
			
		||||
    int connected;
 | 
			
		||||
    struct sockaddr_in server_addr, client_addr;
 | 
			
		||||
    fd_set readset;
 | 
			
		||||
    struct timeval timeout;
 | 
			
		||||
 | 
			
		||||
    sock = socket(AF_INET, SOCK_STREAM, 0);
 | 
			
		||||
    if (sock < 0){
 | 
			
		||||
        KPrintf("[%s:%d] Socket error!\n", __FILE__, __LINE__);
 | 
			
		||||
        goto __exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    server_addr.sin_family = AF_INET;
 | 
			
		||||
    server_addr.sin_port = htons(param.port);
 | 
			
		||||
    server_addr.sin_addr.s_addr = INADDR_ANY;
 | 
			
		||||
    memset(&(server_addr.sin_zero), 0x0, sizeof(server_addr.sin_zero));
 | 
			
		||||
 | 
			
		||||
    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){
 | 
			
		||||
        KPrintf("Unable to bind!\n");
 | 
			
		||||
        goto __exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (listen(sock, 5) == -1){
 | 
			
		||||
        KPrintf("Listen error!\n");
 | 
			
		||||
        goto __exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int cur_tid = GetKTaskDescriptor()->id.id;
 | 
			
		||||
 | 
			
		||||
    timeout.tv_sec = 5;
 | 
			
		||||
    timeout.tv_usec = 0;
 | 
			
		||||
    while (param.mode != IPERF_MODE_STOP){
 | 
			
		||||
        FD_ZERO(&readset);
 | 
			
		||||
        FD_SET(sock, &readset);
 | 
			
		||||
 | 
			
		||||
        if (select(sock + 1, &readset, NULL, NULL, &timeout) == 0) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sin_size = sizeof(struct sockaddr_in);
 | 
			
		||||
 | 
			
		||||
        connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
 | 
			
		||||
 | 
			
		||||
        printf("new client connected from (%s, %d)\n",
 | 
			
		||||
                   inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
 | 
			
		||||
        struct sock_conn_cb *sccb = malloc(sizeof(struct sock_conn_cb));
 | 
			
		||||
        sccb->connected = connected;
 | 
			
		||||
        sccb->client_addr = client_addr;
 | 
			
		||||
        sccb->server_addr = server_addr;
 | 
			
		||||
        sccb->parent_id = cur_tid;
 | 
			
		||||
        int tid = KTaskCreate("iperf server", iperf_sever_worker, sccb, LWIP_TASK_STACK_SIZE, 20);
 | 
			
		||||
        // iperf_sever_worker(sccb);
 | 
			
		||||
        if (tid) {
 | 
			
		||||
            StartupKTask(tid);
 | 
			
		||||
        } else {
 | 
			
		||||
            KPrintf("[%s] Failed to create server worker.\n", __func__);
 | 
			
		||||
            free(sccb);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
__exit:
 | 
			
		||||
    if (sock >= 0) closesocket(sock);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void iperf_server(void *thread_param)
 | 
			
		||||
{
 | 
			
		||||
    uint8_t *recv_data;
 | 
			
		||||
    socklen_t sin_size;
 | 
			
		||||
    x_ticks_t tick1, tick2;
 | 
			
		||||
    int sock = -1, connected, bytes_received;
 | 
			
		||||
    uint64 recvlen;
 | 
			
		||||
    struct sockaddr_in server_addr, client_addr;
 | 
			
		||||
    fd_set readset;
 | 
			
		||||
    struct timeval timeout;
 | 
			
		||||
 | 
			
		||||
    sock = socket(AF_INET, SOCK_STREAM, 0);
 | 
			
		||||
    if (sock < 0){
 | 
			
		||||
        KPrintf("[%s:%d] Socket error!\n", __FILE__, __LINE__);
 | 
			
		||||
        goto __exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    recv_data = (uint8_t *)malloc(IPERF_BUFSZ);
 | 
			
		||||
    if (recv_data == NULL){
 | 
			
		||||
        KPrintf("No memory!\n");
 | 
			
		||||
        goto __exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    server_addr.sin_family = AF_INET;
 | 
			
		||||
    server_addr.sin_port = htons(param.port);
 | 
			
		||||
    server_addr.sin_addr.s_addr = INADDR_ANY;
 | 
			
		||||
    memset(&(server_addr.sin_zero), 0x0, sizeof(server_addr.sin_zero));
 | 
			
		||||
 | 
			
		||||
    if (bind(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1){
 | 
			
		||||
        KPrintf("Unable to bind!\n");
 | 
			
		||||
        goto __exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (listen(sock, 5) == -1){
 | 
			
		||||
        KPrintf("Listen error!\n");
 | 
			
		||||
        goto __exit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    timeout.tv_sec = 3;
 | 
			
		||||
    timeout.tv_usec = 0;
 | 
			
		||||
 | 
			
		||||
    while (param.mode != IPERF_MODE_STOP){
 | 
			
		||||
        FD_ZERO(&readset);
 | 
			
		||||
        FD_SET(sock, &readset);
 | 
			
		||||
 | 
			
		||||
        if (select(sock + 1, &readset, NULL, NULL, &timeout) == 0) {
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        sin_size = sizeof(struct sockaddr_in);
 | 
			
		||||
 | 
			
		||||
        connected = accept(sock, (struct sockaddr *)&client_addr, &sin_size);
 | 
			
		||||
 | 
			
		||||
        printf("new client connected from (%s, %d)\n",
 | 
			
		||||
                   inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
 | 
			
		||||
 | 
			
		||||
        int flag = 1;
 | 
			
		||||
        setsockopt(connected,
 | 
			
		||||
                    IPPROTO_TCP,     /* set option at TCP level */
 | 
			
		||||
                    TCP_NODELAY,     /* name of option */
 | 
			
		||||
                    (void *) &flag,  /* the cast is historical cruft */
 | 
			
		||||
                    sizeof(int));    /* length of option value */
 | 
			
		||||
 | 
			
		||||
        recvlen = 0;
 | 
			
		||||
        tick1 = CurrentTicksGain();
 | 
			
		||||
        while (param.mode != IPERF_MODE_STOP){
 | 
			
		||||
            bytes_received = recv(connected, recv_data, IPERF_BUFSZ, 0);
 | 
			
		||||
            if (bytes_received == 0) {
 | 
			
		||||
                KPrintf("client disconnected (%s, %d)\n",
 | 
			
		||||
                   inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
 | 
			
		||||
                break;
 | 
			
		||||
            } else if (bytes_received < 0) {
 | 
			
		||||
                KPrintf("recv error, client: (%s, %d)\n",
 | 
			
		||||
                   inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            recvlen += bytes_received;
 | 
			
		||||
 | 
			
		||||
            tick2 = CurrentTicksGain();
 | 
			
		||||
            if (tick2 - tick1 >= TICK_PER_SECOND * 5) {
 | 
			
		||||
                double speed;
 | 
			
		||||
                // int integer, decimal;
 | 
			
		||||
                KTaskDescriptorType tid;
 | 
			
		||||
 | 
			
		||||
                tid = GetKTaskDescriptor();
 | 
			
		||||
                speed = (double)(recvlen * TICK_PER_SECOND / (125 * (tick2 - tick1)));
 | 
			
		||||
                speed = speed / 1000.0f;
 | 
			
		||||
                printf("%s: %2.4f Mbps!\n", tid->task_base_info.name, speed);
 | 
			
		||||
                tick1 = tick2;
 | 
			
		||||
                recvlen = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (connected >= 0) closesocket(connected);
 | 
			
		||||
        connected = -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
__exit:
 | 
			
		||||
    if (sock >= 0) closesocket(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 <host>    run in client mode, connecting to <host>\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 <time>    the number of multi-threaded \ns");
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int iperf(int argc, char **argv)
 | 
			
		||||
{
 | 
			
		||||
    int mode = 0; /* server mode */
 | 
			
		||||
    char *host = NULL;
 | 
			
		||||
    int port = IPERF_PORT;
 | 
			
		||||
    int numtid = 1;
 | 
			
		||||
    int use_udp = 0;
 | 
			
		||||
    int index = 1;
 | 
			
		||||
 | 
			
		||||
    if (argc == 1)
 | 
			
		||||
    {
 | 
			
		||||
        goto __usage;
 | 
			
		||||
    }
 | 
			
		||||
    if (strcmp(argv[1], "-u") == 0)
 | 
			
		||||
    {
 | 
			
		||||
        index = 2;
 | 
			
		||||
        use_udp = 1;
 | 
			
		||||
    }
 | 
			
		||||
    if (strcmp(argv[index], "-h") == 0) goto __usage;
 | 
			
		||||
    else if (strcmp(argv[index], "--stop") == 0)
 | 
			
		||||
    {
 | 
			
		||||
        /* stop iperf */
 | 
			
		||||
        param.mode = IPERF_MODE_STOP;
 | 
			
		||||
        printf("iperf stop.\n");
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    else if (strcmp(argv[index], "-s") == 0)
 | 
			
		||||
    {
 | 
			
		||||
        mode = IPERF_MODE_SERVER; /* server mode */
 | 
			
		||||
 | 
			
		||||
        /* iperf -s -p 5000 */
 | 
			
		||||
        if (argc >= 4)
 | 
			
		||||
        {
 | 
			
		||||
            if (strcmp(argv[index + 1], "-p") == 0)
 | 
			
		||||
            {
 | 
			
		||||
                port = atoi(argv[index + 2]);
 | 
			
		||||
            }
 | 
			
		||||
            else goto __usage;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if (strcmp(argv[index], "-c") == 0)
 | 
			
		||||
    {
 | 
			
		||||
        mode = IPERF_MODE_CLIENT; /* client mode */
 | 
			
		||||
        if (argc < 3) goto __usage;
 | 
			
		||||
 | 
			
		||||
        host = argv[index + 1];
 | 
			
		||||
        if (argc >= 5)
 | 
			
		||||
        {
 | 
			
		||||
            /* iperf -c host -p port */
 | 
			
		||||
            if (strcmp(argv[index + 2], "-p") == 0)
 | 
			
		||||
            {
 | 
			
		||||
                port = atoi(argv[index + 3]);
 | 
			
		||||
            }
 | 
			
		||||
            else goto __usage;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else goto __usage;
 | 
			
		||||
 | 
			
		||||
    if (argc >= 7)
 | 
			
		||||
    {
 | 
			
		||||
        if(strcmp(argv[argc - 2], "-m") == 0)
 | 
			
		||||
        {
 | 
			
		||||
            numtid = atoi(argv[argc - 1]);
 | 
			
		||||
        }
 | 
			
		||||
        else  goto __usage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* start iperf */
 | 
			
		||||
    if (param.mode == IPERF_MODE_STOP)
 | 
			
		||||
    {
 | 
			
		||||
        int i = 0;
 | 
			
		||||
        char tid_name[NAME_NUM_MAX + 1] = {0};
 | 
			
		||||
 | 
			
		||||
        param.mode = mode;
 | 
			
		||||
        param.port = port;
 | 
			
		||||
        if (param.host)
 | 
			
		||||
        {
 | 
			
		||||
            free(param.host);
 | 
			
		||||
            param.host = NULL;
 | 
			
		||||
        }
 | 
			
		||||
        if (host) param.host = strdup(host);
 | 
			
		||||
 | 
			
		||||
        for (i = 0; i < numtid; i++)
 | 
			
		||||
        {
 | 
			
		||||
            int32 tid = 0;
 | 
			
		||||
            void (*function)(void *parameter);
 | 
			
		||||
 | 
			
		||||
            if (use_udp)
 | 
			
		||||
            {
 | 
			
		||||
                if (mode == IPERF_MODE_CLIENT)
 | 
			
		||||
                {
 | 
			
		||||
                    snprintf(tid_name, sizeof(tid_name), "iperfc%02d", i + 1);
 | 
			
		||||
                    function = iperf_udp_client;
 | 
			
		||||
                }
 | 
			
		||||
                else if (mode == IPERF_MODE_SERVER)
 | 
			
		||||
                {
 | 
			
		||||
                    snprintf(tid_name, sizeof(tid_name), "iperfd%02d", i + 1);
 | 
			
		||||
                    function = iperf_udp_server;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                if (mode == IPERF_MODE_CLIENT)
 | 
			
		||||
                {
 | 
			
		||||
                    snprintf(tid_name, sizeof(tid_name), "iperfc%02d", i + 1);
 | 
			
		||||
                    function = iperf_client;
 | 
			
		||||
                }
 | 
			
		||||
                else if (mode == IPERF_MODE_SERVER)
 | 
			
		||||
                {
 | 
			
		||||
                    snprintf(tid_name, sizeof(tid_name), "iperfd%02d", i + 1);
 | 
			
		||||
                    function = iperf_server_multithread;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            tid = KTaskCreate(tid_name, function, NULL, LWIP_TASK_STACK_SIZE, 20);
 | 
			
		||||
            if (tid) StartupKTask(tid);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        KPrintf("Please stop iperf firstly, by:\n");
 | 
			
		||||
        KPrintf("iperf --stop\n");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
__usage:
 | 
			
		||||
    iperf_usage();
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if LWIP_TCP
 | 
			
		||||
static void
 | 
			
		||||
lwiperf_report(void *arg, enum lwiperf_report_type report_type,
 | 
			
		||||
  const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port,
 | 
			
		||||
  u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec)
 | 
			
		||||
{
 | 
			
		||||
  LWIP_UNUSED_ARG(arg);
 | 
			
		||||
  LWIP_UNUSED_ARG(local_addr);
 | 
			
		||||
  LWIP_UNUSED_ARG(local_port);
 | 
			
		||||
 
 | 
			
		||||
  printf("IPERF report: type=%d, remote: %s:%d, total bytes: %"U32_F", duration in ms: %"U32_F", kbits/s: %"U32_F"\n",
 | 
			
		||||
    (int)report_type, ipaddr_ntoa(remote_addr), (int)remote_port, bytes_transferred, ms_duration, bandwidth_kbitpsec);
 | 
			
		||||
}
 | 
			
		||||
#endif /* LWIP_TCP */
 | 
			
		||||
 
 | 
			
		||||
 
 | 
			
		||||
void
 | 
			
		||||
lwiperf_example_init(void)
 | 
			
		||||
{
 | 
			
		||||
#if LWIP_TCP
 | 
			
		||||
  ip4_addr_t ipaddr;
 | 
			
		||||
 
 | 
			
		||||
 lwiperf_start_tcp_server_default(lwiperf_report, NULL);
 | 
			
		||||
 
 | 
			
		||||
  // IP4_ADDR(&ipaddr,192,168,0,181);
 | 
			
		||||
  // lwiperf_start_tcp_client_default(&ipaddr, lwiperf_report, NULL);
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(8),
 | 
			
		||||
    iperf, iperf, netutils iperf);
 | 
			
		||||
 | 
			
		||||
extern void *lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void *report_arg);
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(8),
 | 
			
		||||
    lwiperf_tcp_server, lwiperf_example_init, netutils lwipperf);
 | 
			
		||||
| 
						 | 
				
			
			@ -30,7 +30,8 @@ static void LwipSetIPTask(void *param)
 | 
			
		|||
{
 | 
			
		||||
    uint8_t enet_port = *(uint8_t *)param; ///< test enet port 
 | 
			
		||||
    printf("lw: [%s] config netport id[%d]\n", __func__, enet_port);
 | 
			
		||||
    lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
 | 
			
		||||
    // lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
 | 
			
		||||
    lwip_config_tcp(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LwipSetIPTest(int argc, char *argv[])
 | 
			
		||||
| 
						 | 
				
			
			@ -64,7 +65,8 @@ void LwipSetIPTest(int argc, char *argv[])
 | 
			
		|||
        sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]);
 | 
			
		||||
        memcpy(lwip_eth0_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr));
 | 
			
		||||
    }
 | 
			
		||||
    sys_thread_new("SET ip address", LwipSetIPTask, &enet_id, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
 | 
			
		||||
    // sys_thread_new("SET ip address", LwipSetIPTask, &enet_id, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
 | 
			
		||||
    LwipSetIPTask(&enet_id);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5),
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -37,59 +37,17 @@
 | 
			
		|||
ip4_addr_t ping_addr;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
char arg_ip[20] = {192, 168, 130, 50};
 | 
			
		||||
 | 
			
		||||
void LwipPingTest(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    int result = 0;
 | 
			
		||||
    uint8_t enet_port = 0; ///< test enet port 0
 | 
			
		||||
 | 
			
		||||
    if(argc >= 4)
 | 
			
		||||
    {
 | 
			
		||||
        printf("lw: [%s] ip %s mask %s gw %s for netport %s\n", __func__, argv[1], argv[2], argv[3], argv[4]);
 | 
			
		||||
        sscanf(argv[1], "%d.%d.%d.%d", &lwip_ipaddr[0], &lwip_ipaddr[1], &lwip_ipaddr[2], &lwip_ipaddr[3]);
 | 
			
		||||
        sscanf(argv[2], "%d.%d.%d.%d", &lwip_netmask[0], &lwip_netmask[1], &lwip_netmask[2], &lwip_netmask[3]);
 | 
			
		||||
        sscanf(argv[3], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]);
 | 
			
		||||
        sscanf(argv[4], "%d", &enet_port);
 | 
			
		||||
 | 
			
		||||
        if(0 == enet_port)
 | 
			
		||||
        {
 | 
			
		||||
            memcpy(lwip_eth0_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr));
 | 
			
		||||
            memcpy(lwip_eth0_netmask, lwip_netmask, strlen(lwip_netmask));
 | 
			
		||||
            memcpy(lwip_eth0_gwaddr, lwip_gwaddr, strlen(lwip_gwaddr));
 | 
			
		||||
        }
 | 
			
		||||
        if(1 == enet_port)
 | 
			
		||||
        {
 | 
			
		||||
            memcpy(lwip_eth1_ipaddr, lwip_ipaddr, strlen(lwip_ipaddr));
 | 
			
		||||
            memcpy(lwip_eth1_netmask, lwip_netmask, strlen(lwip_netmask));
 | 
			
		||||
            memcpy(lwip_eth1_gwaddr, lwip_gwaddr, strlen(lwip_gwaddr));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else if(argc == 3)
 | 
			
		||||
    {
 | 
			
		||||
        sscanf(argv[2], "%d", &enet_port);
 | 
			
		||||
        printf("lw: [%s] gw %s netport %d\n", __func__, argv[1], enet_port);
 | 
			
		||||
    if (argc == 2) {
 | 
			
		||||
        printf("lw: [%s] ping %s\n", __func__, argv[1]);
 | 
			
		||||
        if(isdigit(argv[1][0]))
 | 
			
		||||
        {
 | 
			
		||||
            if(sscanf(argv[1], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]) == EOF)
 | 
			
		||||
            {
 | 
			
		||||
                lw_notice("input wrong ip\n");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
#if (LWIP_DHCP) && (PING_USE_SOCKETS)
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            get_url_ip(argv[1]);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
#endif
 | 
			
		||||
    }
 | 
			
		||||
    else if(argc == 2)
 | 
			
		||||
    {
 | 
			
		||||
        printf("lw: [%s] gw %s\n", __func__, argv[1]);
 | 
			
		||||
        if(isdigit(argv[1][0]))
 | 
			
		||||
        {
 | 
			
		||||
            if(sscanf(argv[1], "%d.%d.%d.%d", &lwip_gwaddr[0], &lwip_gwaddr[1], &lwip_gwaddr[2], &lwip_gwaddr[3]) == EOF)
 | 
			
		||||
            if(sscanf(argv[1], "%d.%d.%d.%d", &arg_ip[0], &arg_ip[1], &arg_ip[2], &arg_ip[3]) == EOF)
 | 
			
		||||
            {
 | 
			
		||||
                lw_notice("input wrong ip\n");
 | 
			
		||||
                return;
 | 
			
		||||
| 
						 | 
				
			
			@ -106,12 +64,11 @@ void LwipPingTest(int argc, char *argv[])
 | 
			
		|||
 | 
			
		||||
    printf("lw: [%s] argc %d\n", __func__, argc);
 | 
			
		||||
 | 
			
		||||
    IP4_ADDR(&ping_addr, lwip_gwaddr[0], lwip_gwaddr[1], lwip_gwaddr[2], lwip_gwaddr[3]);
 | 
			
		||||
    lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, lwip_gwaddr);
 | 
			
		||||
    IP4_ADDR(&ping_addr, arg_ip[0], arg_ip[1], arg_ip[2], arg_ip[3]);
 | 
			
		||||
    ping_init(&ping_addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(5),
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(2),
 | 
			
		||||
     ping, LwipPingTest, ping [IP] 10 times);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -19,15 +19,19 @@
 | 
			
		|||
*/
 | 
			
		||||
 | 
			
		||||
#include "board.h"
 | 
			
		||||
#include "lwip_demo.h"
 | 
			
		||||
#include "sys_arch.h"
 | 
			
		||||
#include "lwip/sockets.h"
 | 
			
		||||
#include "tcpecho_raw.h"
 | 
			
		||||
#include <shell.h>
 | 
			
		||||
#include <sys.h>
 | 
			
		||||
#include <xizi.h>
 | 
			
		||||
#include "lwip_demo.h"
 | 
			
		||||
#include "lwip/sockets.h"
 | 
			
		||||
#include "tcpecho_raw.h"
 | 
			
		||||
char tcp_demo_msg[LWIP_TEST_MSG_SIZE] = { 0 };
 | 
			
		||||
char tcp_demo_ip[] = {192, 168, 250, 252};
 | 
			
		||||
u16_t tcp_demo_port = LWIP_TARGET_PORT;
 | 
			
		||||
u16_t tcp_demo_port = 80;
 | 
			
		||||
int tcp_send_num = 0;
 | 
			
		||||
int tcp_send_task_on = 0;
 | 
			
		||||
uint32 tcp_interval = 50;
 | 
			
		||||
 | 
			
		||||
/******************************************************************************/
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -58,17 +62,34 @@ static void LwipTcpSendTask(void *arg)
 | 
			
		|||
 | 
			
		||||
    lw_notice("tcp connect success, start to send.\n");
 | 
			
		||||
    lw_notice("\n\nTarget Port:%d\n\n", tcp_sock.sin_port);
 | 
			
		||||
    tcp_send_task_on = 1;
 | 
			
		||||
 | 
			
		||||
    while(tcp_send_num > 0 || tcp_send_num == -1)
 | 
			
		||||
    {
 | 
			
		||||
        sendto(fd, tcp_demo_msg, strlen(tcp_demo_msg), 0, (struct sockaddr*)&tcp_sock, sizeof(struct sockaddr));
 | 
			
		||||
 | 
			
		||||
    lw_notice("Send tcp msg: %s ", tcp_demo_msg);
 | 
			
		||||
        lw_notice("Send tcp msg: %s \n", tcp_demo_msg);
 | 
			
		||||
        if(tcp_send_num > 0)
 | 
			
		||||
        {
 | 
			
		||||
            tcp_send_num--;
 | 
			
		||||
        }
 | 
			
		||||
        DelayKTask(tcp_interval);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    closesocket(fd);
 | 
			
		||||
    tcp_send_task_on = 0;
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void LwipTcpSendTest(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    if(tcp_send_task_on){
 | 
			
		||||
        tcp_send_num = 0;
 | 
			
		||||
        printf("waitting send task exit...\n");
 | 
			
		||||
        while(tcp_send_task_on){
 | 
			
		||||
            DelayKTask(1000);
 | 
			
		||||
        }
 | 
			
		||||
        tcp_send_num = 1;
 | 
			
		||||
    }
 | 
			
		||||
    LwipTcpSocketParamType param;
 | 
			
		||||
    uint8_t enet_port = 0;
 | 
			
		||||
    memset(tcp_demo_msg, 0, LWIP_TEST_MSG_SIZE);
 | 
			
		||||
| 
						 | 
				
			
			@ -88,8 +109,10 @@ void LwipTcpSendTest(int argc, char *argv[])
 | 
			
		|||
        {
 | 
			
		||||
            sscanf(argv[2], "%d.%d.%d.%d", &tcp_demo_ip[0], &tcp_demo_ip[1], &tcp_demo_ip[2], &tcp_demo_ip[3]);
 | 
			
		||||
        }
 | 
			
		||||
        sscanf(argv[3], "%d", &tcp_send_num);
 | 
			
		||||
        sscanf(argv[4], "%d", &tcp_interval);
 | 
			
		||||
    }
 | 
			
		||||
    lw_notice("get ipaddr %d.%d.%d.%d:%d\n", tcp_demo_ip[0], tcp_demo_ip[1], tcp_demo_ip[2], tcp_demo_ip[3], tcp_demo_port);
 | 
			
		||||
    lw_notice("get ipaddr %d.%d.%d.%d:%d send msg %d times\n", tcp_demo_ip[0], tcp_demo_ip[1], tcp_demo_ip[2], tcp_demo_ip[3], tcp_demo_port, tcp_send_num);
 | 
			
		||||
    lwip_config_tcp(enet_port, lwip_ipaddr, lwip_netmask, tcp_demo_ip);
 | 
			
		||||
 | 
			
		||||
    memcpy(param.ip, tcp_demo_ip, 4);
 | 
			
		||||
| 
						 | 
				
			
			@ -101,7 +124,7 @@ void LwipTcpSendTest(int argc, char *argv[])
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
 | 
			
		||||
     TCPSend, LwipTcpSendTest, TCP Send message);
 | 
			
		||||
     TCPSend, LwipTcpSendTest, TCPSend msg [ip:port [num [interval]]]);
 | 
			
		||||
 | 
			
		||||
void LwipTcpRecvTest(void)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,14 +23,18 @@
 | 
			
		|||
#include "lwip/sockets.h"
 | 
			
		||||
#include <shell.h>
 | 
			
		||||
#include <sys.h>
 | 
			
		||||
#include <xizi.h>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#define PBUF_SIZE 27
 | 
			
		||||
 | 
			
		||||
static struct udp_pcb *udpecho_raw_pcb;
 | 
			
		||||
 | 
			
		||||
char udp_demo_ip[] = {192, 168, 250, 252};
 | 
			
		||||
char udp_demo_ip[] = {192, 168, 131, 1};
 | 
			
		||||
u16_t udp_demo_port = LWIP_TARGET_PORT;
 | 
			
		||||
int32 udp_send_num = 0;
 | 
			
		||||
int8 udp_send_task_on = 0;
 | 
			
		||||
uint32 udp_interval = 50;
 | 
			
		||||
 | 
			
		||||
char hello_str[] = {"hello world\r\n"};
 | 
			
		||||
char udp_demo_msg[] = "\nThis one is UDP package!!!\n";
 | 
			
		||||
| 
						 | 
				
			
			@ -66,21 +70,37 @@ static void LwipUDPSendTask(void *arg)
 | 
			
		|||
 | 
			
		||||
    lw_notice("UDP connect success, start to send.\n");
 | 
			
		||||
    lw_notice("\n\nTarget Port:%d\n\n", udp_sock.sin_port);
 | 
			
		||||
    udp_send_task_on = 1;
 | 
			
		||||
 | 
			
		||||
    while(udp_send_num > 0 || udp_send_num == -1)
 | 
			
		||||
    {
 | 
			
		||||
        sendto(socket_fd, udp_demo_msg, strlen(udp_demo_msg), 0, (struct sockaddr*)&udp_sock, sizeof(struct sockaddr));
 | 
			
		||||
    lw_notice("Send UDP msg: %s ", udp_demo_msg);
 | 
			
		||||
        lw_notice("Send UDP msg: %s \n", udp_demo_msg);
 | 
			
		||||
        DelayKTask(udp_interval);
 | 
			
		||||
        udp_send_num--;
 | 
			
		||||
    }
 | 
			
		||||
    closesocket(socket_fd);
 | 
			
		||||
    udp_send_task_on = 0;
 | 
			
		||||
    return;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void *LwipUdpSendTest(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
    if(udp_send_task_on){
 | 
			
		||||
        udp_send_num = 0;
 | 
			
		||||
        printf("waitting send task exit...\n");
 | 
			
		||||
        while(udp_send_task_on){
 | 
			
		||||
            DelayKTask(1000);
 | 
			
		||||
        }
 | 
			
		||||
        udp_send_num = 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint8_t enet_port = 0; ///< test enet port 0
 | 
			
		||||
    memset(udp_demo_msg, 0, sizeof(udp_demo_msg));
 | 
			
		||||
 | 
			
		||||
    if(argc == 1)
 | 
			
		||||
    {
 | 
			
		||||
        lw_print("lw: [%s] gw %d.%d.%d.%d\n", __func__, udp_demo_ip[0], udp_demo_ip[1], udp_demo_ip[2], udp_demo_ip[3]);
 | 
			
		||||
        lw_print("lw: [%s] gw %d.%d.%d.%d:%d\n", __func__, udp_demo_ip[0], udp_demo_ip[1], udp_demo_ip[2], udp_demo_ip[3], udp_demo_port);
 | 
			
		||||
        strncpy(udp_demo_msg, hello_str, strlen(hello_str));
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
| 
						 | 
				
			
			@ -89,18 +109,23 @@ void *LwipUdpSendTest(int argc, char *argv[])
 | 
			
		|||
        strncat(udp_demo_msg, "\r\n", 2);
 | 
			
		||||
        if(argc == 3)
 | 
			
		||||
        {
 | 
			
		||||
            sscanf(argv[2], "%d.%d.%d.%d", &udp_demo_ip[0], &udp_demo_ip[1], &udp_demo_ip[2], &udp_demo_ip[3]);
 | 
			
		||||
            sscanf(argv[2], "%d.%d.%d.%d:%d", &udp_demo_ip[0], &udp_demo_ip[1], &udp_demo_ip[2], &udp_demo_ip[3], &udp_demo_port);
 | 
			
		||||
        }
 | 
			
		||||
        if(argc > 3)
 | 
			
		||||
        {
 | 
			
		||||
            sscanf(argv[3], "%d", &udp_send_num);
 | 
			
		||||
            sscanf(argv[4], "%d", &udp_interval);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    lw_print("lw: [%s] gw %d.%d.%d.%d\n", __func__, udp_demo_ip[0], udp_demo_ip[1], udp_demo_ip[2], udp_demo_ip[3]);
 | 
			
		||||
    lw_print("lw: [%s] gw %d.%d.%d.%d:%d send time %d udp_interval %d\n", __func__, udp_demo_ip[0], udp_demo_ip[1], udp_demo_ip[2], udp_demo_ip[3], udp_demo_port, udp_send_num, udp_interval);
 | 
			
		||||
 | 
			
		||||
    lwip_config_net(enet_port, lwip_ipaddr, lwip_netmask, udp_demo_ip);
 | 
			
		||||
    sys_thread_new("udp send", LwipUDPSendTask, NULL, LWIP_TASK_STACK_SIZE, LWIP_DEMO_TASK_PRIO);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
SHELL_EXPORT_CMD(SHELL_CMD_PERMISSION(0) | SHELL_CMD_TYPE(SHELL_TYPE_CMD_MAIN) | SHELL_CMD_PARAM_NUM(3),
 | 
			
		||||
     UDPSend, LwipUdpSendTest, UDP send echo);
 | 
			
		||||
     UDPSend, LwipUdpSendTest, UDPSend msg [ip:port [num [interval]]]);
 | 
			
		||||
 | 
			
		||||
static void LwipUdpRecvTask(void *arg, struct udp_pcb *upcb, struct pbuf *p,
 | 
			
		||||
                 const ip_addr_t *addr, u16_t port)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -38,6 +38,7 @@
 | 
			
		|||
 *
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <sys/time.h>
 | 
			
		||||
#include <xs_ktask.h>
 | 
			
		||||
#include "lwip/opt.h"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +124,9 @@ ping_prepare_echo( struct icmp_echo_hdr *iecho, u16_t len)
 | 
			
		|||
    ((char*)iecho)[sizeof(struct icmp_echo_hdr) + i] = (char)i;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
#ifndef CHECKSUM_GEN_ICMP
 | 
			
		||||
  iecho->chksum = inet_chksum(iecho, len);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if PING_USE_SOCKETS
 | 
			
		||||
| 
						 | 
				
			
			@ -208,7 +211,9 @@ ping_recv(int s)
 | 
			
		|||
 | 
			
		||||
      LWIP_DEBUGF( PING_DEBUG, ("ping: recv "));
 | 
			
		||||
      ip_addr_debug_print_val(PING_DEBUG, fromaddr);
 | 
			
		||||
#ifdef LWIP_DEBUG
 | 
			
		||||
      LWIP_DEBUGF( PING_DEBUG, (" %"U32_F" ms\n", (sys_now() - ping_time)));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
      /* todo: support ICMP6 echo */
 | 
			
		||||
#if LWIP_IPV4
 | 
			
		||||
| 
						 | 
				
			
			@ -232,7 +237,9 @@ ping_recv(int s)
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  if (len == 0) {
 | 
			
		||||
#ifdef LWIP_DEBUG
 | 
			
		||||
    LWIP_DEBUGF( PING_DEBUG, ("ping: recv - %"U32_F" ms - timeout\n", (sys_now()-ping_time)));
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* do some ping result processing */
 | 
			
		||||
| 
						 | 
				
			
			@ -274,7 +281,7 @@ ping_thread(void *arg)
 | 
			
		|||
  lw_print("lw: [%s] ping start!\n", __func__);
 | 
			
		||||
 | 
			
		||||
  ret = lwip_setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout));
 | 
			
		||||
  LWIP_ASSERT("setting receive timeout failed", ret != 0);
 | 
			
		||||
  LWIP_ASSERT("setting receive timeout failed", ret == 0);
 | 
			
		||||
  LWIP_UNUSED_ARG(ret);
 | 
			
		||||
 | 
			
		||||
  while (cnt --) {
 | 
			
		||||
| 
						 | 
				
			
			@ -521,8 +528,10 @@ int get_url_ip(char* url)
 | 
			
		|||
#endif /* LWIP_DEBUG */
 | 
			
		||||
            if ((recv_len = lwip_ping_recv(s, &ttl)) >= 0)
 | 
			
		||||
            {
 | 
			
		||||
#ifdef LWIP_DEBUG
 | 
			
		||||
                lw_notice("%d bytes from %s icmp_seq=%d ttl=%d time=%d ms\n", recv_len, inet_ntoa(ina), cnt,
 | 
			
		||||
                ttl, sys_now() - ping_time);
 | 
			
		||||
#endif
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue