Compare commits
26 Commits
tos_ai_sig
...
master
| Author | SHA1 | Date |
|---|---|---|
|
|
87fd8e839d | |
|
|
c18f082949 | |
|
|
4c4ac49b76 | |
|
|
5a8f31a2b5 | |
|
|
2af78131df | |
|
|
e5608ba067 | |
|
|
c5ed849343 | |
|
|
85f804213f | |
|
|
d3ab42b8b8 | |
|
|
4f5c747a63 | |
|
|
ddb37a743a | |
|
|
86bc533bb8 | |
|
|
e38c8775ac | |
|
|
30832d6e0f | |
|
|
088e7fe364 | |
|
|
8adb89f1e1 | |
|
|
e21869f48b | |
|
|
10816214f3 | |
|
|
60c16485e6 | |
|
|
b25b558153 | |
|
|
4d3452ef60 | |
|
|
e20f5adc12 | |
|
|
ecd3074c35 | |
|
|
0832ca17e5 | |
|
|
cbe7ac98e2 | |
|
|
b80e0d06a3 |
|
|
@ -0,0 +1,12 @@
|
|||
## [2.5.2] - 2022-06-28
|
||||
### Changed
|
||||
- modify the global lock to protect the at agent.
|
||||
|
||||
## [2.5.1] - 2022-06-02
|
||||
### Added
|
||||
- add dynamic create and destroy api for task, sem, mutex, event, timer and corresponding unit test case.
|
||||
- add tos_task_find api.
|
||||
|
||||
### Changed
|
||||
- `TOS_CFG_TASK_DYNAMIC_CREATE_EN` change to `TOS_CFG_OBJ_DYNAMIC_CREATE_EN`.
|
||||
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u
|
||||
|
||||
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
|
||||
#define TOS_CFG_OBJ_DYNAMIC_CREATE_EN 1u
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
project(hello_world)
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
|
||||
|
||||
set(TINY_ROOT ../../../)
|
||||
|
||||
include_directories(${TINY_ROOT}/osal/cmsis_os)
|
||||
include_directories(${TINY_ROOT}/kernel/core/include)
|
||||
include_directories(${TINY_ROOT}/kernel/evtdrv/include)
|
||||
include_directories(${TINY_ROOT}/kernel/hal/include)
|
||||
include_directories(${TINY_ROOT}/kernel/pm/include)
|
||||
|
||||
set(CMSIS_SRCS ${TINY_ROOT}/osal/cmsis_os/cmsis_os.c)
|
||||
aux_source_directory(${TINY_ROOT}/kernel/core CORE_SRCS)
|
||||
aux_source_directory(${TINY_ROOT}/kernel/evtdrv EVTDRV_SRCS)
|
||||
aux_source_directory(${TINY_ROOT}/kernel/pm PM_SRCS)
|
||||
|
||||
set(ARCH_ROOT ${TINY_ROOT}/arch/linux)
|
||||
|
||||
include_directories(${ARCH_ROOT}/common/include)
|
||||
include_directories(${ARCH_ROOT}/posix/gcc)
|
||||
|
||||
aux_source_directory(${ARCH_ROOT}/common ARCH_COMMON_SRCS)
|
||||
aux_source_directory(${ARCH_ROOT}/posix/gcc ARCH_POSIX_SRCS)
|
||||
|
||||
set(ARCH_SRCS ${ARCH_COMMON_SRCS} ${ARCH_POSIX_SRCS})
|
||||
|
||||
set(TINY_SRCS ${ARCH_SRCS} ${CMSIS_SRCS} ${EVTDRV_SRCS} ${PM_SRCS} ${CORE_SRCS} )
|
||||
|
||||
include_directories(./)
|
||||
include_directories(./inc)
|
||||
|
||||
set(APP_SRCS src/main.c)
|
||||
|
||||
add_executable(hello_world ${APP_SRCS} ${TINY_SRCS})
|
||||
|
||||
target_link_libraries(hello_world pthread)
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
###################################################################
|
||||
#automatic detection QTOP and LOCALDIR
|
||||
CUR_DIR := $(patsubst %/,%,$(dir $(realpath $(firstword $(MAKEFILE_LIST)))))
|
||||
TRYQTOP := $(shell if [ -n "$$QTOP" ] ; then\
|
||||
echo $$QTOP;\
|
||||
else\
|
||||
cd $(CUR_DIR); while /usr/bin/test ! -e qmk ; do \
|
||||
dir=`cd ../;pwd`; \
|
||||
if [ "$$dir" = "/" ] ; then \
|
||||
echo Cannot find QTOP in $(firstword $(MAKEFILE_LIST)) 1>&2; \
|
||||
exit 1; \
|
||||
fi ; \
|
||||
cd $$dir; \
|
||||
done ; \
|
||||
pwd; \
|
||||
fi)
|
||||
QTOP ?= $(realpath ${TRYQTOP})
|
||||
|
||||
ifeq ($(QTOP),)
|
||||
$(error Please run this in a tree)
|
||||
endif
|
||||
LOCALDIR = $(patsubst %/,%,$(subst $(realpath $(QTOP))/,,$(CUR_DIR)))
|
||||
export QTOP
|
||||
|
||||
####################################################################
|
||||
|
||||
|
||||
export BP=Linux_Posix
|
||||
|
||||
TREE_LIB_ENABLE=1
|
||||
lib=
|
||||
subdirs =
|
||||
|
||||
|
||||
all::
|
||||
make -C ${QTOP}/arch BP=${BP}
|
||||
make -C ${QTOP}/kernel BP=${BP}
|
||||
make -C ${QTOP}/osal BP=${BP}
|
||||
make -C ${QTOP}/net BP=${BP}
|
||||
make -C ${QTOP}/devices BP=${BP}
|
||||
exec =
|
||||
LD_A_FILES += $(LIBDIR)/libarch.a
|
||||
LD_A_FILES += $(LIBDIR)/libkernel.a
|
||||
LD_A_FILES += $(LIBDIR)/libhello_world.a
|
||||
LD_A_FILES += $(LIBDIR)/libcmsis_os.a
|
||||
LDFLAGS += -lpthread
|
||||
|
||||
include ${QTOP}/qmk/generic/Make.exec
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,236 @@
|
|||
/**
|
||||
******************************************************************************
|
||||
* @file lwipopts.h
|
||||
* @author MCD Application Team
|
||||
* @version V1.1.0
|
||||
* @date 31-July-2013
|
||||
* @brief lwIP Options Configuration.
|
||||
* This file is based on Utilities\lwip_v1.4.1\src\include\lwip\opt.h
|
||||
* and contains the lwIP configuration for the STM32F4x7 demonstration.
|
||||
******************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* <h2><center>© COPYRIGHT 2013 STMicroelectronics</center></h2>
|
||||
*
|
||||
* Licensed under MCD-ST Liberty SW License Agreement V2, (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.st.com/software_license_agreement_liberty_v2
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __LWIPOPTS_H__
|
||||
#define __LWIPOPTS_H__
|
||||
|
||||
/**
|
||||
* 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==1: Provides VERY minimal functionality. Otherwise,
|
||||
* use lwIP facilities.
|
||||
*/
|
||||
#define NO_SYS 0
|
||||
|
||||
/**
|
||||
* NO_SYS_NO_TIMERS==1: Drop support for sys_timeout when NO_SYS==1
|
||||
* Mainly for compatibility to old versions.
|
||||
*/
|
||||
#define NO_SYS_NO_TIMERS 0
|
||||
|
||||
/* ---------- Memory options ---------- */
|
||||
/* MEM_ALIGNMENT: should be set to the alignment of the CPU for which
|
||||
lwIP is compiled. 4 byte alignment -> define MEM_ALIGNMENT to 4, 2
|
||||
byte alignment -> define MEM_ALIGNMENT to 2. */
|
||||
#define MEM_ALIGNMENT 4
|
||||
|
||||
/* 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 (5 * 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 25
|
||||
/* 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 6
|
||||
/* MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP
|
||||
connections. */
|
||||
#define MEMP_NUM_TCP_PCB_LISTEN 6
|
||||
/* MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP
|
||||
segments. */
|
||||
#define MEMP_NUM_TCP_SEG 150
|
||||
/* MEMP_NUM_SYS_TIMEOUT: the number of simulateously active
|
||||
timeouts. */
|
||||
#define MEMP_NUM_SYS_TIMEOUT 6
|
||||
|
||||
/* ---------- Pbuf options ---------- */
|
||||
/* PBUF_POOL_SIZE: the number of buffers in the pbuf pool. */
|
||||
#define PBUF_POOL_SIZE 25
|
||||
/* PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. */
|
||||
#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS + 40 + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN)
|
||||
|
||||
/* ---------- TCP options ---------- */
|
||||
#define LWIP_TCP 1
|
||||
#define TCP_TTL 255
|
||||
|
||||
/* 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
|
||||
|
||||
/* TCP Maximum segment size. */
|
||||
#define TCP_MSS (1500 - 40) /* TCP_MSS = (Ethernet MTU - IP header size - TCP header size) */
|
||||
|
||||
/* TCP sender buffer space (bytes). */
|
||||
#define TCP_SND_BUF (7 * TCP_MSS)
|
||||
|
||||
/* TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least
|
||||
as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. */
|
||||
|
||||
#define TCP_SND_QUEUELEN (8 * TCP_SND_BUF / TCP_MSS)
|
||||
|
||||
/* TCP receive window. */
|
||||
#define TCP_WND (9 * TCP_MSS)
|
||||
|
||||
/* ---------- ICMP options ---------- */
|
||||
#define LWIP_ICMP 1
|
||||
|
||||
/* ---------- DHCP options ---------- */
|
||||
/* Define LWIP_DHCP to 1 if you want DHCP configuration of
|
||||
interfaces. DHCP is not implemented in lwIP 0.5.1, however, so
|
||||
turning this on does currently not work. */
|
||||
#define LWIP_DHCP 1
|
||||
|
||||
/* ---------- UDP options ---------- */
|
||||
#define LWIP_UDP 1
|
||||
#define UDP_TTL 255
|
||||
|
||||
/* ---------- Statistics options ---------- */
|
||||
#define LWIP_STATS 0
|
||||
#define LWIP_PROVIDE_ERRNO 1
|
||||
|
||||
/* ---------- link callback options ---------- */
|
||||
/* LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface
|
||||
* whenever the link changes (i.e., link down)
|
||||
*/
|
||||
#define LWIP_NETIF_LINK_CALLBACK 0
|
||||
/*
|
||||
--------------------------------------
|
||||
---------- Checksum options ----------
|
||||
--------------------------------------
|
||||
*/
|
||||
|
||||
/*
|
||||
The STM32F4x7 allows computing and verifying the IP, UDP, TCP and ICMP checksums by hardware:
|
||||
- To use this feature let the following define uncommented.
|
||||
- To disable it and process by CPU comment the the checksum.
|
||||
*/
|
||||
#define CHECKSUM_BY_HARDWARE
|
||||
//#undef 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
|
||||
/* CHECKSUM_CHECK_ICMP==0: Check checksums by hardware for incoming ICMP packets.*/
|
||||
#define CHECKSUM_GEN_ICMP 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
|
||||
/* CHECKSUM_CHECK_ICMP==1: Check checksums by hardware for incoming ICMP packets.*/
|
||||
#define CHECKSUM_GEN_ICMP 1
|
||||
#endif
|
||||
|
||||
#define LWIP_TCPIP_CORE_LOCKING 1
|
||||
|
||||
/*
|
||||
----------------------------------------------
|
||||
---------- Sequential layer options ----------
|
||||
----------------------------------------------
|
||||
*/
|
||||
/**
|
||||
* LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c)
|
||||
*/
|
||||
#define LWIP_NETCONN 1
|
||||
|
||||
/*
|
||||
------------------------------------
|
||||
---------- Socket options ----------
|
||||
------------------------------------
|
||||
*/
|
||||
/**
|
||||
* LWIP_SOCKET==1: Enable Socket API (require to use sockets.c)
|
||||
*/
|
||||
#define LWIP_SOCKET 1
|
||||
|
||||
/*
|
||||
---------------------------------
|
||||
---------- OS options ----------
|
||||
---------------------------------
|
||||
*/
|
||||
|
||||
#define DEFAULT_UDP_RECVMBOX_SIZE 10
|
||||
#define DEFAULT_TCP_RECVMBOX_SIZE 10
|
||||
#define DEFAULT_ACCEPTMBOX_SIZE 10
|
||||
#define DEFAULT_THREAD_STACKSIZE 1024 * 2
|
||||
|
||||
#define TCPIP_THREAD_NAME "lwip"
|
||||
#define TCPIP_THREAD_STACKSIZE 1024
|
||||
#define TCPIP_MBOX_SIZE 10
|
||||
#define TCPIP_THREAD_PRIO 1
|
||||
|
||||
#define LWIP_DNS_API_DECLARE_STRUCTS 1
|
||||
#define LWIP_DNS 1
|
||||
|
||||
/** DNS server IP address */
|
||||
#ifndef DNS_SERVER_ADDRESS
|
||||
#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr("208.67.222.222"))) /* resolver1.opendns.com */
|
||||
#endif
|
||||
|
||||
/*
|
||||
----------------------------------------
|
||||
---------- Lwip Debug options ----------
|
||||
----------------------------------------
|
||||
*/
|
||||
#define LWIP_DEBUG 0
|
||||
|
||||
#define ethernet_with_mac 1
|
||||
|
||||
#endif /* __LWIPOPTS_H__ */
|
||||
|
||||
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
#ifndef _TOS_CONFIG_H_
|
||||
#define _TOS_CONFIG_H_
|
||||
|
||||
#include "stddef.h"
|
||||
#include "stdint.h"
|
||||
|
||||
#define TOS_CFG_TASK_PRIO_MAX 10u // 配置TencentOS tiny默认支持的最大优先级数量
|
||||
|
||||
#define TOS_CFG_ROUND_ROBIN_EN 1u // 配置TencentOS tiny的内核是否开启时间片轮转
|
||||
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u // 配置TencentOS tiny是否校验指针合法
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u // TencentOS tiny 事件模块功能宏
|
||||
|
||||
#define TOS_CFG_MMHEAP_EN 1u // 配置TencentOS tiny是否开启动态内存模块
|
||||
|
||||
#define TOS_CFG_MMHEAP_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小
|
||||
|
||||
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小
|
||||
|
||||
#define TOS_CFG_MUTEX_EN 1u // 配置TencentOS tiny是否开启互斥锁模块
|
||||
|
||||
#define TOS_CFG_MESSAGE_QUEUE_EN 1u
|
||||
#define TOS_CFG_MAIL_QUEUE_EN 1u
|
||||
|
||||
#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN 1u
|
||||
|
||||
#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN 1u
|
||||
#define TOS_CFG_TIMER_EN 1u // 配置TencentOS tiny是否开启软件定时器模块
|
||||
|
||||
#define TOS_CFG_SEM_EN 1u // 配置TencentOS tiny是否开启信号量模块
|
||||
|
||||
#define TOS_CFG_MMBLK_EN 1u
|
||||
|
||||
#if (TOS_CFG_QUEUE_EN > 0u)
|
||||
#define TOS_CFG_MSG_EN 1u
|
||||
#else
|
||||
#define TOS_CFG_MSG_EN 0u
|
||||
#endif
|
||||
|
||||
#define TOS_CFG_MSG_POOL_SIZE 10u // 配置TencentOS tiny消息队列大小
|
||||
|
||||
#define TOS_CFG_IDLE_TASK_STK_SIZE 256u // 配置TencentOS tiny空闲任务栈大小
|
||||
|
||||
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u // 配置TencentOS tiny的tick频率
|
||||
|
||||
#define TOS_CFG_CPU_CLOCK 1000000u // 配置TencentOS tiny CPU频率
|
||||
|
||||
#define TOS_CFG_TIMER_AS_PROC 1u // 配置是否将TIMER配置成函数模式
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
# How to run the demo in linux
|
||||
|
||||
## step1
|
||||
make sure your develop environment.
|
||||
+ `cmake` and version greater than 3.8.2
|
||||
+ `gcc` `gdb` `make` is installed
|
||||
|
||||
## step2
|
||||
make `build` directory and compile in `build`
|
||||
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
## step3
|
||||
run program !!
|
||||
|
||||
```bash
|
||||
# in build directory
|
||||
./hello_world
|
||||
```
|
||||
|
||||
## other
|
||||
you can copy this demo to other path, but if you want do it,
|
||||
you need modify `CMakeLists.txt`. find line
|
||||
|
||||
```cmake
|
||||
set(TINY_ROOT ../../../)
|
||||
```
|
||||
|
||||
and modify `path-to-tinyos`
|
||||
```cmake
|
||||
set(TINY_ROOT path-to-tinyos)
|
||||
```
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#include "cmsis_os.h"
|
||||
|
||||
#define TASK1_STK_SIZE 512
|
||||
void task1(void *arg);
|
||||
osThreadDef(task1, osPriorityNormal, 1, TASK1_STK_SIZE);
|
||||
|
||||
#define TASK2_STK_SIZE 512
|
||||
void task2(void *arg);
|
||||
osThreadDef(task2, osPriorityNormal, 1, TASK2_STK_SIZE);
|
||||
|
||||
void task1(void *arg)
|
||||
{
|
||||
int count = 1;
|
||||
while (1) {
|
||||
printf("###This is task1, %d\r\n", count++);
|
||||
osDelay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
void task2(void *arg)
|
||||
{
|
||||
int count = 1;
|
||||
while (1) {
|
||||
#if TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN > 0u
|
||||
k_err_t rc;
|
||||
int depth;
|
||||
|
||||
rc = tos_task_stack_draught_depth(K_NULL, &depth);
|
||||
printf("%d %d\n", rc, depth);
|
||||
#endif
|
||||
|
||||
printf("***This is task2, %d\r\n", count++);
|
||||
osDelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
osThreadCreate(osThread(task1), NULL); // Create task1
|
||||
osThreadCreate(osThread(task2), NULL); // Create task2
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
osKernelInitialize(); //TOS Tiny kernel initialize
|
||||
application_entry(NULL);
|
||||
osKernelStart(); //Start TOS Tiny
|
||||
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
cmake_minimum_required(VERSION 3.8)
|
||||
|
||||
project(mqtt_demo)
|
||||
|
||||
set(CMAKE_BUILD_TYPE "Debug")
|
||||
set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g2 -ggdb")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")
|
||||
|
||||
set(TINY_ROOT ../../../)
|
||||
|
||||
add_definitions(-DMQTT_NETWORK_TYPE_NO_TLS -DMQTT_NETSOCKET_USING_AT)
|
||||
|
||||
## kernel
|
||||
include_directories(${TINY_ROOT}/osal/cmsis_os)
|
||||
include_directories(${TINY_ROOT}/kernel/core/include)
|
||||
include_directories(${TINY_ROOT}/kernel/evtdrv/include)
|
||||
include_directories(${TINY_ROOT}/kernel/hal/include)
|
||||
include_directories(${TINY_ROOT}/kernel/pm/include)
|
||||
|
||||
set(CMSIS_SRCS ${TINY_ROOT}/osal/cmsis_os/cmsis_os.c)
|
||||
aux_source_directory(${TINY_ROOT}/kernel/core CORE_SRCS)
|
||||
aux_source_directory(${TINY_ROOT}/kernel/evtdrv EVTDRV_SRCS)
|
||||
aux_source_directory(${TINY_ROOT}/kernel/pm PM_SRCS)
|
||||
|
||||
set(KERNEL_SRCS ${CMSIS_SRCS} ${EVTDRV_SRCS} ${PM_SRCS} ${CORE_SRCS})
|
||||
|
||||
## net
|
||||
include_directories(${TINY_ROOT}/net/sal_module_wrapper)
|
||||
include_directories(${TINY_ROOT}/components/connectivity/mqttclient/mqttclient)
|
||||
|
||||
aux_source_directory(${TINY_ROOT}/net/sal_module_wrapper SAL_SRCS)
|
||||
|
||||
set(MQTT_ROOT ${TINY_ROOT}/components/connectivity/mqttclient)
|
||||
include_directories(${MQTT_ROOT}/common)
|
||||
include_directories(${MQTT_ROOT}/common/log)
|
||||
include_directories(${MQTT_ROOT}/mqtt)
|
||||
include_directories(${MQTT_ROOT}/mqttclient)
|
||||
include_directories(${MQTT_ROOT}/network)
|
||||
include_directories(${MQTT_ROOT}/platform/TencentOS-tiny)
|
||||
|
||||
aux_source_directory(${MQTT_ROOT}/common MQTT_COMMON)
|
||||
aux_source_directory(${MQTT_ROOT}/common/log MQTT_COMMON_LOG)
|
||||
aux_source_directory(${MQTT_ROOT}/mqttclient MQTT_CLIENT)
|
||||
aux_source_directory(${MQTT_ROOT}/mqtt MQTT_CORE)
|
||||
aux_source_directory(${MQTT_ROOT}/network MQTT_NETWORK)
|
||||
aux_source_directory(${MQTT_ROOT}/platform/TencentOS-tiny MQTT_PLATFORM)
|
||||
|
||||
set(MQTT_SRCS
|
||||
${MQTT_ROOT}/common/log/arch/tencentos-tiny/arch.c
|
||||
${MQTT_COMMON}
|
||||
${MQTT_COMMON_LOG}
|
||||
${MQTT_CLIENT}
|
||||
${MQTT_CORE}
|
||||
${MQTT_NETWORK}
|
||||
${MQTT_PLATFORM}
|
||||
)
|
||||
|
||||
set(NET_SRCS ${MQTT_SRCS} ${SAL_SRCS})
|
||||
|
||||
## arch
|
||||
set(ARCH_ROOT ${TINY_ROOT}/arch/linux)
|
||||
|
||||
include_directories(${ARCH_ROOT}/common/include)
|
||||
include_directories(${ARCH_ROOT}/posix/gcc)
|
||||
|
||||
aux_source_directory(${ARCH_ROOT}/common ARCH_COMMON_SRCS)
|
||||
aux_source_directory(${ARCH_ROOT}/posix/gcc ARCH_POSIX_SRCS)
|
||||
|
||||
set(ARCH_SRCS ${ARCH_COMMON_SRCS} ${ARCH_POSIX_SRCS})
|
||||
|
||||
|
||||
include_directories(${TINY_ROOT}/components/utils/JSON/include)
|
||||
|
||||
set(UTILS_SRCS ${TINY_ROOT}/components/utils/JSON/src/cJSON.c)
|
||||
|
||||
set(TINY_SRCS ${ARCH_SRCS} ${KERNEL_SRCS} ${NET_SRCS} ${UTILS_SRCS})
|
||||
|
||||
## app
|
||||
include_directories(./)
|
||||
include_directories(./inc)
|
||||
|
||||
aux_source_directory(./src APP_SRCS)
|
||||
|
||||
add_executable(mqtt_demo ${APP_SRCS} ${TINY_SRCS})
|
||||
|
||||
target_link_libraries(mqtt_demo pthread)
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
###################################################################
|
||||
#automatic detection QTOP and LOCALDIR
|
||||
CUR_DIR := $(patsubst %/,%,$(dir $(realpath $(firstword $(MAKEFILE_LIST)))))
|
||||
TRYQTOP := $(shell if [ -n "$$QTOP" ] ; then\
|
||||
echo $$QTOP;\
|
||||
else\
|
||||
cd $(CUR_DIR); while /usr/bin/test ! -e qmk ; do \
|
||||
dir=`cd ../;pwd`; \
|
||||
if [ "$$dir" = "/" ] ; then \
|
||||
echo Cannot find QTOP in $(firstword $(MAKEFILE_LIST)) 1>&2; \
|
||||
exit 1; \
|
||||
fi ; \
|
||||
cd $$dir; \
|
||||
done ; \
|
||||
pwd; \
|
||||
fi)
|
||||
QTOP ?= $(realpath ${TRYQTOP})
|
||||
|
||||
ifeq ($(QTOP),)
|
||||
$(error Please run this in a tree)
|
||||
endif
|
||||
LOCALDIR = $(patsubst %/,%,$(subst $(realpath $(QTOP))/,,$(CUR_DIR)))
|
||||
export QTOP
|
||||
|
||||
####################################################################
|
||||
|
||||
|
||||
export BP=Linux_Posix
|
||||
|
||||
TREE_LIB_ENABLE=1
|
||||
lib=
|
||||
subdirs =
|
||||
|
||||
CFGFLAGS += -I$(CUR_DIR)/inc
|
||||
CFGFLAGS += -I$(QTOP)/net/sal_module_wrapper
|
||||
CFGFLAGS += -I$(QTOP)/components/connectivity/Eclipse-Paho-MQTT/wrapper/include
|
||||
CFGFLAGS += -I$(QTOP)/components/connectivity/Eclipse-Paho-MQTT/3rdparty/include
|
||||
|
||||
all::
|
||||
make -C ${QTOP}/arch BP=Linux_Posix
|
||||
make -C ${QTOP}/kernel
|
||||
make -C ${QTOP}/osal
|
||||
make -C ${QTOP}/net
|
||||
make -C ${QTOP}/devices
|
||||
make -C ${QTOP}/components/connectivity/Eclipse-Paho-MQTT
|
||||
|
||||
exec =
|
||||
LD_A_FILES += $(LIBDIR)/libarch.a
|
||||
LD_A_FILES += $(LIBDIR)/libkernel.a
|
||||
LD_A_FILES += $(LIBDIR)/libhello_world.a
|
||||
LD_A_FILES += $(LIBDIR)/libcmsis_os.a
|
||||
LD_A_FILES += $(LIBDIR)/libEclipse-Paho-MQTT.a
|
||||
LD_A_FILES += $(LIBDIR)/libsal_module_wrapper.a
|
||||
LDFLAGS += -lpthread
|
||||
|
||||
include ${QTOP}/qmk/generic/Make.exec
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef TOS_MQTT_CONFIG_H
|
||||
#define TOS_MQTT_CONFIG_H
|
||||
|
||||
#define MQTT_SERVER_IP "111.230.189.156"
|
||||
#define MQTT_SERVER_PORT "1883"
|
||||
#define MQTT_PRODUCT_ID "$product"
|
||||
#define MQTT_DEV_NAME "$dev"
|
||||
#define MQTT_CLIENT_ID "$product$dev"
|
||||
#define MQTT_USR_NAME "$product$dev;21010406;12365;4294967295"
|
||||
#define MQTT_PASSWORD "$sign;hmacsha1"
|
||||
#define MQTT_SUBSCRIBE_TOPIC "$product/$dev/$sub"
|
||||
#define MQTT_PUBLISH_TOPIC "$product/$dev/$pub"
|
||||
|
||||
//#error please replace yourself server configuration
|
||||
/**
|
||||
* 1. run python tool
|
||||
* ```
|
||||
* cd tiny/tools/
|
||||
* python3 mqtt_config_gen.py
|
||||
* ```
|
||||
* then input your server information
|
||||
*
|
||||
* 2. tool will generate `mqtt_config.h` file, copy to replace this file
|
||||
*/
|
||||
|
||||
#endif
|
||||
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
#ifndef _SOCKET_WRAPPER_
|
||||
#define _SOCKET_WRAPPER_
|
||||
|
||||
#include "sal_module_wrapper.h"
|
||||
|
||||
sal_module_t *get_socket_module(void);
|
||||
|
||||
#endif //_SOCKET_WRAPPER_
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef _TOS_CONFIG_H_
|
||||
#define _TOS_CONFIG_H_
|
||||
|
||||
#include "stddef.h"
|
||||
|
||||
#define TOS_CFG_TASK_PRIO_MAX 10u // 配置TencentOS tiny默认支持的最大优先级数量
|
||||
|
||||
#define TOS_CFG_ROUND_ROBIN_EN 1u // 配置TencentOS tiny的内核是否开启时间片轮转
|
||||
|
||||
#define TOS_CFG_OBJECT_VERIFY 0u // 配置TencentOS tiny是否校验指针合法
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u // TencentOS tiny 事件模块功能宏
|
||||
|
||||
#define TOS_CFG_MMHEAP_EN 1u // 配置TencentOS tiny是否开启动态内存模块
|
||||
|
||||
#define TOS_CFG_MMHEAP_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小
|
||||
|
||||
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x100 // 配置TencentOS tiny动态内存池大小
|
||||
|
||||
#define TOS_CFG_MUTEX_EN 1u // 配置TencentOS tiny是否开启互斥锁模块
|
||||
|
||||
#define TOS_CFG_QUEUE_EN 1u // 配置TencentOS tiny是否开启队列模块
|
||||
|
||||
#define TOS_CFG_TIMER_EN 1u // 配置TencentOS tiny是否开启软件定时器模块
|
||||
|
||||
#define TOS_CFG_SEM_EN 1u // 配置TencentOS tiny是否开启信号量模块
|
||||
|
||||
#define TOS_CFG_MMBLK_EN 1u
|
||||
|
||||
#if (TOS_CFG_QUEUE_EN > 0u)
|
||||
#define TOS_CFG_MSG_EN 1u
|
||||
#else
|
||||
#define TOS_CFG_MSG_EN 0u
|
||||
#endif
|
||||
|
||||
#define TOS_CFG_MSG_POOL_SIZE 10u // 配置TencentOS tiny消息队列大小
|
||||
|
||||
#define TOS_CFG_IDLE_TASK_STK_SIZE 256u // 配置TencentOS tiny空闲任务栈大小
|
||||
|
||||
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u // 配置TencentOS tiny的tick频率
|
||||
|
||||
#define TOS_CFG_CPU_CLOCK 1000000u // 配置TencentOS tiny CPU频率
|
||||
|
||||
#define TOS_CFG_TIMER_AS_PROC 1u // 配置是否将TIMER配置成函数模式
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
# How to run the demo in linux
|
||||
|
||||
## step1
|
||||
make sure your develop environment.
|
||||
+ `cmake` and version greater than 3.8.2
|
||||
+ `gcc` `gdb` `make` is installed
|
||||
|
||||
## step2
|
||||
configure your server and add a transmit rule
|
||||
|
||||
reference [tencent cloud IoT guide?](../../../doc/8.TencentOS-tiny对接腾讯云IoTHub开发指南.md)
|
||||
|
||||
additional thing, add a rule for send a message to the demo
|
||||
1. select filter topic is the ${demo device}/event and
|
||||
SELECT * FROM ${demo device}/event
|
||||
2. select action type is Republish and topic is the ${demo device}/control
|
||||
|
||||
the page like this
|
||||
_____________________________________________
|
||||
|规则引擎
|
||||
|--------------------------------------------
|
||||
|基本信息
|
||||
|规则名称 loop
|
||||
|规则描述 未填写
|
||||
|--------------------------------------------
|
||||
|筛选数据
|
||||
|字段 *
|
||||
|Topic ${demo device}/event
|
||||
|条件
|
||||
|当前SQL语句是:
|
||||
|SELECT * ${demo device}/event
|
||||
|--------------------------------------------
|
||||
|行为操作
|
||||
|行为类型 数据转发到另一个Topic ( Republish )
|
||||
|Topic ${demo device}/control
|
||||
| ...
|
||||
_____________________________________________
|
||||
|
||||
|
||||
## step3
|
||||
generate `mqtt_config.h` file to replace `./inc/mqtt_config.h`
|
||||
|
||||
cd `tiny/tools/` directory, run python script
|
||||
```bash
|
||||
python3 mqtt_config_gen.py
|
||||
```
|
||||
|
||||
then input your server configuration, generate `mqtt_config.h` file
|
||||
copy to `./inc/` replace old file
|
||||
|
||||
## step4
|
||||
make `build` directory and compile in `build`
|
||||
|
||||
```bash
|
||||
mkdir build && cd build
|
||||
cmake ..
|
||||
make
|
||||
```
|
||||
|
||||
## step5
|
||||
run program !!
|
||||
|
||||
```bash
|
||||
# in build directory
|
||||
./mqtt_demo
|
||||
```
|
||||
|
||||
## other
|
||||
you can copy this demo to other path, but if you want do it,
|
||||
you need modify `CMakeLists.txt`. find line
|
||||
|
||||
```cmake
|
||||
set(TINY_ROOT ../../../)
|
||||
```
|
||||
|
||||
and modify `path-to-tinyos`
|
||||
```cmake
|
||||
set(TINY_ROOT path-to-tinyos)
|
||||
```
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
#include "cmsis_os.h"
|
||||
#include "socket_wrapper.h"
|
||||
#include "sal_module_wrapper.h"
|
||||
// #include "mqtt_wrapper.h"
|
||||
#include "mqtt_config.h"
|
||||
#include "mqttclient.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int sock_id = 0;
|
||||
|
||||
//mqtt_publisher
|
||||
#define MQTT_PUBLISHER_STK_SIZE 1024
|
||||
void mqtt_publisher(void *pdata);
|
||||
osThreadDef(mqtt_publisher, osPriorityNormal, 1, MQTT_PUBLISHER_STK_SIZE);
|
||||
|
||||
static void tos_topic_handler(void* client, message_data_t* msg)
|
||||
{
|
||||
(void)client;
|
||||
MQTT_LOG_I("-----------------------------------------------------------------------------------");
|
||||
MQTT_LOG_I("%s:%d %s()...\ntopic: %s, qos: %d. \nmessage:\n\t%s\n", __FILE__, __LINE__, __FUNCTION__,
|
||||
msg->topic_name, msg->message->qos, (char *)msg->message->payload);
|
||||
MQTT_LOG_I("-----------------------------------------------------------------------------------\n");
|
||||
}
|
||||
|
||||
void mqtt_publisher(void *pdata)
|
||||
{
|
||||
int error;
|
||||
char buf[100] = {0};
|
||||
mqtt_client_t *client = NULL;
|
||||
mqtt_message_t msg;
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
mqtt_log_init();
|
||||
client = mqtt_lease();
|
||||
|
||||
mqtt_set_port(client, MQTT_SERVER_PORT);
|
||||
mqtt_set_host(client, MQTT_SERVER_IP);
|
||||
mqtt_set_client_id(client, MQTT_CLIENT_ID);
|
||||
mqtt_set_user_name(client, MQTT_USR_NAME);
|
||||
mqtt_set_password(client, MQTT_PASSWORD);
|
||||
mqtt_set_clean_session(client, 1);
|
||||
|
||||
error = mqtt_connect(client);
|
||||
|
||||
MQTT_LOG_D("mqtt connect error is %#x", error);
|
||||
|
||||
mqtt_subscribe(client, MQTT_SUBSCRIBE_TOPIC, QOS0, tos_topic_handler);
|
||||
|
||||
MQTT_LOG_D("mqtt subscribe error is %#x", error);
|
||||
|
||||
memset(&msg, 0, sizeof(msg));
|
||||
|
||||
for (;;)
|
||||
{
|
||||
sprintf(buf, "welcome to mqttclient, this is a publish test, a rand number: %d ...", random_number());
|
||||
|
||||
msg.qos = QOS0;
|
||||
msg.payload = (void *)buf;
|
||||
|
||||
error = mqtt_publish(client, MQTT_PUBLISH_TOPIC, &msg);
|
||||
|
||||
osDelay(4000);
|
||||
}
|
||||
}
|
||||
|
||||
// void mqtt_reciever(void *pdata)
|
||||
// {
|
||||
// uint8_t read_data[100];
|
||||
// int8_t topic[30];
|
||||
// uint32_t read_len;
|
||||
|
||||
// for (;;)
|
||||
// {
|
||||
// read_len = tos_mqtt_receive(topic, sizeof(topic), read_data, sizeof(read_data));
|
||||
// if (read_len >= 0)
|
||||
// {
|
||||
// printf("receive topic-->%s| data-->%s| \n", topic, read_data);
|
||||
// }
|
||||
// osDelay(100);
|
||||
// }
|
||||
// }
|
||||
|
||||
int main(void)
|
||||
{
|
||||
osKernelInitialize(); //TOS Tiny kernel initialize
|
||||
osThreadCreate(osThread(mqtt_publisher), NULL); // start connect and publish
|
||||
osKernelStart(); //Start TOS Tiny
|
||||
|
||||
while (1)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,143 @@
|
|||
#include "socket_wrapper.h"
|
||||
#include "cmsis_os.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
static osMutexId socket_send_lock, socket_recv_lock;
|
||||
|
||||
osMutexDef(socket_send_lock);
|
||||
osMutexDef(socket_recv_lock);
|
||||
|
||||
static osSemaphoreId socket_recv_event;
|
||||
osSemaphoreDef(socket_recv_event);
|
||||
|
||||
int socket_init(void)
|
||||
{
|
||||
socket_send_lock = osMutexCreate(osMutex(socket_send_lock));
|
||||
socket_recv_lock = osMutexCreate(osMutex(socket_recv_lock));
|
||||
socket_recv_event = osSemaphoreCreate(osSemaphore(socket_recv_event),0);
|
||||
|
||||
return (
|
||||
(socket_recv_event != NULL) &&
|
||||
(socket_recv_lock != NULL) &&
|
||||
(socket_send_lock != NULL)
|
||||
);
|
||||
}
|
||||
|
||||
void io_signal_handle(int signal)
|
||||
{
|
||||
osSemaphoreRelease(socket_recv_event);
|
||||
}
|
||||
|
||||
int socket_connect(const char *ip, const char *port, sal_proto_t proto)
|
||||
{
|
||||
struct sockaddr_in addr = {
|
||||
.sin_family = AF_INET,
|
||||
.sin_port = htons(atoi(port))};
|
||||
int socket_proto = 0;
|
||||
struct sigaction sig_install;
|
||||
|
||||
inet_pton(AF_INET, ip, &addr.sin_addr);
|
||||
|
||||
if (TOS_SAL_PROTO_TCP == proto)
|
||||
{
|
||||
socket_proto = IPPROTO_TCP;
|
||||
}
|
||||
else if (TOS_SAL_PROTO_UDP == proto)
|
||||
{
|
||||
socket_proto = IPPROTO_UDP;
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int socket_id = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
fcntl( socket_id, __F_SETOWN, getpid() );
|
||||
fcntl( socket_id, __F_SETSIG, SIGIO );
|
||||
fcntl( socket_id, F_SETFL, O_ASYNC );
|
||||
|
||||
sig_install.sa_flags = 0;
|
||||
sig_install.sa_handler = io_signal_handle;
|
||||
sigfillset( &sig_install.sa_mask );
|
||||
|
||||
if ( 0 != sigaction( SIGIO, &sig_install, NULL ) )
|
||||
{
|
||||
printf( "socket problem installing %d\n",SIGIO );
|
||||
}
|
||||
|
||||
connect(socket_id, &addr, sizeof(addr));
|
||||
return socket_id;
|
||||
}
|
||||
|
||||
int socket_send(int sock, const void *buf, size_t len)
|
||||
{
|
||||
ssize_t send_len = 0, state;
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
osMutexWait(socket_send_lock, TOS_TIME_FOREVER);
|
||||
do
|
||||
{
|
||||
state = send(sock, (buf + send_len), (len - send_len), MSG_DONTWAIT);
|
||||
if (state > 0)
|
||||
{
|
||||
send_len += state;
|
||||
}
|
||||
if (send_len != len)
|
||||
{
|
||||
osSemaphoreWait(socket_recv_event,100);
|
||||
}
|
||||
} while (len != send_len);
|
||||
osMutexRelease(socket_send_lock);
|
||||
return send_len;
|
||||
}
|
||||
|
||||
int socket_recv(int sock, void *buf, size_t len)
|
||||
{
|
||||
ssize_t recv_len = 0, state;
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
osMutexWait(socket_recv_lock, TOS_TIME_FOREVER);
|
||||
do
|
||||
{
|
||||
state = recv(sock, (buf + recv_len), (len - recv_len), MSG_DONTWAIT);
|
||||
if (state > 0)
|
||||
{
|
||||
recv_len += state;
|
||||
}
|
||||
if (recv_len != len)
|
||||
{
|
||||
osSemaphoreWait(socket_recv_event,100);
|
||||
}
|
||||
} while (len != recv_len);
|
||||
osMutexRelease(socket_recv_lock);
|
||||
return recv_len;
|
||||
}
|
||||
|
||||
int socket_close(int sock)
|
||||
{
|
||||
close(sock);
|
||||
}
|
||||
|
||||
static sal_module_t linux_sal = {
|
||||
.init = socket_init,
|
||||
.connect = socket_connect,
|
||||
.send = socket_send,
|
||||
.recv = socket_recv,
|
||||
.close = socket_close,
|
||||
// .sendto = NULL,
|
||||
// .recv_timeout = NULL,
|
||||
// .recvfrom = NULL,
|
||||
// .recvfrom_timeout = NULL,
|
||||
// .parse_domain = NULL,
|
||||
};
|
||||
|
||||
sal_module_t *get_socket_module(void)
|
||||
{
|
||||
return (&linux_sal);
|
||||
}
|
||||
|
|
@ -62,6 +62,25 @@
|
|||
<tool id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler.1731377187" name="GNU RISC-V Cross C Compiler" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.compiler">
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="false" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths.1567947810" name="Include paths (-I)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.compiler.include.paths" useByScannerDiscovery="true" valueType="includePath">
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Debug}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/include/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/include/config}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/include/services/common}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/include/services/explorer}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/common/cryptology/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/common/mqtt_packet/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/common/utils/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/examples}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/platform/network/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/services/explorer/data_template/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/services/explorer/service_mqtt/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/services/common/log_upload/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/c-sdk/services/common/mqtt_client/inc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/net/sal_module_wrapper}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/devices/esp8266}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/fs/kv/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/fs/fatfs/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/fs/vfs/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/kernel/hal/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/net/at/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/net/tencent_firmware_module_wrapper}""/>
|
||||
|
|
@ -70,7 +89,6 @@
|
|||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/arch/common/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/arch/rv32i/gcc}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/kernel/core/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/kernel/hal/include}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Core}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/User}""/>
|
||||
<listOptionValue builtIn="false" value=""${workspace_loc:/${ProjName}/Peripheral/inc}""/>
|
||||
|
|
@ -91,6 +109,7 @@
|
|||
<option id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnosys.351964161" name="Do not use syscalls (--specs=nosys.specs)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.usenewlibnosys" useByScannerDiscovery="false" value="true" valueType="boolean"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.otherobjs.16994550" name="Other objects" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.otherobjs" useByScannerDiscovery="false" valueType="userObjs"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags.1125808200" name="Linker flags (-Xlinker [option])" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.flags" useByScannerDiscovery="false" valueType="stringList"/>
|
||||
<option IS_BUILTIN_EMPTY="false" IS_VALUE_EMPTY="true" id="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs.834465884" name="Libraries (-l)" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.option.c.linker.libs" useByScannerDiscovery="false" valueType="libs"/>
|
||||
<inputType id="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input.1859223768" superClass="ilg.gnumcueclipse.managedbuild.cross.riscv.tool.c.linker.input">
|
||||
<additionalInput kind="additionalinputdependency" paths="$(USER_OBJS)"/>
|
||||
<additionalInput kind="additionalinput" paths="$(LIBS)"/>
|
||||
|
|
@ -123,17 +142,27 @@
|
|||
</toolChain>
|
||||
</folderInfo>
|
||||
<sourceEntries>
|
||||
<entry excluding="platform/hal/wch/ch32v30xx|kernel/hal|devices/esp8266_tencent_firmware|net/tencent_firmware_module_wrapper|kernel/core|net/at|kernel|arch|TencentOS-Tiny|Startup|Peripheral|Ld|Debug|Core" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
<entry excluding="examples/qcloud_csdk_iot_explorer|c-sdk/services/common|c-sdk/include|examples/mqtt_iot_explorer.c|c-sdk/examples|c-sdk/app|c-sdk/services/explorer|c-sdk/explorer|c-sdk/platform|devices/esp8266|c-sdk/common|net/sal_module_wrapper|examples/fatfs_through_vfs_sample.c|User/mqtt_iot_explorer.c|examples/kv_sample.c|fs/fatfs|fs/vfs|fs/kv|components/kv|platform/hal/wch/ch32v30xx|kernel/hal|devices/esp8266_tencent_firmware|net/tencent_firmware_module_wrapper|kernel/core|net/at|kernel|arch|TencentOS-Tiny|Startup|Peripheral|Ld|Debug|Core" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Core"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Debug"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Ld"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Peripheral"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="Startup"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="arch"/>
|
||||
<entry excluding="utils/test|mqtt_packet/test|cryptology/test" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="c-sdk/common"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="c-sdk/include"/>
|
||||
<entry excluding="os/Linux" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="c-sdk/platform"/>
|
||||
<entry excluding="system/test|system/sample|ota/test|ota/sample|mqtt_client/test|mqtt_client/sample|log_upload/test|log_upload/sample|cos/sample|dynreg/test|dynreg/sample|dynreg/src/dynreg.c" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="c-sdk/services/common"/>
|
||||
<entry excluding="service_mqtt/test|service_mqtt/sample|data_template/test|data_template/sample" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="c-sdk/services/explorer"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="devices/esp8266"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="devices/esp8266_tencent_firmware"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="fs/fatfs"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="fs/kv"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="fs/vfs"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="kernel/core"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="kernel/hal"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="net/at"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="net/sal_module_wrapper"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="net/tencent_firmware_module_wrapper"/>
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="platform/hal/wch/ch32v30xx"/>
|
||||
</sourceEntries>
|
||||
|
|
|
|||
|
|
@ -1,61 +1,61 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<launchConfiguration type="ilg.gnumcueclipse.debug.gdbjtag.openocd.launchConfigurationType">
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doSecondReset" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbCLient" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true"/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.enableSemihosting" value="false"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.firstResetType" value="init"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off set architecture riscv:rv32 set remotetimeout unlimited"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerConnectionAddress" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${eclipse_home}toolchain/OpenOCD/bin/openocd.exe"/>
|
||||
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerLog" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerOther" value="-f "${eclipse_home}toolchain/OpenOCD/bin/wch-riscv.cfg""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTclPortNumber" value="6666"/>
|
||||
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherInitCommands" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherRunCommands" value=""/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.secondResetType" value="halt"/>
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value="${eclipse_home}template/wizard/WCH/RISC-V/CH32V307/NoneOS/CH32V307xx.svd"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU OpenOCD"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value=""/>
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="handle_reset"/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value=""/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${eclipse_home}toolchain/RISC-V Embedded GCC/bin/riscv-none-embed-gdb.exe"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false"/>
|
||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value=""/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="obj\TencentOS-Tiny.elf"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="TencentOS-Tiny"/>
|
||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true"/>
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value=""/>
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doContinue" value="true" />
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doDebugInRam" value="false" />
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doFirstReset" value="true" />
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateConsole" value="true" />
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doGdbServerAllocateTelnetConsole" value="false" />
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doSecondReset" value="true" />
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbCLient" value="true" />
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.doStartGdbServer" value="true" />
|
||||
<booleanAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.enableSemihosting" value="false" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.firstResetType" value="init" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherCommands" value="set mem inaccessible-by-default off
set architecture riscv:rv32
set remotetimeout unlimited" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbClientOtherOptions" value="" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerConnectionAddress" value="" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerExecutable" value="${eclipse_home}toolchain/OpenOCD/bin/openocd.exe" />
|
||||
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerGdbPortNumber" value="3333" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerLog" value="" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerOther" value="-f "${eclipse_home}toolchain/OpenOCD/bin/wch-riscv.cfg"" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTclPortNumber" value="6666" />
|
||||
<intAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.gdbServerTelnetPortNumber" value="4444" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherInitCommands" value="" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.otherRunCommands" value="" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.openocd.secondResetType" value="halt" />
|
||||
<stringAttribute key="ilg.gnumcueclipse.debug.gdbjtag.svdPath" value="${eclipse_home}template/wizard/WCH/RISC-V/CH32V307/NoneOS/CH32V307xx.svd" />
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageFileName" value="" />
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.imageOffset" value="" />
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.ipAddress" value="localhost" />
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.jtagDevice" value="GNU MCU OpenOCD" />
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadImage" value="true" />
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.loadSymbols" value="true" />
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.pcRegister" value="" />
|
||||
<intAttribute key="org.eclipse.cdt.debug.gdbjtag.core.portNumber" value="3333" />
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setPcRegister" value="false" />
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setResume" value="false" />
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.setStopAt" value="true" />
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.stopAt" value="handle_reset" />
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsFileName" value="" />
|
||||
<stringAttribute key="org.eclipse.cdt.debug.gdbjtag.core.symbolsOffset" value="" />
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForImage" value="false" />
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useFileForSymbols" value="false" />
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForImage" value="true" />
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useProjBinaryForSymbols" value="true" />
|
||||
<booleanAttribute key="org.eclipse.cdt.debug.gdbjtag.core.useRemoteTarget" value="true" />
|
||||
<stringAttribute key="org.eclipse.cdt.dsf.gdb.DEBUG_NAME" value="${eclipse_home}toolchain/RISC-V Embedded GCC/bin/riscv-none-embed-gdb.exe" />
|
||||
<booleanAttribute key="org.eclipse.cdt.dsf.gdb.UPDATE_THREADLIST_ON_SUSPEND" value="false" />
|
||||
<intAttribute key="org.eclipse.cdt.launch.ATTR_BUILD_BEFORE_LAUNCH_ATTR" value="2" />
|
||||
<stringAttribute key="org.eclipse.cdt.launch.COREFILE_PATH" value="" />
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROGRAM_NAME" value="obj\TencentOS-Tiny.elf" />
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_ATTR" value="TencentOS-Tiny" />
|
||||
<booleanAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_AUTO_ATTR" value="true" />
|
||||
<stringAttribute key="org.eclipse.cdt.launch.PROJECT_BUILD_CONFIG_ID_ATTR" value="" />
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS">
|
||||
<listEntry value="/TencentOS-Tiny"/>
|
||||
<listEntry value="/TencentOS-Tiny" />
|
||||
</listAttribute>
|
||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||
<listEntry value="4"/>
|
||||
<listEntry value="4" />
|
||||
</listAttribute>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <memoryBlockExpressionList context="Context string"/> "/>
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory"/>
|
||||
<stringAttribute key="org.eclipse.dsf.launch.MEMORY_BLOCKS" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<memoryBlockExpressionList context="Context string"/>
" />
|
||||
<stringAttribute key="process_factory_id" value="org.eclipse.cdt.dsf.gdb.GdbProcessFactory" />
|
||||
</launchConfiguration>
|
||||
|
|
|
|||
|
|
@ -1,18 +1,18 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<projectDescription>
|
||||
<name>TencentOS-Tiny</name>
|
||||
<comment />
|
||||
<projects />
|
||||
<comment/>
|
||||
<projects/>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
|
||||
<triggers>clean,full,incremental,</triggers>
|
||||
<arguments />
|
||||
<arguments/>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
|
||||
<triggers>full,incremental,</triggers>
|
||||
<arguments />
|
||||
<arguments/>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
|
|
@ -24,43 +24,93 @@
|
|||
<link>
|
||||
<name>arch</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-2-PROJECT_LOC/arch/risc-v/risc-v3a</location>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/arch/risc-v/risc-v3a</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>kernel/core</name>
|
||||
<name>c-sdk/common</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-2-PROJECT_LOC/kernel/core</location>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/components/connectivity/iot-hub-device-c-sdk/common</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>net/at</name>
|
||||
<name>c-sdk/include</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-2-PROJECT_LOC/net/at</location>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/components/connectivity/iot-hub-device-c-sdk/include</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>net/tencent_firmware_module_wrapper</name>
|
||||
<name>c-sdk/platform</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-2-PROJECT_LOC/net/tencent_firmware_module_wrapper</location>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/components/connectivity/iot-hub-device-c-sdk/platform</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>devices/esp8266</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/devices/esp8266</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>devices/esp8266_tencent_firmware</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-2-PROJECT_LOC/devices/esp8266_tencent_firmware</location>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/devices/esp8266_tencent_firmware</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>fs/fatfs</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/components/fs/fatfs/wrapper</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>fs/kv</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/components/fs/kv</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>fs/vfs</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/components/fs/vfs</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>kernel/core</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/kernel/core</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>kernel/hal</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-2-PROJECT_LOC/kernel/hal</location>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/kernel/hal</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>net/at</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/net/at</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>net/sal_module_wrapper</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/net/sal_module_wrapper</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>net/tencent_firmware_module_wrapper</name>
|
||||
<type>2</type>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/net/tencent_firmware_module_wrapper</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>platform/hal/wch/ch32v30xx</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-2-PROJECT_LOC/platform/hal/wch/ch32v30xx/src</location>
|
||||
<locationURI>PARENT-2-PROJECT_LOC/platform/hal/wch/ch32v30xx/src</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>c-sdk/services/common</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-2-PROJECT_LOC/components/connectivity/iot-hub-device-c-sdk/services/common</location>
|
||||
</link>
|
||||
<link>
|
||||
<name>c-sdk/services/explorer</name>
|
||||
<type>2</type>
|
||||
<location>PARENT-2-PROJECT_LOC/components/connectivity/iot-hub-device-c-sdk/services/explorer</location>
|
||||
</link>
|
||||
</linkedResources>
|
||||
<filteredResources>
|
||||
<filter>
|
||||
<id>1595986042669</id>
|
||||
<name />
|
||||
<name/>
|
||||
<type>22</type>
|
||||
<matcher>
|
||||
<id>org.eclipse.ui.ide.multiFilter</id>
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@
|
|||
|
||||
#define TOS_CFG_OBJECT_VERIFY 1u
|
||||
|
||||
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 1u
|
||||
|
||||
#define TOS_CFG_OBJ_DYNAMIC_CREATE_EN 1u
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u
|
||||
|
||||
|
|
@ -24,7 +23,7 @@
|
|||
|
||||
#define TOS_CFG_MMHEAP_DEFAULT_POOL_EN 1u
|
||||
|
||||
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x3000
|
||||
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x8000
|
||||
|
||||
#define TOS_CFG_MAIL_QUEUE_EN 1u
|
||||
|
||||
|
|
@ -44,7 +43,7 @@
|
|||
|
||||
#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN 0u
|
||||
|
||||
#define TOS_CFG_CPU_SYSTICK_PRIO 0xF0 //V307优先级高四位有效
|
||||
#define TOS_CFG_CPU_SYSTICK_PRIO 0xF0 //V307<EFBFBD><EFBFBD><EFBFBD>ȼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>Ч
|
||||
|
||||
|
||||
#define TOS_CFG_IDLE_TASK_STK_SIZE 512u
|
||||
|
|
|
|||
|
|
@ -8,12 +8,11 @@
|
|||
#include "ch32v30x_it.h"
|
||||
#include "tos_k.h"
|
||||
#include "tos_at.h"
|
||||
|
||||
extern at_agent_t esp8266_tf_agent;
|
||||
extern at_agent_t esp8266_agent;
|
||||
|
||||
void NMI_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void HardFault_Handler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
|
||||
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void UART6_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
void UART7_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
|
||||
|
|
@ -78,7 +77,7 @@ void UART6_IRQHandler(void)
|
|||
if(USART_GetITStatus(UART6, USART_IT_RXNE) != RESET)
|
||||
{
|
||||
data= USART_ReceiveData(UART6);
|
||||
tos_at_uart_input_byte(&esp8266_tf_agent,data);
|
||||
tos_at_uart_input_byte(&esp8266_agent,data);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,56 +7,229 @@
|
|||
*******************************************************************************/
|
||||
#include "debug.h"
|
||||
#include "tos_k.h"
|
||||
#include "sdio.h"
|
||||
#include "lcd_init.h"
|
||||
#include "lcd.h"
|
||||
#include "pic.h"
|
||||
#include "spi_flash.h"
|
||||
|
||||
|
||||
void led_init(void)
|
||||
void led_key_init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure = {0};
|
||||
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);
|
||||
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_GPIOA, ENABLE);
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOE, &GPIO_InitStructure);
|
||||
GPIO_SetBits(GPIOE,GPIO_Pin_2);
|
||||
GPIO_SetBits(GPIOE,GPIO_Pin_3);
|
||||
GPIO_SetBits(GPIOE,GPIO_Pin_4);
|
||||
GPIO_SetBits(GPIOE,GPIO_Pin_5);
|
||||
/* key 1 2 3 */
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_8;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
}
|
||||
#define TASK1_STK_SIZE 1024
|
||||
k_task_t task1;
|
||||
__aligned(4) uint8_t task1_stk[TASK1_STK_SIZE];
|
||||
|
||||
uint8_t get_key(void)
|
||||
{
|
||||
uint16_t value=0;
|
||||
if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) & GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)\
|
||||
& GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)) == 0 )
|
||||
{
|
||||
Delay_Ms(15);
|
||||
if((GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0) & GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)\
|
||||
& GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_8)) == 0 )
|
||||
{
|
||||
value= GPIO_ReadInputData(GPIOA);
|
||||
if((value&0x1)==0) return 1;
|
||||
else if((value&0x2)==0)return 2;
|
||||
else if((value&0x100)==0) return 3;
|
||||
else return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TASK2_STK_SIZE 1024
|
||||
k_task_t task2;
|
||||
__aligned(4) uint8_t task2_stk[TASK2_STK_SIZE];
|
||||
void lcd_test()
|
||||
{
|
||||
u8 i,j;
|
||||
float t=0;
|
||||
|
||||
LCD_ShowString(0,0,"Welcome TencentOS",WHITE,BLACK,32,0);
|
||||
LCD_ShowString(0,40,"LCD_W:",WHITE,BLACK,16,0);
|
||||
LCD_ShowIntNum(48,40,LCD_W,3,WHITE,BLACK,16);
|
||||
LCD_ShowString(80,40,"LCD_H:",WHITE,BLACK,16,0);
|
||||
LCD_ShowIntNum(128,40,LCD_H,3,WHITE,BLACK,16);
|
||||
LCD_ShowString(80,40,"LCD_H:",WHITE,BLACK,16,0);
|
||||
LCD_ShowString(0,70,"Increaseing Nun:",WHITE,BLACK,16,0);
|
||||
LCD_ShowFloatNum1(128,70,t,4,WHITE,BLACK,16);
|
||||
t+=0.11;
|
||||
for(j=0;j<3;j++)
|
||||
{
|
||||
for(i=0;i<6;i++)
|
||||
{
|
||||
LCD_ShowPicture(40*i,120+j*40,40,40,gImage_1);
|
||||
}
|
||||
}
|
||||
printf("lcd test finish\r\n");
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn show_sdcard_info
|
||||
*
|
||||
* @brief SD Card information.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void show_sdcard_info(void)
|
||||
{
|
||||
switch(SDCardInfo.CardType)
|
||||
{
|
||||
case SDIO_STD_CAPACITY_SD_CARD_V1_1:printf("Card Type:SDSC V1.1\r\n");break;
|
||||
case SDIO_STD_CAPACITY_SD_CARD_V2_0:printf("Card Type:SDSC V2.0\r\n");break;
|
||||
case SDIO_HIGH_CAPACITY_SD_CARD:printf("Card Type:SDHC V2.0\r\n");break;
|
||||
case SDIO_MULTIMEDIA_CARD:printf("Card Type:MMC Card\r\n");break;
|
||||
}
|
||||
printf("Card ManufacturerID:%d\r\n",SDCardInfo.SD_cid.ManufacturerID);
|
||||
printf("Card RCA:%d\r\n",SDCardInfo.RCA);
|
||||
printf("Card Capacity:%d MB\r\n",(u32)(SDCardInfo.CardCapacity>>20));
|
||||
printf("Card BlockSize:%d\r\n\r\n",SDCardInfo.CardBlockSize);
|
||||
}
|
||||
const u8 TEXT_Buf[]={"CH32V307 SPI FLASH W25Qxx"};
|
||||
void spi_flash_test(void)
|
||||
{
|
||||
u8 datap[SIZE];
|
||||
u16 Flash_Model;
|
||||
// SPI_Flash_Init();
|
||||
Delay_Ms(50);
|
||||
|
||||
Flash_Model = SPI_Flash_ReadID();
|
||||
|
||||
switch(Flash_Model)
|
||||
{
|
||||
case W25Q80:
|
||||
printf("W25Q80 OK!\r\n");
|
||||
break;
|
||||
|
||||
case W25Q16:
|
||||
printf("W25Q16 OK!\r\n");
|
||||
break;
|
||||
|
||||
case W25Q32:
|
||||
printf("W25Q32 OK!\r\n");
|
||||
break;
|
||||
|
||||
case W25Q64:
|
||||
printf("W25Q64 OK!\r\n");
|
||||
break;
|
||||
|
||||
case W25Q128:
|
||||
printf("W25Q128 OK!\r\n");
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("Fail!\r\n");
|
||||
break;
|
||||
}
|
||||
printf("Start Read W25Qxx before erase....\r\n");
|
||||
SPI_Flash_Read(datap,0x0,SIZE);
|
||||
for(int16_t i=0;i<SIZE;i++)
|
||||
{
|
||||
printf("%x ", datap[i] );
|
||||
}
|
||||
printf("\r\n" );
|
||||
|
||||
printf("Start Erase W25Qxx....\r\n");
|
||||
SPI_Flash_Erase_Sector(0);
|
||||
|
||||
Delay_Ms(500);
|
||||
|
||||
printf("Start Read W25Qxx....\r\n");
|
||||
SPI_Flash_Read(datap,0x0,SIZE);
|
||||
for(int16_t i=0;i<SIZE;i++)
|
||||
{
|
||||
printf("%x ", datap[i] );
|
||||
}
|
||||
printf("\r\n" );
|
||||
|
||||
Delay_Ms(500);
|
||||
|
||||
printf("Start Write W25Qxx....\r\n");
|
||||
SPI_Flash_Write((u8*)TEXT_Buf,0,SIZE);
|
||||
|
||||
Delay_Ms(500);
|
||||
|
||||
SPI_Flash_Read(datap,0x0,SIZE);
|
||||
printf("%s\r\n", datap );
|
||||
|
||||
if(memcmp(TEXT_Buf, datap, SIZE))
|
||||
{
|
||||
LCD_ShowString(16,16+16+16,"SPI Flash: Fail",WHITE,BLACK,16,0);
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD_ShowString(16,16+16+16,"SPI Flash: OK",WHITE,BLACK,16,0);
|
||||
}
|
||||
}
|
||||
|
||||
u8 buf[512];
|
||||
u8 Readbuf[512];
|
||||
|
||||
/* sdcard test */
|
||||
void SD_Card_test(void)
|
||||
{
|
||||
u32 i;
|
||||
u32 Sector_Nums;
|
||||
|
||||
while(SD_Init())
|
||||
{
|
||||
printf("SD Card Error!\r\n");
|
||||
delay_ms(1000);
|
||||
}
|
||||
|
||||
show_sdcard_info();
|
||||
|
||||
printf("SD Card OK\r\n");
|
||||
Sector_Nums = ((u32)(SDCardInfo.CardCapacity>>20))/2;
|
||||
printf("Sector_Nums:%d\r\n", Sector_Nums);
|
||||
|
||||
for(i=0; i<512; i++){
|
||||
buf[i] = i;
|
||||
}
|
||||
|
||||
for(i=0; i<Sector_Nums/2; i++)
|
||||
{
|
||||
if(SD_WriteDisk(buf,i,1)) {printf("Wr %d sector fail\n", i);}
|
||||
if(SD_ReadDisk(Readbuf,i,1)){ printf("Rd %d sector fail\n", i);}
|
||||
|
||||
if(memcmp(buf, Readbuf, 512))
|
||||
{
|
||||
printf(" %d sector Verify fail\n", i);
|
||||
LCD_ShowString(16,16+16+16+16,"SD Sector:FAIL",WHITE,BLACK,16,0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i==Sector_Nums/2)
|
||||
{
|
||||
LCD_ShowString(16,16+16+16+16+16,"SD: OK",WHITE,BLACK,16,0);
|
||||
printf("SD OK\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
LCD_ShowString(16,16+16+16+16+16,"SD ALL: FAIL",WHITE,BLACK,16,0);
|
||||
}
|
||||
}
|
||||
|
||||
#define APPLICATION_TASK_STK_SIZE 4096
|
||||
k_task_t application_task;
|
||||
__aligned(4) uint8_t application_task_stk[APPLICATION_TASK_STK_SIZE];
|
||||
|
||||
extern void application_entry1(void *arg);
|
||||
|
||||
void task1_entry(void *arg)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
printf("###I am task1\r\n");
|
||||
tos_task_delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
void task2_entry(void *arg)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
printf("***I am task2\r\n");
|
||||
tos_task_delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
extern void application_entry(void *arg);
|
||||
|
||||
volatile uint8_t key=0;
|
||||
/*******************************************************************************
|
||||
* Function Name : main
|
||||
* Description : Main program.
|
||||
|
|
@ -65,51 +238,41 @@ void task2_entry(void *arg)
|
|||
*******************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
u8 i,j;
|
||||
float t=0;
|
||||
Delay_Init();
|
||||
USART_Printf_Init(115200);
|
||||
printf("SystemClk:%d\r\n",SystemCoreClock);
|
||||
led_init();
|
||||
LCD_Init();//LCD³õʼ»¯
|
||||
LCD_Fill(0,0,LCD_W,LCD_H,WHITE);
|
||||
|
||||
led_key_init();
|
||||
LCD_Init();
|
||||
SPI_Flash_Init();
|
||||
printf("Welcome to TencentOS tiny(%s)\r\n", TOS_VERSION);
|
||||
LCD_ShowString(0,0,"Welcome to TencentOS",RED,WHITE,16,0);
|
||||
LCD_Fill(0,0,LCD_W,LCD_H,BLACK);
|
||||
LCD_ShowString(0,0,"Welcome to TencentOS",WHITE,BLACK,16,0);
|
||||
|
||||
tos_knl_init();
|
||||
tos_task_create(&application_task, "application_task", application_entry1, NULL, 4, application_task_stk, APPLICATION_TASK_STK_SIZE, 0);
|
||||
//tos_task_create(&task1, "task1", task1_entry, NULL, 3, task1_stk, TASK1_STK_SIZE, 0); // Create task1
|
||||
//tos_task_create(&task2, "task2", task2_entry, NULL, 3, task2_stk, TASK2_STK_SIZE, 0);// Create task2
|
||||
tos_task_create(&application_task, "application_task", application_entry, NULL, 4, application_task_stk, APPLICATION_TASK_STK_SIZE, 0);
|
||||
tos_knl_start();
|
||||
|
||||
printf("should not run at here!\r\n");
|
||||
while(!key)
|
||||
{
|
||||
key=get_key();
|
||||
}
|
||||
|
||||
while(1)
|
||||
{
|
||||
LCD_ShowString(0,0,"Welcome TencentOS",RED,WHITE,32,0);
|
||||
LCD_ShowString(0,40,"LCD_W:",RED,WHITE,16,0);
|
||||
LCD_ShowIntNum(48,40,LCD_W,3,RED,WHITE,16);
|
||||
LCD_ShowString(80,40,"LCD_H:",RED,WHITE,16,0);
|
||||
LCD_ShowIntNum(128,40,LCD_H,3,RED,WHITE,16);
|
||||
LCD_ShowString(80,40,"LCD_H:",RED,WHITE,16,0);
|
||||
LCD_ShowString(0,70,"Increaseing Nun:",RED,WHITE,16,0);
|
||||
LCD_ShowFloatNum1(128,70,t,4,RED,WHITE,16);
|
||||
t+=0.11;
|
||||
for(j=0;j<3;j++)
|
||||
{
|
||||
for(i=0;i<6;i++)
|
||||
{
|
||||
LCD_ShowPicture(40*i,120+j*40,40,40,gImage_1);
|
||||
printf("pic test\r\n");
|
||||
}
|
||||
}
|
||||
printf("lcd test\r\n");
|
||||
}
|
||||
switch(key)
|
||||
{
|
||||
case 1:
|
||||
lcd_test();
|
||||
break;
|
||||
case 2:
|
||||
LCD_Fill(0,0,LCD_W,LCD_H,BLACK);
|
||||
spi_flash_test();
|
||||
SD_Card_test();
|
||||
break;
|
||||
case 3:
|
||||
LCD_Fill(0,0,LCD_W,LCD_H,BLACK);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
while(1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,348 @@
|
|||
/********************************** (C) COPYRIGHT *******************************
|
||||
* File Name : sdio.h
|
||||
* Author : WCH
|
||||
* Version : V1.0.0
|
||||
* Date : 2021/06/06
|
||||
* Description : This file contains the headers of the SDIO.
|
||||
*******************************************************************************/
|
||||
#ifndef __SDIO_H
|
||||
#define __SDIO_H
|
||||
|
||||
#include"debug.h"
|
||||
|
||||
#define delay_ms(x) Delay_Ms(x)
|
||||
|
||||
|
||||
/*SDIO flag*/
|
||||
#define SDIO_FLAG_CCRCFAIL ((uint32_t)0x00000001)
|
||||
#define SDIO_FLAG_DCRCFAIL ((uint32_t)0x00000002)
|
||||
#define SDIO_FLAG_CTIMEOUT ((uint32_t)0x00000004)
|
||||
#define SDIO_FLAG_DTIMEOUT ((uint32_t)0x00000008)
|
||||
#define SDIO_FLAG_TXUNDERR ((uint32_t)0x00000010)
|
||||
#define SDIO_FLAG_RXOVERR ((uint32_t)0x00000020)
|
||||
#define SDIO_FLAG_CMDREND ((uint32_t)0x00000040)
|
||||
#define SDIO_FLAG_CMDSENT ((uint32_t)0x00000080)
|
||||
#define SDIO_FLAG_DATAEND ((uint32_t)0x00000100)
|
||||
#define SDIO_FLAG_STBITERR ((uint32_t)0x00000200)
|
||||
#define SDIO_FLAG_DBCKEND ((uint32_t)0x00000400)
|
||||
#define SDIO_FLAG_CMDACT ((uint32_t)0x00000800)
|
||||
#define SDIO_FLAG_TXACT ((uint32_t)0x00001000)
|
||||
#define SDIO_FLAG_RXACT ((uint32_t)0x00002000)
|
||||
#define SDIO_FLAG_TXFIFOHE ((uint32_t)0x00004000)
|
||||
#define SDIO_FLAG_RXFIFOHF ((uint32_t)0x00008000)
|
||||
#define SDIO_FLAG_TXFIFOF ((uint32_t)0x00010000)
|
||||
#define SDIO_FLAG_RXFIFOF ((uint32_t)0x00020000)
|
||||
#define SDIO_FLAG_TXFIFOE ((uint32_t)0x00040000)
|
||||
#define SDIO_FLAG_RXFIFOE ((uint32_t)0x00080000)
|
||||
#define SDIO_FLAG_TXDAVL ((uint32_t)0x00100000)
|
||||
#define SDIO_FLAG_RXDAVL ((uint32_t)0x00200000)
|
||||
#define SDIO_FLAG_SDIOIT ((uint32_t)0x00400000)
|
||||
#define SDIO_FLAG_CEATAEND ((uint32_t)0x00800000)
|
||||
|
||||
/* SDIO clock */
|
||||
#define SDIO_INIT_CLK_DIV 0xFE
|
||||
#define SDIO_TRANSFER_CLK_DIV 0x00
|
||||
|
||||
/* SDIO work mode */
|
||||
#define SD_POLLING_MODE 0
|
||||
#define SD_DMA_MODE 1
|
||||
|
||||
/*SDIO Err define */
|
||||
typedef enum
|
||||
{
|
||||
/* special err */
|
||||
SD_CMD_CRC_FAIL = (1),
|
||||
SD_DATA_CRC_FAIL = (2),
|
||||
SD_CMD_RSP_TIMEOUT = (3),
|
||||
SD_DATA_TIMEOUT = (4),
|
||||
SD_TX_UNDERRUN = (5),
|
||||
SD_RX_OVERRUN = (6),
|
||||
SD_START_BIT_ERR = (7),
|
||||
SD_CMD_OUT_OF_RANGE = (8),
|
||||
SD_ADDR_MISALIGNED = (9),
|
||||
SD_BLOCK_LEN_ERR = (10),
|
||||
SD_ERASE_SEQ_ERR = (11),
|
||||
SD_BAD_ERASE_PARAM = (12),
|
||||
SD_WRITE_PROT_VIOLATION = (13),
|
||||
SD_LOCK_UNLOCK_FAILED = (14),
|
||||
SD_COM_CRC_FAILED = (15),
|
||||
SD_ILLEGAL_CMD = (16),
|
||||
SD_CARD_ECC_FAILED = (17),
|
||||
SD_CC_ERROR = (18),
|
||||
SD_GENERAL_UNKNOWN_ERROR = (19),
|
||||
SD_STREAM_READ_UNDERRUN = (20),
|
||||
SD_STREAM_WRITE_OVERRUN = (21),
|
||||
SD_CID_CSD_OVERWRITE = (22),
|
||||
SD_WP_ERASE_SKIP = (23),
|
||||
SD_CARD_ECC_DISABLED = (24),
|
||||
SD_ERASE_RESET = (25),
|
||||
SD_AKE_SEQ_ERROR = (26),
|
||||
SD_INVALID_VOLTRANGE = (27),
|
||||
SD_ADDR_OUT_OF_RANGE = (28),
|
||||
SD_SWITCH_ERROR = (29),
|
||||
SD_SDIO_DISABLED = (30),
|
||||
SD_SDIO_FUNCTION_BUSY = (31),
|
||||
SD_SDIO_FUNCTION_FAILED = (32),
|
||||
SD_SDIO_UNKNOWN_FUNCTION = (33),
|
||||
/* Standard err */
|
||||
SD_INTERNAL_ERROR,
|
||||
SD_NOT_CONFIGURED,
|
||||
SD_REQUEST_PENDING,
|
||||
SD_REQUEST_NOT_APPLICABLE,
|
||||
SD_INVALID_PARAMETER,
|
||||
SD_UNSUPPORTED_FEATURE,
|
||||
SD_UNSUPPORTED_HW,
|
||||
SD_ERROR,
|
||||
SD_OK = 0
|
||||
} SD_Error;
|
||||
|
||||
/*SD——CSD*/
|
||||
typedef struct
|
||||
{
|
||||
u8 CSDStruct;
|
||||
u8 SysSpecVersion;
|
||||
u8 Reserved1;
|
||||
u8 TAAC;
|
||||
u8 NSAC;
|
||||
u8 MaxBusClkFrec;
|
||||
u16 CardComdClasses;
|
||||
u8 RdBlockLen;
|
||||
u8 PartBlockRead;
|
||||
u8 WrBlockMisalign;
|
||||
u8 RdBlockMisalign;
|
||||
u8 DSRImpl;
|
||||
u8 Reserved2;
|
||||
u32 DeviceSize;
|
||||
u8 MaxRdCurrentVDDMin;
|
||||
u8 MaxRdCurrentVDDMax;
|
||||
u8 MaxWrCurrentVDDMin;
|
||||
u8 MaxWrCurrentVDDMax;
|
||||
u8 DeviceSizeMul;
|
||||
u8 EraseGrSize;
|
||||
u8 EraseGrMul;
|
||||
u8 WrProtectGrSize;
|
||||
u8 WrProtectGrEnable;
|
||||
u8 ManDeflECC;
|
||||
u8 WrSpeedFact;
|
||||
u8 MaxWrBlockLen;
|
||||
u8 WriteBlockPaPartial;
|
||||
u8 Reserved3;
|
||||
u8 ContentProtectAppli;
|
||||
u8 FileFormatGrouop;
|
||||
u8 CopyFlag;
|
||||
u8 PermWrProtect;
|
||||
u8 TempWrProtect;
|
||||
u8 FileFormat;
|
||||
u8 ECC;
|
||||
u8 CSD_CRC;
|
||||
u8 Reserved4;
|
||||
} SD_CSD;
|
||||
|
||||
/*SD——CID*/
|
||||
typedef struct
|
||||
{
|
||||
u8 ManufacturerID;
|
||||
u16 OEM_AppliID;
|
||||
u32 ProdName1;
|
||||
u8 ProdName2;
|
||||
u8 ProdRev;
|
||||
u32 ProdSN;
|
||||
u8 Reserved1;
|
||||
u16 ManufactDate;
|
||||
u8 CID_CRC;
|
||||
u8 Reserved2;
|
||||
} SD_CID;
|
||||
|
||||
/* SD statue */
|
||||
typedef enum
|
||||
{
|
||||
SD_CARD_READY = ((uint32_t)0x00000001),
|
||||
SD_CARD_IDENTIFICATION = ((uint32_t)0x00000002),
|
||||
SD_CARD_STANDBY = ((uint32_t)0x00000003),
|
||||
SD_CARD_TRANSFER = ((uint32_t)0x00000004),
|
||||
SD_CARD_SENDING = ((uint32_t)0x00000005),
|
||||
SD_CARD_RECEIVING = ((uint32_t)0x00000006),
|
||||
SD_CARD_PROGRAMMING = ((uint32_t)0x00000007),
|
||||
SD_CARD_DISCONNECTED = ((uint32_t)0x00000008),
|
||||
SD_CARD_ERROR = ((uint32_t)0x000000FF)
|
||||
}SDCardState;
|
||||
|
||||
/* SD informatiion */
|
||||
typedef struct
|
||||
{
|
||||
SD_CSD SD_csd;
|
||||
SD_CID SD_cid;
|
||||
long long CardCapacity;
|
||||
u32 CardBlockSize;
|
||||
u16 RCA;
|
||||
u8 CardType;
|
||||
} SD_CardInfo;
|
||||
extern SD_CardInfo SDCardInfo;
|
||||
|
||||
/* SDIO instruction*/
|
||||
#define SD_CMD_GO_IDLE_STATE ((u8)0)
|
||||
#define SD_CMD_SEND_OP_COND ((u8)1)
|
||||
#define SD_CMD_ALL_SEND_CID ((u8)2)
|
||||
#define SD_CMD_SET_REL_ADDR ((u8)3)
|
||||
#define SD_CMD_SET_DSR ((u8)4)
|
||||
#define SD_CMD_SDIO_SEN_OP_COND ((u8)5)
|
||||
#define SD_CMD_HS_SWITCH ((u8)6)
|
||||
#define SD_CMD_SEL_DESEL_CARD ((u8)7)
|
||||
#define SD_CMD_HS_SEND_EXT_CSD ((u8)8)
|
||||
#define SD_CMD_SEND_CSD ((u8)9)
|
||||
#define SD_CMD_SEND_CID ((u8)10)
|
||||
#define SD_CMD_READ_DAT_UNTIL_STOP ((u8)11)
|
||||
#define SD_CMD_STOP_TRANSMISSION ((u8)12)
|
||||
#define SD_CMD_SEND_STATUS ((u8)13)
|
||||
#define SD_CMD_HS_BUSTEST_READ ((u8)14)
|
||||
#define SD_CMD_GO_INACTIVE_STATE ((u8)15)
|
||||
#define SD_CMD_SET_BLOCKLEN ((u8)16)
|
||||
#define SD_CMD_READ_SINGLE_BLOCK ((u8)17)
|
||||
#define SD_CMD_READ_MULT_BLOCK ((u8)18)
|
||||
#define SD_CMD_HS_BUSTEST_WRITE ((u8)19)
|
||||
#define SD_CMD_WRITE_DAT_UNTIL_STOP ((u8)20)
|
||||
#define SD_CMD_SET_BLOCK_COUNT ((u8)23)
|
||||
#define SD_CMD_WRITE_SINGLE_BLOCK ((u8)24)
|
||||
#define SD_CMD_WRITE_MULT_BLOCK ((u8)25)
|
||||
#define SD_CMD_PROG_CID ((u8)26)
|
||||
#define SD_CMD_PROG_CSD ((u8)27)
|
||||
#define SD_CMD_SET_WRITE_PROT ((u8)28)
|
||||
#define SD_CMD_CLR_WRITE_PROT ((u8)29)
|
||||
#define SD_CMD_SEND_WRITE_PROT ((u8)30)
|
||||
#define SD_CMD_SD_ERASE_GRP_START ((u8)32)
|
||||
#define SD_CMD_SD_ERASE_GRP_END ((u8)33)
|
||||
#define SD_CMD_ERASE_GRP_START ((u8)35)
|
||||
#define SD_CMD_ERASE_GRP_END ((u8)36)
|
||||
#define SD_CMD_ERASE ((u8)38)
|
||||
#define SD_CMD_FAST_IO ((u8)39)
|
||||
#define SD_CMD_GO_IRQ_STATE ((u8)40)
|
||||
#define SD_CMD_LOCK_UNLOCK ((u8)42)
|
||||
#define SD_CMD_APP_CMD ((u8)55)
|
||||
#define SD_CMD_GEN_CMD ((u8)56)
|
||||
#define SD_CMD_NO_CMD ((u8)64)
|
||||
|
||||
/*Following commands are SD Card Specific commands.
|
||||
SDIO_APP_CMD :CMD55 should be sent before sending these commands.
|
||||
*/
|
||||
#define SD_CMD_APP_SD_SET_BUSWIDTH ((u8)6)
|
||||
#define SD_CMD_SD_APP_STAUS ((u8)13)
|
||||
#define SD_CMD_SD_APP_SEND_NUM_WRITE_BLOCKS ((u8)22)
|
||||
#define SD_CMD_SD_APP_OP_COND ((u8)41)
|
||||
#define SD_CMD_SD_APP_SET_CLR_CARD_DETECT ((u8)42)
|
||||
#define SD_CMD_SD_APP_SEND_SCR ((u8)51)
|
||||
#define SD_CMD_SDIO_RW_DIRECT ((u8)52)
|
||||
#define SD_CMD_SDIO_RW_EXTENDED ((u8)53)
|
||||
|
||||
/*Following commands are SD Card Specific security commands.
|
||||
SDIO_APP_CMD should be sent before sending these commands.
|
||||
*/
|
||||
#define SD_CMD_SD_APP_GET_MKB ((u8)43)
|
||||
#define SD_CMD_SD_APP_GET_MID ((u8)44)
|
||||
#define SD_CMD_SD_APP_SET_CER_RN1 ((u8)45)
|
||||
#define SD_CMD_SD_APP_GET_CER_RN2 ((u8)46)
|
||||
#define SD_CMD_SD_APP_SET_CER_RES2 ((u8)47)
|
||||
#define SD_CMD_SD_APP_GET_CER_RES1 ((u8)48)
|
||||
#define SD_CMD_SD_APP_SECURE_READ_MULTIPLE_BLOCK ((u8)18)
|
||||
#define SD_CMD_SD_APP_SECURE_WRITE_MULTIPLE_BLOCK ((u8)25)
|
||||
#define SD_CMD_SD_APP_SECURE_ERASE ((u8)38)
|
||||
#define SD_CMD_SD_APP_CHANGE_SECURE_AREA ((u8)49)
|
||||
#define SD_CMD_SD_APP_SECURE_WRITE_MKB ((u8)48)
|
||||
|
||||
/* SD definition */
|
||||
#define SDIO_STD_CAPACITY_SD_CARD_V1_1 ((u32)0x00000000)
|
||||
#define SDIO_STD_CAPACITY_SD_CARD_V2_0 ((u32)0x00000001)
|
||||
#define SDIO_HIGH_CAPACITY_SD_CARD ((u32)0x00000002)
|
||||
#define SDIO_MULTIMEDIA_CARD ((u32)0x00000003)
|
||||
#define SDIO_SECURE_DIGITAL_IO_CARD ((u32)0x00000004)
|
||||
#define SDIO_HIGH_SPEED_MULTIMEDIA_CARD ((u32)0x00000005)
|
||||
#define SDIO_SECURE_DIGITAL_IO_COMBO_CARD ((u32)0x00000006)
|
||||
#define SDIO_HIGH_CAPACITY_MMC_CARD ((u32)0x00000007)
|
||||
|
||||
/* SDIO parameter definition */
|
||||
#define SDIO_STATIC_FLAGS ((u32)0x000005FF)
|
||||
#define SDIO_CMD0TIMEOUT ((u32)0x00010000)
|
||||
#define SDIO_DATATIMEOUT ((u32)0xFFFFFFFF)
|
||||
#define SDIO_FIFO_Address ((u32)0x40018080)
|
||||
|
||||
/* Mask for errors Card Status R1 (OCR Register) */
|
||||
#define SD_OCR_ADDR_OUT_OF_RANGE ((u32)0x80000000)
|
||||
#define SD_OCR_ADDR_MISALIGNED ((u32)0x40000000)
|
||||
#define SD_OCR_BLOCK_LEN_ERR ((u32)0x20000000)
|
||||
#define SD_OCR_ERASE_SEQ_ERR ((u32)0x10000000)
|
||||
#define SD_OCR_BAD_ERASE_PARAM ((u32)0x08000000)
|
||||
#define SD_OCR_WRITE_PROT_VIOLATION ((u32)0x04000000)
|
||||
#define SD_OCR_LOCK_UNLOCK_FAILED ((u32)0x01000000)
|
||||
#define SD_OCR_COM_CRC_FAILED ((u32)0x00800000)
|
||||
#define SD_OCR_ILLEGAL_CMD ((u32)0x00400000)
|
||||
#define SD_OCR_CARD_ECC_FAILED ((u32)0x00200000)
|
||||
#define SD_OCR_CC_ERROR ((u32)0x00100000)
|
||||
#define SD_OCR_GENERAL_UNKNOWN_ERROR ((u32)0x00080000)
|
||||
#define SD_OCR_STREAM_READ_UNDERRUN ((u32)0x00040000)
|
||||
#define SD_OCR_STREAM_WRITE_OVERRUN ((u32)0x00020000)
|
||||
#define SD_OCR_CID_CSD_OVERWRIETE ((u32)0x00010000)
|
||||
#define SD_OCR_WP_ERASE_SKIP ((u32)0x00008000)
|
||||
#define SD_OCR_CARD_ECC_DISABLED ((u32)0x00004000)
|
||||
#define SD_OCR_ERASE_RESET ((u32)0x00002000)
|
||||
#define SD_OCR_AKE_SEQ_ERROR ((u32)0x00000008)
|
||||
#define SD_OCR_ERRORBITS ((u32)0xFDFFE008)
|
||||
|
||||
/* Masks for R6 Response */
|
||||
#define SD_R6_GENERAL_UNKNOWN_ERROR ((u32)0x00002000)
|
||||
#define SD_R6_ILLEGAL_CMD ((u32)0x00004000)
|
||||
#define SD_R6_COM_CRC_FAILED ((u32)0x00008000)
|
||||
|
||||
#define SD_VOLTAGE_WINDOW_SD ((u32)0x80100000)
|
||||
#define SD_HIGH_CAPACITY ((u32)0x40000000)
|
||||
#define SD_STD_CAPACITY ((u32)0x00000000)
|
||||
#define SD_CHECK_PATTERN ((u32)0x000001AA)
|
||||
#define SD_VOLTAGE_WINDOW_MMC ((u32)0x80FF8000)
|
||||
|
||||
#define SD_MAX_VOLT_TRIAL ((u32)0x0000FFFF)
|
||||
#define SD_ALLZERO ((u32)0x00000000)
|
||||
|
||||
#define SD_WIDE_BUS_SUPPORT ((u32)0x00040000)
|
||||
#define SD_SINGLE_BUS_SUPPORT ((u32)0x00010000)
|
||||
#define SD_CARD_LOCKED ((u32)0x02000000)
|
||||
#define SD_CARD_PROGRAMMING ((u32)0x00000007)
|
||||
#define SD_CARD_RECEIVING ((u32)0x00000006)
|
||||
#define SD_DATATIMEOUT ((u32)0xFFFFFFFF)
|
||||
#define SD_0TO7BITS ((u32)0x000000FF)
|
||||
#define SD_8TO15BITS ((u32)0x0000FF00)
|
||||
#define SD_16TO23BITS ((u32)0x00FF0000)
|
||||
#define SD_24TO31BITS ((u32)0xFF000000)
|
||||
#define SD_MAX_DATA_LENGTH ((u32)0x01FFFFFF)
|
||||
|
||||
#define SD_HALFFIFO ((u32)0x00000008)
|
||||
#define SD_HALFFIFOBYTES ((u32)0x00000020)
|
||||
|
||||
/*Command Class Supported */
|
||||
#define SD_CCCC_LOCK_UNLOCK ((u32)0x00000080)
|
||||
#define SD_CCCC_WRITE_PROT ((u32)0x00000040)
|
||||
#define SD_CCCC_ERASE ((u32)0x00000020)
|
||||
|
||||
/*CMD8*/
|
||||
#define SDIO_SEND_IF_COND ((u32)0x00000008)
|
||||
|
||||
SD_Error SD_Init(void);
|
||||
void SDIO_Clock_Set(u8 clkdiv);
|
||||
void SDIO_Send_Cmd(u8 cmdindex,u8 waitrsp,u32 arg);
|
||||
void SDIO_Send_Data_Cfg(u32 datatimeout,u32 datalen,u8 blksize,u8 dir);
|
||||
SD_Error SD_PowerON(void);
|
||||
SD_Error SD_PowerOFF(void);
|
||||
SD_Error SD_InitializeCards(void);
|
||||
SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo);
|
||||
SD_Error SD_EnableWideBusOperation(u32 wmode);
|
||||
SD_Error SD_SetDeviceMode(u32 mode);
|
||||
SD_Error SD_SelectDeselect(u32 addr);
|
||||
SD_Error SD_SendStatus(uint32_t *pcardstatus);
|
||||
SDCardState SD_GetState(void);
|
||||
SD_Error SD_ReadBlock(u8 *buf,long long addr,u16 blksize);
|
||||
SD_Error SD_ReadMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks);
|
||||
SD_Error SD_WriteBlock(u8 *buf,long long addr, u16 blksize);
|
||||
SD_Error SD_WriteMultiBlocks(u8 *buf,long long addr,u16 blksize,u32 nblks);
|
||||
SD_Error SD_ProcessIRQSrc(void);
|
||||
void SD_DMA_Config(u32*mbuf,u32 bufsize,u32 dir);
|
||||
u8 SD_ReadDisk(u8*buf,u32 sector,u8 cnt);
|
||||
u8 SD_WriteDisk(u8*buf,u32 sector,u8 cnt);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,468 @@
|
|||
#include "spi_flash.h"
|
||||
#include "debug.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI1_ReadWriteByte
|
||||
*
|
||||
* @brief SPI1 read or write one byte.
|
||||
*
|
||||
* @param TxData - write one byte data.
|
||||
*
|
||||
* @return Read one byte data.
|
||||
*/
|
||||
u8 SPI1_ReadWriteByte(u8 TxData)
|
||||
{
|
||||
u8 i=0;
|
||||
|
||||
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET)
|
||||
{
|
||||
i++;
|
||||
if(i>200)return 0;
|
||||
}
|
||||
|
||||
SPI_I2S_SendData(SPI3, TxData);
|
||||
i=0;
|
||||
|
||||
while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET)
|
||||
{
|
||||
i++;
|
||||
if(i>200)return 0;
|
||||
}
|
||||
|
||||
return SPI_I2S_ReceiveData(SPI3);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_Init
|
||||
*
|
||||
* @brief Configuring the SPI for operation flash.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_Flash_Init(void)
|
||||
{
|
||||
GPIO_InitTypeDef GPIO_InitStructure={0};
|
||||
SPI_InitTypeDef SPI_InitStructure={0};
|
||||
|
||||
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA/*|RCC_APB2Periph_SPI1*/|RCC_APB2Periph_GPIOB, ENABLE );
|
||||
RCC_APB1PeriphClockCmd( RCC_APB1Periph_SPI3, ENABLE );
|
||||
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init(GPIOA, &GPIO_InitStructure);
|
||||
GPIO_SetBits(GPIOA, GPIO_Pin_15); //SPI3_NSS
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init( GPIOB, &GPIO_InitStructure );//SPI3_SCK
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
|
||||
GPIO_Init( GPIOB, &GPIO_InitStructure );//SPI3_MISO
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
|
||||
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
|
||||
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
|
||||
GPIO_Init( GPIOB, &GPIO_InitStructure );//SPI3_MOSI
|
||||
|
||||
SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;
|
||||
SPI_InitStructure.SPI_Mode = SPI_Mode_Master;
|
||||
SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;
|
||||
SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;
|
||||
SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;
|
||||
SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;
|
||||
SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_16;
|
||||
SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;
|
||||
SPI_InitStructure.SPI_CRCPolynomial = 7;
|
||||
SPI_Init(SPI3, &SPI_InitStructure);
|
||||
|
||||
SPI_Cmd(SPI3, ENABLE);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_ReadSR
|
||||
*
|
||||
* @brief Read W25Qxx status register.
|
||||
* ¡ª¡ªBIT7 6 5 4 3 2 1 0
|
||||
* ¡ª¡ªSPR RV TB BP2 BP1 BP0 WEL BUSY
|
||||
*
|
||||
* @return byte - status register value.
|
||||
*/
|
||||
u8 SPI_Flash_ReadSR(void)
|
||||
{
|
||||
u8 byte=0;
|
||||
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
SPI1_ReadWriteByte(W25X_ReadStatusReg);
|
||||
byte=SPI1_ReadWriteByte(0Xff);
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
|
||||
return byte;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_FLASH_Write_SR
|
||||
*
|
||||
* @brief Write W25Qxx status register.
|
||||
*
|
||||
* @param sr - status register value.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_FLASH_Write_SR(u8 sr)
|
||||
{
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
SPI1_ReadWriteByte(W25X_WriteStatusReg);
|
||||
SPI1_ReadWriteByte(sr);
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_Wait_Busy
|
||||
*
|
||||
* @brief Wait flash free.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_Flash_Wait_Busy(void)
|
||||
{
|
||||
while((SPI_Flash_ReadSR()&0x01)==0x01);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_FLASH_Write_Enable
|
||||
*
|
||||
* @brief Enable flash write.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_FLASH_Write_Enable(void)
|
||||
{
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
SPI1_ReadWriteByte(W25X_WriteEnable);
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_FLASH_Write_Disable
|
||||
*
|
||||
* @brief Disable flash write.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_FLASH_Write_Disable(void)
|
||||
{
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
SPI1_ReadWriteByte(W25X_WriteDisable);
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_ReadID
|
||||
*
|
||||
* @brief Read flash ID.
|
||||
*
|
||||
* @return Temp - FLASH ID.
|
||||
*/
|
||||
u16 SPI_Flash_ReadID(void)
|
||||
{
|
||||
u16 Temp = 0;
|
||||
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
Delay_Ms(10);
|
||||
SPI1_ReadWriteByte(W25X_ManufactDeviceID);
|
||||
SPI1_ReadWriteByte(0x00);
|
||||
SPI1_ReadWriteByte(0x00);
|
||||
SPI1_ReadWriteByte(0x00);
|
||||
Temp|=SPI1_ReadWriteByte(0xFF)<<8;
|
||||
Temp|=SPI1_ReadWriteByte(0xFF);
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
|
||||
return Temp;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_Erase_Sector
|
||||
*
|
||||
* @brief Erase one sector(4Kbyte).
|
||||
*
|
||||
* @param Dst_Addr - 0 ¡ª¡ª 2047
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_Flash_Erase_Sector(u32 Dst_Addr)
|
||||
{
|
||||
Dst_Addr*=4096;
|
||||
SPI_FLASH_Write_Enable();
|
||||
SPI_Flash_Wait_Busy();
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
SPI1_ReadWriteByte(W25X_SectorErase);
|
||||
SPI1_ReadWriteByte((u8)((Dst_Addr)>>16));
|
||||
SPI1_ReadWriteByte((u8)((Dst_Addr)>>8));
|
||||
SPI1_ReadWriteByte((u8)Dst_Addr);
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
SPI_Flash_Wait_Busy();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_Erase_Sector
|
||||
*
|
||||
* @brief Erase amount sector(4Kbyte).
|
||||
*
|
||||
* @param addr - Initial address(24bit).
|
||||
* size - Data length.
|
||||
*
|
||||
* @return errcode
|
||||
*/
|
||||
int SPI_Flash_Erase(u32 Addr, int size)
|
||||
{
|
||||
uint32_t begin;
|
||||
uint32_t end;
|
||||
int i;
|
||||
|
||||
if (size < 0
|
||||
|| Addr > SPI_FLASH_TOTAL_SIZE
|
||||
|| Addr + size > SPI_FLASH_TOTAL_SIZE)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
begin = Addr / SPI_FLASH_SECTOR * SPI_FLASH_SECTOR;
|
||||
end = (Addr + size - 1) / SPI_FLASH_SECTOR * SPI_FLASH_SECTOR;
|
||||
|
||||
for (i = begin; i <= end; i += SPI_FLASH_SECTOR)
|
||||
{
|
||||
SPI_Flash_Erase_Sector(i);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_Read
|
||||
*
|
||||
* @brief Read data from flash.
|
||||
*
|
||||
* @param pBuffer -
|
||||
* ReadAddr -Initial address(24bit).
|
||||
* size - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 size)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
SPI1_ReadWriteByte(W25X_ReadData);
|
||||
SPI1_ReadWriteByte((u8)((ReadAddr)>>16));
|
||||
SPI1_ReadWriteByte((u8)((ReadAddr)>>8));
|
||||
SPI1_ReadWriteByte((u8)ReadAddr);
|
||||
|
||||
for(i=0;i<size;i++)
|
||||
{
|
||||
pBuffer[i]=SPI1_ReadWriteByte(0XFF);
|
||||
}
|
||||
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_Write_Page
|
||||
*
|
||||
* @brief Write data by one page.
|
||||
*
|
||||
* @param pBuffer -
|
||||
* WriteAddr - Initial address(24bit).
|
||||
* size - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_Flash_Write_Page(u8* pBuffer,u32 WriteAddr,u16 size)
|
||||
{
|
||||
u16 i;
|
||||
|
||||
SPI_FLASH_Write_Enable();
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
SPI1_ReadWriteByte(W25X_PageProgram);
|
||||
SPI1_ReadWriteByte((u8)((WriteAddr)>>16));
|
||||
SPI1_ReadWriteByte((u8)((WriteAddr)>>8));
|
||||
SPI1_ReadWriteByte((u8)WriteAddr);
|
||||
|
||||
for(i=0;i<size;i++)
|
||||
{
|
||||
SPI1_ReadWriteByte(pBuffer[i]);
|
||||
}
|
||||
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
SPI_Flash_Wait_Busy();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_Write_NoCheck
|
||||
*
|
||||
* @brief Write data to flash.(need Erase)
|
||||
* All data in address rang is 0xFF.
|
||||
*
|
||||
* @param pBuffer -
|
||||
* WriteAddr - Initial address(24bit).
|
||||
* size - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_Flash_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 size)
|
||||
{
|
||||
u16 pageremain;
|
||||
|
||||
pageremain=256-WriteAddr%256;
|
||||
|
||||
if(size<=pageremain)pageremain=size;
|
||||
|
||||
while(1)
|
||||
{
|
||||
SPI_Flash_Write_Page(pBuffer,WriteAddr,pageremain);
|
||||
|
||||
if(size==pageremain)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
pBuffer+=pageremain;
|
||||
WriteAddr+=pageremain;
|
||||
size-=pageremain;
|
||||
|
||||
if(size>256)pageremain=256;
|
||||
else pageremain=size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_Write
|
||||
*
|
||||
* @brief Write data to flash.(no need Erase)
|
||||
*
|
||||
* @param pBuffer -
|
||||
* WriteAddr - Initial address(24bit).
|
||||
* size - Data length.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 size)
|
||||
{
|
||||
u32 secpos;
|
||||
u16 secoff;
|
||||
u16 secremain;
|
||||
u16 i;
|
||||
|
||||
secpos=WriteAddr/4096;
|
||||
secoff=WriteAddr%4096;
|
||||
secremain=4096-secoff;
|
||||
|
||||
if(size<=secremain)secremain=size;
|
||||
|
||||
while(1)
|
||||
{
|
||||
SPI_Flash_Read(SPI_FLASH_BUF,secpos*4096,4096);
|
||||
|
||||
for(i=0;i<secremain;i++)
|
||||
{
|
||||
if(SPI_FLASH_BUF[secoff+i]!=0XFF)break;
|
||||
}
|
||||
|
||||
if(i<secremain)
|
||||
{
|
||||
SPI_Flash_Erase_Sector(secpos);
|
||||
|
||||
for(i=0;i<secremain;i++)
|
||||
{
|
||||
SPI_FLASH_BUF[i+secoff]=pBuffer[i];
|
||||
}
|
||||
|
||||
SPI_Flash_Write_NoCheck(SPI_FLASH_BUF,secpos*4096,4096);
|
||||
|
||||
}
|
||||
else{
|
||||
SPI_Flash_Write_NoCheck(pBuffer,WriteAddr,secremain);
|
||||
}
|
||||
|
||||
if(size==secremain){
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
secpos++;
|
||||
secoff=0;
|
||||
|
||||
pBuffer+=secremain;
|
||||
WriteAddr+=secremain;
|
||||
size-=secremain;
|
||||
|
||||
if(size>4096)
|
||||
{
|
||||
secremain=4096;
|
||||
}
|
||||
else
|
||||
{
|
||||
secremain=size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_Erase_Chip
|
||||
*
|
||||
* @brief Erase all FLASH pages.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_Flash_Erase_Chip(void)
|
||||
{
|
||||
SPI_FLASH_Write_Enable();
|
||||
SPI_Flash_Wait_Busy();
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
SPI1_ReadWriteByte(W25X_ChipErase);
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
SPI_Flash_Wait_Busy();
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_PowerDown
|
||||
*
|
||||
* @brief Enter power down mode.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_Flash_PowerDown(void)
|
||||
{
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
SPI1_ReadWriteByte(W25X_PowerDown);
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
Delay_Us(3);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
* @fn SPI_Flash_WAKEUP
|
||||
*
|
||||
* @brief Power down wake up.
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void SPI_Flash_WAKEUP(void)
|
||||
{
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 0);
|
||||
SPI1_ReadWriteByte(W25X_ReleasePowerDown);
|
||||
GPIO_WriteBit(GPIOA, GPIO_Pin_15, 1);
|
||||
Delay_Us(3);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
#ifndef __SPI_FLASH_H
|
||||
#define __SPI_FLASH_H
|
||||
#include "debug.h"
|
||||
#include "string.h"
|
||||
|
||||
/* Winbond SPIFalsh ID */
|
||||
#define W25Q80 0XEF13
|
||||
#define W25Q16 0XEF14
|
||||
#define W25Q32 0XEF15
|
||||
#define W25Q64 0XEF16
|
||||
#define W25Q128 0XEF17
|
||||
|
||||
/* Winbond W25Q64 */
|
||||
#define SPI_FLASH_PAGESIZE 256
|
||||
#define SPI_FLASH_SECTOR 4096
|
||||
#define SPI_FLASH_TOTAL_SIZE 0x7FFFFF
|
||||
|
||||
/* Winbond SPIFalsh Instruction List */
|
||||
#define W25X_WriteEnable 0x06
|
||||
#define W25X_WriteDisable 0x04
|
||||
#define W25X_ReadStatusReg 0x05
|
||||
#define W25X_WriteStatusReg 0x01
|
||||
#define W25X_ReadData 0x03
|
||||
#define W25X_FastReadData 0x0B
|
||||
#define W25X_FastReadDual 0x3B
|
||||
#define W25X_PageProgram 0x02
|
||||
#define W25X_BlockErase 0xD8
|
||||
#define W25X_SectorErase 0x20
|
||||
#define W25X_ChipErase 0xC7
|
||||
#define W25X_PowerDown 0xB9
|
||||
#define W25X_ReleasePowerDown 0xAB
|
||||
#define W25X_DeviceID 0xAB
|
||||
#define W25X_ManufactDeviceID 0x90
|
||||
#define W25X_JedecDeviceID 0x9F
|
||||
|
||||
#define SIZE sizeof(TEXT_Buf)
|
||||
u8 SPI_FLASH_BUF[4096];
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
u8 SPI1_ReadWriteByte(u8 TxData);
|
||||
void SPI_Flash_Init(void);
|
||||
u8 SPI_Flash_ReadSR(void);
|
||||
void SPI_FLASH_Write_SR(u8 sr);
|
||||
void SPI_Flash_Wait_Busy(void);
|
||||
void SPI_FLASH_Write_Enable(void);
|
||||
void SPI_FLASH_Write_Disable(void);
|
||||
u16 SPI_Flash_ReadID(void);
|
||||
void SPI_Flash_Erase_Sector(u32 Dst_Addr);
|
||||
int SPI_Flash_Erase(u32 Addr, int size);
|
||||
void SPI_Flash_Read(u8* pBuffer,u32 ReadAddr,u16 size);
|
||||
void SPI_Flash_Write_Page(u8* pBuffer,u32 WriteAddr,u16 size);
|
||||
void SPI_Flash_Write_NoCheck(u8* pBuffer,u32 WriteAddr,u16 size);
|
||||
void SPI_Flash_Write(u8* pBuffer,u32 WriteAddr,u16 size);
|
||||
void SPI_Flash_Erase_Chip(void);
|
||||
void SPI_Flash_PowerDown(void);
|
||||
void SPI_Flash_WAKEUP(void);
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
#include "tos_kv.h"
|
||||
#include "spi_flash.h"
|
||||
|
||||
#define SECTOR_SIZE 4096 // sector size for spiflash
|
||||
#define SECTOR_SIZE_LOG2 12 // 2 ^ 12 = 4096
|
||||
|
||||
int ch32v30x_spiflash_read(uint32_t addr, void *buf, size_t len)
|
||||
{
|
||||
SPI_Flash_Read(buf, addr, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ch32v30x_spiflash_write(uint32_t addr, const void *buf, size_t len)
|
||||
{
|
||||
SPI_Flash_Write((void*)buf, addr, len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ch32v30x_spiflash_erase(uint32_t addr, size_t size)
|
||||
{
|
||||
return SPI_Flash_Erase(addr, size);
|
||||
}
|
||||
|
||||
kv_flash_drv_t ch32v30x_spiflash_drv = {
|
||||
.write = ch32v30x_spiflash_write,
|
||||
.read = ch32v30x_spiflash_read,
|
||||
.erase = ch32v30x_spiflash_erase,
|
||||
};
|
||||
|
||||
kv_flash_prop_t ch32v30x_spiflash_prop = {
|
||||
.sector_size_log2 = SECTOR_SIZE_LOG2,
|
||||
.pgm_type = KV_FLASH_PROGRAM_TYPE_BYTE,
|
||||
};
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
#include "tos_k.h"
|
||||
#include "tos_hal.h"
|
||||
#include "ff.h"
|
||||
#include "tos_vfs.h"
|
||||
#include "tos_fatfs_drv.h"
|
||||
#include "tos_fatfs_vfs.h"
|
||||
|
||||
char buf[512];
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
int fd, ret;
|
||||
vfs_err_t err;
|
||||
extern vfs_blkdev_ops_t sd_dev;
|
||||
extern vfs_fs_ops_t fatfs_ops;
|
||||
|
||||
err = tos_vfs_block_device_register("/dev/sd", &sd_dev);
|
||||
if (err != VFS_ERR_NONE) {
|
||||
printf("/dev/sd block device register failed!\n");
|
||||
}
|
||||
|
||||
err = tos_vfs_fs_register("fatfs_sd", &fatfs_ops);
|
||||
if (err != VFS_ERR_NONE) {
|
||||
printf("fatfs_sd fs register failed!\n");
|
||||
}
|
||||
|
||||
if (tos_vfs_fs_mkfs("/dev/sd", "fatfs_sd", FM_FAT32, 0) != 0) {
|
||||
printf("mkfs failed!\n");
|
||||
}
|
||||
|
||||
if (tos_vfs_fs_mount("/dev/sd", "/fs/fatfs_sd", "fatfs_sd") != 0) {
|
||||
printf("mount failed!\n");
|
||||
}
|
||||
|
||||
fd = tos_vfs_open("/fs/fatfs_sd/test_file.txt", VFS_OFLAG_CREATE_ALWAYS | VFS_OFLAG_WRITE);
|
||||
if (fd < 0) {
|
||||
printf("open failed!\n");
|
||||
}
|
||||
|
||||
ret = tos_vfs_write(fd, "fatfs sample content", strlen("fatfs sample content"));
|
||||
if (ret >= 0) {
|
||||
printf("write ok\n");
|
||||
printf("write data:\n%s\n", "fatfs sample content");
|
||||
} else {
|
||||
printf("write error: %d\n", ret);
|
||||
}
|
||||
ret = tos_vfs_close(fd);
|
||||
if (ret < 0) {
|
||||
printf("close failed!\n");
|
||||
}
|
||||
|
||||
fd = tos_vfs_open("/fs/fatfs_sd/test_file.txt", VFS_OFLAG_EXISTING | VFS_OFLAG_READ);
|
||||
if (fd < 0) {
|
||||
printf("open file error!\n");
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = tos_vfs_read(fd, buf, sizeof(buf));
|
||||
if (ret >= 0) {
|
||||
printf("read ok: %d\n", ret);
|
||||
printf("read data:\n%s\n", buf);
|
||||
} else {
|
||||
printf("read error: %d\n", ret);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////
|
||||
ret = tos_vfs_lseek(fd, 2, VFS_SEEK_CUR);
|
||||
if (ret < 0) {
|
||||
printf("lseek error\n");
|
||||
}
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
ret = tos_vfs_read(fd, buf, sizeof(buf));
|
||||
if (ret >= 0) {
|
||||
printf("read ok: %d\n", ret);
|
||||
printf("read data:\n%s\n", buf);
|
||||
} else {
|
||||
printf("read error: %d\n", ret);
|
||||
}
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
tos_vfs_close(fd);
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#include "tos_k.h"
|
||||
|
||||
#define TASK1_STK_SIZE 1024
|
||||
k_task_t task1;
|
||||
uint8_t task1_stk[TASK1_STK_SIZE];
|
||||
|
||||
|
||||
#define TASK2_STK_SIZE 1024
|
||||
k_task_t task2;
|
||||
uint8_t task2_stk[TASK2_STK_SIZE];
|
||||
|
||||
void task1_entry(void *arg)
|
||||
{
|
||||
while (1) {
|
||||
printf("###I am task1\r\n");
|
||||
tos_task_delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
void task2_entry(void *arg)
|
||||
{
|
||||
while (1) {
|
||||
printf("***I am task2\r\n");
|
||||
tos_task_delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
tos_task_create(&task1, "task1", task1_entry, NULL, 3, task1_stk, TASK1_STK_SIZE, 0); // Create task1
|
||||
tos_task_create(&task2, "task2", task2_entry, NULL, 3, task2_stk, TASK2_STK_SIZE, 0);// Create task2
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
#include "tos_kv.h"
|
||||
|
||||
extern kv_flash_drv_t ch32v30x_spiflash_drv;
|
||||
extern kv_flash_prop_t ch32v30x_spiflash_prop;
|
||||
|
||||
//#define KV_SAMPLE_DEBUG
|
||||
|
||||
void disp_value(uint8_t *value, uint32_t value_len)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
printf("value_len: %d\r\n", value_len);
|
||||
|
||||
printf("\"");
|
||||
for (i = 0; i < value_len; ++i) {
|
||||
printf("%c", value[i]);
|
||||
}
|
||||
printf("\"\r\n\n");
|
||||
}
|
||||
|
||||
void kv_test(void)
|
||||
{
|
||||
int has_key;
|
||||
kv_err_t err;
|
||||
uint8_t value_buf[40];
|
||||
uint32_t value_len;
|
||||
|
||||
err = tos_kv_init(0, 2 * 4096, &ch32v30x_spiflash_drv, &ch32v30x_spiflash_prop);
|
||||
printf("kv init, rc: %d\r\n", err);
|
||||
|
||||
has_key = tos_kv_has_key("key00");
|
||||
printf("has key[%s] ? %s\r\n\n", "key00", has_key ? "True" : "False");
|
||||
|
||||
err = tos_kv_set("key00", "value_00", strlen("value_00"));
|
||||
printf("kv set(%s), rc: %d\r\n\n", "key00", err);
|
||||
|
||||
has_key = tos_kv_has_key("key00");
|
||||
printf("has key[%s] ? %s\r\n\n", "key00", has_key ? "True" : "False");
|
||||
|
||||
if (err == KV_ERR_NONE) {
|
||||
err = tos_kv_get("key00", value_buf, sizeof(value_buf), &value_len);
|
||||
printf("kv get(%s), rc: %d\r\n\n", "key00", err);
|
||||
|
||||
if (err == KV_ERR_NONE) {
|
||||
disp_value(value_buf, value_len);
|
||||
}
|
||||
|
||||
#ifdef KV_SAMPLE_DEBUG
|
||||
tos_kv_walkthru();
|
||||
#endif
|
||||
}
|
||||
|
||||
err = tos_kv_set("key00", "value_xx", strlen("value_xx"));
|
||||
printf("kv set(%s), rc: %d\r\n\n", "key00", err);
|
||||
|
||||
if (err == KV_ERR_NONE) {
|
||||
err = tos_kv_get("key00", value_buf, sizeof(value_buf), &value_len);
|
||||
printf("kv get(%s), rc: %d\r\n\n", "key00", err);
|
||||
|
||||
if (err == KV_ERR_NONE) {
|
||||
disp_value(value_buf, value_len);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KV_SAMPLE_DEBUG
|
||||
tos_kv_walkthru();
|
||||
#endif
|
||||
|
||||
err = tos_kv_del("key00");
|
||||
printf("kv del(%s), rc: %d\r\n\n", "key00", err);
|
||||
|
||||
has_key = tos_kv_has_key("key00");
|
||||
printf("has key[%s] ? %s\r\n\n", "key00", has_key ? "True" : "False");
|
||||
|
||||
#ifdef KV_SAMPLE_DEBUG
|
||||
tos_kv_walkthru();
|
||||
#endif
|
||||
}
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
kv_test();
|
||||
}
|
||||
|
||||
|
|
@ -31,7 +31,7 @@ void mqtt_demo_task(void)
|
|||
char *product_id = PRODUCT_ID;
|
||||
char *device_name = DEVICE_NAME;
|
||||
char *key = DEVICE_KEY;
|
||||
|
||||
|
||||
device_info_t dev_info;
|
||||
memset(&dev_info, 0, sizeof(device_info_t));
|
||||
|
||||
|
|
@ -39,11 +39,11 @@ void mqtt_demo_task(void)
|
|||
* Please Choose your AT Port first, default is HAL_UART_2(USART2)
|
||||
*/
|
||||
ret = esp8266_tencent_firmware_sal_init(HAL_UART_PORT_2);
|
||||
|
||||
|
||||
if (ret < 0) {
|
||||
printf("esp8266 tencent firmware sal init fail, ret is %d\r\n", ret);
|
||||
}
|
||||
|
||||
|
||||
esp8266_tencent_firmware_join_ap("TencentOS", "tencentos");
|
||||
|
||||
strncpy(dev_info.product_id, product_id, PRODUCT_ID_MAX_SIZE);
|
||||
|
|
@ -72,25 +72,25 @@ void mqtt_demo_task(void)
|
|||
} else {
|
||||
printf("module mqtt sub success\n");
|
||||
}
|
||||
|
||||
|
||||
memset(report_topic_name, 0, sizeof(report_topic_name));
|
||||
size = snprintf(report_topic_name, TOPIC_NAME_MAX_SIZE, "$thing/up/property/%s/%s", product_id, device_name);
|
||||
|
||||
if (size < 0 || size > sizeof(report_topic_name) - 1) {
|
||||
printf("pub topic content length not enough! content size:%d buf size:%d", size, (int)sizeof(report_topic_name));
|
||||
}
|
||||
|
||||
|
||||
while (1) {
|
||||
tos_sleep_ms(5000);
|
||||
|
||||
/* use AT+PUB AT command */
|
||||
memset(payload, 0, sizeof(payload));
|
||||
snprintf(payload, sizeof(payload), REPORT_DATA_TEMPLATE, lightness++);
|
||||
|
||||
|
||||
if (lightness > 100) {
|
||||
lightness = 0;
|
||||
}
|
||||
|
||||
|
||||
if (tos_tf_module_mqtt_pub(report_topic_name, QOS0, payload) != 0) {
|
||||
printf("module mqtt pub fail\n");
|
||||
break;
|
||||
|
|
@ -100,7 +100,7 @@ void mqtt_demo_task(void)
|
|||
}
|
||||
}
|
||||
|
||||
void application_entry1(void *arg)
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
mqtt_demo_task();
|
||||
while (1) {
|
||||
|
|
@ -0,0 +1,326 @@
|
|||
/**
|
||||
* @copyright
|
||||
*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved.
|
||||
*
|
||||
* Licensed under the MIT License(the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @file data_template_sample.c
|
||||
* @brief
|
||||
* @author fancyxu (fancyxu@tencent.com)
|
||||
* @version 1.0
|
||||
* @date 2021-09-27
|
||||
*
|
||||
* @par Change Log:
|
||||
* <table>
|
||||
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||
* <tr><td>2021-09-27 <td>1.0 <td>fancyxu <td>first commit
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include "qcloud_iot_common.h"
|
||||
#include "qcloud_iot_explorer.h"
|
||||
#include "data_template_config.h"
|
||||
|
||||
#include "utils_log.h"
|
||||
|
||||
#include "esp8266.h"
|
||||
|
||||
/**
|
||||
* @brief MQTT event callback, @see MQTTEventHandleFun
|
||||
*
|
||||
* @param[in] client pointer to mqtt client
|
||||
* @param[in] handle_context context
|
||||
* @param[in] msg msg
|
||||
*/
|
||||
static void _mqtt_event_handler(void *client, void *handle_context, MQTTEventMsg *msg)
|
||||
{
|
||||
MQTTMessage *mqtt_message = (MQTTMessage *)msg->msg;
|
||||
uintptr_t packet_id = (uintptr_t)msg->msg;
|
||||
|
||||
switch (msg->event_type) {
|
||||
case MQTT_EVENT_UNDEF:
|
||||
Log_i("undefined event occur.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_DISCONNECT:
|
||||
Log_i("MQTT disconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_RECONNECT:
|
||||
Log_i("MQTT reconnect.");
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_RECEIVED:
|
||||
Log_i("topic message arrived but without any related handle: topic=%.*s, topic_msg=%.*s",
|
||||
mqtt_message->topic_len, STRING_PTR_PRINT_SANITY_CHECK(mqtt_message->topic_name),
|
||||
mqtt_message->payload_len, STRING_PTR_PRINT_SANITY_CHECK((char *)mqtt_message->payload));
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBSCRIBE_SUCCESS:
|
||||
Log_i("subscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBSCRIBE_TIMEOUT:
|
||||
Log_i("subscribe wait ack timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_SUBSCRIBE_NACK:
|
||||
Log_i("subscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBE_SUCCESS:
|
||||
Log_i("unsubscribe success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBE_TIMEOUT:
|
||||
Log_i("unsubscribe timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_UNSUBSCRIBE_NACK:
|
||||
Log_i("unsubscribe nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_SUCCESS:
|
||||
Log_i("publish success, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_TIMEOUT:
|
||||
Log_i("publish timeout, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
case MQTT_EVENT_PUBLISH_NACK:
|
||||
Log_i("publish nack, packet-id=%u", (unsigned int)packet_id);
|
||||
break;
|
||||
|
||||
default:
|
||||
Log_i("Should NOT arrive here.");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Setup MQTT construct parameters.
|
||||
*
|
||||
* @param[in,out] initParams @see MQTTInitParams
|
||||
* @param[in] device_info @see DeviceInfo
|
||||
*/
|
||||
static void _setup_connect_init_params(MQTTInitParams *init_params, DeviceInfo *device_info)
|
||||
{
|
||||
init_params->device_info = device_info;
|
||||
init_params->command_timeout = QCLOUD_IOT_MQTT_COMMAND_TIMEOUT;
|
||||
init_params->keep_alive_interval_ms = QCLOUD_IOT_MQTT_KEEP_ALIVE_INTERNAL;
|
||||
init_params->auto_connect_enable = 1;
|
||||
init_params->event_handle.h_fp = _mqtt_event_handler;
|
||||
init_params->event_handle.context = NULL;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Data template callback
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
static void _method_control_callback(UtilsJsonValue client_token, UtilsJsonValue params, void *usr_data)
|
||||
{
|
||||
char buf[256];
|
||||
Log_i("recv msg[%.*s]: params=%.*s", client_token.value_len, client_token.value, params.value_len, params.value);
|
||||
IOT_DataTemplate_PropertyControlReply(usr_data, buf, sizeof(buf), 0, client_token);
|
||||
usr_data_template_property_parse(params);
|
||||
}
|
||||
|
||||
static void _method_get_status_reply_callback(UtilsJsonValue client_token, int code, UtilsJsonValue reported,
|
||||
UtilsJsonValue control, void *usr_data)
|
||||
{
|
||||
char buf[256];
|
||||
Log_i("recv msg[%.*s]: code=%d|reported=%.*s|control=%.*s", client_token.value_len, client_token.value, code,
|
||||
reported.value_len, STRING_PTR_PRINT_SANITY_CHECK(reported.value), control.value_len,
|
||||
STRING_PTR_PRINT_SANITY_CHECK(control.value));
|
||||
usr_data_template_property_parse(control);
|
||||
IOT_DataTemplate_PropertyClearControl(usr_data, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
static void _method_action_callback(UtilsJsonValue client_token, UtilsJsonValue action_id, UtilsJsonValue params,
|
||||
void *usr_data)
|
||||
{
|
||||
UsrActionIndex index;
|
||||
int rc;
|
||||
DataTemplatePropertyValue value_time, value_color, value_total_time;
|
||||
|
||||
char buf[256];
|
||||
|
||||
Log_i("recv msg[%.*s]: action_id=%.*s|params=%.*s", client_token.value_len, client_token.value, action_id.value_len,
|
||||
action_id.value, params.value_len, params.value);
|
||||
|
||||
rc = usr_data_template_action_parse(action_id, params, &index);
|
||||
if (rc) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (index) {
|
||||
case USR_ACTION_INDEX_LIGHT_BLINK:
|
||||
value_time = usr_data_template_action_input_value_get(USR_ACTION_INDEX_LIGHT_BLINK,
|
||||
USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TIME);
|
||||
value_color = usr_data_template_action_input_value_get(USR_ACTION_INDEX_LIGHT_BLINK,
|
||||
USR_ACTION_LIGHT_BLINK_INPUT_INDEX_COLOR);
|
||||
value_total_time = usr_data_template_action_input_value_get(USR_ACTION_INDEX_LIGHT_BLINK,
|
||||
USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TOTAL_TIME);
|
||||
Log_i("light[%d] blink %d every %d s ", value_color.value_enum, value_time.value_int,
|
||||
value_total_time.value_int);
|
||||
usr_data_template_action_reply(usr_data, buf, sizeof(buf), index, client_token, 0, "{\"err_code\":0}");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Data template upstream
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief Report status.
|
||||
*
|
||||
* @param[in,out] client pointer to mqtt client
|
||||
*/
|
||||
static void _cycle_report(void *client)
|
||||
{
|
||||
static int lightness = 0;
|
||||
char buf[256];
|
||||
static Timer sg_cycle_report_timer;
|
||||
DataTemplatePropertyValue property_value;
|
||||
|
||||
if (HAL_Timer_Expired(&sg_cycle_report_timer)) {
|
||||
usr_data_template_event_post(client, buf, sizeof(buf), USR_EVENT_INDEX_STATUS_REPORT,
|
||||
"{\"status\":0,\"message\":\"ok\"}");
|
||||
|
||||
property_value.value_int = lightness;
|
||||
if (++lightness > 100) {
|
||||
lightness = 0;
|
||||
}
|
||||
usr_data_template_property_value_set(USR_PROPERTY_INDEX_BRIGHTNESS, property_value);
|
||||
HAL_Timer_Countdown(&sg_cycle_report_timer, 10);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Init usr data template and data.
|
||||
*
|
||||
*/
|
||||
static void _usr_init(void)
|
||||
{
|
||||
usr_data_template_init();
|
||||
|
||||
DataTemplatePropertyValue value;
|
||||
value.value_int = 0;
|
||||
usr_data_template_property_value_set(USR_PROPERTY_INDEX_POWER_SWITCH, value);
|
||||
value.value_enum = 0;
|
||||
usr_data_template_property_value_set(USR_PROPERTY_INDEX_COLOR, value);
|
||||
value.value_int = 10;
|
||||
usr_data_template_property_value_set(USR_PROPERTY_INDEX_BRIGHTNESS, value);
|
||||
value.value_string = "light";
|
||||
usr_data_template_property_value_set(USR_PROPERTY_INDEX_NAME, value);
|
||||
value.value_int = 30;
|
||||
usr_data_template_property_struct_value_set(USR_PROPERTY_INDEX_POSITION, USR_PROPERTY_POSITION_INDEX_LONGITUDE,
|
||||
value);
|
||||
value.value_int = 30;
|
||||
usr_data_template_property_struct_value_set(USR_PROPERTY_INDEX_POSITION, USR_PROPERTY_POSITION_INDEX_LATITUDE,
|
||||
value);
|
||||
value.value_string = "high";
|
||||
usr_data_template_property_value_set(USR_PROPERTY_INDEX_POWER, value);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Main
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
int data_template_app()
|
||||
{
|
||||
int rc;
|
||||
char buf[1024];
|
||||
|
||||
// init log level
|
||||
LogHandleFunc func = {0};
|
||||
|
||||
func.log_malloc = HAL_Malloc;
|
||||
func.log_free = HAL_Free;
|
||||
func.log_get_current_time_str = HAL_Timer_Current;
|
||||
func.log_printf = HAL_Printf;
|
||||
utils_log_init(func, LOG_LEVEL_INFO, 2048);
|
||||
|
||||
DeviceInfo device_info;
|
||||
|
||||
rc = HAL_GetDevInfo((void *)&device_info);
|
||||
if (rc) {
|
||||
Log_e("get device info failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
_usr_init();
|
||||
|
||||
// init connection
|
||||
MQTTInitParams init_params = DEFAULT_MQTT_INIT_PARAMS;
|
||||
_setup_connect_init_params(&init_params, &device_info);
|
||||
|
||||
// create MQTT client and connect with server
|
||||
void *client = IOT_MQTT_Construct(&init_params);
|
||||
if (client) {
|
||||
Log_i("Cloud Device Construct Success");
|
||||
} else {
|
||||
Log_e("MQTT Construct failed!");
|
||||
return QCLOUD_ERR_FAILURE;
|
||||
}
|
||||
|
||||
// subscribe normal topics and wait result
|
||||
IotDataTemplateCallback callback = DEFAULT_DATA_TEMPLATE_CALLBACK;
|
||||
callback.property_callback.method_control_callback = _method_control_callback;
|
||||
callback.property_callback.method_get_status_reply_callback = _method_get_status_reply_callback;
|
||||
callback.action_callback.method_action_callback = _method_action_callback;
|
||||
|
||||
rc = IOT_DataTemplate_Init(client, callback, client);
|
||||
if (rc) {
|
||||
Log_e("Client Subscribe Topic Failed: %d", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
IOT_DataTemplate_PropertyGetStatus(client, buf, sizeof(buf));
|
||||
|
||||
while (1) {
|
||||
rc = IOT_MQTT_Yield(client, QCLOUD_IOT_MQTT_YIELD_TIMEOUT);
|
||||
switch (rc) {
|
||||
case QCLOUD_RET_SUCCESS:
|
||||
break;
|
||||
case QCLOUD_ERR_MQTT_ATTEMPTING_RECONNECT:
|
||||
continue;
|
||||
case QCLOUD_RET_MQTT_RECONNECTED:
|
||||
IOT_DataTemplate_PropertyGetStatus(client, buf, sizeof(buf));
|
||||
break;
|
||||
default:
|
||||
Log_e("Exit loop caused of errCode:%d", rc);
|
||||
goto exit;
|
||||
}
|
||||
_cycle_report(client);
|
||||
usr_data_template_property_report(client, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
exit:
|
||||
IOT_DataTemplate_Deinit(client);
|
||||
rc |= IOT_MQTT_Destroy(&client);
|
||||
utils_log_deinit();
|
||||
return rc;
|
||||
}
|
||||
|
||||
void application_entry(void *arg)
|
||||
{
|
||||
esp8266_sal_init(HAL_UART_PORT_6);
|
||||
|
||||
esp8266_join_ap("Mculover666", "mculover666");
|
||||
|
||||
data_template_app();
|
||||
}
|
||||
|
|
@ -0,0 +1,494 @@
|
|||
/**
|
||||
* @copyright
|
||||
*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved.
|
||||
*
|
||||
* Licensed under the MIT License(the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @file data_template_config.c
|
||||
* @brief
|
||||
* @author fancyxu (fancyxu@tencent.com)
|
||||
* @version 1.0
|
||||
* @date 2021-10-09
|
||||
*
|
||||
* @par Change Log:
|
||||
* <table>
|
||||
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||
* <tr><td>2021-10-09 <td>1.0 <td>fancyxu <td>first commit
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#include "data_template_config.h"
|
||||
|
||||
/**
|
||||
* @brief Set property value.
|
||||
*
|
||||
* @param[in,out] property pointer to property
|
||||
* @param[in] value value to set, should match with property type
|
||||
* @return 0 for success.
|
||||
*/
|
||||
static int _set_property_value(DataTemplateProperty* property, UtilsJsonValue value)
|
||||
{
|
||||
int i, rc = 0;
|
||||
|
||||
switch (property->type) {
|
||||
case DATA_TEMPLATE_TYPE_INT:
|
||||
case DATA_TEMPLATE_TYPE_ENUM:
|
||||
case DATA_TEMPLATE_TYPE_BOOL:
|
||||
return utils_json_value_data_get(value, UTILS_JSON_VALUE_TYPE_INT32, &property->value.value_int);
|
||||
case DATA_TEMPLATE_TYPE_TIME:
|
||||
return utils_json_value_data_get(value, UTILS_JSON_VALUE_TYPE_UINT32, &property->value.value_time);
|
||||
case DATA_TEMPLATE_TYPE_STRING:
|
||||
case DATA_TEMPLATE_TYPE_STRING_ENUM:
|
||||
if (!property->value.value_string) { // no need copy
|
||||
return 0;
|
||||
}
|
||||
strncpy(property->value.value_string, value.value, value.value_len);
|
||||
property->value.value_string[value.value_len] = '\0';
|
||||
return 0;
|
||||
case DATA_TEMPLATE_TYPE_FLOAT:
|
||||
return utils_json_value_data_get(value, UTILS_JSON_VALUE_TYPE_FLOAT, &property->value.value_float);
|
||||
case DATA_TEMPLATE_TYPE_STRUCT:
|
||||
for (i = 0; i < property->value.value_struct.count; i++) {
|
||||
rc |= _set_property_value(property->value.value_struct.property + i, value);
|
||||
}
|
||||
return rc;
|
||||
case DATA_TEMPLATE_TYPE_ARRAY:
|
||||
Log_e("array type is not supportted yet!");
|
||||
return -1;
|
||||
default:
|
||||
Log_e("unkown type!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get property node in json.
|
||||
*
|
||||
* @param[out] json_buf buffer to put node
|
||||
* @param[in] buf_len buffer length
|
||||
* @param[in] property property to get node
|
||||
* @return 0 for success.
|
||||
*/
|
||||
static int _get_property_node(char* json_buf, int buf_len, const DataTemplateProperty* property)
|
||||
{
|
||||
int len, i;
|
||||
switch (property->type) {
|
||||
case DATA_TEMPLATE_TYPE_INT:
|
||||
case DATA_TEMPLATE_TYPE_ENUM:
|
||||
case DATA_TEMPLATE_TYPE_BOOL:
|
||||
return HAL_Snprintf(json_buf, buf_len, "\"%s\":%d", property->key, property->value.value_int);
|
||||
case DATA_TEMPLATE_TYPE_TIME:
|
||||
return HAL_Snprintf(json_buf, buf_len, "\"%s\":%u", property->key, property->value.value_time);
|
||||
case DATA_TEMPLATE_TYPE_STRING:
|
||||
case DATA_TEMPLATE_TYPE_STRING_ENUM:
|
||||
if (!property->value.value_string) {
|
||||
return 0;
|
||||
}
|
||||
return HAL_Snprintf(json_buf, buf_len, "\"%s\":\"%s\"", property->key, property->value.value_string);
|
||||
case DATA_TEMPLATE_TYPE_FLOAT:
|
||||
return HAL_Snprintf(json_buf, buf_len, "\"%s\":%f", property->key, property->value.value_float);
|
||||
case DATA_TEMPLATE_TYPE_STRUCT:
|
||||
len = HAL_Snprintf(json_buf, buf_len, "\"%s\":{", property->key);
|
||||
for (i = 0; i < property->value.value_struct.count; i++) {
|
||||
len += _get_property_node(json_buf + len, buf_len - len, property->value.value_struct.property + i);
|
||||
json_buf[len++] = ',';
|
||||
}
|
||||
json_buf[--len] = '}';
|
||||
return len + 1;
|
||||
case DATA_TEMPLATE_TYPE_ARRAY:
|
||||
Log_e("array type is not supportted yet!");
|
||||
return -1;
|
||||
default:
|
||||
Log_e("unkown type!");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse property array.
|
||||
*
|
||||
* @param[in] json_buf json string to parse
|
||||
* @param[in] buf_len json len
|
||||
* @param[in,out] properties pointer to property array
|
||||
* @param[in] property_count count of property
|
||||
*/
|
||||
static void _parse_property_array(const char* json_buf, int buf_len, DataTemplateProperty* properties,
|
||||
int property_count)
|
||||
{
|
||||
DataTemplateProperty* property;
|
||||
UtilsJsonValue value;
|
||||
for (int i = 0; i < property_count; i++) {
|
||||
property = &properties[i];
|
||||
if (!utils_json_value_get(property->key, strlen(property->key), json_buf, buf_len, &value)) {
|
||||
property->need_report = !_set_property_value(property, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* user property
|
||||
**************************************************************************************/
|
||||
|
||||
#define TOTAL_USR_PROPERTY_COUNT 6
|
||||
|
||||
static DataTemplateProperty sg_usr_data_template_property[TOTAL_USR_PROPERTY_COUNT];
|
||||
|
||||
#define TOTAL_USR_PROPERTY_STRUCT_POSITION_COUNT 2
|
||||
|
||||
static DataTemplateProperty sg_usr_property_position[TOTAL_USR_PROPERTY_STRUCT_POSITION_COUNT];
|
||||
|
||||
static void _init_data_template_property_position(void)
|
||||
{
|
||||
sg_usr_property_position[USR_PROPERTY_POSITION_INDEX_LONGITUDE].value.value_int = 0;
|
||||
sg_usr_property_position[USR_PROPERTY_POSITION_INDEX_LONGITUDE].key = "longitude";
|
||||
sg_usr_property_position[USR_PROPERTY_POSITION_INDEX_LONGITUDE].type = DATA_TEMPLATE_TYPE_INT;
|
||||
|
||||
sg_usr_property_position[USR_PROPERTY_POSITION_INDEX_LATITUDE].value.value_int = 0;
|
||||
sg_usr_property_position[USR_PROPERTY_POSITION_INDEX_LATITUDE].key = "latitude";
|
||||
sg_usr_property_position[USR_PROPERTY_POSITION_INDEX_LATITUDE].type = DATA_TEMPLATE_TYPE_INT;
|
||||
}
|
||||
|
||||
static void _init_data_template_property(void)
|
||||
{
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER_SWITCH].value.value_bool = 0;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER_SWITCH].key = "power_switch";
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER_SWITCH].type = DATA_TEMPLATE_TYPE_BOOL;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER_SWITCH].need_report = 1;
|
||||
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_COLOR].value.value_enum = 0;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_COLOR].key = "color";
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_COLOR].type = DATA_TEMPLATE_TYPE_ENUM;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_COLOR].need_report = 1;
|
||||
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_BRIGHTNESS].value.value_int = 0;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_BRIGHTNESS].key = "brightness";
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_BRIGHTNESS].type = DATA_TEMPLATE_TYPE_INT;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_BRIGHTNESS].need_report = 1;
|
||||
|
||||
static char sg_usr_property_name[64 + 1];
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_NAME].value.value_string = sg_usr_property_name;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_NAME].key = "name";
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_NAME].type = DATA_TEMPLATE_TYPE_STRING;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_NAME].need_report = 1;
|
||||
|
||||
_init_data_template_property_position();
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POSITION].value.value_struct.property = sg_usr_property_position;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POSITION].value.value_struct.count =
|
||||
TOTAL_USR_PROPERTY_STRUCT_POSITION_COUNT;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POSITION].key = "position";
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POSITION].type = DATA_TEMPLATE_TYPE_STRUCT;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POSITION].need_report = 1;
|
||||
|
||||
static char sg_usr_property_power[64 + 1];
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER].value.value_string_enum = sg_usr_property_power;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER].key = "power";
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER].type = DATA_TEMPLATE_TYPE_STRING_ENUM;
|
||||
sg_usr_data_template_property[USR_PROPERTY_INDEX_POWER].need_report = 1;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* user event
|
||||
**************************************************************************************/
|
||||
|
||||
#define TOTAL_USR_EVENT_COUNT 3
|
||||
|
||||
DataTemplateEvent sg_usr_data_template_event[TOTAL_USR_EVENT_COUNT];
|
||||
|
||||
/**
|
||||
* @brief Sample of event post params.
|
||||
*
|
||||
*/
|
||||
static const char* sg_usr_event_status_report_params = "{\"status\":0,\"message\":\"ok\"}";
|
||||
static const char* sg_usr_event_low_voltage_params = "{\"voltage\":1.0}";
|
||||
static const char* sg_usr_event_hardware_fault_params = "{\"name\":\"broken\",\"error_code\":-1}";
|
||||
|
||||
static void _init_data_template_event(void)
|
||||
{
|
||||
sg_usr_data_template_event[USR_EVENT_INDEX_STATUS_REPORT].event_id = "status_report";
|
||||
sg_usr_data_template_event[USR_EVENT_INDEX_STATUS_REPORT].type = IOT_DATA_TEMPLATE_EVENT_TYPE_INFO;
|
||||
sg_usr_data_template_event[USR_EVENT_INDEX_STATUS_REPORT].params = sg_usr_event_status_report_params;
|
||||
|
||||
sg_usr_data_template_event[USR_EVENT_INDEX_LOW_VOLTAGE].event_id = "low_voltage";
|
||||
sg_usr_data_template_event[USR_EVENT_INDEX_LOW_VOLTAGE].type = IOT_DATA_TEMPLATE_EVENT_TYPE_ALERT;
|
||||
sg_usr_data_template_event[USR_EVENT_INDEX_LOW_VOLTAGE].params = sg_usr_event_low_voltage_params;
|
||||
|
||||
sg_usr_data_template_event[USR_EVENT_INDEX_HARDWARE_FAULT].event_id = "hardware_fault";
|
||||
sg_usr_data_template_event[USR_EVENT_INDEX_HARDWARE_FAULT].type = IOT_DATA_TEMPLATE_EVENT_TYPE_FAULT;
|
||||
sg_usr_data_template_event[USR_EVENT_INDEX_HARDWARE_FAULT].params = sg_usr_event_hardware_fault_params;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* user action
|
||||
**************************************************************************************/
|
||||
|
||||
#define TOTAL_USR_ACTION_COUNT 1
|
||||
|
||||
DataTemplateAction sg_usr_data_template_action[TOTAL_USR_ACTION_COUNT];
|
||||
|
||||
#define TOTAL_USR_ACTION_LIGHT_BLINK_INPUT_PARAMS_COUNT 3
|
||||
|
||||
static DataTemplateProperty sg_usr_action_light_blink_input[TOTAL_USR_ACTION_LIGHT_BLINK_INPUT_PARAMS_COUNT];
|
||||
|
||||
static void _init_data_template_action_light_blink_input(void)
|
||||
{
|
||||
sg_usr_action_light_blink_input[USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TIME].value.value_int = 0;
|
||||
sg_usr_action_light_blink_input[USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TIME].key = "time";
|
||||
sg_usr_action_light_blink_input[USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TIME].type = DATA_TEMPLATE_TYPE_INT;
|
||||
|
||||
sg_usr_action_light_blink_input[USR_ACTION_LIGHT_BLINK_INPUT_INDEX_COLOR].value.value_int = 0;
|
||||
sg_usr_action_light_blink_input[USR_ACTION_LIGHT_BLINK_INPUT_INDEX_COLOR].key = "color";
|
||||
sg_usr_action_light_blink_input[USR_ACTION_LIGHT_BLINK_INPUT_INDEX_COLOR].type = DATA_TEMPLATE_TYPE_ENUM;
|
||||
|
||||
sg_usr_action_light_blink_input[USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TOTAL_TIME].value.value_int = 0;
|
||||
sg_usr_action_light_blink_input[USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TOTAL_TIME].key = "total_time";
|
||||
sg_usr_action_light_blink_input[USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TOTAL_TIME].type = DATA_TEMPLATE_TYPE_INT;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Sample of action reply.
|
||||
*
|
||||
*/
|
||||
static IotDataTemplateActionReply sg_usr_action_light_blink_reply = {
|
||||
.code = 0,
|
||||
.client_token = {.value = "test", .value_len = 4},
|
||||
.response = "{\"err_code\":0}",
|
||||
};
|
||||
|
||||
static void _init_data_template_action(void)
|
||||
{
|
||||
_init_data_template_action_light_blink_input();
|
||||
sg_usr_data_template_action[USR_ACTION_INDEX_LIGHT_BLINK].action_id = "light_blink";
|
||||
sg_usr_data_template_action[USR_ACTION_INDEX_LIGHT_BLINK].input_struct.value_struct.property =
|
||||
sg_usr_action_light_blink_input;
|
||||
sg_usr_data_template_action[USR_ACTION_INDEX_LIGHT_BLINK].input_struct.value_struct.count =
|
||||
TOTAL_USR_ACTION_LIGHT_BLINK_INPUT_PARAMS_COUNT;
|
||||
sg_usr_data_template_action[USR_ACTION_INDEX_LIGHT_BLINK].reply = sg_usr_action_light_blink_reply;
|
||||
}
|
||||
|
||||
/**************************************************************************************
|
||||
* API
|
||||
**************************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Init user data template(property/event/action).
|
||||
*
|
||||
*/
|
||||
void usr_data_template_init(void)
|
||||
{
|
||||
_init_data_template_property();
|
||||
_init_data_template_event();
|
||||
_init_data_template_action();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get property value.
|
||||
*
|
||||
* @param[in] index @see UsrPropertyIndex
|
||||
* @return @see DataTemplatePropertyValue
|
||||
*/
|
||||
DataTemplatePropertyValue usr_data_template_property_value_get(UsrPropertyIndex index)
|
||||
{
|
||||
return sg_usr_data_template_property[index].value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set property value.
|
||||
*
|
||||
* @param[in] index @see UsrPropertyIndex
|
||||
* @param[in] value @see DataTemplatePropertyValue, @note value should match property type.
|
||||
*/
|
||||
void usr_data_template_property_value_set(UsrPropertyIndex index, DataTemplatePropertyValue value)
|
||||
{
|
||||
if (sg_usr_data_template_property[index].type == DATA_TEMPLATE_TYPE_STRING ||
|
||||
sg_usr_data_template_property[index].type == DATA_TEMPLATE_TYPE_STRING_ENUM) {
|
||||
strncpy(sg_usr_data_template_property[index].value.value_string, value.value_string,
|
||||
strlen(value.value_string));
|
||||
}
|
||||
sg_usr_data_template_property[index].value = value;
|
||||
sg_usr_data_template_property[index].need_report = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get property(struct) value.
|
||||
*
|
||||
* @param[in] struct_index @see UsrPropertyIndex, @note DATA_TEMPLATE_TYPE_STRUCT is required here.
|
||||
* @param[in] property_index depends on which struct
|
||||
* @return @see DataTemplatePropertyValue
|
||||
*/
|
||||
DataTemplatePropertyValue usr_data_template_property_struct_value_get(UsrPropertyIndex struct_index, int property_index)
|
||||
{
|
||||
return sg_usr_data_template_property[struct_index].value.value_struct.property[property_index].value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Set property(struct) value.
|
||||
*
|
||||
* @param[in] struct_index @see UsrPropertyIndex, @note DATA_TEMPLATE_TYPE_STRUCT is required here.
|
||||
* @param[in] property_index depends on which struct
|
||||
* @param[in] value @see DataTemplatePropertyValue, @note value should match property type.
|
||||
*/
|
||||
void usr_data_template_property_struct_value_set(UsrPropertyIndex struct_index, int property_index,
|
||||
DataTemplatePropertyValue value)
|
||||
{
|
||||
if (sg_usr_data_template_property[struct_index].value.value_struct.property[property_index].type ==
|
||||
DATA_TEMPLATE_TYPE_STRING ||
|
||||
sg_usr_data_template_property[struct_index].value.value_struct.property[property_index].type ==
|
||||
DATA_TEMPLATE_TYPE_STRING_ENUM) {
|
||||
strncpy(
|
||||
sg_usr_data_template_property[struct_index].value.value_struct.property[property_index].value.value_string,
|
||||
value.value_string, strlen(value.value_string));
|
||||
}
|
||||
sg_usr_data_template_property[struct_index].need_report = 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse control message and set property value.
|
||||
*
|
||||
* @param[in] params params filed of control message
|
||||
*/
|
||||
void usr_data_template_property_parse(UtilsJsonValue params)
|
||||
{
|
||||
_parse_property_array(params.value, params.value_len, sg_usr_data_template_property, TOTAL_USR_PROPERTY_COUNT);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get property status.
|
||||
*
|
||||
* @param[in] index @see UsrPropertyIndex
|
||||
* @return need_report
|
||||
*/
|
||||
int usr_data_template_property_status_get(UsrPropertyIndex index)
|
||||
{
|
||||
return sg_usr_data_template_property[index].need_report;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Report all the properties needed report.
|
||||
*
|
||||
* @param[in,out] client pointer to mqtt client
|
||||
* @param[in] buf buffer to report
|
||||
* @param[in] buf_len buffer length
|
||||
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
|
||||
*/
|
||||
int usr_data_template_property_report(void* client, char* buf, int buf_len)
|
||||
{
|
||||
char params[512];
|
||||
memset(params, 0, sizeof(params));
|
||||
params[0] = '{';
|
||||
int offset = 1;
|
||||
for (int i = 0; i < TOTAL_USR_PROPERTY_COUNT; i++) {
|
||||
DataTemplateProperty* property = &sg_usr_data_template_property[i];
|
||||
if (property->need_report) {
|
||||
offset += _get_property_node(params + offset, sizeof(params) - offset, property);
|
||||
if (offset > 0) {
|
||||
params[offset++] = ',';
|
||||
}
|
||||
property->need_report = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (offset > 0) {
|
||||
params[--offset] = '}';
|
||||
return IOT_DataTemplate_PropertyReport(client, buf, buf_len, params);
|
||||
}
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Post event.
|
||||
*
|
||||
* @param[in,out] client pointer to mqtt client
|
||||
* @param[in] buf buffer to report
|
||||
* @param[in] buf_len buffer length
|
||||
* @param[in] id @see UsrEventIndex
|
||||
* @param[in] params user should construct params according to event.
|
||||
*/
|
||||
void usr_data_template_event_post(void* client, char* buf, int buf_len, UsrEventIndex id, const char* params)
|
||||
{
|
||||
if (params) {
|
||||
sg_usr_data_template_event[id].params = params;
|
||||
}
|
||||
IOT_DataTemplate_EventPost(client, buf, buf_len, sg_usr_data_template_event[id]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Parse action message and set action input params.
|
||||
*
|
||||
* @param[in] action_id action id
|
||||
* @param[in] params params of action
|
||||
* @param[out] index @see UsrActionIndex
|
||||
* @return 0 for success, QCLOUD_ERR_JSON_PARSE for invalid json.
|
||||
*/
|
||||
int usr_data_template_action_parse(UtilsJsonValue action_id, UtilsJsonValue params, UsrActionIndex* index)
|
||||
{
|
||||
DataTemplateProperty* property;
|
||||
|
||||
int input_property_count;
|
||||
|
||||
for (int i = 0; i < TOTAL_USR_ACTION_COUNT; i++) {
|
||||
if (!strncmp(action_id.value, sg_usr_data_template_action[i].action_id, action_id.value_len)) {
|
||||
property = sg_usr_data_template_action[i].input_struct.value_struct.property;
|
||||
input_property_count = sg_usr_data_template_action[i].input_struct.value_struct.count;
|
||||
|
||||
// 1. reset need report
|
||||
for (int j = 0; j < input_property_count; j++) {
|
||||
property[j].need_report = 0;
|
||||
}
|
||||
|
||||
// 2. parse
|
||||
_parse_property_array(params.value, params.value_len, property, input_property_count);
|
||||
|
||||
// 3. check all the input params is set
|
||||
for (int j = 0; j < input_property_count; j++) {
|
||||
if (!property[j].need_report) {
|
||||
return QCLOUD_ERR_JSON_PARSE;
|
||||
}
|
||||
}
|
||||
*index = i;
|
||||
return QCLOUD_RET_SUCCESS;
|
||||
}
|
||||
}
|
||||
return QCLOUD_ERR_JSON_PARSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get input value, should call after usr_data_template_action_parse
|
||||
*
|
||||
* @param[in] index index get from usr_data_template_action_parse
|
||||
* @param[in] property_index property index of action input params
|
||||
* @return @see DataTemplatePropertyValue
|
||||
*/
|
||||
DataTemplatePropertyValue usr_data_template_action_input_value_get(UsrActionIndex index, int property_index)
|
||||
{
|
||||
return sg_usr_data_template_action[index].input_struct.value_struct.property[property_index].value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Reply action, should call after parse action message.
|
||||
*
|
||||
* @param[in,out] client pointer to mqtt client
|
||||
* @param[in] buf buffer to report
|
||||
* @param[in] buf_len buffer length
|
||||
* @param[in] index @see UsrActionIndex
|
||||
* @param[in] client_token client token of action message
|
||||
* @param[in] code result code for action, 0 for success
|
||||
* @param[in] response action output params, user should construct params according to action
|
||||
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
|
||||
*/
|
||||
int usr_data_template_action_reply(void* client, char* buf, int buf_len, UsrActionIndex index,
|
||||
UtilsJsonValue client_token, int code, const char* response)
|
||||
{
|
||||
sg_usr_data_template_action[index].reply.code = code;
|
||||
sg_usr_data_template_action[index].reply.client_token = client_token;
|
||||
sg_usr_data_template_action[index].reply.response = response;
|
||||
return IOT_DataTemplate_ActionReply(client, buf, buf_len, sg_usr_data_template_action[index].reply);
|
||||
}
|
||||
|
|
@ -0,0 +1,264 @@
|
|||
/**
|
||||
* @copyright
|
||||
*
|
||||
* Tencent is pleased to support the open source community by making IoT Hub available.
|
||||
* Copyright(C) 2018 - 2021 THL A29 Limited, a Tencent company.All rights reserved.
|
||||
*
|
||||
* Licensed under the MIT License(the "License"); you may not use this file except in
|
||||
* compliance with the License. You may obtain a copy of the License at
|
||||
* http://opensource.org/licenses/MIT
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @file data_template_config.h
|
||||
* @brief
|
||||
* @author fancyxu (fancyxu@tencent.com)
|
||||
* @version 1.0
|
||||
* @date 2021-10-09
|
||||
*
|
||||
* @par Change Log:
|
||||
* <table>
|
||||
* <tr><th>Date <th>Version <th>Author <th>Description
|
||||
* <tr><td>2021-10-09 <td>1.0 <td>fancyxu <td>first commit
|
||||
* </table>
|
||||
*/
|
||||
|
||||
#ifndef IOT_HUB_DEVICE_C_SDK_APP_DATA_TEMPLATE_DATA_TEMPLATE_CONFIG_H_
|
||||
#define IOT_HUB_DEVICE_C_SDK_APP_DATA_TEMPLATE_DATA_TEMPLATE_CONFIG_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "qcloud_iot_common.h"
|
||||
#include "qcloud_iot_data_template.h"
|
||||
|
||||
/**
|
||||
* @brief Type of property.
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
// basic type
|
||||
DATA_TEMPLATE_TYPE_INT,
|
||||
DATA_TEMPLATE_TYPE_ENUM,
|
||||
DATA_TEMPLATE_TYPE_STRING_ENUM,
|
||||
DATA_TEMPLATE_TYPE_FLOAT,
|
||||
DATA_TEMPLATE_TYPE_BOOL,
|
||||
DATA_TEMPLATE_TYPE_STRING,
|
||||
DATA_TEMPLATE_TYPE_TIME,
|
||||
// construct by basic type
|
||||
DATA_TEMPLATE_TYPE_STRUCT,
|
||||
DATA_TEMPLATE_TYPE_ARRAY,
|
||||
} DataTemplatePropertyType;
|
||||
|
||||
/**
|
||||
* @brief Declaration.
|
||||
*
|
||||
*/
|
||||
typedef struct DataTemplateProperty DataTemplateProperty;
|
||||
typedef union DataTemplatePropertyValue DataTemplatePropertyValue;
|
||||
|
||||
/**
|
||||
* @brief Property value definition.
|
||||
*
|
||||
*/
|
||||
union DataTemplatePropertyValue {
|
||||
int32_t value_int;
|
||||
int32_t value_enum;
|
||||
char* value_string_enum;
|
||||
float value_float;
|
||||
int32_t value_bool;
|
||||
char* value_string;
|
||||
uint32_t value_time;
|
||||
struct {
|
||||
DataTemplateProperty* property;
|
||||
int count;
|
||||
} value_struct;
|
||||
DataTemplatePropertyValue* value_arrary; /**< not supportted yet */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Property definition.
|
||||
*
|
||||
*/
|
||||
struct DataTemplateProperty {
|
||||
DataTemplatePropertyType type;
|
||||
const char* key;
|
||||
DataTemplatePropertyValue value;
|
||||
int need_report;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Event definition.
|
||||
*
|
||||
*/
|
||||
#define DataTemplateEvent IotDataTemplateEventData
|
||||
|
||||
/**
|
||||
* @brief Action definition.
|
||||
*
|
||||
*/
|
||||
typedef struct {
|
||||
const char* action_id;
|
||||
DataTemplatePropertyValue input_struct;
|
||||
IotDataTemplateActionReply reply;
|
||||
} DataTemplateAction;
|
||||
|
||||
/**************************************************************************************
|
||||
* usr data template definition
|
||||
**************************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
USR_PROPERTY_INDEX_POWER_SWITCH = 0,
|
||||
USR_PROPERTY_INDEX_COLOR,
|
||||
USR_PROPERTY_INDEX_BRIGHTNESS,
|
||||
USR_PROPERTY_INDEX_NAME,
|
||||
USR_PROPERTY_INDEX_POSITION,
|
||||
USR_PROPERTY_INDEX_POWER,
|
||||
} UsrPropertyIndex;
|
||||
|
||||
typedef enum {
|
||||
USR_PROPERTY_POSITION_INDEX_LONGITUDE = 0,
|
||||
USR_PROPERTY_POSITION_INDEX_LATITUDE,
|
||||
} UsrPropertyPositionIndex;
|
||||
|
||||
typedef enum {
|
||||
USR_EVENT_INDEX_STATUS_REPORT = 0,
|
||||
USR_EVENT_INDEX_LOW_VOLTAGE,
|
||||
USR_EVENT_INDEX_HARDWARE_FAULT,
|
||||
} UsrEventIndex;
|
||||
|
||||
typedef enum {
|
||||
USR_ACTION_INDEX_LIGHT_BLINK = 0,
|
||||
} UsrActionIndex;
|
||||
|
||||
typedef enum {
|
||||
USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TIME = 0,
|
||||
USR_ACTION_LIGHT_BLINK_INPUT_INDEX_COLOR,
|
||||
USR_ACTION_LIGHT_BLINK_INPUT_INDEX_TOTAL_TIME,
|
||||
} UsrActionLightBlinkInputIndex;
|
||||
|
||||
/**************************************************************************************
|
||||
* api for user data template
|
||||
**************************************************************************************/
|
||||
|
||||
/**
|
||||
* @brief Init user data template(property/event/action).
|
||||
*
|
||||
*/
|
||||
void usr_data_template_init(void);
|
||||
|
||||
/**
|
||||
* @brief Get property value.
|
||||
*
|
||||
* @param[in] index @see UsrPropertyIndex
|
||||
* @return @see DataTemplatePropertyValue
|
||||
*/
|
||||
DataTemplatePropertyValue usr_data_template_property_value_get(UsrPropertyIndex index);
|
||||
|
||||
/**
|
||||
* @brief Set property value.
|
||||
*
|
||||
* @param[in] index @see UsrPropertyIndex
|
||||
* @param[in] value @see DataTemplatePropertyValue, @note value should match property type.
|
||||
*/
|
||||
void usr_data_template_property_value_set(UsrPropertyIndex index, DataTemplatePropertyValue value);
|
||||
|
||||
/**
|
||||
* @brief Get property(struct) value.
|
||||
*
|
||||
* @param[in] struct_index @see UsrPropertyIndex, @note DATA_TEMPLATE_TYPE_STRUCT is required here.
|
||||
* @param[in] property_index depends on which struct
|
||||
* @return @see DataTemplatePropertyValue
|
||||
*/
|
||||
DataTemplatePropertyValue usr_data_template_property_struct_value_get(UsrPropertyIndex struct_index,
|
||||
int property_index);
|
||||
|
||||
/**
|
||||
* @brief Set property(struct) value.
|
||||
*
|
||||
* @param[in] struct_index @see UsrPropertyIndex, @note DATA_TEMPLATE_TYPE_STRUCT is required here.
|
||||
* @param[in] property_index depends on which struct
|
||||
* @param[in] value @see DataTemplatePropertyValue, @note value should match property type.
|
||||
*/
|
||||
void usr_data_template_property_struct_value_set(UsrPropertyIndex struct_index, int property_index,
|
||||
DataTemplatePropertyValue value);
|
||||
|
||||
/**
|
||||
* @brief Parse control message and set property value.
|
||||
*
|
||||
* @param[in] params params filed of control message
|
||||
*/
|
||||
void usr_data_template_property_parse(UtilsJsonValue params);
|
||||
|
||||
/**
|
||||
* @brief Get property status.
|
||||
*
|
||||
* @param[in] index @see UsrPropertyIndex
|
||||
* @return need_report
|
||||
*/
|
||||
int usr_data_template_property_status_get(UsrPropertyIndex index);
|
||||
|
||||
/**
|
||||
* @brief Report all the properties needed report.
|
||||
*
|
||||
* @param[in,out] client pointer to mqtt client
|
||||
* @param[in] buf buffer to report
|
||||
* @param[in] buf_len buffer length
|
||||
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
|
||||
*/
|
||||
int usr_data_template_property_report(void* client, char* buf, int buf_len);
|
||||
|
||||
/**
|
||||
* @brief Post event.
|
||||
*
|
||||
* @param[in,out] client pointer to mqtt client
|
||||
* @param[in] buf buffer to report
|
||||
* @param[in] buf_len buffer length
|
||||
* @param[in] id @see UsrEventIndex
|
||||
* @param[in] params user should construct params according to event.
|
||||
*/
|
||||
void usr_data_template_event_post(void* client, char* buf, int buf_len, UsrEventIndex id, const char* params);
|
||||
|
||||
/**
|
||||
* @brief Parse action message and set action input params.
|
||||
*
|
||||
* @param[in] action_id action id
|
||||
* @param[in] params params of action
|
||||
* @param[out] index @see UsrActionIndex
|
||||
* @return 0 for success, QCLOUD_ERR_JSON_PARSE for invalid json.
|
||||
*/
|
||||
int usr_data_template_action_parse(UtilsJsonValue action_id, UtilsJsonValue params, UsrActionIndex* index);
|
||||
|
||||
/**
|
||||
* @brief Get input value, should call after usr_data_template_action_parse
|
||||
*
|
||||
* @param[in] index index get from usr_data_template_action_parse
|
||||
* @param[in] property_index property index of action input params
|
||||
* @return @see DataTemplatePropertyValue
|
||||
*/
|
||||
DataTemplatePropertyValue usr_data_template_action_input_value_get(UsrActionIndex index, int property_index);
|
||||
|
||||
/**
|
||||
* @brief Reply action, should call after parse action message.
|
||||
*
|
||||
* @param[in,out] client pointer to mqtt client
|
||||
* @param[in] buf buffer to report
|
||||
* @param[in] buf_len buffer length
|
||||
* @param[in] index @see UsrActionIndex
|
||||
* @param[in] client_token client token of action message
|
||||
* @param[in] code result code for action, 0 for success
|
||||
* @param[in] response action output params, user should construct params according to action
|
||||
* @return packet id (>=0) when success, or err code (<0) @see IotReturnCode
|
||||
*/
|
||||
int usr_data_template_action_reply(void* client, char* buf, int buf_len, UsrActionIndex index,
|
||||
UtilsJsonValue client_token, int code, const char* response);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // IOT_HUB_DEVICE_C_SDK_APP_DATA_TEMPLATE_DATA_TEMPLATE_CONFIG_H_
|
||||
|
|
@ -0,0 +1,404 @@
|
|||
;********************** COPYRIGHT(c) 2017 STMicroelectronics ******************
|
||||
;* File Name : startup_stm32l431xx.s
|
||||
;* Author : MCD Application Team
|
||||
;* Description : STM32L431xx Ultra Low Power devices vector table for MDK-ARM toolchain.
|
||||
;* This module performs:
|
||||
;* - Set the initial SP
|
||||
;* - Set the initial PC == Reset_Handler
|
||||
;* - Set the vector table entries with the exceptions ISR address
|
||||
;* - Branches to __main in the C library (which eventually
|
||||
;* calls main()).
|
||||
;* After Reset the Cortex-M4 processor is in Thread mode,
|
||||
;* priority is Privileged, and the Stack is set to Main.
|
||||
;* <<< Use Configuration Wizard in Context Menu >>>
|
||||
;*******************************************************************************
|
||||
;*
|
||||
;* Redistribution and use in source and binary forms, with or without modification,
|
||||
;* are permitted provided that the following conditions are met:
|
||||
;* 1. Redistributions of source code must retain the above copyright notice,
|
||||
;* this list of conditions and the following disclaimer.
|
||||
;* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
;* this list of conditions and the following disclaimer in the documentation
|
||||
;* and/or other materials provided with the distribution.
|
||||
;* 3. Neither the name of STMicroelectronics nor the names of its contributors
|
||||
;* may be used to endorse or promote products derived from this software
|
||||
;* without specific prior written permission.
|
||||
;*
|
||||
;* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
;* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
;* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
;* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
;* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
;* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
;* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
;* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
;* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
;* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
;*
|
||||
;*******************************************************************************
|
||||
;
|
||||
; Amount of memory (in bytes) allocated for Stack
|
||||
; Tailor this value to your application needs
|
||||
; <h> Stack Configuration
|
||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Stack_Size EQU 0x100
|
||||
|
||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||
Stack_Mem SPACE Stack_Size
|
||||
__initial_sp
|
||||
|
||||
|
||||
; <h> Heap Configuration
|
||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||
; </h>
|
||||
|
||||
Heap_Size EQU 0x100
|
||||
|
||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||
__heap_base
|
||||
Heap_Mem SPACE Heap_Size
|
||||
__heap_limit
|
||||
|
||||
PRESERVE8
|
||||
THUMB
|
||||
|
||||
|
||||
; Vector Table Mapped to Address 0 at Reset
|
||||
AREA RESET, DATA, READONLY
|
||||
EXPORT __Vectors
|
||||
EXPORT __Vectors_End
|
||||
EXPORT __Vectors_Size
|
||||
|
||||
__Vectors DCD __initial_sp ; Top of Stack
|
||||
DCD Reset_Handler ; Reset Handler
|
||||
DCD NMI_Handler ; NMI Handler
|
||||
DCD HardFault_Handler ; Hard Fault Handler
|
||||
DCD MemManage_Handler ; MPU Fault Handler
|
||||
DCD BusFault_Handler ; Bus Fault Handler
|
||||
DCD UsageFault_Handler ; Usage Fault Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SVC_Handler ; SVCall Handler
|
||||
DCD DebugMon_Handler ; Debug Monitor Handler
|
||||
DCD 0 ; Reserved
|
||||
DCD PendSV_Handler ; PendSV Handler
|
||||
DCD SysTick_Handler ; SysTick Handler
|
||||
|
||||
; External Interrupts
|
||||
DCD WWDG_IRQHandler ; Window WatchDog
|
||||
DCD PVD_PVM_IRQHandler ; PVD/PVM1/PVM2/PVM3/PVM4 through EXTI Line detection
|
||||
DCD TAMP_STAMP_IRQHandler ; Tamper and TimeStamps through the EXTI line
|
||||
DCD RTC_WKUP_IRQHandler ; RTC Wakeup through the EXTI line
|
||||
DCD FLASH_IRQHandler ; FLASH
|
||||
DCD RCC_IRQHandler ; RCC
|
||||
DCD EXTI0_IRQHandler ; EXTI Line0
|
||||
DCD EXTI1_IRQHandler ; EXTI Line1
|
||||
DCD EXTI2_IRQHandler ; EXTI Line2
|
||||
DCD EXTI3_IRQHandler ; EXTI Line3
|
||||
DCD EXTI4_IRQHandler ; EXTI Line4
|
||||
DCD DMA1_Channel1_IRQHandler ; DMA1 Channel 1
|
||||
DCD DMA1_Channel2_IRQHandler ; DMA1 Channel 2
|
||||
DCD DMA1_Channel3_IRQHandler ; DMA1 Channel 3
|
||||
DCD DMA1_Channel4_IRQHandler ; DMA1 Channel 4
|
||||
DCD DMA1_Channel5_IRQHandler ; DMA1 Channel 5
|
||||
DCD DMA1_Channel6_IRQHandler ; DMA1 Channel 6
|
||||
DCD DMA1_Channel7_IRQHandler ; DMA1 Channel 7
|
||||
DCD ADC1_IRQHandler ; ADC1
|
||||
DCD CAN1_TX_IRQHandler ; CAN1 TX
|
||||
DCD CAN1_RX0_IRQHandler ; CAN1 RX0
|
||||
DCD CAN1_RX1_IRQHandler ; CAN1 RX1
|
||||
DCD CAN1_SCE_IRQHandler ; CAN1 SCE
|
||||
DCD EXTI9_5_IRQHandler ; External Line[9:5]s
|
||||
DCD TIM1_BRK_TIM15_IRQHandler ; TIM1 Break and TIM15
|
||||
DCD TIM1_UP_TIM16_IRQHandler ; TIM1 Update and TIM16
|
||||
DCD TIM1_TRG_COM_IRQHandler ; TIM1 Trigger and Commutation
|
||||
DCD TIM1_CC_IRQHandler ; TIM1 Capture Compare
|
||||
DCD TIM2_IRQHandler ; TIM2
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD I2C1_EV_IRQHandler ; I2C1 Event
|
||||
DCD I2C1_ER_IRQHandler ; I2C1 Error
|
||||
DCD I2C2_EV_IRQHandler ; I2C2 Event
|
||||
DCD I2C2_ER_IRQHandler ; I2C2 Error
|
||||
DCD SPI1_IRQHandler ; SPI1
|
||||
DCD SPI2_IRQHandler ; SPI2
|
||||
DCD USART1_IRQHandler ; USART1
|
||||
DCD USART2_IRQHandler ; USART2
|
||||
DCD USART3_IRQHandler ; USART3
|
||||
DCD EXTI15_10_IRQHandler ; External Line[15:10]
|
||||
DCD RTC_Alarm_IRQHandler ; RTC Alarm (A and B) through EXTI Line
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD SDMMC1_IRQHandler ; SDMMC1
|
||||
DCD 0 ; Reserved
|
||||
DCD SPI3_IRQHandler ; SPI3
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD TIM6_DAC_IRQHandler ; TIM6 and DAC1&2 underrun errors
|
||||
DCD TIM7_IRQHandler ; TIM7
|
||||
DCD DMA2_Channel1_IRQHandler ; DMA2 Channel 1
|
||||
DCD DMA2_Channel2_IRQHandler ; DMA2 Channel 2
|
||||
DCD DMA2_Channel3_IRQHandler ; DMA2 Channel 3
|
||||
DCD DMA2_Channel4_IRQHandler ; DMA2 Channel 4
|
||||
DCD DMA2_Channel5_IRQHandler ; DMA2 Channel 5
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD COMP_IRQHandler ; COMP Interrupt
|
||||
DCD LPTIM1_IRQHandler ; LP TIM1 interrupt
|
||||
DCD LPTIM2_IRQHandler ; LP TIM2 interrupt
|
||||
DCD 0 ; Reserved
|
||||
DCD DMA2_Channel6_IRQHandler ; DMA2 Channel 6
|
||||
DCD DMA2_Channel7_IRQHandler ; DMA2 Channel 7
|
||||
DCD LPUART1_IRQHandler ; LP UART1 interrupt
|
||||
DCD QUADSPI_IRQHandler ; Quad SPI global interrupt
|
||||
DCD I2C3_EV_IRQHandler ; I2C3 event
|
||||
DCD I2C3_ER_IRQHandler ; I2C3 error
|
||||
DCD SAI1_IRQHandler ; Serial Audio Interface 1 global interrupt
|
||||
DCD 0 ; Reserved
|
||||
DCD SWPMI1_IRQHandler ; Serial Wire Interface 1 global interrupt
|
||||
DCD TSC_IRQHandler ; Touch Sense Controller global interrupt
|
||||
DCD 0 ; Reserved
|
||||
DCD 0 ; Reserved
|
||||
DCD RNG_IRQHandler ; RNG global interrupt
|
||||
DCD FPU_IRQHandler ; FPU
|
||||
DCD CRS_IRQHandler ; CRS interrupt
|
||||
|
||||
__Vectors_End
|
||||
|
||||
__Vectors_Size EQU __Vectors_End - __Vectors
|
||||
|
||||
AREA |.text|, CODE, READONLY
|
||||
|
||||
; Reset handler
|
||||
Reset_Handler PROC
|
||||
EXPORT Reset_Handler [WEAK]
|
||||
IMPORT SystemInit
|
||||
IMPORT __main
|
||||
|
||||
LDR R0, =SystemInit
|
||||
BLX R0
|
||||
LDR R0, =__main
|
||||
BX R0
|
||||
ENDP
|
||||
|
||||
; Dummy Exception Handlers (infinite loops which can be modified)
|
||||
|
||||
NMI_Handler PROC
|
||||
EXPORT NMI_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
HardFault_Handler\
|
||||
PROC
|
||||
EXPORT HardFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
MemManage_Handler\
|
||||
PROC
|
||||
EXPORT MemManage_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
BusFault_Handler\
|
||||
PROC
|
||||
EXPORT BusFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
UsageFault_Handler\
|
||||
PROC
|
||||
EXPORT UsageFault_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SVC_Handler PROC
|
||||
EXPORT SVC_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
DebugMon_Handler\
|
||||
PROC
|
||||
EXPORT DebugMon_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
PendSV_Handler PROC
|
||||
EXPORT PendSV_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
SysTick_Handler PROC
|
||||
EXPORT SysTick_Handler [WEAK]
|
||||
B .
|
||||
ENDP
|
||||
|
||||
Default_Handler PROC
|
||||
|
||||
EXPORT WWDG_IRQHandler [WEAK]
|
||||
EXPORT PVD_PVM_IRQHandler [WEAK]
|
||||
EXPORT TAMP_STAMP_IRQHandler [WEAK]
|
||||
EXPORT RTC_WKUP_IRQHandler [WEAK]
|
||||
EXPORT FLASH_IRQHandler [WEAK]
|
||||
EXPORT RCC_IRQHandler [WEAK]
|
||||
EXPORT EXTI0_IRQHandler [WEAK]
|
||||
EXPORT EXTI1_IRQHandler [WEAK]
|
||||
EXPORT EXTI2_IRQHandler [WEAK]
|
||||
EXPORT EXTI3_IRQHandler [WEAK]
|
||||
EXPORT EXTI4_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel1_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel2_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel3_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel4_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel5_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel6_IRQHandler [WEAK]
|
||||
EXPORT DMA1_Channel7_IRQHandler [WEAK]
|
||||
EXPORT ADC1_IRQHandler [WEAK]
|
||||
EXPORT CAN1_TX_IRQHandler [WEAK]
|
||||
EXPORT CAN1_RX0_IRQHandler [WEAK]
|
||||
EXPORT CAN1_RX1_IRQHandler [WEAK]
|
||||
EXPORT CAN1_SCE_IRQHandler [WEAK]
|
||||
EXPORT EXTI9_5_IRQHandler [WEAK]
|
||||
EXPORT TIM1_BRK_TIM15_IRQHandler [WEAK]
|
||||
EXPORT TIM1_UP_TIM16_IRQHandler [WEAK]
|
||||
EXPORT TIM1_TRG_COM_IRQHandler [WEAK]
|
||||
EXPORT TIM1_CC_IRQHandler [WEAK]
|
||||
EXPORT TIM2_IRQHandler [WEAK]
|
||||
EXPORT I2C1_EV_IRQHandler [WEAK]
|
||||
EXPORT I2C1_ER_IRQHandler [WEAK]
|
||||
EXPORT I2C2_EV_IRQHandler [WEAK]
|
||||
EXPORT I2C2_ER_IRQHandler [WEAK]
|
||||
EXPORT SPI1_IRQHandler [WEAK]
|
||||
EXPORT SPI2_IRQHandler [WEAK]
|
||||
EXPORT USART1_IRQHandler [WEAK]
|
||||
EXPORT USART2_IRQHandler [WEAK]
|
||||
EXPORT USART3_IRQHandler [WEAK]
|
||||
EXPORT EXTI15_10_IRQHandler [WEAK]
|
||||
EXPORT RTC_Alarm_IRQHandler [WEAK]
|
||||
EXPORT SDMMC1_IRQHandler [WEAK]
|
||||
EXPORT SPI3_IRQHandler [WEAK]
|
||||
EXPORT TIM6_DAC_IRQHandler [WEAK]
|
||||
EXPORT TIM7_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Channel1_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Channel2_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Channel3_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Channel4_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Channel5_IRQHandler [WEAK]
|
||||
EXPORT COMP_IRQHandler [WEAK]
|
||||
EXPORT LPTIM1_IRQHandler [WEAK]
|
||||
EXPORT LPTIM2_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Channel6_IRQHandler [WEAK]
|
||||
EXPORT DMA2_Channel7_IRQHandler [WEAK]
|
||||
EXPORT LPUART1_IRQHandler [WEAK]
|
||||
EXPORT QUADSPI_IRQHandler [WEAK]
|
||||
EXPORT I2C3_EV_IRQHandler [WEAK]
|
||||
EXPORT I2C3_ER_IRQHandler [WEAK]
|
||||
EXPORT SAI1_IRQHandler [WEAK]
|
||||
EXPORT SWPMI1_IRQHandler [WEAK]
|
||||
EXPORT TSC_IRQHandler [WEAK]
|
||||
EXPORT RNG_IRQHandler [WEAK]
|
||||
EXPORT FPU_IRQHandler [WEAK]
|
||||
EXPORT CRS_IRQHandler [WEAK]
|
||||
|
||||
WWDG_IRQHandler
|
||||
PVD_PVM_IRQHandler
|
||||
TAMP_STAMP_IRQHandler
|
||||
RTC_WKUP_IRQHandler
|
||||
FLASH_IRQHandler
|
||||
RCC_IRQHandler
|
||||
EXTI0_IRQHandler
|
||||
EXTI1_IRQHandler
|
||||
EXTI2_IRQHandler
|
||||
EXTI3_IRQHandler
|
||||
EXTI4_IRQHandler
|
||||
DMA1_Channel1_IRQHandler
|
||||
DMA1_Channel2_IRQHandler
|
||||
DMA1_Channel3_IRQHandler
|
||||
DMA1_Channel4_IRQHandler
|
||||
DMA1_Channel5_IRQHandler
|
||||
DMA1_Channel6_IRQHandler
|
||||
DMA1_Channel7_IRQHandler
|
||||
ADC1_IRQHandler
|
||||
CAN1_TX_IRQHandler
|
||||
CAN1_RX0_IRQHandler
|
||||
CAN1_RX1_IRQHandler
|
||||
CAN1_SCE_IRQHandler
|
||||
EXTI9_5_IRQHandler
|
||||
TIM1_BRK_TIM15_IRQHandler
|
||||
TIM1_UP_TIM16_IRQHandler
|
||||
TIM1_TRG_COM_IRQHandler
|
||||
TIM1_CC_IRQHandler
|
||||
TIM2_IRQHandler
|
||||
I2C1_EV_IRQHandler
|
||||
I2C1_ER_IRQHandler
|
||||
I2C2_EV_IRQHandler
|
||||
I2C2_ER_IRQHandler
|
||||
SPI1_IRQHandler
|
||||
SPI2_IRQHandler
|
||||
USART1_IRQHandler
|
||||
USART2_IRQHandler
|
||||
USART3_IRQHandler
|
||||
EXTI15_10_IRQHandler
|
||||
RTC_Alarm_IRQHandler
|
||||
SDMMC1_IRQHandler
|
||||
SPI3_IRQHandler
|
||||
TIM6_DAC_IRQHandler
|
||||
TIM7_IRQHandler
|
||||
DMA2_Channel1_IRQHandler
|
||||
DMA2_Channel2_IRQHandler
|
||||
DMA2_Channel3_IRQHandler
|
||||
DMA2_Channel4_IRQHandler
|
||||
DMA2_Channel5_IRQHandler
|
||||
COMP_IRQHandler
|
||||
LPTIM1_IRQHandler
|
||||
LPTIM2_IRQHandler
|
||||
DMA2_Channel6_IRQHandler
|
||||
DMA2_Channel7_IRQHandler
|
||||
LPUART1_IRQHandler
|
||||
QUADSPI_IRQHandler
|
||||
I2C3_EV_IRQHandler
|
||||
I2C3_ER_IRQHandler
|
||||
SAI1_IRQHandler
|
||||
SWPMI1_IRQHandler
|
||||
TSC_IRQHandler
|
||||
RNG_IRQHandler
|
||||
FPU_IRQHandler
|
||||
CRS_IRQHandler
|
||||
|
||||
B .
|
||||
|
||||
ENDP
|
||||
|
||||
ALIGN
|
||||
|
||||
;*******************************************************************************
|
||||
; User Stack and Heap initialization
|
||||
;*******************************************************************************
|
||||
IF :DEF:__MICROLIB
|
||||
|
||||
EXPORT __initial_sp
|
||||
EXPORT __heap_base
|
||||
EXPORT __heap_limit
|
||||
|
||||
ELSE
|
||||
|
||||
IMPORT __use_two_region_memory
|
||||
EXPORT __user_initial_stackheap
|
||||
|
||||
__user_initial_stackheap
|
||||
|
||||
LDR R0, = Heap_Mem
|
||||
LDR R1, =(Stack_Mem + Stack_Size)
|
||||
LDR R2, = (Heap_Mem + Heap_Size)
|
||||
LDR R3, = Stack_Mem
|
||||
BX LR
|
||||
|
||||
ALIGN
|
||||
|
||||
ENDIF
|
||||
|
||||
END
|
||||
|
||||
;************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE*****
|
||||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#define TOS_CFG_ROUND_ROBIN_EN 0u
|
||||
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u
|
||||
|
||||
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
|
||||
#define TOS_CFG_OBJ_DYNAMIC_CREATE_EN 1u
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#define TOS_CFG_ROUND_ROBIN_EN 0u
|
||||
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u
|
||||
|
||||
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 1u
|
||||
#define TOS_CFG_OBJ_DYNAMIC_CREATE_EN 1u
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u
|
||||
|
||||
|
|
|
|||
|
|
@ -305,9 +305,6 @@ void application_entry(void *arg)
|
|||
{
|
||||
char *str = "TencentOS-tiny";
|
||||
|
||||
// 初始化tencent-os tiny定时器模块
|
||||
timer_init();
|
||||
|
||||
// 初始化按键检测模块
|
||||
stm32g0xx_key_init();
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#define TOS_CFG_ROUND_ROBIN_EN 1u
|
||||
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 0u
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u
|
||||
|
||||
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
|
||||
#define TOS_CFG_OBJ_DYNAMIC_CREATE_EN 1u
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,9 @@
|
|||
#define TOS_CFG_ROUND_ROBIN_EN 0u
|
||||
|
||||
|
||||
#define TOS_CFG_OBJECT_VERIFY 0u
|
||||
|
||||
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
|
||||
#define TOS_CFG_OBJECT_VERIFY 1u
|
||||
|
||||
#define TOS_CFG_OBJ_DYNAMIC_CREATE_EN 1u
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#define TOS_CFG_ROUND_ROBIN_EN 0u
|
||||
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u
|
||||
|
||||
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 1u
|
||||
#define TOS_CFG_OBJ_DYNAMIC_CREATE_EN 1u
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u
|
||||
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@
|
|||
|
||||
#define TOS_CFG_ROUND_ROBIN_EN 1u
|
||||
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 0u
|
||||
#define TOS_CFG_OBJECT_VERIFY_EN 1u
|
||||
|
||||
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u
|
||||
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 1u
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ bool HAL_Timer_Expired(Timer *timer)
|
|||
* @param[in,out] timer @see Timer
|
||||
* @param[in] timeout_ms ms to count down
|
||||
*/
|
||||
void HAL_Timer_CountdownMs(Timer *timer, unsigned int timeout_ms)
|
||||
void HAL_Timer_CountdownMs(Timer *timer, uint32_t timeout_ms)
|
||||
{
|
||||
k_tick_t tick;
|
||||
k_tick_t now;
|
||||
|
|
@ -81,7 +81,7 @@ void HAL_Timer_CountdownMs(Timer *timer, unsigned int timeout_ms)
|
|||
* @param[in,out] timer @see Timer
|
||||
* @param[in] timeout second to count down
|
||||
*/
|
||||
void HAL_Timer_Countdown(Timer *timer, unsigned int timeout)
|
||||
void HAL_Timer_Countdown(Timer *timer, uint32_t timeout)
|
||||
{
|
||||
k_tick_t now;
|
||||
k_tick_t tick;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,406 @@
|
|||
/*----------------------------------------------------------------------------/
|
||||
/ FatFs - Generic FAT Filesystem module R0.13c /
|
||||
/-----------------------------------------------------------------------------/
|
||||
/
|
||||
/ Copyright (C) 2018, ChaN, all right reserved.
|
||||
/
|
||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
||||
/ source and binary forms, with or without modification, are permitted provided
|
||||
/ that the following condition is met:
|
||||
|
||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
||||
/ this condition and the following disclaimer.
|
||||
/
|
||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
||||
/ and any warranties related to this software are DISCLAIMED.
|
||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
||||
/ by use of this software.
|
||||
/
|
||||
/----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
#ifndef FF_DEFINED
|
||||
#define FF_DEFINED 86604 /* Revision ID */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "ffconf.h" /* FatFs configuration options */
|
||||
|
||||
#if FF_DEFINED != FFCONF_DEF
|
||||
#error Wrong configuration file (ffconf.h).
|
||||
#endif
|
||||
|
||||
|
||||
/* Integer types used for FatFs API */
|
||||
|
||||
#if defined(_WIN32) /* Main development platform */
|
||||
#define FF_INTDEF 2
|
||||
#include <windows.h>
|
||||
typedef unsigned __int64 QWORD;
|
||||
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
||||
#define FF_INTDEF 2
|
||||
#include <stdint.h>
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef uint16_t WORD; /* 16-bit unsigned integer */
|
||||
typedef uint16_t WCHAR; /* 16-bit unsigned integer */
|
||||
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
||||
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
||||
#else /* Earlier than C99 */
|
||||
#define FF_INTDEF 1
|
||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
||||
typedef unsigned short WORD; /* 16-bit unsigned integer */
|
||||
typedef unsigned short WCHAR; /* 16-bit unsigned integer */
|
||||
typedef unsigned long DWORD; /* 32-bit unsigned integer */
|
||||
#endif
|
||||
|
||||
|
||||
/* Definitions of volume management */
|
||||
|
||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
||||
typedef struct {
|
||||
BYTE pd; /* Physical drive number */
|
||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
||||
} PARTITION;
|
||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
||||
#endif
|
||||
|
||||
#if FF_STR_VOLUME_ID
|
||||
#ifndef FF_VOLUME_STRS
|
||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of path name strings on FatFs API */
|
||||
|
||||
#ifndef _INC_TCHAR
|
||||
#define _INC_TCHAR
|
||||
|
||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
||||
typedef WCHAR TCHAR;
|
||||
#define _T(x) L ## x
|
||||
#define _TEXT(x) L ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) u8 ## x
|
||||
#define _TEXT(x) u8 ## x
|
||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
|
||||
typedef DWORD TCHAR;
|
||||
#define _T(x) U ## x
|
||||
#define _TEXT(x) U ## x
|
||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
|
||||
#error Wrong FF_LFN_UNICODE setting
|
||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
||||
typedef char TCHAR;
|
||||
#define _T(x) x
|
||||
#define _TEXT(x) x
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Type of file size variables */
|
||||
|
||||
#if FF_FS_EXFAT
|
||||
#if FF_INTDEF != 2
|
||||
#error exFAT feature wants C99 or later
|
||||
#endif
|
||||
typedef QWORD FSIZE_t;
|
||||
#else
|
||||
typedef DWORD FSIZE_t;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Filesystem object structure (FATFS) */
|
||||
|
||||
typedef struct {
|
||||
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
||||
BYTE pdrv; /* Associated physical drive */
|
||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
||||
WORD id; /* Volume mount ID */
|
||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
||||
WORD csize; /* Cluster size [sectors] */
|
||||
#if FF_MAX_SS != FF_MIN_SS
|
||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
||||
#endif
|
||||
#if FF_USE_LFN
|
||||
WCHAR* lfnbuf; /* LFN working buffer */
|
||||
#endif
|
||||
#if FF_FS_EXFAT
|
||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
||||
#endif
|
||||
#if FF_FS_REENTRANT
|
||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
||||
#endif
|
||||
#if !FF_FS_READONLY
|
||||
DWORD last_clst; /* Last allocated cluster */
|
||||
DWORD free_clst; /* Number of free clusters */
|
||||
#endif
|
||||
#if FF_FS_RPATH
|
||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
||||
#endif
|
||||
#endif
|
||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
||||
DWORD fsize; /* Size of an FAT [sectors] */
|
||||
DWORD volbase; /* Volume base sector */
|
||||
DWORD fatbase; /* FAT base sector */
|
||||
DWORD dirbase; /* Root directory base sector/cluster */
|
||||
DWORD database; /* Data base sector */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD bitbase; /* Allocation bitmap base sector */
|
||||
#endif
|
||||
DWORD winsect; /* Current sector appearing in the win[] */
|
||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
||||
} FATFS;
|
||||
|
||||
|
||||
|
||||
/* Object ID and allocation information (FFOBJID) */
|
||||
|
||||
typedef struct {
|
||||
FATFS* fs; /* Pointer to the hosting volume of this object */
|
||||
WORD id; /* Hosting volume mount ID */
|
||||
BYTE attr; /* Object attribute */
|
||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
|
||||
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
||||
#if FF_FS_EXFAT
|
||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
||||
#endif
|
||||
#if FF_FS_LOCK
|
||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
||||
#endif
|
||||
} FFOBJID;
|
||||
|
||||
|
||||
|
||||
/* File object structure (FIL) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
||||
BYTE flag; /* File status flags */
|
||||
BYTE err; /* Abort flag (error code) */
|
||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
||||
#if !FF_FS_READONLY
|
||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
||||
#endif
|
||||
#if FF_USE_FASTSEEK
|
||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
||||
#endif
|
||||
#if !FF_FS_TINY
|
||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
||||
#endif
|
||||
} FIL;
|
||||
|
||||
|
||||
|
||||
/* Directory object structure (DIR) */
|
||||
|
||||
typedef struct {
|
||||
FFOBJID obj; /* Object identifier */
|
||||
DWORD dptr; /* Current read/write offset */
|
||||
DWORD clust; /* Current cluster */
|
||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
||||
#if FF_USE_LFN
|
||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
||||
#endif
|
||||
#if FF_USE_FIND
|
||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
||||
#endif
|
||||
} DIR;
|
||||
|
||||
|
||||
|
||||
/* File information structure (FILINFO) */
|
||||
|
||||
typedef struct {
|
||||
FSIZE_t fsize; /* File size */
|
||||
WORD fdate; /* Modified date */
|
||||
WORD ftime; /* Modified time */
|
||||
BYTE fattrib; /* File attribute */
|
||||
#if FF_USE_LFN
|
||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
||||
#else
|
||||
TCHAR fname[12 + 1]; /* File name */
|
||||
#endif
|
||||
} FILINFO;
|
||||
|
||||
|
||||
|
||||
/* File function return code (FRESULT) */
|
||||
|
||||
typedef enum {
|
||||
FR_OK = 0, /* (0) Succeeded */
|
||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
||||
FR_INT_ERR, /* (2) Assertion failed */
|
||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
||||
FR_NO_FILE, /* (4) Could not find the file */
|
||||
FR_NO_PATH, /* (5) Could not find the path */
|
||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
||||
FR_INVALID_PARAMETER, /* (19) Given parameter is invalid */
|
||||
FR_INVALID_DEV_OPS, /* (20) */
|
||||
} FRESULT;
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* FatFs module application interface */
|
||||
|
||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
||||
|
||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
||||
#define f_error(fp) ((fp)->err)
|
||||
#define f_tell(fp) ((fp)->fptr)
|
||||
#define f_size(fp) ((fp)->obj.objsize)
|
||||
#define f_rewind(fp) f_lseek((fp), 0)
|
||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
||||
#define f_rmdir(path) f_unlink(path)
|
||||
#define f_unmount(path) f_mount(0, path, 0)
|
||||
|
||||
#ifndef EOF
|
||||
#define EOF (-1)
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Additional user defined functions */
|
||||
|
||||
/* RTC function */
|
||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
||||
DWORD get_fattime (void);
|
||||
#endif
|
||||
|
||||
/* LFN support functions */
|
||||
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
||||
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
||||
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
||||
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
||||
#endif
|
||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
||||
void ff_memfree (void* mblock); /* Free memory block */
|
||||
#endif
|
||||
|
||||
/* Sync functions */
|
||||
#if FF_FS_REENTRANT
|
||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
||||
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/*--------------------------------------------------------------*/
|
||||
/* Flags and offset address */
|
||||
|
||||
|
||||
/* File access mode and open method flags (3rd argument of f_open) */
|
||||
#define FA_READ 0x01
|
||||
#define FA_WRITE 0x02
|
||||
#define FA_OPEN_EXISTING 0x00
|
||||
#define FA_CREATE_NEW 0x04
|
||||
#define FA_CREATE_ALWAYS 0x08
|
||||
#define FA_OPEN_ALWAYS 0x10
|
||||
#define FA_OPEN_APPEND 0x30
|
||||
|
||||
/* Fast seek controls (2nd argument of f_lseek) */
|
||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
||||
|
||||
/* Format options (2nd argument of f_mkfs) */
|
||||
#define FM_FAT 0x01
|
||||
#define FM_FAT32 0x02
|
||||
#define FM_EXFAT 0x04
|
||||
#define FM_ANY 0x07
|
||||
#define FM_SFD 0x08
|
||||
|
||||
/* Filesystem type (FATFS.fs_type) */
|
||||
#define FS_FAT12 1
|
||||
#define FS_FAT16 2
|
||||
#define FS_FAT32 3
|
||||
#define FS_EXFAT 4
|
||||
|
||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
||||
#define AM_RDO 0x01 /* Read only */
|
||||
#define AM_HID 0x02 /* Hidden */
|
||||
#define AM_SYS 0x04 /* System */
|
||||
#define AM_DIR 0x10 /* Directory */
|
||||
#define AM_ARC 0x20 /* Archive */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* FF_DEFINED */
|
||||
|
|
@ -0,0 +1,288 @@
|
|||
/*---------------------------------------------------------------------------/
|
||||
/ FatFs Functional Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FFCONF_DEF 86604 /* Revision ID */
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Function Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_READONLY 0
|
||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
||||
/ and optional writing functions as well. */
|
||||
|
||||
|
||||
#define FF_FS_MINIMIZE 0
|
||||
/* This option defines minimization level to remove some basic API functions.
|
||||
/
|
||||
/ 0: Basic functions are fully enabled.
|
||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
||||
/ are removed.
|
||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
||||
/ 3: f_lseek() function is removed in addition to 2. */
|
||||
|
||||
|
||||
#define FF_USE_STRFUNC 1
|
||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
||||
/
|
||||
/ 0: Disable string functions.
|
||||
/ 1: Enable without LF-CRLF conversion.
|
||||
/ 2: Enable with LF-CRLF conversion. */
|
||||
|
||||
|
||||
#define FF_USE_FIND 0
|
||||
/* This option switches filtered directory read functions, f_findfirst() and
|
||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
||||
|
||||
|
||||
#define FF_USE_MKFS 1
|
||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FASTSEEK 1
|
||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_EXPAND 0
|
||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_CHMOD 0
|
||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
||||
|
||||
|
||||
#define FF_USE_LABEL 1
|
||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
||||
/ (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
#define FF_USE_FORWARD 0
|
||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Locale and Namespace Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_CODE_PAGE 936
|
||||
/* This option specifies the OEM code page to be used on the target system.
|
||||
/ Incorrect code page setting can cause a file open failure.
|
||||
/
|
||||
/ 437 - U.S.
|
||||
/ 720 - Arabic
|
||||
/ 737 - Greek
|
||||
/ 771 - KBL
|
||||
/ 775 - Baltic
|
||||
/ 850 - Latin 1
|
||||
/ 852 - Latin 2
|
||||
/ 855 - Cyrillic
|
||||
/ 857 - Turkish
|
||||
/ 860 - Portuguese
|
||||
/ 861 - Icelandic
|
||||
/ 862 - Hebrew
|
||||
/ 863 - Canadian French
|
||||
/ 864 - Arabic
|
||||
/ 865 - Nordic
|
||||
/ 866 - Russian
|
||||
/ 869 - Greek 2
|
||||
/ 932 - Japanese (DBCS)
|
||||
/ 936 - Simplified Chinese (DBCS)
|
||||
/ 949 - Korean (DBCS)
|
||||
/ 950 - Traditional Chinese (DBCS)
|
||||
/ 0 - Include all code pages above and configured by f_setcp()
|
||||
*/
|
||||
|
||||
|
||||
#define FF_USE_LFN 3
|
||||
#define FF_MAX_LFN 255
|
||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
||||
/
|
||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
||||
/
|
||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
||||
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
|
||||
/ specification.
|
||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
||||
/ ff_memfree() in ffsystem.c, need to be added to the project. */
|
||||
|
||||
|
||||
#define FF_LFN_UNICODE 0
|
||||
/* This option switches the character encoding on the API when LFN is enabled.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
||||
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
||||
/
|
||||
/ Also behavior of string I/O functions will be affected by this option.
|
||||
/ When LFN is not enabled, this option has no effect. */
|
||||
|
||||
|
||||
#define FF_LFN_BUF 255
|
||||
#define FF_SFN_BUF 12
|
||||
/* This set of options defines size of file name members in the FILINFO structure
|
||||
/ which is used to read out directory items. These values should be suffcient for
|
||||
/ the file names to read. The maximum possible length of the read file name depends
|
||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
||||
|
||||
|
||||
#define FF_STRF_ENCODE 3
|
||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
||||
/ This option selects assumption of character encoding ON THE FILE to be
|
||||
/ read/written via those functions.
|
||||
/
|
||||
/ 0: ANSI/OEM in current CP
|
||||
/ 1: Unicode in UTF-16LE
|
||||
/ 2: Unicode in UTF-16BE
|
||||
/ 3: Unicode in UTF-8
|
||||
*/
|
||||
|
||||
|
||||
#define FF_FS_RPATH 0
|
||||
/* This option configures support for relative path.
|
||||
/
|
||||
/ 0: Disable relative path and remove related functions.
|
||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
||||
/ 2: f_getcwd() function is available in addition to 1.
|
||||
*/
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ Drive/Volume Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_VOLUMES 3
|
||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
||||
|
||||
|
||||
#define FF_STR_VOLUME_ID 0
|
||||
#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
||||
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
||||
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
||||
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
||||
/ not defined, a user defined volume string table needs to be defined as:
|
||||
/
|
||||
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
||||
*/
|
||||
|
||||
|
||||
#define FF_MULTI_PARTITION 0
|
||||
/* This option switches support for multiple volumes on the physical drive.
|
||||
/ By default (0), each logical drive number is bound to the same physical drive
|
||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
||||
/ When this function is enabled (1), each logical drive number can be bound to
|
||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
||||
/ funciton will be available. */
|
||||
|
||||
|
||||
#define FF_MIN_SS 512
|
||||
#define FF_MAX_SS 512
|
||||
/* This set of options configures the range of sector size to be supported. (512,
|
||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
||||
/ GET_SECTOR_SIZE command. */
|
||||
|
||||
|
||||
#define FF_USE_TRIM 0
|
||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
||||
/ disk_ioctl() function. */
|
||||
|
||||
|
||||
#define FF_FS_NOFSINFO 0
|
||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
||||
/ option, and f_getfree() function at first time after volume mount will force
|
||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
||||
/
|
||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------/
|
||||
/ System Configurations
|
||||
/---------------------------------------------------------------------------*/
|
||||
|
||||
#define FF_FS_TINY 0
|
||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
||||
|
||||
|
||||
#define FF_FS_EXFAT 0
|
||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
||||
/ To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1)
|
||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
||||
|
||||
|
||||
#define FF_FS_NORTC 0
|
||||
#define FF_NORTC_MON 1
|
||||
#define FF_NORTC_MDAY 1
|
||||
#define FF_NORTC_YEAR 2018
|
||||
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
||||
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
||||
|
||||
|
||||
#define FF_FS_LOCK 0
|
||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
||||
/ is 1.
|
||||
/
|
||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
||||
/ should avoid illegal open, remove and rename to the open objects.
|
||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
||||
/ can be opened simultaneously under file lock control. Note that the file
|
||||
/ lock control is independent of re-entrancy. */
|
||||
|
||||
|
||||
/* #include <somertos.h> // O/S definitions */
|
||||
#define FF_FS_REENTRANT 0
|
||||
#define FF_FS_TIMEOUT 1000
|
||||
#define FF_SYNC_t HANDLE
|
||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
||||
/ module itself. Note that regardless of this option, file access to different
|
||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
||||
/ to the same volume is under control of this function.
|
||||
/
|
||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
||||
/ function, must be added to the project. Samples are available in
|
||||
/ option/syscall.c.
|
||||
/
|
||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
||||
/ included somewhere in the scope of ff.h. */
|
||||
|
||||
|
||||
|
||||
/*--- End of configuration options ---*/
|
||||
|
|
@ -1312,44 +1312,44 @@ __DEBUG__ kv_err_t tos_kv_walkthru(void)
|
|||
uint32_t cur_blk;
|
||||
kv_blk_hdr_t blk_hdr;
|
||||
|
||||
printf("workspace: 0x%x [%d block]\n", KV_MGR_WORKSPACE, KV_BLK_ADDR2IDX(KV_MGR_WORKSPACE));
|
||||
printf("workspace: 0x%x [%d block]\r\n", KV_MGR_WORKSPACE, KV_BLK_ADDR2IDX(KV_MGR_WORKSPACE));
|
||||
|
||||
KV_BLK_FOR_EACH(cur_blk) {
|
||||
printf("[%d] block\n", i++);
|
||||
printf("addr: 0x%x\n", cur_blk);
|
||||
printf("[%d] block\r\n", i++);
|
||||
printf("addr: 0x%x\r\n", cur_blk);
|
||||
|
||||
if (kv_blk_hdr_read(cur_blk, &blk_hdr) != KV_ERR_NONE) {
|
||||
printf("block header read failed\n");
|
||||
printf("block header read failed\r\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!KV_BLK_IS_LEGAL(&blk_hdr)) {
|
||||
printf("block not formatted\n");
|
||||
printf("block not formatted\r\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (KV_BLK_IS_GC_SRC(&blk_hdr)) {
|
||||
printf("block is gc-src\n");
|
||||
printf("block is gc-src\r\n");
|
||||
}
|
||||
|
||||
if (KV_BLK_IS_GC_DST(&blk_hdr)) {
|
||||
printf("block is gc-dst\n");
|
||||
printf("block is gc-dst\r\n");
|
||||
}
|
||||
|
||||
if (KV_BLK_IS_GC_DONE(&blk_hdr)) {
|
||||
printf("block is gc-done\n");
|
||||
printf("block is gc-done\r\n");
|
||||
}
|
||||
|
||||
if (KV_BLK_IS_GC_DST_NOT_DONE(&blk_hdr)) {
|
||||
printf("block is gc-dst but not done\n");
|
||||
printf("block is gc-dst but not done\r\n");
|
||||
}
|
||||
|
||||
if (kv_block_walkthru(cur_blk) != KV_ERR_NONE) {
|
||||
printf("block diagnosis failed\n");
|
||||
printf("block diagnosis failed\r\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("\n\n");
|
||||
printf("\r\n\n");
|
||||
}
|
||||
|
||||
return KV_ERR_NONE;
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ __API__ vfs_err_t tos_vfs_fs_mkfs(const char *device_path, const char *fs_name,
|
|||
{
|
||||
vfs_fsmap_t *fsmap = K_NULL;
|
||||
vfs_inode_t *device_inode = K_NULL;
|
||||
vfs_inode_t *fs_inode = K_NULL;
|
||||
//vfs_inode_t *fs_inode = K_NULL;
|
||||
|
||||
fsmap = vfs_fsmap_get(fs_name);
|
||||
if (!fsmap) {
|
||||
|
|
@ -194,7 +194,7 @@ __API__ vfs_err_t tos_vfs_fs_mkfs(const char *device_path, const char *fs_name,
|
|||
return VFS_ERR_INODE_INVALID;
|
||||
}
|
||||
|
||||
fs_inode->ops.fs_ops = fsmap->ops;
|
||||
//device_inode->ops.fs_ops = fsmap->ops;
|
||||
|
||||
if (!fsmap->ops->mkfs) {
|
||||
return VFS_ERR_OPS_NULL;
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ static int ec600s_check_ready(void)
|
|||
{
|
||||
at_echo_t echo;
|
||||
int try = 0;
|
||||
|
||||
|
||||
while (try++ < 10) {
|
||||
tos_at_echo_create(&echo, NULL, 0, NULL);
|
||||
tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT\r\n");
|
||||
|
|
@ -60,7 +60,7 @@ static int ec600s_echo_close(void)
|
|||
int try = 0;
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, NULL);
|
||||
|
||||
|
||||
while (try++ < 10) {
|
||||
tos_at_cmd_exec(AT_AGENT, &echo, 1000, "ATE0\r\n");
|
||||
if (echo.status == AT_ECHO_STATUS_OK) {
|
||||
|
|
@ -75,7 +75,7 @@ static int ec600s_sim_card_check(void)
|
|||
at_echo_t echo;
|
||||
int try = 0;
|
||||
char echo_buffer[32];
|
||||
|
||||
|
||||
tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL);
|
||||
while (try++ < 10) {
|
||||
tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+CPIN?\r\n");
|
||||
|
|
@ -84,7 +84,7 @@ static int ec600s_sim_card_check(void)
|
|||
}
|
||||
tos_sleep_ms(2000);
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ static int ec600s_signal_quality_check(void)
|
|||
at_echo_t echo;
|
||||
char echo_buffer[32], *str;
|
||||
int try = 0;
|
||||
|
||||
|
||||
tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL);
|
||||
while (try++ < 10) {
|
||||
tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+CSQ\r\n");
|
||||
|
|
@ -106,7 +106,7 @@ static int ec600s_signal_quality_check(void)
|
|||
if (!str) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
sscanf(str, "+CSQ:%d,%d", &rssi, &ber);
|
||||
if (rssi != 99) {
|
||||
return 0;
|
||||
|
|
@ -122,7 +122,7 @@ static int ec600s_gsm_network_check(void)
|
|||
at_echo_t echo;
|
||||
char echo_buffer[32], *str;
|
||||
int try = 0;
|
||||
|
||||
|
||||
tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL);
|
||||
while (try++ < 10) {
|
||||
tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+CREG?\r\n");
|
||||
|
|
@ -140,8 +140,8 @@ static int ec600s_gsm_network_check(void)
|
|||
}
|
||||
tos_sleep_ms(2000);
|
||||
}
|
||||
|
||||
return -1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int ec600s_gprs_network_check(void)
|
||||
|
|
@ -168,7 +168,7 @@ static int ec600s_gprs_network_check(void)
|
|||
}
|
||||
tos_sleep_ms(2000);
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -181,7 +181,7 @@ static int ec600s_close_apn(void)
|
|||
if (echo.status == AT_ECHO_STATUS_OK) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -206,17 +206,17 @@ static int ec600s_set_apn(void)
|
|||
static int ec600s_init(void)
|
||||
{
|
||||
printf("Init ec600s ...\n" );
|
||||
|
||||
|
||||
if (ec600s_check_ready() != 0) {
|
||||
printf("wait module ready timeout, please check your module\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (ec600s_echo_close() != 0) {
|
||||
printf("echo close failed,please check your module\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if(ec600s_sim_card_check() != 0) {
|
||||
printf("sim card check failed,please insert your card\n");
|
||||
return -1;
|
||||
|
|
@ -226,22 +226,22 @@ static int ec600s_init(void)
|
|||
printf("signal quality check status failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if(ec600s_gsm_network_check() != 0) {
|
||||
printf("GSM network register status check fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if(ec600s_gprs_network_check() != 0) {
|
||||
printf("GPRS network register status check fail\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if(ec600s_close_apn() != 0) {
|
||||
printf("close apn failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (ec600s_set_apn() != 0) {
|
||||
printf("apn set FAILED\n");
|
||||
return -1;
|
||||
|
|
@ -259,14 +259,14 @@ static int ec600s_connect_establish(int id, sal_proto_t proto)
|
|||
char *query_result_str = NULL;
|
||||
char *remote_ip = NULL;
|
||||
char *remote_port = NULL;
|
||||
|
||||
|
||||
tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL);
|
||||
tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+QISTATE=1,%d\r\n", id);
|
||||
if (echo.status != AT_ECHO_STATUS_OK) {
|
||||
printf("query socket %d state fail\r\n", id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
sprintf(except_str, "+QISTATE: %d", id);
|
||||
query_result_str = strstr(echo_buffer, except_str);
|
||||
if (query_result_str) {
|
||||
|
|
@ -277,13 +277,13 @@ static int ec600s_connect_establish(int id, sal_proto_t proto)
|
|||
|
||||
memset(except_str, 0, sizeof(except_str));
|
||||
sprintf(except_str, "+QIOPEN: %d,0", id);
|
||||
|
||||
|
||||
remote_ip = (char*)tos_at_channel_ip_get(AT_AGENT, id);
|
||||
remote_port = (char*)tos_at_channel_port_get(AT_AGENT, id);
|
||||
if (!remote_ip || !remote_port) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, except_str);
|
||||
tos_at_cmd_exec_until(AT_AGENT, &echo, 4000, "AT+QIOPEN=1,%d,\"%s\",\"%s\",%d,0,1\r\n",
|
||||
id, proto == TOS_SAL_PROTO_UDP ? "UDP" : "TCP", remote_ip, atoi(remote_port));
|
||||
|
|
@ -291,32 +291,32 @@ static int ec600s_connect_establish(int id, sal_proto_t proto)
|
|||
printf("establish socket %d on module fail\r\n", id);
|
||||
return -3;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ec600s_connect(const char *ip, const char *port, sal_proto_t proto)
|
||||
{
|
||||
int id;
|
||||
|
||||
|
||||
id = tos_at_channel_alloc(AT_AGENT, ip, port);
|
||||
if (id == -1) {
|
||||
printf("at channel alloc fail\r\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
if (ec600s_connect_establish(id, proto) < 0) {
|
||||
tos_at_channel_free(AT_AGENT, id);
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
static int ec600s_connect_with_size(const char *ip, const char *port, sal_proto_t proto, size_t socket_buffer_size)
|
||||
{
|
||||
int id;
|
||||
|
||||
|
||||
id = tos_at_channel_alloc_with_size(AT_AGENT, ip, port, socket_buffer_size);
|
||||
if (id == -1) {
|
||||
printf("at channel alloc fail\r\n");
|
||||
|
|
@ -327,7 +327,7 @@ static int ec600s_connect_with_size(const char *ip, const char *port, sal_proto_
|
|||
tos_at_channel_free(AT_AGENT, id);
|
||||
return -2;
|
||||
}
|
||||
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
@ -348,29 +348,21 @@ int ec600s_send(int id, const void *buf, size_t len)
|
|||
if (!tos_at_channel_is_working(AT_AGENT, id)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (tos_at_global_lock_pend(AT_AGENT) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, ">");
|
||||
|
||||
tos_at_cmd_exec_until(AT_AGENT, &echo, 1000, "AT+QISEND=%d,%d\r\n", id, len);
|
||||
|
||||
if (echo.status != AT_ECHO_STATUS_EXPECT) {
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, "SEND OK");
|
||||
tos_at_raw_data_send_until(AT_AGENT, &echo, 10000, (uint8_t *)buf, len);
|
||||
if (echo.status != AT_ECHO_STATUS_EXPECT) {
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
@ -388,34 +380,26 @@ int ec600s_sendto(int id, char *ip, char *port, const void *buf, size_t len)
|
|||
{
|
||||
at_echo_t echo;
|
||||
|
||||
if (tos_at_global_lock_pend(AT_AGENT) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, ">");
|
||||
tos_at_cmd_exec_until(AT_AGENT, &echo, 1000, "AT+QISEND=%d,%d\r\n", id, len);
|
||||
|
||||
if (echo.status != AT_ECHO_STATUS_EXPECT) {
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, "SEND OK");
|
||||
tos_at_raw_data_send(AT_AGENT, &echo, 1000, (uint8_t *)buf, len);
|
||||
if (echo.status != AT_ECHO_STATUS_EXPECT) {
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void ec600s_transparent_mode_exit(void)
|
||||
{
|
||||
at_echo_t echo;
|
||||
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, NULL);
|
||||
tos_at_cmd_exec(AT_AGENT, &echo, 500, "+++");
|
||||
}
|
||||
|
|
@ -423,7 +407,7 @@ static void ec600s_transparent_mode_exit(void)
|
|||
static int ec600s_close(int id)
|
||||
{
|
||||
at_echo_t echo;
|
||||
|
||||
|
||||
ec600s_transparent_mode_exit();
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, NULL);
|
||||
|
|
@ -467,7 +451,7 @@ __STATIC__ void ec600s_incoming_data_process(void)
|
|||
+QIURC: "recv",<sockid>,<datalen>
|
||||
<data content>
|
||||
*/
|
||||
|
||||
|
||||
while (1) {
|
||||
if (tos_at_uart_read(AT_AGENT, &data, 1) != 1) {
|
||||
return;
|
||||
|
|
@ -492,7 +476,7 @@ __STATIC__ void ec600s_incoming_data_process(void)
|
|||
if (tos_at_uart_read(AT_AGENT, &data, 1) != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
do {
|
||||
#if !defined(MIN)
|
||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
||||
|
|
@ -529,7 +513,7 @@ __STATIC__ void ec600s_domain_data_process(void)
|
|||
if (data == '0') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (data == '\"') {
|
||||
/* start parser domain */
|
||||
while (1) {
|
||||
|
|
@ -595,7 +579,7 @@ sal_module_t sal_module_ec600s = {
|
|||
|
||||
int ec600s_sal_init(hal_uart_port_t uart_port)
|
||||
{
|
||||
|
||||
|
||||
if (tos_at_init(AT_AGENT, "ec600s_at", ec600s_at_parse_task_stk,
|
||||
uart_port, ec600s_at_event,
|
||||
sizeof(ec600s_at_event) / sizeof(ec600s_at_event[0])) != 0) {
|
||||
|
|
@ -608,7 +592,7 @@ int ec600s_sal_init(hal_uart_port_t uart_port)
|
|||
if (tos_sal_module_init() != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -623,7 +607,7 @@ int ec600s_sal_deinit()
|
|||
tos_sal_module_register_default();
|
||||
|
||||
tos_at_deinit(AT_AGENT);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -105,12 +105,15 @@ int esp8266_join_ap(const char *ssid, const char *pwd)
|
|||
{
|
||||
int try = 0;
|
||||
at_echo_t echo;
|
||||
char echo_buffer[128];
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, NULL);
|
||||
tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), NULL);
|
||||
while (try++ < 10) {
|
||||
tos_at_cmd_exec(AT_AGENT, &echo, 15000, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, pwd);
|
||||
tos_at_cmd_exec(AT_AGENT, &echo, 20000, "AT+CWJAP=\"%s\",\"%s\"\r\n", ssid, pwd);
|
||||
if (echo.status == AT_ECHO_STATUS_OK) {
|
||||
return 0;
|
||||
if (strstr(echo_buffer, "WIFI GOT IP")) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
|
|
@ -200,10 +203,6 @@ static int esp8266_send(int id, const void *buf, size_t len)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (tos_at_global_lock_pend(AT_AGENT) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), ">");
|
||||
#if TOS_CFG_MODULE_SINGLE_LINK_EN > 0u
|
||||
tos_at_cmd_exec_until(&echo, 5000,
|
||||
|
|
@ -218,7 +217,6 @@ static int esp8266_send(int id, const void *buf, size_t len)
|
|||
tos_at_channel_set_broken(AT_AGENT, id);
|
||||
}
|
||||
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -234,11 +232,9 @@ static int esp8266_send(int id, const void *buf, size_t len)
|
|||
tos_at_channel_set_broken(AT_AGENT, id);
|
||||
}
|
||||
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
@ -251,10 +247,6 @@ static int esp8266_sendto(int id, char *ip, char *port, const void *buf, size_t
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (tos_at_global_lock_pend(AT_AGENT) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_at_echo_create(&echo, echo_buffer, sizeof(echo_buffer), ">");
|
||||
|
||||
if (ip && port) {
|
||||
|
|
@ -280,7 +272,6 @@ static int esp8266_sendto(int id, char *ip, char *port, const void *buf, size_t
|
|||
tos_at_channel_set_broken(AT_AGENT, id);
|
||||
}
|
||||
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -296,11 +287,9 @@ static int esp8266_sendto(int id, char *ip, char *port, const void *buf, size_t
|
|||
tos_at_channel_set_broken(AT_AGENT, id);
|
||||
}
|
||||
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
tos_at_global_lock_post(AT_AGENT);
|
||||
return len;
|
||||
}
|
||||
|
||||
|
|
@ -317,9 +306,9 @@ static int esp8266_recvfrom(int id, void *buf, size_t len)
|
|||
static int esp8266_close(int id)
|
||||
{
|
||||
at_echo_t echo;
|
||||
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, NULL);
|
||||
|
||||
|
||||
#if TOS_CFG_MODULE_SINGLE_LINK_EN > 0u
|
||||
tos_at_cmd_exec(AT_AGENT, &echo, 1000, "AT+CIPCLOSE\r\n");
|
||||
#else
|
||||
|
|
@ -441,7 +430,7 @@ __STATIC__ void esp8266_incoming_data_process(void)
|
|||
if (tos_at_uart_read(AT_AGENT, buffer, read_len) != read_len) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
//delay has two reason, wait for the data to be cached and untrigger scheduling
|
||||
tos_stopwatch_delay(200);
|
||||
|
||||
|
|
@ -501,7 +490,7 @@ int esp8266_sal_deinit()
|
|||
tos_sal_module_register_default();
|
||||
|
||||
tos_at_deinit(AT_AGENT);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -36,12 +36,13 @@ int esp8266_tencent_firmware_module_mqtt_conn(mqtt_param_t init_params)
|
|||
|
||||
tos_at_echo_create(&echo, NULL, 0, "+TCMQTTCONN:OK");
|
||||
while (try++ < 10) {
|
||||
tos_at_cmd_exec_until(AT_AGENT, &echo, 2000, "AT+TCMQTTCONN=%d,%d,%d,%d,%d\r\n", init_params.tls_mode,
|
||||
tos_at_cmd_exec_until(AT_AGENT, &echo, 10000, "AT+TCMQTTCONN=%d,%d,%d,%d,%d\r\n", init_params.tls_mode,
|
||||
init_params.command_timeout, init_params.keep_alive_interval_ms,
|
||||
init_params.clean_session, init_params.auto_connect_enable);
|
||||
if (echo.status == AT_ECHO_STATUS_EXPECT) {
|
||||
return 0;
|
||||
}
|
||||
tos_task_delay(1000);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -74,7 +75,7 @@ int esp8266_tencent_firmware_module_mqtt_publ(const char *topic, qos_t qos, char
|
|||
}
|
||||
|
||||
tos_at_echo_create(&echo, NULL, 0, "+TCMQTTPUBL:OK");
|
||||
tos_at_raw_data_send_until(AT_AGENT, &echo, 1000, (uint8_t *)payload, strlen(payload));
|
||||
tos_at_raw_data_send_until(AT_AGENT, &echo, 3000, (uint8_t *)payload, strlen(payload));
|
||||
if (echo.status != AT_ECHO_STATUS_EXPECT) {
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -89,7 +90,7 @@ int esp8266_tencent_firmware_module_mqtt_pub(const char *topic, qos_t qos, char
|
|||
|
||||
tos_at_echo_create(&echo, NULL, 0, "+TCMQTTPUB:OK");
|
||||
|
||||
tos_at_cmd_exec_until(AT_AGENT, &echo, 1000, "AT+TCMQTTPUB=\"%s\",%d,\"%s\"\r\n", topic, qos, payload);
|
||||
tos_at_cmd_exec_until(AT_AGENT, &echo, 3000, "AT+TCMQTTPUB=\"%s\",%d,\"%s\"\r\n", topic, qos, payload);
|
||||
if (echo.status == AT_ECHO_STATUS_EXPECT) {
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -233,7 +233,7 @@ k_err_t tos_task_destroy(k_task_t *task)
|
|||
|
||||
- **功能描述**
|
||||
|
||||
销毁任务。
|
||||
销毁静态创建的任务。
|
||||
|
||||
- **参数解释**
|
||||
|
||||
|
|
@ -255,7 +255,7 @@ k_err_t tos_task_destroy_dyn(k_task_t *task)
|
|||
|
||||
- **功能描述**
|
||||
|
||||
static函数,非对外接口,销毁动态创建(tos_task_create_dyn)的任务,默认由tos_task_destroy()函数调用。
|
||||
销毁动态创建(tos_task_create_dyn)的任务。
|
||||
|
||||
- **参数解释**
|
||||
|
||||
|
|
|
|||
|
|
@ -1,16 +1,26 @@
|
|||
# TencentOS tiny 代码目录说明
|
||||
# TencentOS Tiny 代码目录说明
|
||||
|
||||
|
||||
|一级目录 | 二级目录 | 三级目录 |说明 |
|
||||
|---------|---------|---------|---------|
|
||||
| arch | arm | |TencentOS tiny适配的IP核架构(含M核中断、调度、tick相关代码) |
|
||||
| board | TencentOS_tiny_EVB_MX | |TencentOS tiny 定制开发板demo,包含AT适配框架、MQTT协议、安全组件等 |
|
||||
| | risc-v | |TencentOS tiny适配的IP核架构(含risc-v核中断、调度、tick相关代码) |
|
||||
| board | TencentOS_tiny_EVB_G0 | |TencentOS tiny 定制开发板G0 demo,包含AT适配框架、MQTT协议、驱动实现等 |
|
||||
| | TencentOS_Tiny_CH32V307_EVB | |TencentOS tiny 定制开发板CH32V307 demo,包含AT适配框架、MQTT协议、驱动实现等 |
|
||||
| | TencentOS_Tiny_EVB_MX_Plus | |TencentOS tiny 定制开发板EVB_MX+ demo,包含AT适配框架、MQTT协议、驱动实现等 |
|
||||
| component | connectivity | loraWAN | loRaWAN协议栈实现源码及适配层|
|
||||
| | |Eclipse-Paho-MQTT| MQTT协议栈实现源码及适配层|
|
||||
| | |TencentCloud_SDK| 腾讯云C-SDK实现源码及适配层|
|
||||
| | fs | | 文件系统实现源码|
|
||||
| | security | | mbedtls 安全协议源码 |
|
||||
| devices | | |TencentOS tiny适配的一些外设驱动(如串口wifi gprs 驱动等) |
|
||||
| | |mqttclient| MQTT协议栈实现源码及适配层|
|
||||
| | |iot-hub-device-c-sdk| 腾讯云C-SDK实现源码及适配层|
|
||||
| | fs | vfs | 虚拟文件系统API实现源码 |
|
||||
| | | fatfs | fat文件系统开源实现源码 |
|
||||
| | | kv | KV存储实现源码 |
|
||||
| | | littlefs | 开源littlefs源码 |
|
||||
| | security | mbedtls | mbedtls 安全协议源码 |
|
||||
| | elfloader | | |
|
||||
| | ota | | |
|
||||
| | gui | | 包含常见开源GUI实现,如LittleVGL,GUILite,STemWin等 |
|
||||
| | shell | | |
|
||||
| devices | | |TencentOS tiny适配的一些通信模组驱动(如串口wifi gprs 驱动等) |
|
||||
| doc | | |TencentOS tiny相关技术文档及开发指南 |
|
||||
| examples | | |TencentOS tiny提供的功能示例 |
|
||||
| kernel | core | | TencentOS tiny内核源码|
|
||||
|
|
@ -20,8 +30,10 @@
|
|||
| | lora_module_wrapper | | TencentOS tiny为串口类LoraWAN模块提供的移植框架|
|
||||
| | lwip | | Lwip协议实现源码及适配层 |
|
||||
| | sal_module_wrapper | | TencentOS tiny为串口类网络模块(wifi gprs)提供的socket移植框架 |
|
||||
| | socket_wrapper | | 标准BSD Socket接口实现 |
|
||||
| | tencent_firmware_module_wrapper | | TencentOS tiny提供的腾讯定制模组移植框架 |
|
||||
| osal | cmsis_os | |TencentOS tiny提供的cmsis os 适配 |
|
||||
| | posix | |轻量级posix接口实现 |
|
||||
| platform | hal | | TencentOS tiny适配的部分芯片的驱动实现源码|
|
||||
| | vendor_bsp | | 芯片厂家提供的原厂bsp固件库,如STM32的HAL库|
|
||||
| test | | |存放TencentOS tiny提供的一些测试代码,含内核及上层模块示例及测试代码 |
|
||||
|
|
@ -32,3 +44,4 @@
|
|||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,17 +1,19 @@
|
|||
# TencentOS tiny定制开发板EVB_LX快速入门指南
|
||||
# GD32V-RISC-V物联网操作系统TencentOS-Tiny案例实践指南
|
||||
|
||||
| Revision | Date | Description |
|
||||
| -------- | --------- | ----------- |
|
||||
| 1.0 | 2020-2-12 | 文档初版 |
|
||||
| 2.0 | 2021-12-20 | GD32V-RISC-V物联网操作系统TencentOS-Tiny案例实践指南 |
|
||||
|
||||
## 1. 定制开发板EVB_LX硬件简介
|
||||
## 一、定制开发板EVB_LX硬件简介
|
||||
|
||||
### 1.1 开发板简介
|
||||
|
||||
EVB_LX+是腾讯物联网操作系统TencentOS tiny 团队联合兆易创新(GD32)、南京厚德物联网有限公司三方合作设计的一款物联网评估板,用于TencentOS tiny 基础内核、RISC-V新IP核架构和IoT组件功能体验和评估。
|
||||
开发板功能图如下所示:
|
||||
|
||||

|
||||
|
||||
|
||||
### 1.2 开发板特性
|
||||
**CPU** :GD32VF103RBT6, 108MHz,128K Flash,32KB SRAM
|
||||
|
||||
|
|
@ -102,64 +104,679 @@ OLED液晶显示模块用来向用户显示系统状态、参数或者要输入
|
|||
Micro USB线的功能是供电及调试,将线一头与开发板的Micro接口(GD-Link)连接,另一头接到电脑的USB口上。(程序下载完了,也可以把usb线接到pc uart的端口,用于打印日志)
|
||||

|
||||
|
||||
## 二、 定制开发板EVB_LX软件开发环境准备
|
||||
|
||||
### 2.1 MounRiver Studio IDE下载与安装
|
||||
|
||||
MounRiver Studio(MRS)是一款面向RISC-V、ARM等内核MCU的集成开发环境,提供专业嵌入式项目所需的开发、调试环境、烧录工具已经完善的项目管理能力,是目前使用相对方便的GD32V开发环境。这里我们使用该IDE来进行risc-v相关应用开发。首先,我们到MounRiver Studio官网下载软件安装包,下载地址:http://www.mounriver.com/download
|
||||
|
||||

|
||||
|
||||
安装完成后打开软件可以进入到欢迎界面
|
||||
|
||||

|
||||
|
||||
|
||||
### 2.2 新建GD32V工程
|
||||
|
||||
菜单栏点击File->New->MounRiver project 开始创建工程
|
||||
|
||||

|
||||
|
||||
进入工程向导后,按照如下图所示选择芯片,填写工程信息。
|
||||
|
||||

|
||||
|
||||
完成后会生成工程,如图所示:
|
||||
|
||||

|
||||
|
||||
### 2.3 编译下载调试GD32V工程
|
||||
|
||||
MRS IDE导入的是默认的LED闪灯程序,由于我们开发板EVB LX的LED灯跟兆易创新官方评估板的GPIO不一样,使用的GPIOB,Pin2,这里我们修改下main.c中的led初始化代码。
|
||||
将如下代码复制替换main.c文件中的全部代码:
|
||||
|
||||
```
|
||||
#include "gd32vf103.h"
|
||||
#include "gd32vf103r_start.h"
|
||||
#include "systick.h"
|
||||
|
||||
void led_init(void);
|
||||
|
||||
/*!
|
||||
\brief main function
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
int main(void)
|
||||
{
|
||||
led_init();
|
||||
|
||||
while(1){
|
||||
/* turn on LED */
|
||||
gpio_bit_set(GPIOB, GPIO_PIN_2);
|
||||
/* insert 200 ms delay */
|
||||
delay_1ms(200);
|
||||
|
||||
/* turn off LED */
|
||||
gpio_bit_reset(GPIOB, GPIO_PIN_2);
|
||||
|
||||
/* insert 200 ms delay */
|
||||
delay_1ms(200);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initialize the LEDs
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void led_init(void)
|
||||
{
|
||||
/* enable the LED clock */
|
||||
rcu_periph_clock_enable(RCU_GPIOB);
|
||||
/* configure LED GPIO port */
|
||||
gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_2);
|
||||
|
||||
/* turn off LED */
|
||||
gpio_bit_reset(GPIOB, GPIO_PIN_2);
|
||||
}
|
||||
```
|
||||
|
||||
完成代码拷贝覆盖后,点击如下图所示图标编译工程,编译完成后可以在控制台输出看到编译结果。
|
||||
|
||||

|
||||
|
||||
如下图所示,点击debug按钮,就可以进入调试模式,程序下载到开发板上,可以打断点、单步、跳步执行,全速执行,查看寄存器,反汇编、内存等
|
||||
|
||||

|
||||
|
||||
执行全速运行后,可以看到开发板上的用户LED灯间隔闪烁。
|
||||
|
||||
除了调试按钮外,我们也可以点击下载按钮直接将程序烧写到开发板上,如下图所示:
|
||||
|
||||

|
||||
|
||||
本实验代码下载链接:https://share.weiyun.com/4XXWaOzU 密码:cy4m5f
|
||||
|
||||
GD32V-RISC-V物联网操作系统TencentOS-Tiny案例实践指南(20211220)\SourceCode\EVB_LX_GD32V_LED.rar
|
||||
|
||||
## 三、TencentOS Tiny内核移植
|
||||
|
||||
### 3.1 准备裸机工程
|
||||
移植TencentOS Tiny内核前,我们先准备一个简单的点灯工程,这里跟前面的步骤一样,我们先使用MounRiver Studio IDE 基于GD32V生成基础工程;
|
||||
基础的裸机工程包含LED、串口、液晶显示屏驱动。这里我把裸机工程给大家准备好了,大家下载EVB_LX_GD32V_Printf_Lcd.rar 解压后使用IDE打开即可。
|
||||
裸机工程代码下载链接:https://share.weiyun.com/4XXWaOzU 密码:cy4m5f
|
||||
|
||||
GD32V-RISC-V物联网操作系统TencentOS-Tiny案例实践指南(20211220)\SourceCode\EVB_LX_GD32V_Printf_Lcd.rar
|
||||
|
||||
### 3.2 准备内核源码
|
||||
在TencentOS Tiny 官方项目仓下载内核代码,下载地址: https://github.com/Tencent/TencentOS-tiny
|
||||
|
||||
拷贝如下目录的内核代码到新建的TencentOS-Tiny文件夹备用(请严格按照一下目录拷贝,不需要拷贝多余的)
|
||||
|
||||
| 一级目录 | 二级目录 | 三级目录 | 四级目录 | 五级目录 | 说明 |
|
||||
| ---------- | -------- | -------- | --------- | -------- | ---------------------------------------------------- |
|
||||
| arch | arm | risc-v | common | | TencentOS tiny 中断tick相关代码 |
|
||||
| | | | rv32i | gcc | TencentOS Tiny risc-v调度汇编 GCC |
|
||||
| | | | bumblebee | gcc | GD32V 中断配置相关代码 |
|
||||
| kernel | core | | | | TencentOS tiny内核源码 |
|
||||
| | hal | | | | TencentOS tiny驱动抽象层 |
|
||||
| | pm | | | | TencentOS tiny低功耗源码 |
|
||||
| TOS_CONFIG | | | | | TencentOS tiny配置头文件,用户自定义,从模板修改过来 |
|
||||
|
||||
|
||||
这里只介绍TencentOS tiny的内核移植,所以这里只需要用到 arch、kernel两个目录下的源码。
|
||||
|
||||
将全部内核源码复制到工程目录下,如下图:
|
||||
|
||||

|
||||
|
||||
然后我们在工程界面按F5刷新工程,就可以在源码目录看到TencentOS Tiny的内核源码了,如图所示:
|
||||
|
||||

|
||||
|
||||
### 3.3 添加内核初始化和相关任务代码
|
||||
|
||||
|
||||
1)首先在main.c 中包含内核头文件 #include "tos_k.h"
|
||||
|
||||
2)添加Tick处理函数 eclic_mtip_handler
|
||||
|
||||
```
|
||||
void eclic_mtip_handler() {
|
||||
port_systick_config((uint32_t)k_cpu_cycle_per_tick);
|
||||
if (tos_knl_is_running()) {
|
||||
tos_knl_irq_enter();
|
||||
tos_tick_handler();
|
||||
tos_knl_irq_leave();
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
3) 新建两个测试任务
|
||||
|
||||
```
|
||||
#define TASK1_STK_SIZE 1024
|
||||
k_task_t task1;
|
||||
uint8_t task1_stk[TASK1_STK_SIZE];
|
||||
|
||||
|
||||
#define TASK2_STK_SIZE 1024
|
||||
k_task_t task2;
|
||||
uint8_t task2_stk[TASK2_STK_SIZE];
|
||||
|
||||
void task1_entry(void *arg)
|
||||
{
|
||||
int count = 0;
|
||||
while (1) {
|
||||
printf("###I am task1,count is %d\r\n",count++);
|
||||
tos_task_delay(2000);
|
||||
}
|
||||
}
|
||||
|
||||
void task2_entry(void *arg)
|
||||
{
|
||||
int count = 0;
|
||||
while (1) {
|
||||
printf("***I am task2,count is %d\r\n",count++);
|
||||
tos_task_delay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
4) 在main函数中while(1)前面增加操作系统初始化函数
|
||||
|
||||
|
||||
```
|
||||
printf("Welcome to TencentOS tiny(%s)\r\n", TOS_VERSION);
|
||||
tos_knl_init(); // TencentOS Tiny kernel initialize
|
||||
tos_task_create(&task1, "task1", task1_entry, NULL, 4, task1_stk, TASK1_STK_SIZE, 0); // Create task1
|
||||
tos_task_create(&task2, "task2", task2_entry, NULL, 3, task2_stk, TASK2_STK_SIZE, 0);// Create task2
|
||||
tos_knl_start();
|
||||
|
||||
|
||||
```
|
||||
|
||||
5)在工程里面配置TencentOS Tiny 头文件编译目录
|
||||
|
||||
如图,需要在IDE里面配置TencentOS Tiny的编译头文件目录,按如图所示配置即可:
|
||||

|
||||
|
||||
除了增加C编译的头文件,还要增加汇编文件的头文件目录,如下图所示:
|
||||
|
||||

|
||||
|
||||
6) 修改tos_config.h文件
|
||||
|
||||
我们在TencentOS_Tiny文件下新建TOS_CONFIG文件夹,在改文件夹下面新建tos_config.h,代码如下:
|
||||
|
||||
|
||||
```
|
||||
#ifndef INC_TOS_CONFIG_H_
|
||||
#define INC_TOS_CONFIG_H_
|
||||
|
||||
#include "gd32vf103.h"
|
||||
#include "stddef.h"
|
||||
|
||||
|
||||
#define TOS_CFG_TASK_PRIO_MAX 10u // 配置TencentOS tiny默认支持的最大优先级数量
|
||||
|
||||
|
||||
#define TOS_CFG_ROUND_ROBIN_EN 0u // 配置TencentOS tiny的内核是否开启时间片轮转
|
||||
|
||||
|
||||
#define TOS_CFG_OBJECT_VERIFY 0u // 配置TencentOS tiny是否校验指针合法
|
||||
|
||||
#define TOS_CFG_TASK_DYNAMIC_CREATE_EN 0u // TencentOS tiny 动态任务创建功能宏
|
||||
|
||||
|
||||
#define TOS_CFG_EVENT_EN 1u // TencentOS tiny 事件模块功能宏
|
||||
|
||||
#define TOS_CFG_MMBLK_EN 1u //配置TencentOS tiny是否开启内存块管理模块
|
||||
|
||||
#define TOS_CFG_MMHEAP_EN 1u //配置TencentOS tiny是否开启动态内存模块
|
||||
|
||||
#define TOS_CFG_MMHEAP_DEFAULT_POOL_EN 1u // TencentOS tiny 默认动态内存池功能宏
|
||||
|
||||
#define TOS_CFG_MMHEAP_DEFAULT_POOL_SIZE 0x1000 // 配置TencentOS tiny默认动态内存池大小
|
||||
|
||||
|
||||
#define TOS_CFG_MUTEX_EN 1u // 配置TencentOS tiny是否开启互斥锁模块
|
||||
|
||||
#define TOS_CFG_MESSAGE_QUEUE_EN 1u // 配置TencentOS tiny是否开启消息队列模块
|
||||
|
||||
#define TOS_CFG_MAIL_QUEUE_EN 1u // 配置TencentOS tiny是否开启消息邮箱模块
|
||||
|
||||
#define TOS_CFG_PRIORITY_MESSAGE_QUEUE_EN 1u // 配置TencentOS tiny是否开启优先级消息队列模块
|
||||
|
||||
#define TOS_CFG_PRIORITY_MAIL_QUEUE_EN 1u // 配置TencentOS tiny是否开启优先级消息邮箱模块
|
||||
|
||||
#define TOS_CFG_TIMER_EN 0u // 配置TencentOS tiny是否开启软件定时器模块
|
||||
|
||||
#define TOS_CFG_PWR_MGR_EN 0u // 配置TencentOS tiny是否开启外设电源管理模块
|
||||
|
||||
#define TOS_CFG_TICKLESS_EN 0u // 配置Tickless 低功耗模块开关
|
||||
|
||||
|
||||
#define TOS_CFG_SEM_EN 1u // 配置TencentOS tiny是否开启信号量模块
|
||||
|
||||
#define TOS_CFG_TASK_STACK_DRAUGHT_DEPTH_DETACT_EN 0u // 配置TencentOS tiny是否开启任务栈深度检测
|
||||
|
||||
#define TOS_CFG_IDLE_TASK_STK_SIZE 512u // 配置TencentOS tiny空闲任务栈大小
|
||||
|
||||
|
||||
#define TOS_CFG_CPU_SYSTICK_PRIO 0xF
|
||||
|
||||
|
||||
#define TOS_CFG_IRQ_STK_SIZE 128u
|
||||
|
||||
|
||||
#define TOS_CFG_CPU_TICK_PER_SECOND 1000u // 配置TencentOS tiny的tick频率
|
||||
|
||||
#define TOS_CFG_CPU_CLOCK (SystemCoreClock) // 配置TencentOS tiny CPU频率
|
||||
|
||||
|
||||
#define TOS_CFG_TIMER_AS_PROC 1u // 配置是否将TIMER配置成函数模式
|
||||
|
||||
|
||||
|
||||
#endif /* INC_TOS_CONFIG_H_ */
|
||||
|
||||
|
||||
|
||||
```
|
||||
|
||||
7)编译下载测试
|
||||
|
||||
编译完成下载到开发板,通过串口助手我们可以看到两个任务交替运行,打印task信息,说明内核移植成功,如下图所示:
|
||||
|
||||

|
||||
|
||||
本实验代码下载链接:https://share.weiyun.com/4XXWaOzU 密码:cy4m5f
|
||||
|
||||
GD32V-RISC-V物联网操作系统TencentOS-Tiny案例实践指南(20211220)\SourceCode\EVB_LX_GD32V_TencentOS_Tiny.rar
|
||||
|
||||
|
||||
## 四、 基于TencentOS Tiny 和E53_SC1模块采集光照强度实验
|
||||
|
||||
1) E53_SC1 扩展模块介绍
|
||||
E53_SC1扩展模块包含一个BH1750 传感器和一个高亮LED灯,功能示意图如下:
|
||||
|
||||

|
||||
|
||||
将模块插到开发板的E53接口即可
|
||||
|
||||
2) 编写BH1750驱动
|
||||
BH1750FIV是一个采用标准IIC总线接口的环境光强传感器,共有六种工作模式,分为连续型和一次型,连续型又分为高精度1、2和低精度模式,单次型同样分为高精度1、2和低精度模式。单次型与连续型的区别在于单次型读完一次数据就会自动转为PowerDown模式。
|
||||
比如一次型低分辨率模式的时序图如下图所示:
|
||||
|
||||

|
||||
|
||||
根据时序,编写的核心驱动程序如下,对BH1750 传感器进行初始化、启动测量,等待测量结果,读取测量值。
|
||||
|
||||
|
||||
```
|
||||
|
||||
void Init_BH1750(void)
|
||||
{
|
||||
uint8_t t_Data = 0x01;
|
||||
/* configure GPIO */
|
||||
gpio_config();
|
||||
/* configure I2C */
|
||||
i2c_config();
|
||||
|
||||
BH1750_I2C_Master_Transmit(BH1750_Addr,&t_Data,1);
|
||||
}
|
||||
|
||||
|
||||
void Start_BH1750(void)
|
||||
{
|
||||
uint8_t t_Data = 0x10;
|
||||
BH1750_I2C_Master_Transmit(BH1750_Addr,&t_Data,1);
|
||||
}
|
||||
|
||||
|
||||
void Init_E53_SC1(void)
|
||||
{
|
||||
Init_Light();
|
||||
Init_BH1750();
|
||||
}
|
||||
|
||||
void E53_SC1_Read_Data(void)
|
||||
{
|
||||
|
||||
Start_BH1750();
|
||||
delay_ms(180);
|
||||
BH1750_I2C_Master_Receive(BH1750_Addr+1,BUF,2);
|
||||
result=BUF[0];
|
||||
result=(result<<8)+BUF[1];
|
||||
E53_SC1_Data.Lux=(float)(result/1.2);
|
||||
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
3)基于上个章节移植好的TencentOS Tiny工程,在其中一个任务1中添加E53_SC1初始化,获取光照强度,打印在串口,并显示在液晶屏OLED上
|
||||
|
||||
详细代码如下:
|
||||
|
||||
|
||||
```
|
||||
void task1_entry(void *arg)
|
||||
{
|
||||
int count = 1;
|
||||
Init_E53_SC1();
|
||||
E53_SC1_LED_StatusSet(OFF);
|
||||
while (1) {
|
||||
printf("###I am task1,count is %d\r\n",count++);
|
||||
if (count/10==1)
|
||||
{
|
||||
E53_SC1_LED_StatusSet(ON);// Open E53 led
|
||||
}
|
||||
else if (count/10==6) {
|
||||
E53_SC1_LED_StatusSet(OFF);// Open E53 led
|
||||
}
|
||||
E53_SC1_Read_Data();
|
||||
printf("\r\n********E53_SC1_BH1750 Value is %d\r\n",(int)E53_SC1_Data.Lux);
|
||||
memset(payload, 0, sizeof(payload));
|
||||
snprintf(payload,sizeof(payload),"%d ",(int)E53_SC1_Data.Lux);
|
||||
OLED_ShowString(48, 3, (uint8_t*)payload, 8);
|
||||
|
||||
tos_task_delay(100);
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
编译完成,可以在开发板上看到液晶屏实时显示了光照强度值,单位LUX;
|
||||
|
||||

|
||||
|
||||
同时串口会打印相应的logo,如下图:
|
||||
|
||||

|
||||
|
||||
|
||||
本实验代码下载链接:https://share.weiyun.com/4XXWaOzU 密码:cy4m5f
|
||||
|
||||
GD32V-RISC-V物联网操作系统TencentOS-Tiny案例实践指南(20211220)\SourceCode\EVB_LX_GD32V_TencentOS_Tiny_BH1750.rar
|
||||
|
||||
## 五、基于TencentOS Tiny 将 BH1750传感器采集的光照强度数据上传到腾讯云物联网平台和腾讯连连小程序
|
||||
|
||||
|
||||
基于TencentOS Tiny EVB LX RISC-V开发板要完成腾讯云IoT Explorer对接,需要完成两个部分的工作。
|
||||
一是:腾讯云IoT explorer 上完成项目、产品、设备创建、参数配置
|
||||
二是:基于TencentOS Tiny完成应用开发,向腾讯云上报业务数据。
|
||||
|
||||
|
||||
### 1. 云端操作步骤
|
||||
1.1. 新建项目
|
||||
登录[腾讯云物联网开发平台](https://cloud.tencent.com/product/iotexplorer),点击新建项目,填写项目名称和简介:
|
||||
|
||||

|
||||
|
||||
1.2. 新建产品
|
||||
点击项目名称进入到该项目中,点击新建产品:
|
||||
|
||||

|
||||
|
||||
产品新建成功后,可在产品列表页查看到:
|
||||
|
||||

|
||||
|
||||
1.3. 数据模板
|
||||
进入产品,点击【数据模板】,点击【导入JSON】,导入下面的JSON代码:
|
||||
```json
|
||||
{
|
||||
"version": "1.0",
|
||||
"properties": [
|
||||
{
|
||||
"id": "power_switch",
|
||||
"name": "电灯开关",
|
||||
"desc": "控制电灯开灭",
|
||||
"required": true,
|
||||
"mode": "rw",
|
||||
"define": {
|
||||
"type": "bool",
|
||||
"mapping": {
|
||||
"0": "关",
|
||||
"1": "开"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "brightness",
|
||||
"name": "光照强度",
|
||||
"desc": "",
|
||||
"mode": "r",
|
||||
"define": {
|
||||
"type": "int",
|
||||
"min": "0",
|
||||
"max": "20000",
|
||||
"start": "0",
|
||||
"step": "1",
|
||||
"unit": "lx"
|
||||
},
|
||||
"required": false
|
||||
}
|
||||
],
|
||||
"events": [],
|
||||
"actions": [],
|
||||
"profile": {
|
||||
"ProductId": "TCC64FUFGD",
|
||||
"CategoryId": "3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
导入之后自动根据json文件创建的属性如下:
|
||||
|
||||

|
||||
|
||||
1.4. 创建设备
|
||||
点击【设备调试】,进入后点击【新建设备】,创建真实设备:
|
||||
|
||||

|
||||
|
||||
创建成功之后进入设备,查看到产品ID、设备名称、设备秘钥,记录下来,一会终端程序会使用到。
|
||||
|
||||

|
||||
|
||||
|
||||
### 2. 基于TencentOS Tiny 完成设备侧应用开发
|
||||
|
||||
本实验代码下载链接:https://share.weiyun.com/4XXWaOzU 密码:cy4m5f
|
||||
|
||||
GD32V-RISC-V物联网操作系统TencentOS-Tiny案例实践指南(20211220)\SourceCode\EVB_LX_GD32V_TencentOS_Tiny_IoT_Explorer.rar
|
||||
|
||||
进入 < EVB_LX_GD32V_TencentOS_Tiny_IoT_Explorer> 目录,打开EVB_LX_GD32V_TencentOS_Tiny_IoT_Explorer工程。
|
||||
|
||||

|
||||
|
||||
2.1. 修改WIFI接入信息
|
||||
打开`main.c`文件编辑,在application_entry函数中修改要接入WIFI的名称和密码(建议使用手机热点,不要有特殊字符):
|
||||
|
||||

|
||||
|
||||
2.2. 修改云端对接信息
|
||||
终端的MQTT客户端需要对应的产品ID、设备ID,密码,我们使用前面从云端获取到的产品ID、设备名称、设备密钥,然后利用如下的python脚本来生成mqtt 用户名 密码等信息:
|
||||
|
||||
python脚本如下,也可以到https://github.com/OpenAtomFoundation/TencentOS-tiny/blob/master/tools/mqtt_config_gen.py 获取。
|
||||
|
||||
```
|
||||
#!/usr/bin/python
|
||||
# -*- coding: UTF-8 -*-
|
||||
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
import random
|
||||
import string
|
||||
import time
|
||||
from string import Template
|
||||
|
||||
# bind raw_input to input in Python 2
|
||||
try:
|
||||
input = raw_input
|
||||
except NameError:
|
||||
pass
|
||||
|
||||
product_id = input("product id:")
|
||||
dev_name = input("device name:")
|
||||
passwd = input("password:")
|
||||
sub = input("subscribe topic:[default:control]")
|
||||
if sub == "":
|
||||
sub = "control"
|
||||
pub = input("publish topic:[default:event]")
|
||||
if pub == "":
|
||||
pub = "event"
|
||||
|
||||
client_id = product_id + dev_name
|
||||
# expire time: 2^32 - 1 = 4294967295
|
||||
username = client_id+";21010406;12365;{}".format(4294967295)
|
||||
|
||||
def hmacsha1(content, passwd):
|
||||
passwd_byte = base64.b64decode(passwd)
|
||||
return hmac.new(passwd_byte, content, digestmod=hashlib.sha1).hexdigest()
|
||||
|
||||
username = username.encode("utf-8")
|
||||
passwd = passwd.encode("utf-8")
|
||||
sign = hmacsha1(username, passwd)
|
||||
|
||||
template = ('#ifndef TOS_MQTT_CONFIG_H\n'
|
||||
'#define TOS_MQTT_CONFIG_H\n'
|
||||
'\n'
|
||||
'#define MQTT_SERVER_IP "111.230.189.156"\n'
|
||||
'#define MQTT_SERVER_PORT "1883"\n'
|
||||
'#define MQTT_PRODUCT_ID "$product"\n'
|
||||
'#define MQTT_DEV_NAME "$dev"\n'
|
||||
'#define MQTT_CLIENT_ID "$product$dev"\n'
|
||||
'#define MQTT_USR_NAME "$product$dev;21010406;12365;4294967295"\n'
|
||||
'#define MQTT_PASSWORD "$sign;hmacsha1"\n'
|
||||
'#define MQTT_SUBSCRIBE_TOPIC "$product/$dev/$sub"\n'
|
||||
'#define MQTT_PUBLISH_TOPIC "$product/$dev/$pub"\n'
|
||||
'\n'
|
||||
'#endif\n'
|
||||
'\n')
|
||||
|
||||
src = Template(template)
|
||||
|
||||
d = {
|
||||
'product':product_id,
|
||||
'dev':dev_name,
|
||||
'sign':sign,
|
||||
'sub':sub,
|
||||
'pub':pub
|
||||
}
|
||||
|
||||
#do the substitution
|
||||
dst = src.substitute(d)
|
||||
print("===============Generate mqtt_config.h==================")
|
||||
print(dst)
|
||||
with open('mqtt_config.h', 'w') as f:
|
||||
f.write(dst)
|
||||
|
||||
|
||||
```
|
||||
|
||||
运行python脚本,一次输入产品ID、设备名称、设备密钥,就可以生成对用的mqtt信息了,如下图所示:
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
同样在main.c文件内,修改云端配置信息,使用上面脚本生成的信息替换:
|
||||
|
||||

|
||||
|
||||
|
||||
2.3. 编译工程
|
||||
点击编译按钮,编译整个工程并将程序下载到开发板,由于GD-Link的设计问题,这里下载到RISC-V开发板会非常慢,大家耐心等待一下。
|
||||
下载完成,打开热点,复位开发板,我们可以看到终端输出相关log,如下图:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 3. 云端平台查看设备数据
|
||||
回到腾讯云物联网开发平台,可以看到设备状态变为【在线】:
|
||||
|
||||

|
||||
|
||||
点击【设备日志】一栏,可以看到设备上报的光照强度:
|
||||
|
||||

|
||||
|
||||
点击【在线调试】一栏,修改属性【期望值】后点击【发送】,可以对灯泡进行远程控制。
|
||||
|
||||

|
||||
|
||||
### 4、腾讯连连小程序操作步骤
|
||||
1. 添加家庭
|
||||
手机端在【微信】搜索【腾讯连连】小程序,首次使用需要进入后点击【我的】->【家庭管理】,添加一个你喜欢的名称即可。
|
||||
|
||||
2. 添加调试设备
|
||||
返回【首页】,点击右上角“加号”图标:
|
||||
|
||||

|
||||
|
||||
进入后点击右上角扫码图标:
|
||||
|
||||

|
||||
|
||||
在腾讯云物联网开发平台进入【设备调试】,点击对应设备后的【二维码】:
|
||||
|
||||

|
||||
|
||||
腾讯连连扫描此二维码即可成功添加设备,添加成功之后如图:
|
||||
|
||||

|
||||
|
||||
点击此设备即可实时查看数据,并下发控制指令:
|
||||
|
||||

|
||||
|
||||
|
||||
3. 修改腾讯连连显示面板
|
||||
进入【交互开发】,点击【面板配置】一栏:
|
||||
|
||||

|
||||
|
||||
在此页面中可以自己根据喜好配置小程序显示面板,保存之后,在腾讯连连小程序删除设备,重新扫描绑定设备即可生效。
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 2. 定制开发板EVB_LX软件开发环境准备
|
||||
|
||||
### 2.1 Nuclei Studio IDE下载
|
||||
目前GD32V成熟的集成开发环境是由芯来科技提供的Nuclei Studio IDE,TencentOS tiny中的RISC-V项目也是基于Nuclei Studio IDE。首先我们下载Nuclei Studio IDE软件开发包,下载链接为https://www.nucleisys.com/download.php 如下图所示。
|
||||
|
||||

|
||||
|
||||
单击“Nuclei Studio:芯来集成开发环境(Nuclei Studio IDE)”即可进入下载页面。
|
||||
### 2.2 Nuclei Studio IDE安装
|
||||
下载下来的芯来集成开发环境(IDE)Nuclei Studio压缩包解压后包含若干个文件。
|
||||
Nuclei Studio软件包:该软件包中包含了Nuclei Studio IDE的软件。注意:具体版本以及文件名可能会不断更新;
|
||||
HBird_Driver.exe:此文件为芯来蜂鸟调试器的USB驱动安装文件,调试时需要安装此驱动使得其USB能够被识别;
|
||||
JDK安装文件:jdk-8u512-windows-x64.exe;
|
||||
|
||||
* 1.Nuclei Studio IDE是基于eclipse的,eclipse需要jdk环境支持,你的电脑如果没有安装jdk环境需要先安装jdk-8u512-windows-x64.exe,直接双击安装即可,如果已经安装可以跳过;
|
||||
* 2.安装HBird_Driver.exe
|
||||
* 3.Nuclei Studio软件本身为绿色软件无需安装,安装好JDK运行环境后,直接单击Nuclei Studio文件夹中eclipsec.exe即可启动Nuclei Studio。
|
||||
|
||||

|
||||
|
||||
直接单击NucleiStudio_IDE文件包中NucleiStudio文件夹下面的eclipse.exe可执行文件,即可启动Nuclei Studio;
|
||||
第一次启动Nuclei Studio后,将会弹出对话框要求设置Workspace目录,该目录将用于放置后续创建项目的文件夹,如图所示;
|
||||
|
||||

|
||||
|
||||
设置好Workspace目录之后,确保Workspace的路径中没有中文,单击“Launch”按钮,将会启动Nuclei Studio。第一次启动后的Nuclei Studio界面如图所示。
|
||||
|
||||

|
||||
|
||||
### 2.3 导入基于TencentOS tiny的RISC-V工程
|
||||
先下载TencentOS tiny项目,下载地址为:
|
||||
https://github.com/Tencent/TencentOS-tiny
|
||||
官方地址直接下载zip包或者直接使用下面的命令clone下来:
|
||||
|
||||
git clone https://github.com/Tencent/TencentOS-tiny.git
|
||||
|
||||
在菜单栏选择”File->Import“,出现如图对话框,选择”General“菜单下”Exit Project into Workspace“,设置导入方式,然后点击按钮”Next“。
|
||||
|
||||

|
||||
|
||||
选择导入的方式后,点击” Browse“按钮选择TencentOS tiny项目中GD32V工程路径。注意:进入到” TencentOS-tiny\board\TencentOS_tiny_EVB_LX\eclipse"这一级目录即可,如图所示。
|
||||
|
||||

|
||||
|
||||
### 2.4 编译下载调试基于TencentOS tiny的RISC-V工程
|
||||
|
||||
导入之后,就可看到TencentOS tiny的hello_world工程了,如图所示:
|
||||

|
||||
|
||||
Hello_world工程文件夹上右键 Debug As,选择Debug Configuration,配置调试参数,如下图所示:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
然后点击Debug即可进入调试窗口,如下图所示,可以进行单步、跳步执行,设置断点等
|
||||
|
||||

|
||||
|
|
@ -0,0 +1,263 @@
|
|||
# CH32V_EVB开发套件TencentOS Tiny 入门指南
|
||||
|
||||
| Revision | Date | Description |
|
||||
| -------- | --------- | ----------- |
|
||||
| 1.0 | 2022-05-15 | CH32V_EVB开发套件TencentOS Tiny 入门指南 |
|
||||
|
||||
## 一、定制开发板CH32V_EVB硬件简介
|
||||
|
||||
### 1.1 开发板简介
|
||||
|
||||
CH32V_EVB是腾讯物联网操作系统TencentOS tiny 团队联合沁恒微电子设计的一款物联网评估板,用于TencentOS tiny 基础内核、RISC-V IP核架构和IoT组件功能体验和评估。
|
||||
开发板实物如下图:
|
||||
|
||||

|
||||
|
||||
|
||||
### 1.2 开发板特性
|
||||
- 内置TencentOS Tiny开源物联网操作系统
|
||||
- 开发板采用沁恒RISC-V MCU CH32V307VCT6芯片,CH32V305/7系列是基于沁恒自研RISC-V架构微处理器青稞V4系列设计的32位工业级互联型微控制器,配备了硬件堆栈区、快速中断入口,在标准RISC-V基础上大大提高了中断响应速度。加入单精度浮点指令集,扩充堆栈区,具有更高的运算性能。扩展串口UART数量到8组,定时器到10组,其中4组高级定时器。提供USB2.0高速接口(480Mbps)并内置了PHY收发器,以太网MAC升级到千兆并集成了10M-PHY模块。
|
||||
- 64KB SRAM,256KB Flash
|
||||
- 板载Type-C接口WCH-LINK仿真器
|
||||
- 板载esp8266 WiFi模组,支持腾讯云固件
|
||||
- 板载以太网接口
|
||||
- 板载物联网俱乐部WAN Interface接口,可支持NB-IoT、WiFi、4G cat1、LoRa等模组
|
||||
- 板载物联网俱乐部E53 Interface接口,可扩展全系E53传感器以及音频模块;
|
||||
- 板载标准24P DVP摄像头接口,可支持最高500万像素摄像头;
|
||||
- 板载1.54寸 IPS高清显示屏,支持240*240分辨率;
|
||||
- 预留SD卡、用户按键、SPI Flash,
|
||||
- 扩展IO口,方便开发者扩展硬件模块
|
||||
|
||||
|
||||
|
||||
### 1.3 开发板硬件详解
|
||||
|
||||
#### 1.3.1 电源电路
|
||||
* 电源稳压电路
|
||||
外部USB输入电压一般为5V,但这并不能直接作为电源给开发板供电,CH32V_EVB上的元器件供电电压范围普遍在1.8V-3.6V,推荐电压均为3.3V,因此需要将5V的电平转换成3.3V供给开发板上数字IC使用,这里使用TLV62569DBVR作为3.3V稳压器芯片。
|
||||
TLV62569DBVR是TI出品的一款高效率脉冲宽度降压型DC/DC转换器。输入电压2.5V-5.5V,输出电压可调范围为:0.6V-5.5V,输出电流可以达到2A。在我们提供的电路中将输出调节至3.3V,让开发板正常工作。
|
||||

|
||||
|
||||
#### 1.3.2 CH32V最小系统电路
|
||||
单片机最小系统或者叫最小硬件单元电路,指用最少元器件组成的单片机可以正常工作的系统。最小系统基本由电源、单片机、晶振、按键复位电路、用户LED等接口组成,电源使用3.3V直接供电,其他部分原理图如下:
|
||||

|
||||
|
||||
#### 1.3.3 WCH-Link仿真器下载器电路
|
||||
板载仿真器可以让开发调试更方便。WCH-Link是沁恒微电子官方提供的MCU仿真器方案,可以支持CH32V系列risc-v MCU下载调试,也可以支持ARM Cortex M核下载调试,同时支持虚拟串口功能,电路如下:
|
||||

|
||||
|
||||
#### 1.3.4 LCD显示电路
|
||||
TFT LCD液晶显示模块用来向用户显示系统状态、参数或者要输入系统的功能。为了展示良好的视觉效果,开发板使用ST7789V 控制器驱动的TFT LCD显示屏,分辨率为240*240。该款LCD使用SPI接口,由于SPI接口空闲时引脚要上拉,因此下面的原理图中接了10k电阻上拉,然后才接入MCU引脚。
|
||||

|
||||
|
||||
#### 1.3.5 以太网电路
|
||||
开发板主控CH32V307芯片内置了以太网控制器,这里外围电路只需要使用一个RJ45以太网变压器 HY911105AE即可,HY911105AE带变压器和LED灯,电路如下图所示:
|
||||

|
||||
|
||||
#### 1.3.6 USB HOST/Device电路
|
||||
开发板主控CH32V307芯片内置了一个高速和低速USB控制器,这里开发板将两个UCB都通过TYPE-C口引出了,电路如下:
|
||||

|
||||
|
||||
#### 1.3.7 存储电路扩展
|
||||
开发板带有一个SPI Nor Flash芯片扩展和单bit SD卡扩展,可用于用户存储一部分数据和存储空间扩展,电路图如下:
|
||||

|
||||
|
||||
#### 1.3.8 多串口切换电路
|
||||
开发板带有多串口切换功能,通过跳线帽可以切换串口映射关系,通过组合,可以使用PC机上的串口助手发送AT命令来调试WAN口的通信模组或者板载WiFi;也可以使用正常模式通过MCU串口来控制WiFi和WAN口模组,同时wch-link虚拟串口连接PC可以做日志输出。串口切换电路图如下:
|
||||
|
||||

|
||||
|
||||
#### 1.3.9 E53 传感器扩展接口
|
||||
开发板设计有E53接口的传感器扩展板接口,该接口可兼容所有E53接口的传感器扩展板,实现不同物联网案例场景的快速搭建。该接口可接入UART、SPI、I2C、ADC等通信协议的传感器,也可以扩展音频模块,其原理图如下图所示。
|
||||

|
||||
|
||||
#### 1.3.10 WAN通信模块扩展接口
|
||||
开发板设计有通信扩展板的扩展接口,该接口可接入WIFI、NB-IoT、2G、腾讯定制IoT模组、LoRaWAN等不同通信方式的通信扩展板,以满足不同场景上云的需求,其原理图如下图所示。
|
||||

|
||||
|
||||
#### 1.3.11 ESP8266 WIFI电路
|
||||
|
||||
开发板板载了一个esp8266 WiFi模块,通过串口AT命令进行控制,电路如下图所示:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### 1.3.13 摄像头电路
|
||||
|
||||
开发板板载了标准的DVP 24P摄像头接口,可以接OV2640 OV5640等摄像头模组,MCU芯片内置DVP摄像头控制器,电路图和控制引脚参考如下:
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### 1.3.12 扩展IO
|
||||
|
||||
开发板多余的IO引脚全部引出,如下图所示:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
## 二、 定制开发板CH32V_EVB软件开发环境准备
|
||||
|
||||
### 2.1 MounRiver Studio IDE下载与安装
|
||||
|
||||
MounRiver Studio(MRS)是一款面向RISC-V、ARM等内核MCU的集成开发环境,提供专业嵌入式项目所需的开发、调试环境、烧录工具已经完善的项目管理能力,是目前使用相对方便的国产自研RISC-V开发环境。这里我们使用该IDE来进行risc-v相关应用开发。首先,我们到MounRiver Studio官网下载软件安装包,下载地址:http://www.mounriver.com/download
|
||||
|
||||

|
||||
|
||||
安装完成后打开软件可以进入到欢迎界面
|
||||
|
||||

|
||||
|
||||
|
||||
### 2.2 新建CH32V工程
|
||||
|
||||
菜单栏点击File->New->MounRiver project 开始创建工程
|
||||
|
||||

|
||||
|
||||
进入工程向导后,按照如下图所示选择芯片,填写工程信息。
|
||||
|
||||

|
||||
|
||||
完成后会生成工程,如图所示:
|
||||
|
||||

|
||||
|
||||
### 2.3 编译下载调试CH32V工程
|
||||
|
||||
MRS IDE默认集成了TencentOS Tiny工程模板,一键即可生成TencentOS TIny 内核基础工程,点击如下图所示图标编译工程,编译完成后可以在控制台输出看到编译结果。
|
||||
|
||||

|
||||
|
||||
如下图所示,使用USB线连接和PC机和开发板,点击debug按钮,就可以进入调试模式,程序下载到开发板上,可以打断点、单步、跳步执行,全速执行,查看寄存器,反汇编、内存等
|
||||
|
||||

|
||||
|
||||
全速运行后,可以看到串口助手打印TencentOS Tiny的日志信息,可以看到两个任务交替运行。
|
||||
|
||||

|
||||
|
||||
除了调试按钮外,我们也可以点击下载按钮直接将程序烧写到开发板上,如下图所示:
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
## 三、基于TencentOS Tiny 和CH32V_EVB开发板对接腾讯云物联网平台和腾讯连连小程序
|
||||
|
||||
基于TencentOS Tiny CH32V_EVB RISC-V 开发板要完成腾讯云IoT Explorer对接,需要完成两个部分的工作。
|
||||
一是:腾讯云IoT explorer 上完成项目、产品、设备创建、参数配置
|
||||
二是:基于TencentOS Tiny完成应用开发,向腾讯云上报业务数据。
|
||||
|
||||
|
||||
### 1. 云端操作步骤
|
||||
1.1. 新建项目
|
||||
登录[腾讯云物联网开发平台](https://cloud.tencent.com/product/iotexplorer),点击新建项目,填写项目名称和简介:
|
||||
|
||||

|
||||
|
||||
1.2. 新建产品
|
||||
点击项目名称进入到该项目中,点击新建产品:
|
||||
|
||||

|
||||
|
||||
产品新建成功后,可在产品列表页查看到:
|
||||
|
||||

|
||||
|
||||
1.3. 数据模板
|
||||
|
||||
平台自动创建的物模型(数据模板)如下:
|
||||
|
||||

|
||||
|
||||
1.4. 创建设备
|
||||
点击【设备调试】,进入后点击【新建设备】,创建真实设备:
|
||||
|
||||

|
||||
|
||||
创建成功之后进入设备,查看到产品ID、设备名称、设备秘钥,记录下来,一会终端程序会使用到。
|
||||
|
||||

|
||||
|
||||
|
||||
### 2. 基于TencentOS Tiny 完成设备侧应用开发
|
||||
|
||||
CH32V-RISC-V物联网操作系统TencentOS-Tiny案例实践指南
|
||||
|
||||
https://github.com/OpenAtomFoundation/TencentOS-tiny 上clone整个代码仓源码,进入 < TencentOS-tiny\board\TencentOS_Tiny_CH32V307_EVB> 目录,打开 CH32V_EVB_TencentOS_Tiny_IoT_Explorer工程。
|
||||
|
||||

|
||||
|
||||
2.1. 修改WIFI接入信息
|
||||
打开`mqtt_iot_explorer.c`文件编辑,在mqtt_demo_task函数中修改要接入WIFI的名称和密码(建议使用手机热点,不要有特殊字符):
|
||||
|
||||

|
||||
|
||||
2.2. 修改云端对接信息
|
||||
终端的MQTT客户端需要对应的产品ID、设备ID,密码,我们使用前面从云端获取到的产品ID、设备名称、设备密钥,
|
||||
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
2.3. 编译工程
|
||||
点击编译按钮,编译整个工程并将程序下载到开发板。下载完成,打开热点,复位开发板,我们可以看到终端输出相关log,如下图:
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
### 3. 云端平台查看设备数据
|
||||
回到腾讯云物联网开发平台,可以看到设备状态变为【在线】:
|
||||
|
||||

|
||||
|
||||
点击【设备日志】一栏,可以看到设备上报的光照强度:
|
||||
|
||||

|
||||
|
||||
点击【在线调试】一栏,修改属性【期望值】后点击【发送】,可以对灯泡进行远程控制。
|
||||
|
||||

|
||||
|
||||
### 4、腾讯连连小程序操作步骤
|
||||
1. 添加家庭
|
||||
手机端在【微信】搜索【腾讯连连】小程序,首次使用需要进入后点击【我的】->【家庭管理】,添加一个你喜欢的名称即可。
|
||||
|
||||
2. 添加调试设备
|
||||
返回【首页】,点击右上角“加号”图标:
|
||||
|
||||

|
||||
|
||||
进入后点击右上角扫码图标:
|
||||
|
||||

|
||||
|
||||
在腾讯云物联网开发平台进入【设备调试】,点击对应设备后的【二维码】:
|
||||
|
||||

|
||||
|
||||
腾讯连连扫描此二维码即可成功添加设备,添加成功之后如图:
|
||||
|
||||

|
||||
|
||||
点击此设备即可实时查看数据,并下发控制指令:
|
||||
|
||||

|
||||
|
||||
|
||||
3. 修改腾讯连连显示面板
|
||||
进入【交互开发】,点击【面板配置】一栏:
|
||||
|
||||

|
||||
|
||||
在此页面中可以自己根据喜好配置小程序显示面板,保存之后,在腾讯连连小程序删除设备,重新扫描绑定设备即可生效。
|
||||
|
||||
|
After Width: | Height: | Size: 2.0 MiB |
|
After Width: | Height: | Size: 78 KiB |
|
After Width: | Height: | Size: 521 KiB |
|
After Width: | Height: | Size: 42 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 71 KiB |
|
After Width: | Height: | Size: 131 KiB |
|
After Width: | Height: | Size: 37 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 74 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 21 KiB |
|
After Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 53 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 112 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 157 KiB |
|
After Width: | Height: | Size: 62 KiB |
|
After Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 83 KiB |
|
After Width: | Height: | Size: 92 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 87 KiB |