Added LwIP and CYW43362 firmware.

Signed-off-by: Yilin Sun <imi415@imi.moe>
This commit is contained in:
Yilin Sun 2022-12-11 21:31:13 +08:00
parent 5c073784f6
commit 2bf5753208
Signed by: imi415
GPG Key ID: 17F01E106F9F5E0A
30 changed files with 42371 additions and 34 deletions

View File

@ -2,7 +2,9 @@ BasedOnStyle: Google
IndentWidth: 4
AlignConsecutiveMacros: AcrossEmptyLines
AlignConsecutiveDeclarations: AcrossEmptyLines
AlignConsecutiveAssignments: AcrossEmptyLinesAndComments
AlignConsecutiveAssignments: Consecutive
AllowShortBlocksOnASingleLine: Never
AllowShortFunctionsOnASingleLine: Empty
BreakBeforeBraces: Custom
BraceWrapping:
AfterEnum: false

View File

@ -1,4 +1,7 @@
Checks: >
*,
-altera-unroll-loops,
-hicpp-no-assembler
-cert-err33-c,
-hicpp-no-assembler,
-hicpp-signed-bitwise,
-modernize-macro-to-enum

3
.gitmodules vendored
View File

@ -7,3 +7,6 @@
[submodule "lib/freertos"]
path = lib/freertos
url = https://github.com/FreeRTOS/FreeRTOS-Kernel.git
[submodule "lib/lwip/lwip"]
path = lib/lwip/lwip
url = https://github.com/lwip-tcpip/lwip.git

View File

@ -6,10 +6,12 @@ enable_language(CXX)
enable_language(ASM)
# Different linker scripts
set(TARGET_LDSCRIPT_FLASH "${CMAKE_SOURCE_DIR}/SDK/devices/MIMXRT1052/gcc/MIMXRT1052xxxxx_flexspi_nor.ld")
set(TARGET_LDSCRIPT_RAM "${CMAKE_SOURCE_DIR}/SDK/devices/MIMXRT1052/gcc/MIMXRT1052xxxxx_ram.ld")
set(TARGET_LDSCRIPT_FLASH "${CMAKE_SOURCE_DIR}/app_flexspi.ld")
set(TARGET_LDSCRIPT_RAM "${CMAKE_SOURCE_DIR}/app_ram.ld")
set(TARGET_SOURCES
"SDK/components/lists/fsl_component_generic_list.c"
"SDK/components/osa/fsl_os_abstraction_free_rtos.c"
"SDK/components/serial_manager/fsl_component_serial_manager.c"
"SDK/components/serial_manager/fsl_component_serial_port_uart.c"
"SDK/components/uart/fsl_adapter_lpuart.c"
@ -90,13 +92,24 @@ set(TARGET_SOURCES
"SDK/devices/MIMXRT1052/utilities/fsl_sbrk.c"
"SDK/devices/MIMXRT1052/utilities/str/fsl_str.c"
"SDK/devices/MIMXRT1052/xip/fsl_flexspi_nor_boot.c"
"SDK/middleware/sdmmc/common/fsl_sdmmc_common.c"
"SDK/middleware/sdmmc/osa/fsl_sdmmc_osa.c"
"SDK/middleware/sdmmc/sdio/fsl_sdio.c"
"SDK/middleware/sdmmc/host/usdhc/non_blocking/fsl_sdmmc_host.c"
"board/board.c"
"board/clock_config.c"
"board/dcd.c"
"board/peripherals.c"
"board/pin_mux.c"
"src/freertos_support.c"
"src/lwip_port/sys_arch.c"
"src/main.c"
"src/task_hello.c"
"src/whd_port/cy_network_buffer.c"
"src/whd_port/hal/cyhal_sdio.c"
"src/whd_port/resources/whd_resources.c"
"src/whd_port/resources/firmware/COMPONENT_43362/43362A2_bin.c"
"src/whd_port/resources/nvram/cyw43362A2_nvram_image.c"
"src/whd_port/rtos/cyabs_rtos.c"
"xip/fire_rt1052_pro_flexspi_nor_config.c"
)
@ -106,7 +119,9 @@ set(TARGET_C_DEFINES
"MCUXPRESSO_SDK"
"PRINTF_ADVANCED_ENABLE=1"
"PRINTF_FLOAT_ENABLE=1"
"SDK_OS_FREE_RTOS"
"SERIAL_PORT_TYPE_UART"
"USE_RTOS=1"
"__STARTUP_CLEAR_BSS"
"__STARTUP_INITIALIZE_NONCACHEDATA"
)
@ -120,6 +135,8 @@ set(TARGET_C_DEFINES_XIP
set(TARGET_C_INCLUDES
"SDK/CMSIS/Core/Include"
"SDK/components/lists"
"SDK/components/osa"
"SDK/components/serial_manager"
"SDK/components/uart"
"SDK/devices/MIMXRT1052"
@ -127,6 +144,10 @@ set(TARGET_C_INCLUDES
"SDK/devices/MIMXRT1052/utilities"
"SDK/devices/MIMXRT1052/utilities/debug_console"
"SDK/devices/MIMXRT1052/utilities/str"
"SDK/middleware/sdmmc/common"
"SDK/middleware/sdmmc/host/usdhc"
"SDK/middleware/sdmmc/osa"
"SDK/middleware/sdmmc/sdio"
"board"
"include"
)
@ -134,13 +155,14 @@ set(TARGET_C_INCLUDES
# Shared libraries linked with application
set(TARGET_LIBS
"freertos_kernel"
"lwip"
"m"
"whd"
)
# Shared library and linker script search paths
set(TARGET_LIB_DIRECTORIES
"SDK/devices/MIMXRT1052/gcc"
)
# Conditional flags
@ -170,6 +192,9 @@ set(FREERTOS_PORT "GCC_ARM_CM7" CACHE STRING "" FORCE)
set(FREERTOS_CONFIG_FILE_DIRECTORY "${CMAKE_SOURCE_DIR}/include" CACHE STRING "" FORCE)
add_subdirectory(lib/freertos)
set(LWIP_ADDITIONAL_INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include/lwip_port" CACHE STRING "")
add_subdirectory(lib/lwip)
# Shared sources, includes and definitions
add_compile_definitions(${TARGET_C_DEFINES})
include_directories(${TARGET_C_INCLUDES})

12
app_flexspi.ld Normal file
View File

@ -0,0 +1,12 @@
INCLUDE "MIMXRT1052xxxxx_flexspi_nor.ld"
SECTIONS {
.data2 : {
. = ALIGN(4);
*(.freertos_heap)
*(.freertos_heap*)
*(.lwip_mem)
*(.lwip_mem*)
. = ALIGN(4);
} > m_data2
}

12
app_ram.ld Normal file
View File

@ -0,0 +1,12 @@
INCLUDE "MIMXRT1052xxxxx_ram.ld"
SECTIONS {
.data2 : {
. = ALIGN(4);
*(.freertos_heap)
*(.freertos_heap*)
*(.lwip_mem)
*(.lwip_mem*)
. = ALIGN(4);
} > m_data2
}

View File

@ -63,8 +63,8 @@
/* Memory allocation related definitions. */
#define configSUPPORT_STATIC_ALLOCATION 0
#define configSUPPORT_DYNAMIC_ALLOCATION 1
#define configTOTAL_HEAP_SIZE ((size_t)(32 * 1024))
#define configAPPLICATION_ALLOCATED_HEAP 0
#define configTOTAL_HEAP_SIZE ((size_t)(128 * 1024))
#define configAPPLICATION_ALLOCATED_HEAP 1
/* Hook function related definitions. */
#define configUSE_IDLE_HOOK 0

View File

@ -0,0 +1 @@
#define NVRAM_GENERATED_MAC_ADDRESS "macaddr=00:A0:50:f8:74:9a"

View File

@ -0,0 +1,8 @@
#ifndef LWIP_ARCH_CC_H
#define LWIP_ARCH_CC_H
#define LWIP_TIMEVAL_PRIVATE 0
#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) __attribute__((section(".lwip_mem"), aligned(4))) u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)]
#endif /* LWIP_ARCH_CC_H */

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmdit <goldsimon@gmx.de>
*
*/
#ifndef LWIP_ARCH_SYS_ARCH_H
#define LWIP_ARCH_SYS_ARCH_H
#include "lwip/opt.h"
#include "lwip/arch.h"
/** This is returned by _fromisr() sys functions to tell the outermost function
* that a higher priority task was woken and the scheduler needs to be invoked.
*/
#define ERR_NEED_SCHED 123
/* This port includes FreeRTOS headers in sys_arch.c only.
* FreeRTOS uses pointers as object types. We use wrapper structs instead of
* void pointers directly to get a tiny bit of type safety.
*/
void sys_arch_msleep(u32_t delay_ms);
#define sys_msleep(ms) sys_arch_msleep(ms)
#if SYS_LIGHTWEIGHT_PROT
typedef u32_t sys_prot_t;
#endif /* SYS_LIGHTWEIGHT_PROT */
#if !LWIP_COMPAT_MUTEX
struct _sys_mut {
void *mut;
};
typedef struct _sys_mut sys_mutex_t;
#define sys_mutex_valid_val(mutex) ((mutex).mut != NULL)
#define sys_mutex_valid(mutex) (((mutex) != NULL) && sys_mutex_valid_val(*(mutex)))
#define sys_mutex_set_invalid(mutex) ((mutex)->mut = NULL)
#endif /* !LWIP_COMPAT_MUTEX */
struct _sys_sem {
void *sem;
};
typedef struct _sys_sem sys_sem_t;
#define sys_sem_valid_val(sema) ((sema).sem != NULL)
#define sys_sem_valid(sema) (((sema) != NULL) && sys_sem_valid_val(*(sema)))
#define sys_sem_set_invalid(sema) ((sema)->sem = NULL)
struct _sys_mbox {
void *mbx;
};
typedef struct _sys_mbox sys_mbox_t;
#define sys_mbox_valid_val(mbox) ((mbox).mbx != NULL)
#define sys_mbox_valid(mbox) (((mbox) != NULL) && sys_mbox_valid_val(*(mbox)))
#define sys_mbox_set_invalid(mbox) ((mbox)->mbx = NULL)
struct _sys_thread {
void *thread_handle;
};
typedef struct _sys_thread sys_thread_t;
#if LWIP_NETCONN_SEM_PER_THREAD
sys_sem_t* sys_arch_netconn_sem_get(void);
void sys_arch_netconn_sem_alloc(void);
void sys_arch_netconn_sem_free(void);
#define LWIP_NETCONN_THREAD_SEM_GET() sys_arch_netconn_sem_get()
#define LWIP_NETCONN_THREAD_SEM_ALLOC() sys_arch_netconn_sem_alloc()
#define LWIP_NETCONN_THREAD_SEM_FREE() sys_arch_netconn_sem_free()
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
#endif /* LWIP_ARCH_SYS_ARCH_H */

View File

@ -0,0 +1,288 @@
#ifndef __LWIPOPTS_H__
#define __LWIPOPTS_H__
#define LWIP_FREERTOS_CHECK_CORE_LOCKING 1
/**
* SYS_LIGHTWEIGHT_PROT==1: if you want inter-task protection for certain
* critical regions during buffer allocation, deallocation and memory
* allocation and deallocation.
*/
#define SYS_LIGHTWEIGHT_PROT 1
/**
* NO_SYS==0: Use RTOS
*/
#define NO_SYS 0
/**
* LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
*/
#define LWIP_NETCONN 1
/**
* LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
*/
#define LWIP_SOCKET 1
/**
* LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and
* SO_RCVTIMEO processing.
*/
#define LWIP_SO_RCVTIMEO 1
/* ---------- Core locking ---------- */
#define LWIP_TCPIP_CORE_LOCKING 1
void sys_lock_tcpip_core(void);
#define LOCK_TCPIP_CORE() sys_lock_tcpip_core()
void sys_unlock_tcpip_core(void);
#define UNLOCK_TCPIP_CORE() sys_unlock_tcpip_core()
void sys_check_core_locking(void);
#define LWIP_ASSERT_CORE_LOCKED() sys_check_core_locking()
void sys_mark_tcpip_thread(void);
#define LWIP_MARK_TCPIP_THREAD() sys_mark_tcpip_thread()
/* ---------- Memory options ---------- */
/**
* MEM_ALIGNMENT: should be set to the alignment of the CPU
* 4 byte alignment -> #define MEM_ALIGNMENT 4
* 2 byte alignment -> #define MEM_ALIGNMENT 2
*/
#ifndef MEM_ALIGNMENT
#define MEM_ALIGNMENT 4
#endif
/**
* 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.
*/
#ifndef MEM_SIZE
#define MEM_SIZE (32 * 1024)
#endif
/* 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. */
#ifndef MEMP_NUM_PBUF
#define MEMP_NUM_PBUF 15
#endif
/* MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One
per active UDP "connection". */
#ifndef MEMP_NUM_UDP_PCB
#define MEMP_NUM_UDP_PCB 7
#endif
/* MEMP_NUM_TCP_PCB: the number of simulatenously active TCP
connections. */
#ifndef MEMP_NUM_TCP_PCB
#define MEMP_NUM_TCP_PCB 10
#endif
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
connections. */
#ifndef MEMP_NUM_TCP_PCB_LISTEN
#define MEMP_NUM_TCP_PCB_LISTEN 6
#endif
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
segments. */
#ifndef MEMP_NUM_TCP_SEG
#define MEMP_NUM_TCP_SEG 22
#endif
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
timeouts. */
#ifndef MEMP_NUM_SYS_TIMEOUT
#define MEMP_NUM_SYS_TIMEOUT 10
#endif
/* ---------- Pbuf options ---------- */
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
#ifndef PBUF_POOL_SIZE
#define PBUF_POOL_SIZE 5
#endif
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
/* Default value is defined in lwip\src\include\lwip\opt.h as
* LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN)*/
/* ---------- TCP options ---------- */
#ifndef LWIP_TCP
#define LWIP_TCP 1
#endif
#ifndef TCP_TTL
#define TCP_TTL 255
#endif
/* Controls if TCP should queue segments that arrive out of
order. Define to 0 if your device is low on memory. */
#ifndef TCP_QUEUE_OOSEQ
#define TCP_QUEUE_OOSEQ 0
#endif
/* TCP Maximum segment size. */
#ifndef TCP_MSS
#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
#endif
/* TCP sender buffer space (bytes). */
#ifndef TCP_SND_BUF
#define TCP_SND_BUF (6 * TCP_MSS) // 2
#endif
/* TCP sender buffer space (pbufs). This must be at least = 2 *
TCP_SND_BUF/TCP_MSS for things to work. */
#ifndef TCP_SND_QUEUELEN
#define TCP_SND_QUEUELEN (3 * TCP_SND_BUF) / TCP_MSS // 6
#endif
/* TCP receive window. */
#ifndef TCP_WND
#define TCP_WND (2 * TCP_MSS)
#endif
/* Enable backlog*/
#ifndef TCP_LISTEN_BACKLOG
#define TCP_LISTEN_BACKLOG 1
#endif
/* ---------- Network Interfaces options ---------- */
/* Support netif api (in netifapi.c). */
#ifndef LWIP_NETIF_API
#define LWIP_NETIF_API 1
#endif
/* ---------- ICMP options ---------- */
#ifndef LWIP_ICMP
#define LWIP_ICMP 1
#endif
/* ---------- DHCP options ---------- */
/* Enable DHCP module. */
#ifndef LWIP_DHCP
#define LWIP_DHCP 1
#endif
/* ---------- UDP options ---------- */
#ifndef LWIP_UDP
#define LWIP_UDP 1
#endif
#ifndef UDP_TTL
#define UDP_TTL 255
#endif
/* ---------- Statistics options ---------- */
#ifndef LWIP_STATS
#define LWIP_STATS 0
#endif
#ifndef LWIP_PROVIDE_ERRNO
#define LWIP_PROVIDE_ERRNO 1
#endif
/*
--------------------------------------
---------- Checksum options ----------
--------------------------------------
*/
/*
Some MCU allow computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
- To use this feature let the following define uncommented.
- To disable it and process by CPU comment the the checksum.
*/
//#define CHECKSUM_BY_HARDWARE
#ifdef CHECKSUM_BY_HARDWARE
/* CHECKSUM_GEN_IP==0: Generate checksums by hardware for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 0
/* CHECKSUM_GEN_UDP==0: Generate checksums by hardware for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 0
/* CHECKSUM_GEN_TCP==0: Generate checksums by hardware for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 0
/* CHECKSUM_CHECK_IP==0: Check checksums by hardware for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 0
/* CHECKSUM_CHECK_UDP==0: Check checksums by hardware for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 0
/* CHECKSUM_CHECK_TCP==0: Check checksums by hardware for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 0
#else
/* CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets.*/
#define CHECKSUM_GEN_IP 1
/* CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets.*/
#define CHECKSUM_GEN_UDP 1
/* CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets.*/
#define CHECKSUM_GEN_TCP 1
/* CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets.*/
#define CHECKSUM_CHECK_IP 1
/* CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets.*/
#define CHECKSUM_CHECK_UDP 1
/* CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets.*/
#define CHECKSUM_CHECK_TCP 1
#endif
/**
* DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread.
* The stack size value itself is platform-dependent, but is passed to
* sys_thread_new() when the thread is created.
*/
#ifndef DEFAULT_THREAD_STACKSIZE
#define DEFAULT_THREAD_STACKSIZE 3000
#endif
/**
* DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread.
* The priority value itself is platform-dependent, but is passed to
* sys_thread_new() when the thread is created.
*/
#ifndef DEFAULT_THREAD_PRIO
#define DEFAULT_THREAD_PRIO 3
#endif
/*
------------------------------------
---------- Debugging options ----------
------------------------------------
*/
#define LWIP_DEBUG
#define TCPIP_MBOX_SIZE 32
#define TCPIP_THREAD_STACKSIZE 1024
#define TCPIP_THREAD_PRIO 8
/**
* DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
* NETCONN_RAW. The queue size value itself is platform-dependent, but is passed
* to sys_mbox_new() when the recvmbox is created.
*/
#define DEFAULT_RAW_RECVMBOX_SIZE 12
/**
* DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
* NETCONN_UDP. The queue size value itself is platform-dependent, but is passed
* to sys_mbox_new() when the recvmbox is created.
*/
#define DEFAULT_UDP_RECVMBOX_SIZE 12
/**
* DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a
* NETCONN_TCP. The queue size value itself is platform-dependent, but is passed
* to sys_mbox_new() when the recvmbox is created.
*/
#define DEFAULT_TCP_RECVMBOX_SIZE 12
/**
* DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections.
* The queue size value itself is platform-dependent, but is passed to
* sys_mbox_new() when the acceptmbox is created.
*/
#define DEFAULT_ACCEPTMBOX_SIZE 12
#if (LWIP_DNS || LWIP_IGMP || LWIP_IPV6) && !defined(LWIP_RAND)
/* When using IGMP or IPv6, LWIP_RAND() needs to be defined to a random-function returning an u32_t random value*/
#include "lwip/arch.h"
u32_t lwip_rand(void);
#define LWIP_RAND() lwip_rand()
#endif
#endif /* __LWIPOPTS_H__ */

View File

@ -0,0 +1,7 @@
#ifndef WHD_RESOURCES_H
#define WHD_RESOURCES_H
extern const unsigned char cyw43362a2_firmware_image[213732];
extern const char cyw43362a2_nvram_image[965];
#endif

15
lib/lwip/CMakeLists.txt Normal file
View File

@ -0,0 +1,15 @@
cmake_minimum_required(VERSION 3.10)
project(lwip)
set(LWIP_DIR lwip)
set(LWIP_INCLUDE_DIRS
${LWIP_ADDITIONAL_INCLUDE_DIR}
lwip/src/include
)
include(lwip/src/Filelists.cmake)
add_library(${PROJECT_NAME} INTERFACE)
target_link_libraries(${PROJECT_NAME} INTERFACE lwipcore)
target_include_directories(${PROJECT_NAME} INTERFACE ${LWIP_INCLUDE_DIRS})

1
lib/lwip/lwip Submodule

@ -0,0 +1 @@
Subproject commit 239918ccc173cb2c2a62f41a40fd893f57faf1d6

View File

@ -3,15 +3,21 @@ cmake_minimum_required(VERSION 3.10)
project(whd)
if(DEFINED WHD_EXTERNAL_PATH)
set(WHD_EXTERNAL_INC ${WHD_EXTERNAL_PATH})
set(WHD_EXTERNAL_INCS
"${WHD_EXTERNAL_PATH}/bsp"
"${WHD_EXTERNAL_PATH}/hal"
"${WHD_EXTERNAL_PATH}/rtos"
)
else()
set(WHD_EXTERNAL_INC "wifi-host-driver/External")
set(WHD_EXTERNAL_INCS
"wifi-host-driver/External/bsp"
"wifi-host-driver/External/hal"
"wifi-host-driver/External/rtos"
)
message(WARNING "No WHD_EXTERNAL_PATH defined, using default.")
endif()
set(WHD_SOURCES
"wifi-host-driver/WiFi_Host_Driver/resources/firmware/COMPONENT_43438/43438A1_bin.c"
"wifi-host-driver/WiFi_Host_Driver/resources/firmware/COMPONENT_43438/43438A1-mfgtest_bin.c"
"wifi-host-driver/WiFi_Host_Driver/src/bus_protocols/whd_bus.c"
"wifi-host-driver/WiFi_Host_Driver/src/bus_protocols/whd_bus_common.c"
"wifi-host-driver/WiFi_Host_Driver/src/bus_protocols/whd_bus_m2m_protocol.c"
@ -38,14 +44,11 @@ set(WHD_SOURCES
)
set(WHD_INCLUDES
"${WHD_EXTERNAL_INC}/bsp"
"${WHD_EXTERNAL_INC}/hal"
"${WHD_EXTERNAL_INC}/rtos"
${WHD_EXTERNAL_INCS}
${WHD_RESOURCE_INCS}
"wifi-host-driver/WiFi_Host_Driver/inc"
"wifi-host-driver/WiFi_Host_Driver/src"
"wifi-host-driver/WiFi_Host_Driver/src/include"
"wifi-host-driver/WiFi_Host_Driver/resources/resource_imp"
"wifi-host-driver/WiFi_Host_Driver/resources/firmware/COMPONENT_43438"
)
set(WHD_DEFINES
@ -54,4 +57,4 @@ set(WHD_DEFINES
add_library(${PROJECT_NAME} ${WHD_SOURCES})
target_include_directories(${PROJECT_NAME} PUBLIC ${WHD_INCLUDES})
target_compile_definitions(${PROJECT_NAME} PRIVATE ${WHD_DEFINES})
target_compile_definitions(${PROJECT_NAME} PRIVATE ${WHD_DEFINES})

5
src/freertos_support.c Normal file
View File

@ -0,0 +1,5 @@
#include "FreeRTOS.h"
#include "task.h"
/* Allocate the DMA-capable heap in OCRAM. */
__attribute__((section(".freertos_heap"))) uint8_t ucHeap[configTOTAL_HEAP_SIZE];

607
src/lwip_port/sys_arch.c Normal file
View File

@ -0,0 +1,607 @@
/*
* Copyright (c) 2017 Simon Goldschmidt
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Simon Goldschmidt <goldsimon@gmx.de>
*
*/
/* lwIP includes. */
#include "lwip/debug.h"
#include "lwip/def.h"
#include "lwip/sys.h"
#include "lwip/mem.h"
#include "lwip/stats.h"
#include "lwip/tcpip.h"
#include "FreeRTOS.h"
#include "semphr.h"
#include "task.h"
/** Set this to 1 if you want the stack size passed to sys_thread_new() to be
* interpreted as number of stack words (FreeRTOS-like).
* Default is that they are interpreted as byte count (lwIP-like).
*/
#ifndef LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS
#define LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS 0
#endif
/** Set this to 1 to use a mutex for SYS_ARCH_PROTECT() critical regions.
* Default is 0 and locks interrupts/scheduler for SYS_ARCH_PROTECT().
*/
#ifndef LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
#define LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX 0
#endif
/** Set this to 1 to include a sanity check that SYS_ARCH_PROTECT() and
* SYS_ARCH_UNPROTECT() are called matching.
*/
#ifndef LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
#define LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK 0
#endif
/** Set this to 1 to let sys_mbox_free check that queues are empty when freed */
#ifndef LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE
#define LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE 0
#endif
/** Set this to 1 to enable core locking check functions in this port.
* For this to work, you'll have to define LWIP_ASSERT_CORE_LOCKED()
* and LWIP_MARK_TCPIP_THREAD() correctly in your lwipopts.h! */
#ifndef LWIP_FREERTOS_CHECK_CORE_LOCKING
#define LWIP_FREERTOS_CHECK_CORE_LOCKING 0
#endif
/** Set this to 0 to implement sys_now() yourself, e.g. using a hw timer.
* Default is 1, where FreeRTOS ticks are used to calculate back to ms.
*/
#ifndef LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS
#define LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS 1
#endif
#if !configSUPPORT_DYNAMIC_ALLOCATION
# error "lwIP FreeRTOS port requires configSUPPORT_DYNAMIC_ALLOCATION"
#endif
#if !INCLUDE_vTaskDelay
# error "lwIP FreeRTOS port requires INCLUDE_vTaskDelay"
#endif
#if !INCLUDE_vTaskSuspend
# error "lwIP FreeRTOS port requires INCLUDE_vTaskSuspend"
#endif
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX || !LWIP_COMPAT_MUTEX
#if !configUSE_MUTEXES
# error "lwIP FreeRTOS port requires configUSE_MUTEXES"
#endif
#endif
#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
static SemaphoreHandle_t sys_arch_protect_mutex;
#endif
#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
static sys_prot_t sys_arch_protect_nesting;
#endif
/* Initialize this module (see description in sys.h) */
void
sys_init(void)
{
#if SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
/* initialize sys_arch_protect global mutex */
sys_arch_protect_mutex = xSemaphoreCreateRecursiveMutex();
LWIP_ASSERT("failed to create sys_arch_protect mutex",
sys_arch_protect_mutex != NULL);
#endif /* SYS_LIGHTWEIGHT_PROT && LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
}
#if configUSE_16_BIT_TICKS == 1
#error This port requires 32 bit ticks or timer overflow will fail
#endif
#if LWIP_FREERTOS_SYS_NOW_FROM_FREERTOS
u32_t
sys_now(void)
{
return xTaskGetTickCount() * portTICK_PERIOD_MS;
}
#endif
u32_t
sys_jiffies(void)
{
return xTaskGetTickCount();
}
#if SYS_LIGHTWEIGHT_PROT
sys_prot_t
sys_arch_protect(void)
{
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
BaseType_t ret;
LWIP_ASSERT("sys_arch_protect_mutex != NULL", sys_arch_protect_mutex != NULL);
ret = xSemaphoreTakeRecursive(sys_arch_protect_mutex, portMAX_DELAY);
LWIP_ASSERT("sys_arch_protect failed to take the mutex", ret == pdTRUE);
#else /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
taskENTER_CRITICAL();
#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
{
/* every nested call to sys_arch_protect() returns an increased number */
sys_prot_t ret = sys_arch_protect_nesting;
sys_arch_protect_nesting++;
LWIP_ASSERT("sys_arch_protect overflow", sys_arch_protect_nesting > ret);
return ret;
}
#else
return 1;
#endif
}
void
sys_arch_unprotect(sys_prot_t pval)
{
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
BaseType_t ret;
#endif
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_SANITY_CHECK
LWIP_ASSERT("unexpected sys_arch_protect_nesting", sys_arch_protect_nesting > 0);
sys_arch_protect_nesting--;
LWIP_ASSERT("unexpected sys_arch_protect_nesting", sys_arch_protect_nesting == pval);
#endif
#if LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX
LWIP_ASSERT("sys_arch_protect_mutex != NULL", sys_arch_protect_mutex != NULL);
ret = xSemaphoreGiveRecursive(sys_arch_protect_mutex);
LWIP_ASSERT("sys_arch_unprotect failed to give the mutex", ret == pdTRUE);
#else /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
taskEXIT_CRITICAL();
#endif /* LWIP_FREERTOS_SYS_ARCH_PROTECT_USES_MUTEX */
LWIP_UNUSED_ARG(pval);
}
#endif /* SYS_LIGHTWEIGHT_PROT */
void
sys_arch_msleep(u32_t delay_ms)
{
TickType_t delay_ticks = pdMS_TO_TICKS(delay_ms);
vTaskDelay(delay_ticks);
}
#if !LWIP_COMPAT_MUTEX
/* Create a new mutex*/
err_t
sys_mutex_new(sys_mutex_t *mutex)
{
LWIP_ASSERT("mutex != NULL", mutex != NULL);
mutex->mut = xSemaphoreCreateRecursiveMutex();
if(mutex->mut == NULL) {
SYS_STATS_INC(mutex.err);
return ERR_MEM;
}
SYS_STATS_INC_USED(mutex);
return ERR_OK;
}
void
sys_mutex_lock(sys_mutex_t *mutex)
{
BaseType_t ret;
LWIP_ASSERT("mutex != NULL", mutex != NULL);
LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
ret = xSemaphoreTakeRecursive(mutex->mut, portMAX_DELAY);
LWIP_ASSERT("failed to take the mutex", ret == pdTRUE);
}
void
sys_mutex_unlock(sys_mutex_t *mutex)
{
BaseType_t ret;
LWIP_ASSERT("mutex != NULL", mutex != NULL);
LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
ret = xSemaphoreGiveRecursive(mutex->mut);
LWIP_ASSERT("failed to give the mutex", ret == pdTRUE);
}
void
sys_mutex_free(sys_mutex_t *mutex)
{
LWIP_ASSERT("mutex != NULL", mutex != NULL);
LWIP_ASSERT("mutex->mut != NULL", mutex->mut != NULL);
SYS_STATS_DEC(mutex.used);
vSemaphoreDelete(mutex->mut);
mutex->mut = NULL;
}
#endif /* !LWIP_COMPAT_MUTEX */
err_t
sys_sem_new(sys_sem_t *sem, u8_t initial_count)
{
LWIP_ASSERT("sem != NULL", sem != NULL);
LWIP_ASSERT("initial_count invalid (not 0 or 1)",
(initial_count == 0) || (initial_count == 1));
sem->sem = xSemaphoreCreateBinary();
if(sem->sem == NULL) {
SYS_STATS_INC(sem.err);
return ERR_MEM;
}
SYS_STATS_INC_USED(sem);
if(initial_count == 1) {
BaseType_t ret = xSemaphoreGive(sem->sem);
LWIP_ASSERT("sys_sem_new: initial give failed", ret == pdTRUE);
}
return ERR_OK;
}
void
sys_sem_signal(sys_sem_t *sem)
{
BaseType_t ret;
LWIP_ASSERT("sem != NULL", sem != NULL);
LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
ret = xSemaphoreGive(sem->sem);
/* queue full is OK, this is a signal only... */
LWIP_ASSERT("sys_sem_signal: sane return value",
(ret == pdTRUE) || (ret == errQUEUE_FULL));
}
u32_t
sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout_ms)
{
BaseType_t ret;
LWIP_ASSERT("sem != NULL", sem != NULL);
LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
if(!timeout_ms) {
/* wait infinite */
ret = xSemaphoreTake(sem->sem, portMAX_DELAY);
LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
} else {
TickType_t timeout_ticks = pdMS_TO_TICKS(timeout_ms);
ret = xSemaphoreTake(sem->sem, timeout_ticks);
if (ret == errQUEUE_EMPTY) {
/* timed out */
return SYS_ARCH_TIMEOUT;
}
LWIP_ASSERT("taking semaphore failed", ret == pdTRUE);
}
/* Old versions of lwIP required us to return the time waited.
This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
here is enough. */
return 1;
}
void
sys_sem_free(sys_sem_t *sem)
{
LWIP_ASSERT("sem != NULL", sem != NULL);
LWIP_ASSERT("sem->sem != NULL", sem->sem != NULL);
SYS_STATS_DEC(sem.used);
vSemaphoreDelete(sem->sem);
sem->sem = NULL;
}
err_t
sys_mbox_new(sys_mbox_t *mbox, int size)
{
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("size > 0", size > 0);
mbox->mbx = xQueueCreate((UBaseType_t)size, sizeof(void *));
if(mbox->mbx == NULL) {
SYS_STATS_INC(mbox.err);
return ERR_MEM;
}
SYS_STATS_INC_USED(mbox);
return ERR_OK;
}
void
sys_mbox_post(sys_mbox_t *mbox, void *msg)
{
BaseType_t ret;
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
ret = xQueueSendToBack(mbox->mbx, &msg, portMAX_DELAY);
LWIP_ASSERT("mbox post failed", ret == pdTRUE);
}
err_t
sys_mbox_trypost(sys_mbox_t *mbox, void *msg)
{
BaseType_t ret;
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
ret = xQueueSendToBack(mbox->mbx, &msg, 0);
if (ret == pdTRUE) {
return ERR_OK;
} else {
LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL);
SYS_STATS_INC(mbox.err);
return ERR_MEM;
}
}
err_t
sys_mbox_trypost_fromisr(sys_mbox_t *mbox, void *msg)
{
BaseType_t ret;
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
ret = xQueueSendToBackFromISR(mbox->mbx, &msg, &xHigherPriorityTaskWoken);
if (ret == pdTRUE) {
if (xHigherPriorityTaskWoken == pdTRUE) {
return ERR_NEED_SCHED;
}
return ERR_OK;
} else {
LWIP_ASSERT("mbox trypost failed", ret == errQUEUE_FULL);
SYS_STATS_INC(mbox.err);
return ERR_MEM;
}
}
u32_t
sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout_ms)
{
BaseType_t ret;
void *msg_dummy;
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
if (!msg) {
msg = &msg_dummy;
}
if (!timeout_ms) {
/* wait infinite */
ret = xQueueReceive(mbox->mbx, &(*msg), portMAX_DELAY);
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
} else {
TickType_t timeout_ticks = pdMS_TO_TICKS(timeout_ms);
ret = xQueueReceive(mbox->mbx, &(*msg), timeout_ticks);
if (ret == errQUEUE_EMPTY) {
/* timed out */
*msg = NULL;
return SYS_ARCH_TIMEOUT;
}
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
}
/* Old versions of lwIP required us to return the time waited.
This is not the case any more. Just returning != SYS_ARCH_TIMEOUT
here is enough. */
return 1;
}
u32_t
sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg)
{
BaseType_t ret;
void *msg_dummy;
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
if (!msg) {
msg = &msg_dummy;
}
ret = xQueueReceive(mbox->mbx, &(*msg), 0);
if (ret == errQUEUE_EMPTY) {
*msg = NULL;
return SYS_MBOX_EMPTY;
}
LWIP_ASSERT("mbox fetch failed", ret == pdTRUE);
return 0;
}
void
sys_mbox_free(sys_mbox_t *mbox)
{
LWIP_ASSERT("mbox != NULL", mbox != NULL);
LWIP_ASSERT("mbox->mbx != NULL", mbox->mbx != NULL);
#if LWIP_FREERTOS_CHECK_QUEUE_EMPTY_ON_FREE
{
UBaseType_t msgs_waiting = uxQueueMessagesWaiting(mbox->mbx);
LWIP_ASSERT("mbox quence not empty", msgs_waiting == 0);
if (msgs_waiting != 0) {
SYS_STATS_INC(mbox.err);
}
}
#endif
vQueueDelete(mbox->mbx);
SYS_STATS_DEC(mbox.used);
}
sys_thread_t
sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio)
{
TaskHandle_t rtos_task;
BaseType_t ret;
sys_thread_t lwip_thread;
size_t rtos_stacksize;
LWIP_ASSERT("invalid stacksize", stacksize > 0);
#if LWIP_FREERTOS_THREAD_STACKSIZE_IS_STACKWORDS
rtos_stacksize = (size_t)stacksize;
#else
rtos_stacksize = (size_t)stacksize / sizeof(StackType_t);
#endif
/* lwIP's lwip_thread_fn matches FreeRTOS' TaskFunction_t, so we can pass the
thread function without adaption here. */
ret = xTaskCreate(thread, name, (configSTACK_DEPTH_TYPE)rtos_stacksize, arg, prio, &rtos_task);
LWIP_ASSERT("task creation failed", ret == pdTRUE);
lwip_thread.thread_handle = rtos_task;
return lwip_thread;
}
#if LWIP_NETCONN_SEM_PER_THREAD
#if configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0
sys_sem_t *
sys_arch_netconn_sem_get(void)
{
void* ret;
TaskHandle_t task = xTaskGetCurrentTaskHandle();
LWIP_ASSERT("task != NULL", task != NULL);
ret = pvTaskGetThreadLocalStoragePointer(task, 0);
return ret;
}
void
sys_arch_netconn_sem_alloc(void)
{
void *ret;
TaskHandle_t task = xTaskGetCurrentTaskHandle();
LWIP_ASSERT("task != NULL", task != NULL);
ret = pvTaskGetThreadLocalStoragePointer(task, 0);
if(ret == NULL) {
sys_sem_t *sem;
err_t err;
/* need to allocate the memory for this semaphore */
sem = mem_malloc(sizeof(sys_sem_t));
LWIP_ASSERT("sem != NULL", sem != NULL);
err = sys_sem_new(sem, 0);
LWIP_ASSERT("err == ERR_OK", err == ERR_OK);
LWIP_ASSERT("sem invalid", sys_sem_valid(sem));
vTaskSetThreadLocalStoragePointer(task, 0, sem);
}
}
void sys_arch_netconn_sem_free(void)
{
void* ret;
TaskHandle_t task = xTaskGetCurrentTaskHandle();
LWIP_ASSERT("task != NULL", task != NULL);
ret = pvTaskGetThreadLocalStoragePointer(task, 0);
if(ret != NULL) {
sys_sem_t *sem = ret;
sys_sem_free(sem);
mem_free(sem);
vTaskSetThreadLocalStoragePointer(task, 0, NULL);
}
}
#else /* configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 */
#error LWIP_NETCONN_SEM_PER_THREAD needs configNUM_THREAD_LOCAL_STORAGE_POINTERS
#endif /* configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 */
#endif /* LWIP_NETCONN_SEM_PER_THREAD */
#if LWIP_FREERTOS_CHECK_CORE_LOCKING
#if LWIP_TCPIP_CORE_LOCKING
/** Flag the core lock held. A counter for recursive locks. */
static u8_t lwip_core_lock_count;
static TaskHandle_t lwip_core_lock_holder_thread;
void
sys_lock_tcpip_core(void)
{
sys_mutex_lock(&lock_tcpip_core);
if (lwip_core_lock_count == 0) {
lwip_core_lock_holder_thread = xTaskGetCurrentTaskHandle();
}
lwip_core_lock_count++;
}
void
sys_unlock_tcpip_core(void)
{
lwip_core_lock_count--;
if (lwip_core_lock_count == 0) {
lwip_core_lock_holder_thread = 0;
}
sys_mutex_unlock(&lock_tcpip_core);
}
#endif /* LWIP_TCPIP_CORE_LOCKING */
#if !NO_SYS
static TaskHandle_t lwip_tcpip_thread;
#endif
void
sys_mark_tcpip_thread(void)
{
#if !NO_SYS
lwip_tcpip_thread = xTaskGetCurrentTaskHandle();
#endif
}
void
sys_check_core_locking(void)
{
/* Embedded systems should check we are NOT in an interrupt context here */
/* E.g. core Cortex-M3/M4 ports:
configASSERT( ( portNVIC_INT_CTRL_REG & portVECTACTIVE_MASK ) == 0 );
Instead, we use more generic FreeRTOS functions here, which should fail from ISR: */
taskENTER_CRITICAL();
taskEXIT_CRITICAL();
#if !NO_SYS
if (lwip_tcpip_thread != 0) {
TaskHandle_t current_thread = xTaskGetCurrentTaskHandle();
#if LWIP_TCPIP_CORE_LOCKING
LWIP_ASSERT("Function called without core lock",
current_thread == lwip_core_lock_holder_thread && lwip_core_lock_count > 0);
#else /* LWIP_TCPIP_CORE_LOCKING */
LWIP_ASSERT("Function called from wrong thread", current_thread == lwip_tcpip_thread);
#endif /* LWIP_TCPIP_CORE_LOCKING */
}
#endif /* !NO_SYS */
}
#endif /* LWIP_FREERTOS_CHECK_CORE_LOCKING*/

View File

@ -15,6 +15,9 @@
#include "whd.h"
#include "whd_wifi_api.h"
/* LwIP */
#include "lwip/init.h"
void task_hello_init(void);
int main(void) {
@ -31,6 +34,8 @@ int main(void) {
task_hello_init();
lwip_init();
vTaskStartScheduler();
for (;;) {

View File

@ -0,0 +1,72 @@
#include "whd_buffer_api.h"
/* LwIP provided pbuf management */
#include "lwip/debug.h"
#include "lwip/pbuf.h"
#define SDIO_BLOCK_SIZE (64U)
whd_result_t cy_host_buffer_get(whd_buffer_t *buffer, whd_buffer_dir_t direction, unsigned short size,
unsigned long timeout_ms) {
UNUSED_PARAMETER(direction);
UNUSED_PARAMETER(timeout_ms);
struct pbuf *p_buffer = NULL;
if ((direction == WHD_NETWORK_TX) && (size <= PBUF_POOL_BUFSIZE)) {
p_buffer = pbuf_alloc(PBUF_RAW, size, PBUF_POOL);
} else {
p_buffer = pbuf_alloc(PBUF_RAW, size + SDIO_BLOCK_SIZE, PBUF_RAM);
if (p_buffer != NULL) {
p_buffer->len = size;
p_buffer->tot_len -= SDIO_BLOCK_SIZE;
}
}
if (p_buffer != NULL) {
*buffer = p_buffer;
return WHD_SUCCESS;
} return WHD_BUFFER_ALLOC_FAIL;
}
void cy_buffer_release(whd_buffer_t buffer, whd_buffer_dir_t direction) {
UNUSED_PARAMETER(direction);
(void)pbuf_free((struct pbuf *)buffer);
}
uint8_t *cy_buffer_get_current_piece_data_pointer(whd_buffer_t buffer) {
LWIP_ASSERT("CY network buffer is NULL", buffer != NULL);
struct pbuf *p_buffer = (struct pbuf *)buffer;
return (uint8_t *)p_buffer->payload;
}
uint16_t cy_buffer_get_current_piece_size(whd_buffer_t buffer) {
LWIP_ASSERT("CY network buffer is NULL", buffer != NULL);
struct pbuf *p_buffer = (struct pbuf *)buffer;
return (uint16_t)p_buffer->len;
}
whd_result_t cy_buffer_set_size(whd_buffer_t buffer, unsigned short size) {
LWIP_ASSERT("CY network buffer is NULL", buffer != NULL);
struct pbuf *p_buffer = (struct pbuf *)buffer;
if (size > (unsigned short)WHD_LINK_MTU + LWIP_MEM_ALIGN_SIZE(LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf))) +
LWIP_MEM_ALIGN_SIZE(size)) {
return WHD_PMK_WRONG_LENGTH;
}
p_buffer->tot_len = size;
p_buffer->len = size;
return CY_RSLT_SUCCESS;
}
whd_result_t cy_buffer_add_remove_at_front(whd_buffer_t *buffer, int32_t add_remove_amount) {
LWIP_ASSERT("CY network buffer is NULL", buffer != NULL);
struct pbuf **p_buffer = (struct pbuf **)buffer;
if ((u8_t)0 != pbuf_header(*p_buffer, (s16_t)(-add_remove_amount))) {
return WHD_PMK_WRONG_LENGTH;
}
return WHD_SUCCESS;
}

View File

@ -0,0 +1,42 @@
#include "cyhal_sdio.h"
#include "fsl_sdio.h"
#define CYHAL_SDIO_UNUSED(x) ((void)(x))
static sdio_card_t s_sdio;
cy_rslt_t cyhal_sdio_init(cyhal_sdio_t *obj, cyhal_gpio_t cmd, cyhal_gpio_t clk, cyhal_gpio_t data0, cyhal_gpio_t data1,
cyhal_gpio_t data2, cyhal_gpio_t data3) {
CYHAL_SDIO_UNUSED(obj);
CYHAL_SDIO_UNUSED(cmd);
CYHAL_SDIO_UNUSED(clk);
CYHAL_SDIO_UNUSED(data0);
CYHAL_SDIO_UNUSED(data1);
CYHAL_SDIO_UNUSED(data2);
CYHAL_SDIO_UNUSED(data3);
;
SDIO_Init(&s_sdio);
return CY_RSLT_SUCCESS;
}
void cyhal_sdio_register_irq(cyhal_sdio_t *obj, cyhal_sdio_irq_handler_t handler, void *handler_arg) {
}
void cyhal_sdio_irq_enable(cyhal_sdio_t *obj, cyhal_sdio_irq_event_t event, bool enable) {
}
cy_rslt_t cyhal_sdio_send_cmd(const cyhal_sdio_t *obj, cyhal_transfer_t direction, cyhal_sdio_command_t command,
uint32_t argument, uint32_t *response) {
}
cy_rslt_t cyhal_sdio_bulk_transfer(cyhal_sdio_t *obj, cyhal_transfer_t direction, uint32_t argument,
const uint32_t *data, uint16_t length, uint32_t *response) {
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
# Image generation
```
bin2c -c -n "cyw43362a2_firmware_image" 43362A2.bin > 43362A2_bin.c
bin2c -c -n "cyw43362a2_mfgtest_image" 43362A2-mfgtest.bin > 43362A2-mfgtest_bin.c
bin2c -c -n "cyw43362a2_p2p_firmware_image" 43362A2-p2p.bin > 43362A2-p2p_bin.c
```

View File

@ -0,0 +1,62 @@
#include "generated_mac_address.txt"
const char cyw43362a2_nvram_image[] =
"manfid=0x2d0" "\x00"
"prodid=0x492" "\x00"
"vendid=0x14e4" "\x00"
"devid=0x4343" "\x00"
"boardtype=0x05a0" "\x00"
"boardrev=0x1301" "\x00" /*Board Revision is REV3.1*/
"boardnum=777" "\x00"
"xtalfreq=26000" "\x00"
"boardflags=0xa00" "\x00"
"sromrev=3" "\x00"
"wl0id=0x431b" "\x00"
NVRAM_GENERATED_MAC_ADDRESS "\x00"
"aa2g=3" "\x00"
"ag0=2" "\x00"
"maxp2ga0=68" "\x00"
"ofdm2gpo=0x44444444" "\x00"
"mcs2gpo0=0x3333" "\x00"
"mcs2gpo1=0x6333" "\x00"
"pa0maxpwr=80" "\x00"
"pa0b0=0x133E" "\x00"
"pa0b1=0xFDBA" "\x00"
"pa0b2=0xFF53" "\x00"
"pa0itssit=62" "\x00"
"pa1itssit=62" "\x00"
"temp_based_dutycy_en=1" "\x00"
"tx_duty_cycle_ofdm=100" "\x00"
"tx_duty_cycle_cck=100" "\x00"
"tx_ofdm_temp_0=115" "\x00"
"tx_cck_temp_0=115" "\x00"
"tx_ofdm_dutycy_0=40" "\x00"
"tx_cck_dutycy_0=40" "\x00"
"tx_ofdm_temp_1=255" "\x00"
"tx_cck_temp_1=255" "\x00"
"tx_ofdm_dutycy_1=40" "\x00"
"tx_cck_dutycy_1=40" "\x00"
"tx_tone_power_index=40" "\x00"
"tx_tone_power_index.fab.3=48" "\x00"
"cckPwrOffset=0" "\x00"
"ccode=0" "\x00"
"rssismf2g=0xa" "\x00"
"rssismc2g=0x3" "\x00"
"rssisav2g=0x7" "\x00"
"triso2g=0" "\x00"
"noise_cal_enable_2g=0" "\x00"
"noise_cal_po_2g=0" "\x00"
"noise_cal_po_2g.fab.3=-2" "\x00"
"swctrlmap_2g=0x050c050c,0x030a030a,0x030a030a,0x0,0x1ff" "\x00"
"temp_add=29767" "\x00"
"temp_mult=425" "\x00"
"temp_q=10" "\x00"
"initxidx2g=45" "\x00"
"tssitime=1" "\x00"
"rfreg033=0x19" "\x00"
"rfreg033_cck=0x1f" "\x00"
"cckPwrIdxCorr=-8" "\x00"
"spuravoid_enable2g=1" "\x00"
"edonthd=-70" "\x00"
"edoffthd=-76" "\x00"
"\x00\x00";

View File

@ -0,0 +1,88 @@
#include <string.h>
/* WHD resource API */
#include "whd_resource_api.h"
/* Private resource storage identifiers */
#include "whd_port/resources/whd_resources.h"
#define RESOURCE_FIRMWARE_NAME cyw43362a2_firmware_image
#define RESOURCE_FIRMWARE_SIZE sizeof(RESOURCE_FIRMWARE_NAME)
/* CYW43362A2 does not have CLM */
#define RESOURCE_CLM_NAME
#define RESOURCE_CLM_SIZE 0
#define RESOURCE_NVRAM_NAME cyw43362a2_nvram_image
#define RESOURCE_NVRAM_SIZE sizeof(RESOURCE_NVRAM_NAME)
#define RESOURCE_BUFFER_SIZE 512
static uint8_t s_resource_buf[RESOURCE_BUFFER_SIZE];
static uint32_t resource_block_size(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *size_out) {
*size_out = RESOURCE_BUFFER_SIZE;
return WHD_SUCCESS;
}
static uint32_t resource_size(whd_driver_t whd_drv, whd_resource_type_t resource, uint32_t *size_out) {
switch (resource) {
case WHD_RESOURCE_WLAN_FIRMWARE:
*size_out = RESOURCE_FIRMWARE_SIZE;
break;
case WHD_RESOURCE_WLAN_NVRAM:
*size_out = RESOURCE_NVRAM_SIZE;
break;
case WHD_RESOURCE_WLAN_CLM:
*size_out = RESOURCE_CLM_SIZE;
break;
default:
*size_out = 0;
break;
}
return WHD_SUCCESS;
}
static uint32_t resource_no_of_blocks(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t *block_count) {
uint32_t res_sz = 0U;
uint32_t blk_sz = 0U;
resource_size(whd_drv, type, &res_sz);
resource_block_size(whd_drv, type, &blk_sz);
*block_count = res_sz / blk_sz;
if (res_sz % blk_sz) *block_count += 1;
return WHD_SUCCESS;
}
static uint32_t resource_block(whd_driver_t whd_drv, whd_resource_type_t type, uint32_t blockno, const uint8_t **data,
uint32_t *size_out) {
uint32_t ret = WHD_SUCCESS;
uint32_t res_sz = 0U;
uint32_t blk_sz = 0U;
ret = resource_size(whd_drv, type, &res_sz);
if (ret != WHD_SUCCESS) {
return ret;
}
ret = resource_block_size(whd_drv, type, &blk_sz);
if (ret != WHD_SUCCESS) {
return ret;
}
switch (type) {
case WHD_RESOURCE_WLAN_FIRMWARE: {
/* TODO: Implement this */
}
}
return WHD_SUCCESS;
}
whd_resource_source_t resource_ops = {
.whd_resource_size = resource_size,
.whd_get_resource_block_size = resource_block_size,
.whd_get_resource_no_of_blocks = resource_no_of_blocks,
.whd_get_resource_block = resource_block,
};

View File

@ -19,6 +19,8 @@
cy_rslt_t cy_rtos_create_thread(cy_thread_t *thread, cy_thread_entry_fn_t entry_function, const char *name, void *stack,
uint32_t stack_size, cy_thread_priority_t priority, cy_thread_arg_t arg) {
(void)stack;
/* Create a semaphore to let the thread join */
SemaphoreHandle_t thr_join_semphr = xSemaphoreCreateBinary();
if (thr_join_semphr == NULL) {
@ -38,11 +40,11 @@ cy_rslt_t cy_rtos_create_thread(cy_thread_t *thread, cy_thread_entry_fn_t entry_
}
cy_rslt_t cy_rtos_exit_thread(void) {
TaskHandle_t cur_task_handle;
SemaphoreHandle_t thr_join_semphore;
TaskHandle_t cur_task_handle = NULL;
SemaphoreHandle_t thr_join_semphore = NULL;
/* Get current task handle and retrieve the semaphore handle from TLS */
cur_task_handle = xTaskGetCurrentTaskHandle();
cur_task_handle = xTaskGetCurrentTaskHandle();
thr_join_semphore = pvTaskGetThreadLocalStoragePointer(cur_task_handle, CY_RTOS_JOIN_SEMPHR_TLS_ID);
/* Notify that the task is now exit. */
@ -54,13 +56,15 @@ cy_rslt_t cy_rtos_exit_thread(void) {
}
cy_rslt_t cy_rtos_terminate_thread(cy_thread_t *thread) {
(void)thread;
/* Empty function, thread resource will be released after task function joined. */
/* WARNING: Current WHD drivers does not call this function. LEAVE IT BLANK FOR NOW. */
return CY_RSLT_SUCCESS;
}
cy_rslt_t cy_rtos_join_thread(cy_thread_t *thread) {
SemaphoreHandle_t thr_join_semaphore;
SemaphoreHandle_t thr_join_semaphore = NULL;
/* Retrieve the semaphore handle from TLS */
thr_join_semaphore = pvTaskGetThreadLocalStoragePointer((TaskHandle_t)*thread, CY_RTOS_JOIN_SEMPHR_TLS_ID);
@ -89,17 +93,16 @@ cy_rslt_t cy_rtos_init_semaphore(cy_semaphore_t *semaphore, uint32_t maxcount, u
cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms, bool in_isr) {
BaseType_t higher_priority_woken = pdFALSE;
if(!in_isr) {
if(xSemaphoreTake(*semaphore, pdMS_TO_TICKS(timeout_ms)) != pdPASS) {
if (!in_isr) {
if (xSemaphoreTake(*semaphore, pdMS_TO_TICKS(timeout_ms)) != pdPASS) {
return CY_RTOS_TIMEOUT;
}
}
else { /* Currently is not used */
if(xSemaphoreTakeFromISR(*semaphore, &higher_priority_woken) != pdPASS) {
} else { /* Currently is not used */
if (xSemaphoreTakeFromISR(*semaphore, &higher_priority_woken) != pdPASS) {
return CY_RTOS_TIMEOUT;
}
if(higher_priority_woken != pdFALSE) {
taskYIELD();
if (higher_priority_woken != pdFALSE) {
taskYIELD()
}
}
@ -109,18 +112,17 @@ cy_rslt_t cy_rtos_get_semaphore(cy_semaphore_t *semaphore, cy_time_t timeout_ms,
cy_rslt_t cy_rtos_set_semaphore(cy_semaphore_t *semaphore, bool in_isr) {
BaseType_t higher_priority_woken = pdFALSE;
if(!in_isr) {
/*
if (!in_isr) {
/*
* Since the semaphores are implemented using queues, this call will also fail if the queue is full.
* So do not check return values here.
*/
xSemaphoreGive(*semaphore);
}
else {
} else {
/* For the same reason as above, do not check return values here. */
xSemaphoreGiveFromISR(*semaphore, &higher_priority_woken);
if(higher_priority_woken != pdFALSE) {
taskYIELD();
if (higher_priority_woken != pdFALSE) {
taskYIELD()
}
}